Coverage Report

Created: 2019-07-24 05:18

/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
35.8k
  MemberAttributes() = default;
54
55
  explicit MemberAttributes(MemberAccess Access)
56
11.9k
      : Attrs(static_cast<uint16_t>(Access)) {}
57
58
537
  MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
59
537
    Attrs = static_cast<uint16_t>(Access);
60
537
    Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
61
537
    Attrs |= static_cast<uint16_t>(Flags);
62
537
  }
63
64
  /// Get the access specifier. Valid for any kind of member.
65
20.4k
  MemberAccess getAccess() const {
66
20.4k
    return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
67
20.4k
  }
68
69
  /// Indicates if a method is defined with friend, virtual, static, etc.
70
7.81k
  MethodKind getMethodKind() const {
71
7.81k
    return MethodKind(
72
7.81k
        (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
73
7.81k
        MethodKindShift);
74
7.81k
  }
75
76
  /// Get the flags that are not included in access control or method
77
  /// properties.
78
2.15k
  MethodOptions getFlags() const {
79
2.15k
    return MethodOptions(
80
2.15k
        unsigned(Attrs) &
81
2.15k
        ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
82
2.15k
  }
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
397
  MemberPointerInfo() = default;
109
110
  MemberPointerInfo(TypeIndex ContainingType,
111
                    PointerToMemberRepresentation Representation)
112
81
      : ContainingType(ContainingType), Representation(Representation) {}
113
114
77
  TypeIndex getContainingType() const { return ContainingType; }
115
51
  PointerToMemberRepresentation getRepresentation() const {
116
51
    return Representation;
117
51
  }
118
119
  TypeIndex ContainingType;
120
  PointerToMemberRepresentation Representation;
121
};
122
123
class TypeRecord {
124
protected:
125
  TypeRecord() = default;
126
74.2k
  explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
127
128
public:
129
18.3k
  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
407
  explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
139
  ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
140
      : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
141
99
        Modifiers(Modifiers) {}
142
143
239
  TypeIndex getModifiedType() const { return ModifiedType; }
144
245
  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
1.01k
  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
316
        ArgumentList(ArgumentList) {}
161
162
754
  TypeIndex getReturnType() const { return ReturnType; }
163
350
  CallingConvention getCallConv() const { return CallConv; }
164
367
  FunctionOptions getOptions() const { return Options; }
165
367
  uint16_t getParameterCount() const { return ParameterCount; }
166
719
  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.52k
  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
244
        ThisPointerAdjustment(ThisPointerAdjustment) {}
190
191
1.17k
  TypeIndex getReturnType() const { return ReturnType; }
192
1.09k
  TypeIndex getClassType() const { return ClassType; }
193
545
  TypeIndex getThisType() const { return ThisType; }
194
545
  CallingConvention getCallConv() const { return CallConv; }
195
668
  FunctionOptions getOptions() const { return Options; }
196
586
  uint16_t getParameterCount() const { return ParameterCount; }
197
1.09k
  TypeIndex getArgumentList() const { return ArgumentList; }
198
586
  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
0
  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
238
  explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
226
  MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
227
                         StringRef Name)
228
      : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
229
118
        FunctionType(FunctionType), Name(Name) {}
230
231
115
  TypeIndex getClassType() const { return ClassType; }
232
115
  TypeIndex getFunctionType() const { return FunctionType; }
233
177
  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.65k
  explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
245
246
  ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
247
511
      : TypeRecord(Kind), ArgIndices(Indices) {}
248
249
1.21k
  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
2.74k
  explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
288
289
  PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
290
      : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
291
0
        Attrs(Attrs) {}
292
293
  PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
294
                PointerOptions PO, uint8_t Size)
295
      : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
296
378
        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
81
        Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
302
303
1.49k
  TypeIndex getReferentType() const { return ReferentType; }
304
305
1.32k
  PointerKind getPointerKind() const {
306
1.32k
    return static_cast<PointerKind>((Attrs >> PointerKindShift) &
307
1.32k
                                    PointerKindMask);
308
1.32k
  }
309
310
13.1k
  PointerMode getMode() const {
311
13.1k
    return static_cast<PointerMode>((Attrs >> PointerModeShift) &
312
13.1k
                                    PointerModeMask);
313
13.1k
  }
314
315
  PointerOptions getOptions() const {
316
    return static_cast<PointerOptions>(Attrs & PointerOptionMask);
317
  }
318
319
797
  uint8_t getSize() const {
320
797
    return (Attrs >> PointerSizeShift) & PointerSizeMask;
321
797
  }
322
323
84
  MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
324
325
4.85k
  bool isPointerToMember() const {
326
4.85k
    return getMode() == PointerMode::PointerToDataMember ||
327
4.85k
           
getMode() == PointerMode::PointerToMemberFunction4.74k
;
328
4.85k
  }
329
330
768
  bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
331
1.46k
  bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
332
333
1.46k
  bool isVolatile() const {
334
1.46k
    return !!(Attrs & uint32_t(PointerOptions::Volatile));
335
1.46k
  }
336
337
1.46k
  bool isUnaligned() const {
338
1.46k
    return !!(Attrs & uint32_t(PointerOptions::Unaligned));
339
1.46k
  }
340
341
1.46k
  bool isRestrict() const {
342
1.46k
    return !!(Attrs & uint32_t(PointerOptions::Restrict));
343
1.46k
  }
344
345
768
  bool isLValueReferenceThisPtr() const {
346
768
    return !!(Attrs & uint32_t(PointerOptions::LValueRefThisPointer));
347
768
  }
348
349
768
  bool isRValueReferenceThisPtr() const {
350
768
    return !!(Attrs & uint32_t(PointerOptions::RValueRefThisPointer));
351
768
  }
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
466
                            uint8_t Size) {
365
466
    uint32_t A = 0;
366
466
    A |= static_cast<uint32_t>(PK);
367
466
    A |= static_cast<uint32_t>(PO);
368
466
    A |= (static_cast<uint32_t>(PM) << PointerModeShift);
369
466
    A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
370
466
    return A;
371
466
  }
372
};
373
374
// LF_NESTTYPE
375
class NestedTypeRecord : public TypeRecord {
376
public:
377
  NestedTypeRecord() = default;
378
398
  explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
379
  NestedTypeRecord(TypeIndex Type, StringRef Name)
380
75
      : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
381
382
95
  TypeIndex getNestedType() const { return Type; }
383
95
  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.88k
  explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
394
  explicit FieldListRecord(ArrayRef<uint8_t> Data)
395
0
      : 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
226
  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
79
        IndexType(IndexType), Size(Size), Name(Name) {}
409
410
61
  TypeIndex getElementType() const { return ElementType; }
411
59
  TypeIndex getIndexType() const { return IndexType; }
412
59
  uint64_t getSize() const { return Size; }
413
103
  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
4.60k
  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
669
        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
10.0k
  bool hasUniqueName() const {
437
10.0k
    return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
438
10.0k
  }
439
440
0
  bool isNested() const {
441
0
    return (Options & ClassOptions::Nested) != ClassOptions::None;
442
0
  }
443
444
0
  bool isForwardRef() const {
445
0
    return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
446
0
  }
447
448
0
  bool containsNestedClass() const {
449
0
    return (Options & ClassOptions::ContainsNestedClass) != ClassOptions::None;
450
0
  }
451
452
0
  bool isScoped() const {
453
0
    return (Options & ClassOptions::Scoped) != ClassOptions::None;
454
0
  }
455
456
1.14k
  uint16_t getMemberCount() const { return MemberCount; }
457
5.04k
  ClassOptions getOptions() const { return Options; }
458
1.14k
  TypeIndex getFieldList() const { return FieldList; }
459
6.21k
  StringRef getName() const { return Name; }
460
1.82k
  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.99k
  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
507
        DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
480
481
0
  HfaKind getHfa() const {
482
0
    uint16_t Value = static_cast<uint16_t>(Options);
483
0
    Value = (Value & HfaKindMask) >> HfaKindShift;
484
0
    return static_cast<HfaKind>(Value);
485
0
  }
486
487
0
  WindowsRTClassKind getWinRTKind() const {
488
0
    uint16_t Value = static_cast<uint16_t>(Options);
489
0
    Value = (Value & WinRTKindMask) >> WinRTKindShift;
490
0
    return static_cast<WindowsRTClassKind>(Value);
491
0
  }
492
493
989
  TypeIndex getDerivationList() const { return DerivationList; }
494
989
  TypeIndex getVTableShape() const { return VTableShape; }
495
1.04k
  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
155
  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
93
        Size(Size) {}
511
512
0
  HfaKind getHfa() const {
513
0
    uint16_t Value = static_cast<uint16_t>(Options);
514
0
    Value = (Value & HfaKindMask) >> HfaKindShift;
515
0
    return static_cast<HfaKind>(Value);
516
0
  }
517
518
70
  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
454
  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
69
        UnderlyingType(UnderlyingType) {}
533
534
492
  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
27
  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
132
  explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
562
  explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
563
17
      : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
564
  explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
565
0
      : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
566
567
108
  ArrayRef<VFTableSlotKind> getSlots() const {
568
108
    if (!SlotsRef.empty())
569
17
      return SlotsRef;
570
91
    return Slots;
571
91
  }
572
573
66
  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
29
  explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
584
  TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
585
0
      : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
586
0
    assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
587
0
    ::memcpy(Guid.Guid, GuidStr.data(), 16);
588
0
  }
589
590
6
  const GUID &getGuid() const { return Guid; }
591
0
  uint32_t getAge() const { return Age; }
592
0
  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
2.06k
  explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
604
  StringIdRecord(TypeIndex Id, StringRef String)
605
672
      : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
606
607
802
  TypeIndex getId() const { return Id; }
608
1.57k
  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
967
  explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
619
  FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
620
      : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
621
371
        FunctionType(FunctionType), Name(Name) {}
622
623
446
  TypeIndex getParentScope() const { return ParentScope; }
624
446
  TypeIndex getFunctionType() const { return FunctionType; }
625
717
  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
1.28k
  explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
637
  UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
638
      : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
639
289
        SourceFile(SourceFile), LineNumber(LineNumber) {}
640
641
1.29k
  TypeIndex getUDT() const { return UDT; }
642
605
  TypeIndex getSourceFile() const { return SourceFile; }
643
605
  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
21
  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
528
  explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
676
  BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
677
      : TypeRecord(TypeRecordKind::BuildInfo),
678
239
        ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
679
680
508
  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
645
  OneMethodRecord() = default;
728
1.09k
  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
0
        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
537
        Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
737
738
536
  TypeIndex getType() const { return Type; }
739
6.19k
  MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
740
536
  MethodOptions getOptions() const { return Attrs.getFlags(); }
741
536
  MemberAccess getAccess() const { return Attrs.getAccess(); }
742
41
  int32_t getVFTableOffset() const { return VFTableOffset; }
743
304
  StringRef getName() const { return Name; }
744
745
2.90k
  bool isIntroducingVirtual() const {
746
2.90k
    return getMethodKind() == MethodKind::IntroducingVirtual ||
747
2.90k
           
getMethodKind() == MethodKind::PureIntroducingVirtual2.75k
;
748
2.90k
  }
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
518
  explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
761
  MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
762
57
      : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
763
764
97
  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
504
  explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
774
  OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
775
                         StringRef Name)
776
      : TypeRecord(TypeRecordKind::OverloadedMethod),
777
57
        NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
778
779
97
  uint16_t getNumOverloads() const { return NumOverloads; }
780
97
  TypeIndex getMethodList() const { return MethodList; }
781
97
  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.75k
  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
0
        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
228
        FieldOffset(Offset), Name(Name) {}
801
802
634
  MemberAccess getAccess() const { return Attrs.getAccess(); }
803
634
  TypeIndex getType() const { return Type; }
804
634
  uint64_t getFieldOffset() const { return FieldOffset; }
805
634
  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
301
  explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
818
  StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
819
      : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
820
0
        Name(Name) {}
821
  StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
822
      : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
823
64
        Name(Name) {}
824
825
59
  MemberAccess getAccess() const { return Attrs.getAccess(); }
826
59
  TypeIndex getType() const { return Type; }
827
59
  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
30.9k
  explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
839
  EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
840
      : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
841
0
        Value(std::move(Value)), Name(Name) {}
842
  EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
843
      : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
844
11.4k
        Value(std::move(Value)), Name(Name) {}
845
846
17.5k
  MemberAccess getAccess() const { return Attrs.getAccess(); }
847
17.5k
  APSInt getValue() const { return Value; }
848
17.5k
  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
65
  explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
860
  VFPtrRecord(TypeIndex Type)
861
72
      : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
862
863
35
  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
92
  explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
873
  BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
874
      : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
875
0
        Offset(Offset) {}
876
  BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
877
      : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
878
80
        Offset(Offset) {}
879
880
51
  MemberAccess getAccess() const { return Attrs.getAccess(); }
881
51
  TypeIndex getBaseType() const { return Type; }
882
51
  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
51
  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
0
        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
64
        VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
904
905
26
  MemberAccess getAccess() const { return Attrs.getAccess(); }
906
26
  TypeIndex getBaseType() const { return BaseType; }
907
26
  TypeIndex getVBPtrType() const { return VBPtrType; }
908
26
  uint64_t getVBPtrOffset() const { return VBPtrOffset; }
909
26
  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
20
  explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
924
  ListContinuationRecord(TypeIndex ContinuationIndex)
925
      : TypeRecord(TypeRecordKind::ListContinuation),
926
        ContinuationIndex(ContinuationIndex) {}
927
928
12
  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
13
  explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
938
939
1
  uint32_t getStartTypeIndex() const { return StartTypeIndex; }
940
8
  uint32_t getTypesCount() const { return TypesCount; }
941
12
  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
5
  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