Coverage Report

Created: 2019-02-21 13:17

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