Coverage Report

Created: 2018-11-16 02:38

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
Line
Count
Source (jump to first uncovered line)
1
//===- TypeRecord.h ---------------------------------------------*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
11
#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
12
13
#include "llvm/ADT/APSInt.h"
14
#include "llvm/ADT/ArrayRef.h"
15
#include "llvm/ADT/Optional.h"
16
#include "llvm/ADT/SmallVector.h"
17
#include "llvm/ADT/StringRef.h"
18
#include "llvm/ADT/iterator_range.h"
19
#include "llvm/DebugInfo/CodeView/CVRecord.h"
20
#include "llvm/DebugInfo/CodeView/CodeView.h"
21
#include "llvm/DebugInfo/CodeView/GUID.h"
22
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
23
#include "llvm/Support/BinaryStreamArray.h"
24
#include "llvm/Support/Endian.h"
25
#include <algorithm>
26
#include <cstdint>
27
#include <vector>
28
29
namespace llvm {
30
namespace codeview {
31
32
using support::little32_t;
33
using support::ulittle16_t;
34
using support::ulittle32_t;
35
36
using CVType = CVRecord<TypeLeafKind>;
37
using RemappedType = RemappedRecord<TypeLeafKind>;
38
39
struct CVMemberRecord {
40
  TypeLeafKind Kind;
41
  ArrayRef<uint8_t> Data;
42
};
43
using CVTypeArray = VarStreamArray<CVType>;
44
using CVTypeRange = iterator_range<CVTypeArray::Iterator>;
45
46
/// Equvalent to CV_fldattr_t in cvinfo.h.
47
struct MemberAttributes {
48
  uint16_t Attrs = 0;
49
50
  enum {
51
    MethodKindShift = 2,
52
  };
53
54
12.2k
  MemberAttributes() = default;
55
56
  explicit MemberAttributes(MemberAccess Access)
57
6.08k
      : Attrs(static_cast<uint16_t>(Access)) {}
58
59
458
  MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
60
458
    Attrs = static_cast<uint16_t>(Access);
61
458
    Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
62
458
    Attrs |= static_cast<uint16_t>(Flags);
63
458
  }
64
65
  /// Get the access specifier. Valid for any kind of member.
66
8.65k
  MemberAccess getAccess() const {
67
8.65k
    return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
68
8.65k
  }
69
70
  /// Indicates if a method is defined with friend, virtual, static, etc.
71
6.37k
  MethodKind getMethodKind() const {
72
6.37k
    return MethodKind(
73
6.37k
        (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
74
6.37k
        MethodKindShift);
75
6.37k
  }
76
77
  /// Get the flags that are not included in access control or method
78
  /// properties.
79
1.97k
  MethodOptions getFlags() const {
80
1.97k
    return MethodOptions(
81
1.97k
        unsigned(Attrs) &
82
1.97k
        ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
83
1.97k
  }
84
85
  /// Is this method virtual.
86
0
  bool isVirtual() const {
87
0
    auto MP = getMethodKind();
88
0
    return MP != MethodKind::Vanilla && MP != MethodKind::Friend &&
89
0
           MP != MethodKind::Static;
90
0
  }
91
92
  /// Does this member introduce a new virtual method.
93
0
  bool isIntroducedVirtual() const {
94
0
    auto MP = getMethodKind();
95
0
    return MP == MethodKind::IntroducingVirtual ||
96
0
           MP == MethodKind::PureIntroducingVirtual;
97
0
  }
98
};
99
100
// Does not correspond to any tag, this is the tail of an LF_POINTER record
101
// if it represents a member pointer.
102
class MemberPointerInfo {
103
public:
104
331
  MemberPointerInfo() = default;
105
106
  MemberPointerInfo(TypeIndex ContainingType,
107
                    PointerToMemberRepresentation Representation)
108
65
      : ContainingType(ContainingType), Representation(Representation) {}
109
110
31
  TypeIndex getContainingType() const { return ContainingType; }
111
21
  PointerToMemberRepresentation getRepresentation() const {
112
21
    return Representation;
113
21
  }
114
115
  TypeIndex ContainingType;
116
  PointerToMemberRepresentation Representation;
117
};
118
119
class TypeRecord {
120
protected:
121
  TypeRecord() = default;
122
37.2k
  explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
123
124
public:
125
10.9k
  TypeRecordKind getKind() const { return Kind; }
126
127
  TypeRecordKind Kind;
128
};
129
130
// LF_MODIFIER
131
class ModifierRecord : public TypeRecord {
132
public:
133
  ModifierRecord() = default;
134
297
  explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
135
  ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
136
      : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
137
75
        Modifiers(Modifiers) {}
138
139
159
  TypeIndex getModifiedType() const { return ModifiedType; }
140
165
  ModifierOptions getModifiers() const { return Modifiers; }
141
142
  TypeIndex ModifiedType;
143
  ModifierOptions Modifiers;
144
};
145
146
// LF_PROCEDURE
147
class ProcedureRecord : public TypeRecord {
148
public:
149
  ProcedureRecord() = default;
150
574
  explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
151
  ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
152
                  FunctionOptions Options, uint16_t ParameterCount,
153
                  TypeIndex ArgumentList)
154
      : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType),
155
        CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
156
219
        ArgumentList(ArgumentList) {}
157
158
455
  TypeIndex getReturnType() const { return ReturnType; }
159
202
  CallingConvention getCallConv() const { return CallConv; }
160
219
  FunctionOptions getOptions() const { return Options; }
161
219
  uint16_t getParameterCount() const { return ParameterCount; }
162
420
  TypeIndex getArgumentList() const { return ArgumentList; }
163
164
  TypeIndex ReturnType;
165
  CallingConvention CallConv;
166
  FunctionOptions Options;
167
  uint16_t ParameterCount;
168
  TypeIndex ArgumentList;
169
};
170
171
// LF_MFUNCTION
172
class MemberFunctionRecord : public TypeRecord {
173
public:
174
  MemberFunctionRecord() = default;
175
2.17k
  explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
176
177
  MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
178
                       TypeIndex ThisType, CallingConvention CallConv,
179
                       FunctionOptions Options, uint16_t ParameterCount,
180
                       TypeIndex ArgumentList, int32_t ThisPointerAdjustment)
181
      : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType),
182
        ClassType(ClassType), ThisType(ThisType), CallConv(CallConv),
183
        Options(Options), ParameterCount(ParameterCount),
184
        ArgumentList(ArgumentList),
185
142
        ThisPointerAdjustment(ThisPointerAdjustment) {}
186
187
920
  TypeIndex getReturnType() const { return ReturnType; }
188
836
  TypeIndex getClassType() const { return ClassType; }
189
419
  TypeIndex getThisType() const { return ThisType; }
190
419
  CallingConvention getCallConv() const { return CallConv; }
191
542
  FunctionOptions getOptions() const { return Options; }
192
460
  uint16_t getParameterCount() const { return ParameterCount; }
193
836
  TypeIndex getArgumentList() const { return ArgumentList; }
194
460
  int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
195
196
  TypeIndex ReturnType;
197
  TypeIndex ClassType;
198
  TypeIndex ThisType;
199
  CallingConvention CallConv;
200
  FunctionOptions Options;
201
  uint16_t ParameterCount;
202
  TypeIndex ArgumentList;
203
  int32_t ThisPointerAdjustment;
204
};
205
206
// LF_LABEL
207
class LabelRecord : public TypeRecord {
208
public:
209
  LabelRecord() = default;
210
1
  explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
211
212
  LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
213
214
  LabelType Mode;
215
};
216
217
// LF_MFUNC_ID
218
class MemberFuncIdRecord : public TypeRecord {
219
public:
220
  MemberFuncIdRecord() = default;
221
129
  explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
222
  MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
223
                         StringRef Name)
224
      : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
225
91
        FunctionType(FunctionType), Name(Name) {}
226
227
65
  TypeIndex getClassType() const { return ClassType; }
228
65
  TypeIndex getFunctionType() const { return FunctionType; }
229
101
  StringRef getName() const { return Name; }
230
231
  TypeIndex ClassType;
232
  TypeIndex FunctionType;
233
  StringRef Name;
234
};
235
236
// LF_ARGLIST
237
class ArgListRecord : public TypeRecord {
238
public:
239
  ArgListRecord() = default;
240
1.15k
  explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
241
242
  ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
243
312
      : TypeRecord(Kind), ArgIndices(Indices) {}
244
245
837
  ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
246
247
  std::vector<TypeIndex> ArgIndices;
248
};
249
250
// LF_SUBSTR_LIST
251
class StringListRecord : public TypeRecord {
252
public:
253
  StringListRecord() = default;
254
88
  explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
255
256
  StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
257
      : TypeRecord(Kind), StringIndices(Indices) {}
258
259
48
  ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
260
261
  std::vector<TypeIndex> StringIndices;
262
};
263
264
// LF_POINTER
265
class PointerRecord : public TypeRecord {
266
public:
267
  static const uint32_t PointerKindShift = 0;
268
  static const uint32_t PointerKindMask = 0x1F;
269
270
  static const uint32_t PointerModeShift = 5;
271
  static const uint32_t PointerModeMask = 0x07;
272
273
  static const uint32_t PointerOptionMask = 0xFF;
274
275
  static const uint32_t PointerSizeShift = 13;
276
  static const uint32_t PointerSizeMask = 0xFF;
277
278
  PointerRecord() = default;
279
1.90k
  explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
280
281
  PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
282
      : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
283
        Attrs(Attrs) {}
284
285
  PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
286
                PointerOptions PO, uint8_t Size)
287
      : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
288
192
        Attrs(calcAttrs(PK, PM, PO, Size)) {}
289
290
  PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
291
                PointerOptions PO, uint8_t Size, const MemberPointerInfo &MPI)
292
      : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
293
65
        Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
294
295
846
  TypeIndex getReferentType() const { return ReferentType; }
296
297
954
  PointerKind getPointerKind() const {
298
954
    return static_cast<PointerKind>((Attrs >> PointerKindShift) &
299
954
                                    PointerKindMask);
300
954
  }
301
302
8.07k
  PointerMode getMode() const {
303
8.07k
    return static_cast<PointerMode>((Attrs >> PointerModeShift) &
304
8.07k
                                    PointerModeMask);
305
8.07k
  }
306
307
1.14k
  PointerOptions getOptions() const {
308
1.14k
    return static_cast<PointerOptions>(Attrs);
309
1.14k
  }
310
311
448
  uint8_t getSize() const {
312
448
    return (Attrs >> PointerSizeShift) & PointerSizeMask;
313
448
  }
314
315
38
  MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
316
317
2.83k
  bool isPointerToMember() const {
318
2.83k
    return getMode() == PointerMode::PointerToDataMember ||
319
2.83k
           
getMode() == PointerMode::PointerToMemberFunction2.79k
;
320
2.83k
  }
321
322
419
  bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
323
831
  bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
324
325
831
  bool isVolatile() const {
326
831
    return !!(Attrs & uint32_t(PointerOptions::Volatile));
327
831
  }
328
329
831
  bool isUnaligned() const {
330
831
    return !!(Attrs & uint32_t(PointerOptions::Unaligned));
331
831
  }
332
333
831
  bool isRestrict() const {
334
831
    return !!(Attrs & uint32_t(PointerOptions::Restrict));
335
831
  }
336
337
  TypeIndex ReferentType;
338
  uint32_t Attrs;
339
  Optional<MemberPointerInfo> MemberInfo;
340
341
  void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
342
                uint8_t Size) {
343
    Attrs = calcAttrs(PK, PM, PO, Size);
344
  }
345
346
private:
347
  static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
348
264
                            uint8_t Size) {
349
264
    uint32_t A = 0;
350
264
    A |= static_cast<uint32_t>(PK);
351
264
    A |= static_cast<uint32_t>(PO);
352
264
    A |= (static_cast<uint32_t>(PM) << PointerModeShift);
353
264
    A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
354
264
    return A;
355
264
  }
356
};
357
358
// LF_NESTTYPE
359
class NestedTypeRecord : public TypeRecord {
360
public:
361
  NestedTypeRecord() = default;
362
339
  explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
363
  NestedTypeRecord(TypeIndex Type, StringRef Name)
364
61
      : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
365
366
71
  TypeIndex getNestedType() const { return Type; }
367
71
  StringRef getName() const { return Name; }
368
369
  TypeIndex Type;
370
  StringRef Name;
371
};
372
373
// LF_FIELDLIST
374
class FieldListRecord : public TypeRecord {
375
public:
376
  FieldListRecord() = default;
377
1.31k
  explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
378
  explicit FieldListRecord(ArrayRef<uint8_t> Data)
379
      : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
380
381
  ArrayRef<uint8_t> Data;
382
};
383
384
// LF_ARRAY
385
class ArrayRecord : public TypeRecord {
386
public:
387
  ArrayRecord() = default;
388
171
  explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
389
  ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
390
              StringRef Name)
391
      : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
392
68
        IndexType(IndexType), Size(Size), Name(Name) {}
393
394
39
  TypeIndex getElementType() const { return ElementType; }
395
37
  TypeIndex getIndexType() const { return IndexType; }
396
37
  uint64_t getSize() const { return Size; }
397
64
  StringRef getName() const { return Name; }
398
399
  TypeIndex ElementType;
400
  TypeIndex IndexType;
401
  uint64_t Size;
402
  StringRef Name;
403
};
404
405
class TagRecord : public TypeRecord {
406
protected:
407
  TagRecord() = default;
408
3.47k
  explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
409
  TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
410
            TypeIndex FieldList, StringRef Name, StringRef UniqueName)
411
      : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
412
416
        FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
413
414
public:
415
  static const int HfaKindShift = 11;
416
  static const int HfaKindMask = 0x1800;
417
  static const int WinRTKindShift = 14;
418
  static const int WinRTKindMask = 0xC000;
419
420
7.71k
  bool hasUniqueName() const {
421
7.71k
    return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
422
7.71k
  }
423
424
  bool isNested() const {
425
    return (Options & ClassOptions::Nested) != ClassOptions::None;
426
  }
427
428
  bool isForwardRef() const {
429
    return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
430
  }
431
432
  bool containsNestedClass() const {
433
    return (Options & ClassOptions::ContainsNestedClass) != ClassOptions::None;
434
  }
435
436
  bool isScoped() const {
437
    return (Options & ClassOptions::Scoped) != ClassOptions::None;
438
  }
439
440
714
  uint16_t getMemberCount() const { return MemberCount; }
441
4.16k
  ClassOptions getOptions() const { return Options; }
442
714
  TypeIndex getFieldList() const { return FieldList; }
443
4.82k
  StringRef getName() const { return Name; }
444
1.37k
  StringRef getUniqueName() const { return UniqueName; }
445
446
  uint16_t MemberCount;
447
  ClassOptions Options;
448
  TypeIndex FieldList;
449
  StringRef Name;
450
  StringRef UniqueName;
451
};
452
453
// LF_CLASS, LF_STRUCTURE, LF_INTERFACE
454
class ClassRecord : public TagRecord {
455
public:
456
  ClassRecord() = default;
457
3.04k
  explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
458
  ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
459
              TypeIndex FieldList, TypeIndex DerivationList,
460
              TypeIndex VTableShape, uint64_t Size, StringRef Name,
461
              StringRef UniqueName)
462
      : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
463
295
        DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
464
465
  HfaKind getHfa() const {
466
    uint16_t Value = static_cast<uint16_t>(Options);
467
    Value = (Value & HfaKindMask) >> HfaKindShift;
468
    return static_cast<HfaKind>(Value);
469
  }
470
471
  WindowsRTClassKind getWinRTKind() const {
472
    uint16_t Value = static_cast<uint16_t>(Options);
473
    Value = (Value & WinRTKindMask) >> WinRTKindShift;
474
    return static_cast<WindowsRTClassKind>(Value);
475
  }
476
477
628
  TypeIndex getDerivationList() const { return DerivationList; }
478
628
  TypeIndex getVTableShape() const { return VTableShape; }
479
687
  uint64_t getSize() const { return Size; }
480
481
  TypeIndex DerivationList;
482
  TypeIndex VTableShape;
483
  uint64_t Size;
484
};
485
486
// LF_UNION
487
struct UnionRecord : public TagRecord {
488
  UnionRecord() = default;
489
43
  explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
490
  UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
491
              uint64_t Size, StringRef Name, StringRef UniqueName)
492
      : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
493
                  UniqueName),
494
64
        Size(Size) {}
495
496
  HfaKind getHfa() const {
497
    uint16_t Value = static_cast<uint16_t>(Options);
498
    Value = (Value & HfaKindMask) >> HfaKindShift;
499
    return static_cast<HfaKind>(Value);
500
  }
501
502
22
  uint64_t getSize() const { return Size; }
503
504
  uint64_t Size;
505
};
506
507
// LF_ENUM
508
class EnumRecord : public TagRecord {
509
public:
510
  EnumRecord() = default;
511
388
  explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
512
  EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
513
             StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
514
      : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
515
                  UniqueName),
516
57
        UnderlyingType(UnderlyingType) {}
517
518
472
  TypeIndex getUnderlyingType() const { return UnderlyingType; }
519
520
  TypeIndex UnderlyingType;
521
};
522
523
// LF_BITFIELD
524
class BitFieldRecord : public TypeRecord {
525
public:
526
  BitFieldRecord() = default;
527
22
  explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
528
  BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
529
      : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
530
57
        BitOffset(BitOffset) {}
531
532
7
  TypeIndex getType() const { return Type; }
533
7
  uint8_t getBitOffset() const { return BitOffset; }
534
7
  uint8_t getBitSize() const { return BitSize; }
535
536
  TypeIndex Type;
537
  uint8_t BitSize;
538
  uint8_t BitOffset;
539
};
540
541
// LF_VTSHAPE
542
class VFTableShapeRecord : public TypeRecord {
543
public:
544
  VFTableShapeRecord() = default;
545
94
  explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
546
  explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
547
9
      : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
548
  explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
549
      : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
550
551
53
  ArrayRef<VFTableSlotKind> getSlots() const {
552
53
    if (!SlotsRef.empty())
553
9
      return SlotsRef;
554
44
    return Slots;
555
44
  }
556
557
36
  uint32_t getEntryCount() const { return getSlots().size(); }
558
559
  ArrayRef<VFTableSlotKind> SlotsRef;
560
  std::vector<VFTableSlotKind> Slots;
561
};
562
563
// LF_TYPESERVER2
564
class TypeServer2Record : public TypeRecord {
565
public:
566
  TypeServer2Record() = default;
567
9
  explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
568
  TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
569
      : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
570
    assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
571
    ::memcpy(Guid.Guid, GuidStr.data(), 16);
572
  }
573
574
7
  const GUID &getGuid() const { return Guid; }
575
0
  uint32_t getAge() const { return Age; }
576
7
  StringRef getName() const { return Name; }
577
578
  GUID Guid;
579
  uint32_t Age;
580
  StringRef Name;
581
};
582
583
// LF_STRING_ID
584
class StringIdRecord : public TypeRecord {
585
public:
586
  StringIdRecord() = default;
587
1.32k
  explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
588
  StringIdRecord(TypeIndex Id, StringRef String)
589
429
      : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
590
591
540
  TypeIndex getId() const { return Id; }
592
1.05k
  StringRef getString() const { return String; }
593
594
  TypeIndex Id;
595
  StringRef String;
596
};
597
598
// LF_FUNC_ID
599
class FuncIdRecord : public TypeRecord {
600
public:
601
  FuncIdRecord() = default;
602
564
  explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
603
  FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
604
      : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
605
261
        FunctionType(FunctionType), Name(Name) {}
606
607
279
  TypeIndex getParentScope() const { return ParentScope; }
608
279
  TypeIndex getFunctionType() const { return FunctionType; }
609
457
  StringRef getName() const { return Name; }
610
611
  TypeIndex ParentScope;
612
  TypeIndex FunctionType;
613
  StringRef Name;
614
};
615
616
// LF_UDT_SRC_LINE
617
class UdtSourceLineRecord : public TypeRecord {
618
public:
619
  UdtSourceLineRecord() = default;
620
942
  explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
621
  UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
622
      : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
623
159
        SourceFile(SourceFile), LineNumber(LineNumber) {}
624
625
921
  TypeIndex getUDT() const { return UDT; }
626
385
  TypeIndex getSourceFile() const { return SourceFile; }
627
385
  uint32_t getLineNumber() const { return LineNumber; }
628
629
  TypeIndex UDT;
630
  TypeIndex SourceFile;
631
  uint32_t LineNumber;
632
};
633
634
// LF_UDT_MOD_SRC_LINE
635
class UdtModSourceLineRecord : public TypeRecord {
636
public:
637
  UdtModSourceLineRecord() = default;
638
36
  explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
639
  UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
640
                         uint32_t LineNumber, uint16_t Module)
641
      : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
642
        SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
643
644
14
  TypeIndex getUDT() const { return UDT; }
645
0
  TypeIndex getSourceFile() const { return SourceFile; }
646
0
  uint32_t getLineNumber() const { return LineNumber; }
647
0
  uint16_t getModule() const { return Module; }
648
649
  TypeIndex UDT;
650
  TypeIndex SourceFile;
651
  uint32_t LineNumber;
652
  uint16_t Module;
653
};
654
655
// LF_BUILDINFO
656
class BuildInfoRecord : public TypeRecord {
657
public:
658
  BuildInfoRecord() = default;
659
308
  explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
660
  BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
661
      : TypeRecord(TypeRecordKind::BuildInfo),
662
183
        ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
663
664
326
  ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
665
666
  /// Indices of known build info arguments.
667
  enum BuildInfoArg {
668
    CurrentDirectory, ///< Absolute CWD path
669
    BuildTool,        ///< Absolute compiler path
670
    SourceFile,       ///< Path to main source file, relative or absolute
671
    TypeServerPDB,    ///< Absolute path of type server PDB (/Fd)
672
    CommandLine,      ///< Full canonical command line (maybe -cc1)
673
    MaxArgs
674
  };
675
676
  SmallVector<TypeIndex, MaxArgs> ArgIndices;
677
};
678
679
// LF_VFTABLE
680
class VFTableRecord : public TypeRecord {
681
public:
682
  VFTableRecord() = default;
683
15
  explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
684
  VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
685
                uint32_t VFPtrOffset, StringRef Name,
686
                ArrayRef<StringRef> Methods)
687
      : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
688
        OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
689
    MethodNames.push_back(Name);
690
    MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
691
  }
692
693
7
  TypeIndex getCompleteClass() const { return CompleteClass; }
694
7
  TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
695
7
  uint32_t getVFPtrOffset() const { return VFPtrOffset; }
696
11
  StringRef getName() const { return makeArrayRef(MethodNames).front(); }
697
698
7
  ArrayRef<StringRef> getMethodNames() const {
699
7
    return makeArrayRef(MethodNames).drop_front();
700
7
  }
701
702
  TypeIndex CompleteClass;
703
  TypeIndex OverriddenVFTable;
704
  uint32_t VFPtrOffset;
705
  std::vector<StringRef> MethodNames;
706
};
707
708
// LF_ONEMETHOD
709
class OneMethodRecord : public TypeRecord {
710
public:
711
616
  OneMethodRecord() = default;
712
841
  explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
713
  OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
714
                  StringRef Name)
715
      : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
716
        VFTableOffset(VFTableOffset), Name(Name) {}
717
  OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
718
                  MethodOptions Options, int32_t VFTableOffset, StringRef Name)
719
      : TypeRecord(TypeRecordKind::OneMethod), Type(Type),
720
458
        Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
721
722
401
  TypeIndex getType() const { return Type; }
723
4.80k
  MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
724
401
  MethodOptions getOptions() const { return Attrs.getFlags(); }
725
401
  MemberAccess getAccess() const { return Attrs.getAccess(); }
726
21
  int32_t getVFTableOffset() const { return VFTableOffset; }
727
189
  StringRef getName() const { return Name; }
728
729
2.23k
  bool isIntroducingVirtual() const {
730
2.23k
    return getMethodKind() == MethodKind::IntroducingVirtual ||
731
2.23k
           
getMethodKind() == MethodKind::PureIntroducingVirtual2.16k
;
732
2.23k
  }
733
734
  TypeIndex Type;
735
  MemberAttributes Attrs;
736
  int32_t VFTableOffset;
737
  StringRef Name;
738
};
739
740
// LF_METHODLIST
741
class MethodOverloadListRecord : public TypeRecord {
742
public:
743
  MethodOverloadListRecord() = default;
744
489
  explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
745
  MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
746
50
      : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
747
748
87
  ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
749
750
  std::vector<OneMethodRecord> Methods;
751
};
752
753
/// For method overload sets.  LF_METHOD
754
class OverloadedMethodRecord : public TypeRecord {
755
public:
756
  OverloadedMethodRecord() = default;
757
481
  explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
758
  OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
759
                         StringRef Name)
760
      : TypeRecord(TypeRecordKind::OverloadedMethod),
761
50
        NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
762
763
87
  uint16_t getNumOverloads() const { return NumOverloads; }
764
87
  TypeIndex getMethodList() const { return MethodList; }
765
87
  StringRef getName() const { return Name; }
766
767
  uint16_t NumOverloads;
768
  TypeIndex MethodList;
769
  StringRef Name;
770
};
771
772
// LF_MEMBER
773
class DataMemberRecord : public TypeRecord {
774
public:
775
  DataMemberRecord() = default;
776
2.42k
  explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
777
  DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
778
                   StringRef Name)
779
      : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
780
        FieldOffset(Offset), Name(Name) {}
781
  DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
782
                   StringRef Name)
783
      : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
784
153
        FieldOffset(Offset), Name(Name) {}
785
786
505
  MemberAccess getAccess() const { return Attrs.getAccess(); }
787
505
  TypeIndex getType() const { return Type; }
788
505
  uint64_t getFieldOffset() const { return FieldOffset; }
789
505
  StringRef getName() const { return Name; }
790
791
  MemberAttributes Attrs;
792
  TypeIndex Type;
793
  uint64_t FieldOffset;
794
  StringRef Name;
795
};
796
797
// LF_STMEMBER
798
class StaticDataMemberRecord : public TypeRecord {
799
public:
800
  StaticDataMemberRecord() = default;
801
270
  explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
802
  StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
803
      : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
804
        Name(Name) {}
805
  StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
806
      : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
807
53
        Name(Name) {}
808
809
43
  MemberAccess getAccess() const { return Attrs.getAccess(); }
810
43
  TypeIndex getType() const { return Type; }
811
43
  StringRef getName() const { return Name; }
812
813
  MemberAttributes Attrs;
814
  TypeIndex Type;
815
  StringRef Name;
816
};
817
818
// LF_ENUMERATE
819
class EnumeratorRecord : public TypeRecord {
820
public:
821
  EnumeratorRecord() = default;
822
8.03k
  explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
823
  EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
824
      : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
825
        Value(std::move(Value)), Name(Name) {}
826
  EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
827
      : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
828
5.75k
        Value(std::move(Value)), Name(Name) {}
829
830
6.10k
  MemberAccess getAccess() const { return Attrs.getAccess(); }
831
6.10k
  APSInt getValue() const { return Value; }
832
6.10k
  StringRef getName() const { return Name; }
833
834
  MemberAttributes Attrs;
835
  APSInt Value;
836
  StringRef Name;
837
};
838
839
// LF_VFUNCTAB
840
class VFPtrRecord : public TypeRecord {
841
public:
842
  VFPtrRecord() = default;
843
23
  explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
844
  VFPtrRecord(TypeIndex Type)
845
62
      : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
846
847
16
  TypeIndex getType() const { return Type; }
848
849
  TypeIndex Type;
850
};
851
852
// LF_BCLASS, LF_BINTERFACE
853
class BaseClassRecord : public TypeRecord {
854
public:
855
  BaseClassRecord() = default;
856
33
  explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
857
  BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
858
      : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
859
        Offset(Offset) {}
860
  BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
861
      : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
862
64
        Offset(Offset) {}
863
864
21
  MemberAccess getAccess() const { return Attrs.getAccess(); }
865
21
  TypeIndex getBaseType() const { return Type; }
866
21
  uint64_t getBaseOffset() const { return Offset; }
867
868
  MemberAttributes Attrs;
869
  TypeIndex Type;
870
  uint64_t Offset;
871
};
872
873
// LF_VBCLASS, LF_IVBCLASS
874
class VirtualBaseClassRecord : public TypeRecord {
875
public:
876
  VirtualBaseClassRecord() = default;
877
25
  explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
878
  VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
879
                         TypeIndex BaseType, TypeIndex VBPtrType,
880
                         uint64_t Offset, uint64_t Index)
881
      : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
882
        VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
883
  VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
884
                         TypeIndex BaseType, TypeIndex VBPtrType,
885
                         uint64_t Offset, uint64_t Index)
886
      : TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
887
58
        VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
888
889
15
  MemberAccess getAccess() const { return Attrs.getAccess(); }
890
15
  TypeIndex getBaseType() const { return BaseType; }
891
15
  TypeIndex getVBPtrType() const { return VBPtrType; }
892
15
  uint64_t getVBPtrOffset() const { return VBPtrOffset; }
893
15
  uint64_t getVTableIndex() const { return VTableIndex; }
894
895
  MemberAttributes Attrs;
896
  TypeIndex BaseType;
897
  TypeIndex VBPtrType;
898
  uint64_t VBPtrOffset;
899
  uint64_t VTableIndex;
900
};
901
902
/// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
903
/// together. The first will end in an LF_INDEX record that points to the next.
904
class ListContinuationRecord : public TypeRecord {
905
public:
906
  ListContinuationRecord() = default;
907
4
  explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
908
  ListContinuationRecord(TypeIndex ContinuationIndex)
909
      : TypeRecord(TypeRecordKind::ListContinuation),
910
        ContinuationIndex(ContinuationIndex) {}
911
912
4
  TypeIndex getContinuationIndex() const { return ContinuationIndex; }
913
914
  TypeIndex ContinuationIndex;
915
};
916
917
// LF_PRECOMP
918
class PrecompRecord : public TypeRecord {
919
public:
920
  PrecompRecord() = default;
921
5
  explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
922
923
1
  uint32_t getStartTypeIndex() const { return StartTypeIndex; }
924
6
  uint32_t getTypesCount() const { return TypesCount; }
925
10
  uint32_t getSignature() const { return Signature; }
926
5
  StringRef getPrecompFilePath() const { return PrecompFilePath; }
927
928
  uint32_t StartTypeIndex;
929
  uint32_t TypesCount;
930
  uint32_t Signature;
931
  StringRef PrecompFilePath;
932
};
933
934
// LF_ENDPRECOMP
935
class EndPrecompRecord : public TypeRecord {
936
public:
937
  EndPrecompRecord() = default;
938
5
  explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
939
940
4
  uint32_t getSignature() const { return Signature; }
941
942
  uint32_t Signature;
943
};
944
945
} // end namespace codeview
946
} // end namespace llvm
947
948
#endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H