Coverage Report

Created: 2018-07-18 22:01

/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
10.8k
  MemberAttributes() = default;
55
56
  explicit MemberAttributes(MemberAccess Access)
57
6.06k
      : Attrs(static_cast<uint16_t>(Access)) {}
58
59
445
  MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
60
445
    Attrs = static_cast<uint16_t>(Access);
61
445
    Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
62
445
    Attrs |= static_cast<uint16_t>(Flags);
63
445
  }
64
65
  /// Get the access specifier. Valid for any kind of member.
66
7.68k
  MemberAccess getAccess() const {
67
7.68k
    return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
68
7.68k
  }
69
70
  /// Indicates if a method is defined with friend, virtual, static, etc.
71
4.52k
  MethodKind getMethodKind() const {
72
4.52k
    return MethodKind(
73
4.52k
        (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
74
4.52k
        MethodKindShift);
75
4.52k
  }
76
77
  /// Get the flags that are not included in access control or method
78
  /// properties.
79
1.01k
  MethodOptions getFlags() const {
80
1.01k
    return MethodOptions(
81
1.01k
        unsigned(Attrs) &
82
1.01k
        ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
83
1.01k
  }
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
317
  MemberPointerInfo() = default;
105
106
  MemberPointerInfo(TypeIndex ContainingType,
107
                    PointerToMemberRepresentation Representation)
108
64
      : ContainingType(ContainingType), Representation(Representation) {}
109
110
31
  TypeIndex getContainingType() const { return ContainingType; }
111
16
  PointerToMemberRepresentation getRepresentation() const {
112
16
    return Representation;
113
16
  }
114
115
  TypeIndex ContainingType;
116
  PointerToMemberRepresentation Representation;
117
};
118
119
class TypeRecord {
120
protected:
121
  TypeRecord() = default;
122
31.7k
  explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
123
124
public:
125
10.1k
  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
246
  explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
135
  ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
136
      : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
137
74
        Modifiers(Modifiers) {}
138
139
149
  TypeIndex getModifiedType() const { return ModifiedType; }
140
149
  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
483
  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
193
        ArgumentList(ArgumentList) {}
157
158
380
  TypeIndex getReturnType() const { return ReturnType; }
159
182
  CallingConvention getCallConv() const { return CallConv; }
160
182
  FunctionOptions getOptions() const { return Options; }
161
182
  uint16_t getParameterCount() const { return ParameterCount; }
162
380
  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
1.70k
  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
136
        ThisPointerAdjustment(ThisPointerAdjustment) {}
186
187
804
  TypeIndex getReturnType() const { return ReturnType; }
188
804
  TypeIndex getClassType() const { return ClassType; }
189
403
  TypeIndex getThisType() const { return ThisType; }
190
403
  CallingConvention getCallConv() const { return CallConv; }
191
403
  FunctionOptions getOptions() const { return Options; }
192
403
  uint16_t getParameterCount() const { return ParameterCount; }
193
804
  TypeIndex getArgumentList() const { return ArgumentList; }
194
403
  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
90
        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
970
  explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
241
242
  ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
243
281
      : TypeRecord(Kind), ArgIndices(Indices) {}
244
245
683
  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
82
  explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
255
256
  StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
257
      : TypeRecord(Kind), StringIndices(Indices) {}
258
259
47
  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.53k
  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
173
        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
64
        Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
294
295
805
  TypeIndex getReferentType() const { return ReferentType; }
296
297
622
  PointerKind getPointerKind() const {
298
622
    return static_cast<PointerKind>((Attrs >> PointerKindShift) &
299
622
                                    PointerKindMask);
300
622
  }
301
302
6.31k
  PointerMode getMode() const {
303
6.31k
    return static_cast<PointerMode>((Attrs >> PointerModeShift) &
304
6.31k
                                    PointerModeMask);
305
6.31k
  }
306
307
622
  PointerOptions getOptions() const {
308
622
    return static_cast<PointerOptions>(Attrs);
309
622
  }
310
311
402
  uint8_t getSize() const {
312
402
    return (Attrs >> PointerSizeShift) & PointerSizeMask;
313
402
  }
314
315
31
  MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
316
317
2.32k
  bool isPointerToMember() const {
318
2.32k
    return getMode() == PointerMode::PointerToDataMember ||
319
2.32k
           
getMode() == PointerMode::PointerToMemberFunction2.28k
;
320
2.32k
  }
321
322
402
  bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
323
790
  bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
324
325
790
  bool isVolatile() const {
326
790
    return !!(Attrs & uint32_t(PointerOptions::Volatile));
327
790
  }
328
329
790
  bool isUnaligned() const {
330
790
    return !!(Attrs & uint32_t(PointerOptions::Unaligned));
331
790
  }
332
333
790
  bool isRestrict() const {
334
790
    return !!(Attrs & uint32_t(PointerOptions::Restrict));
335
790
  }
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
244
                            uint8_t Size) {
349
244
    uint32_t A = 0;
350
244
    A |= static_cast<uint32_t>(PK);
351
244
    A |= static_cast<uint32_t>(PO);
352
244
    A |= (static_cast<uint32_t>(PM) << PointerModeShift);
353
244
    A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
354
244
    return A;
355
244
  }
356
};
357
358
// LF_NESTTYPE
359
class NestedTypeRecord : public TypeRecord {
360
public:
361
  NestedTypeRecord() = default;
362
286
  explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
363
  NestedTypeRecord(TypeIndex Type, StringRef Name)
364
58
      : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
365
366
69
  TypeIndex getNestedType() const { return Type; }
367
69
  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
959
  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
161
  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
64
        IndexType(IndexType), Size(Size), Name(Name) {}
393
394
37
  TypeIndex getElementType() const { return ElementType; }
395
37
  TypeIndex getIndexType() const { return IndexType; }
396
37
  uint64_t getSize() const { return Size; }
397
62
  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
2.74k
  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
382
        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
3.13k
  bool hasUniqueName() const {
421
3.13k
    return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
422
3.13k
  }
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
686
  uint16_t getMemberCount() const { return MemberCount; }
433
879
  ClassOptions getOptions() const { return Options; }
434
686
  TypeIndex getFieldList() const { return FieldList; }
435
1.62k
  StringRef getName() const { return Name; }
436
633
  StringRef getUniqueName() const { return UniqueName; }
437
438
  uint16_t MemberCount;
439
  ClassOptions Options;
440
  TypeIndex FieldList;
441
  StringRef Name;
442
  StringRef UniqueName;
443
};
444
445
// LF_CLASS, LF_STRUCTURE, LF_INTERFACE
446
class ClassRecord : public TagRecord {
447
public:
448
  ClassRecord() = default;
449
2.36k
  explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
450
  ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
451
              TypeIndex FieldList, TypeIndex DerivationList,
452
              TypeIndex VTableShape, uint64_t Size, StringRef Name,
453
              StringRef UniqueName)
454
      : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
455
273
        DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
456
457
  HfaKind getHfa() const {
458
    uint16_t Value = static_cast<uint16_t>(Options);
459
    Value = (Value & HfaKindMask) >> HfaKindShift;
460
    return static_cast<HfaKind>(Value);
461
  }
462
463
  WindowsRTClassKind getWinRTKind() const {
464
    uint16_t Value = static_cast<uint16_t>(Options);
465
    Value = (Value & WinRTKindMask) >> WinRTKindShift;
466
    return static_cast<WindowsRTClassKind>(Value);
467
  }
468
469
610
  TypeIndex getDerivationList() const { return DerivationList; }
470
610
  TypeIndex getVTableShape() const { return VTableShape; }
471
610
  uint64_t getSize() const { return Size; }
472
473
  TypeIndex DerivationList;
474
  TypeIndex VTableShape;
475
  uint64_t Size;
476
};
477
478
// LF_UNION
479
struct UnionRecord : public TagRecord {
480
  UnionRecord() = default;
481
26
  explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
482
  UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
483
              uint64_t Size, StringRef Name, StringRef UniqueName)
484
      : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
485
                  UniqueName),
486
57
        Size(Size) {}
487
488
  HfaKind getHfa() const {
489
    uint16_t Value = static_cast<uint16_t>(Options);
490
    Value = (Value & HfaKindMask) >> HfaKindShift;
491
    return static_cast<HfaKind>(Value);
492
  }
493
494
13
  uint64_t getSize() const { return Size; }
495
496
  uint64_t Size;
497
};
498
499
// LF_ENUM
500
class EnumRecord : public TagRecord {
501
public:
502
  EnumRecord() = default;
503
346
  explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
504
  EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
505
             StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
506
      : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
507
                  UniqueName),
508
52
        UnderlyingType(UnderlyingType) {}
509
510
81
  TypeIndex getUnderlyingType() const { return UnderlyingType; }
511
512
  TypeIndex UnderlyingType;
513
};
514
515
// LF_BITFIELD
516
class BitFieldRecord : public TypeRecord {
517
public:
518
  BitFieldRecord() = default;
519
22
  explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
520
  BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
521
      : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
522
56
        BitOffset(BitOffset) {}
523
524
7
  TypeIndex getType() const { return Type; }
525
7
  uint8_t getBitOffset() const { return BitOffset; }
526
7
  uint8_t getBitSize() const { return BitSize; }
527
528
  TypeIndex Type;
529
  uint8_t BitSize;
530
  uint8_t BitOffset;
531
};
532
533
// LF_VTSHAPE
534
class VFTableShapeRecord : public TypeRecord {
535
public:
536
  VFTableShapeRecord() = default;
537
93
  explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
538
  explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
539
9
      : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
540
  explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
541
      : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
542
543
53
  ArrayRef<VFTableSlotKind> getSlots() const {
544
53
    if (!SlotsRef.empty())
545
9
      return SlotsRef;
546
44
    return Slots;
547
44
  }
548
549
36
  uint32_t getEntryCount() const { return getSlots().size(); }
550
551
  ArrayRef<VFTableSlotKind> SlotsRef;
552
  std::vector<VFTableSlotKind> Slots;
553
};
554
555
// LF_TYPESERVER2
556
class TypeServer2Record : public TypeRecord {
557
public:
558
  TypeServer2Record() = default;
559
5
  explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
560
  TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
561
      : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
562
    assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
563
    ::memcpy(Guid.Guid, GuidStr.data(), 16);
564
  }
565
566
3
  const GUID &getGuid() const { return Guid; }
567
0
  uint32_t getAge() const { return Age; }
568
3
  StringRef getName() const { return Name; }
569
570
  GUID Guid;
571
  uint32_t Age;
572
  StringRef Name;
573
};
574
575
// LF_STRING_ID
576
class StringIdRecord : public TypeRecord {
577
public:
578
  StringIdRecord() = default;
579
710
  explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
580
  StringIdRecord(TypeIndex Id, StringRef String)
581
143
      : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
582
583
250
  TypeIndex getId() const { return Id; }
584
471
  StringRef getString() const { return String; }
585
586
  TypeIndex Id;
587
  StringRef String;
588
};
589
590
// LF_FUNC_ID
591
class FuncIdRecord : public TypeRecord {
592
public:
593
  FuncIdRecord() = default;
594
490
  explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
595
  FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
596
      : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
597
230
        FunctionType(FunctionType), Name(Name) {}
598
599
258
  TypeIndex getParentScope() const { return ParentScope; }
600
258
  TypeIndex getFunctionType() const { return FunctionType; }
601
407
  StringRef getName() const { return Name; }
602
603
  TypeIndex ParentScope;
604
  TypeIndex FunctionType;
605
  StringRef Name;
606
};
607
608
// LF_UDT_SRC_LINE
609
class UdtSourceLineRecord : public TypeRecord {
610
public:
611
  UdtSourceLineRecord() = default;
612
896
  explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
613
  UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
614
      : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
615
141
        SourceFile(SourceFile), LineNumber(LineNumber) {}
616
617
440
  TypeIndex getUDT() const { return UDT; }
618
369
  TypeIndex getSourceFile() const { return SourceFile; }
619
369
  uint32_t getLineNumber() const { return LineNumber; }
620
621
  TypeIndex UDT;
622
  TypeIndex SourceFile;
623
  uint32_t LineNumber;
624
};
625
626
// LF_UDT_MOD_SRC_LINE
627
class UdtModSourceLineRecord : public TypeRecord {
628
public:
629
  UdtModSourceLineRecord() = default;
630
36
  explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
631
  UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
632
                         uint32_t LineNumber, uint16_t Module)
633
      : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
634
        SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
635
636
7
  TypeIndex getUDT() const { return UDT; }
637
0
  TypeIndex getSourceFile() const { return SourceFile; }
638
0
  uint32_t getLineNumber() const { return LineNumber; }
639
0
  uint16_t getModule() const { return Module; }
640
641
  TypeIndex UDT;
642
  TypeIndex SourceFile;
643
  uint32_t LineNumber;
644
  uint16_t Module;
645
};
646
647
// LF_BUILDINFO
648
class BuildInfoRecord : public TypeRecord {
649
public:
650
  BuildInfoRecord() = default;
651
83
  explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
652
  BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
653
      : TypeRecord(TypeRecordKind::BuildInfo),
654
        ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
655
656
46
  ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
657
658
  SmallVector<TypeIndex, 4> ArgIndices;
659
};
660
661
// LF_VFTABLE
662
class VFTableRecord : public TypeRecord {
663
public:
664
  VFTableRecord() = default;
665
15
  explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
666
  VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
667
                uint32_t VFPtrOffset, StringRef Name,
668
                ArrayRef<StringRef> Methods)
669
      : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
670
        OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
671
    MethodNames.push_back(Name);
672
    MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
673
  }
674
675
7
  TypeIndex getCompleteClass() const { return CompleteClass; }
676
7
  TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
677
7
  uint32_t getVFPtrOffset() const { return VFPtrOffset; }
678
11
  StringRef getName() const { return makeArrayRef(MethodNames).front(); }
679
680
7
  ArrayRef<StringRef> getMethodNames() const {
681
7
    return makeArrayRef(MethodNames).drop_front();
682
7
  }
683
684
  TypeIndex CompleteClass;
685
  TypeIndex OverriddenVFTable;
686
  uint32_t VFPtrOffset;
687
  std::vector<StringRef> MethodNames;
688
};
689
690
// LF_ONEMETHOD
691
class OneMethodRecord : public TypeRecord {
692
public:
693
525
  OneMethodRecord() = default;
694
638
  explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
695
  OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
696
                  StringRef Name)
697
      : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
698
        VFTableOffset(VFTableOffset), Name(Name) {}
699
  OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
700
                  MethodOptions Options, int32_t VFTableOffset, StringRef Name)
701
      : TypeRecord(TypeRecordKind::OneMethod), Type(Type),
702
445
        Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
703
704
396
  TypeIndex getType() const { return Type; }
705
3.90k
  MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
706
396
  MethodOptions getOptions() const { return Attrs.getFlags(); }
707
396
  MemberAccess getAccess() const { return Attrs.getAccess(); }
708
21
  int32_t getVFTableOffset() const { return VFTableOffset; }
709
184
  StringRef getName() const { return Name; }
710
711
1.78k
  bool isIntroducingVirtual() const {
712
1.78k
    return getMethodKind() == MethodKind::IntroducingVirtual ||
713
1.78k
           
getMethodKind() == MethodKind::PureIntroducingVirtual1.72k
;
714
1.78k
  }
715
716
  TypeIndex Type;
717
  MemberAttributes Attrs;
718
  int32_t VFTableOffset;
719
  StringRef Name;
720
};
721
722
// LF_METHODLIST
723
class MethodOverloadListRecord : public TypeRecord {
724
public:
725
  MethodOverloadListRecord() = default;
726
398
  explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
727
  MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
728
49
      : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
729
730
87
  ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
731
732
  std::vector<OneMethodRecord> Methods;
733
};
734
735
/// For method overload sets.  LF_METHOD
736
class OverloadedMethodRecord : public TypeRecord {
737
public:
738
  OverloadedMethodRecord() = default;
739
385
  explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
740
  OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
741
                         StringRef Name)
742
      : TypeRecord(TypeRecordKind::OverloadedMethod),
743
49
        NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
744
745
87
  uint16_t getNumOverloads() const { return NumOverloads; }
746
87
  TypeIndex getMethodList() const { return MethodList; }
747
87
  StringRef getName() const { return Name; }
748
749
  uint16_t NumOverloads;
750
  TypeIndex MethodList;
751
  StringRef Name;
752
};
753
754
// LF_MEMBER
755
class DataMemberRecord : public TypeRecord {
756
public:
757
  DataMemberRecord() = default;
758
1.90k
  explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
759
  DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
760
                   StringRef Name)
761
      : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
762
        FieldOffset(Offset), Name(Name) {}
763
  DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
764
                   StringRef Name)
765
      : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
766
150
        FieldOffset(Offset), Name(Name) {}
767
768
504
  MemberAccess getAccess() const { return Attrs.getAccess(); }
769
504
  TypeIndex getType() const { return Type; }
770
504
  uint64_t getFieldOffset() const { return FieldOffset; }
771
504
  StringRef getName() const { return Name; }
772
773
  MemberAttributes Attrs;
774
  TypeIndex Type;
775
  uint64_t FieldOffset;
776
  StringRef Name;
777
};
778
779
// LF_STMEMBER
780
class StaticDataMemberRecord : public TypeRecord {
781
public:
782
  StaticDataMemberRecord() = default;
783
195
  explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
784
  StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
785
      : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
786
        Name(Name) {}
787
  StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
788
      : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
789
51
        Name(Name) {}
790
791
42
  MemberAccess getAccess() const { return Attrs.getAccess(); }
792
42
  TypeIndex getType() const { return Type; }
793
42
  StringRef getName() const { return Name; }
794
795
  MemberAttributes Attrs;
796
  TypeIndex Type;
797
  StringRef Name;
798
};
799
800
// LF_ENUMERATE
801
class EnumeratorRecord : public TypeRecord {
802
public:
803
  EnumeratorRecord() = default;
804
7.52k
  explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
805
  EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
806
      : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
807
        Value(std::move(Value)), Name(Name) {}
808
  EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
809
      : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
810
5.74k
        Value(std::move(Value)), Name(Name) {}
811
812
6.09k
  MemberAccess getAccess() const { return Attrs.getAccess(); }
813
6.09k
  APSInt getValue() const { return Value; }
814
6.09k
  StringRef getName() const { return Name; }
815
816
  MemberAttributes Attrs;
817
  APSInt Value;
818
  StringRef Name;
819
};
820
821
// LF_VFUNCTAB
822
class VFPtrRecord : public TypeRecord {
823
public:
824
  VFPtrRecord() = default;
825
23
  explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
826
  VFPtrRecord(TypeIndex Type)
827
61
      : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
828
829
16
  TypeIndex getType() const { return Type; }
830
831
  TypeIndex Type;
832
};
833
834
// LF_BCLASS, LF_BINTERFACE
835
class BaseClassRecord : public TypeRecord {
836
public:
837
  BaseClassRecord() = default;
838
32
  explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
839
  BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
840
      : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
841
        Offset(Offset) {}
842
  BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
843
      : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
844
62
        Offset(Offset) {}
845
846
20
  MemberAccess getAccess() const { return Attrs.getAccess(); }
847
20
  TypeIndex getBaseType() const { return Type; }
848
20
  uint64_t getBaseOffset() const { return Offset; }
849
850
  MemberAttributes Attrs;
851
  TypeIndex Type;
852
  uint64_t Offset;
853
};
854
855
// LF_VBCLASS, LF_IVBCLASS
856
class VirtualBaseClassRecord : public TypeRecord {
857
public:
858
  VirtualBaseClassRecord() = default;
859
25
  explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
860
  VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
861
                         TypeIndex BaseType, TypeIndex VBPtrType,
862
                         uint64_t Offset, uint64_t Index)
863
      : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
864
        VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
865
  VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
866
                         TypeIndex BaseType, TypeIndex VBPtrType,
867
                         uint64_t Offset, uint64_t Index)
868
      : TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
869
57
        VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
870
871
15
  MemberAccess getAccess() const { return Attrs.getAccess(); }
872
15
  TypeIndex getBaseType() const { return BaseType; }
873
15
  TypeIndex getVBPtrType() const { return VBPtrType; }
874
15
  uint64_t getVBPtrOffset() const { return VBPtrOffset; }
875
15
  uint64_t getVTableIndex() const { return VTableIndex; }
876
877
  MemberAttributes Attrs;
878
  TypeIndex BaseType;
879
  TypeIndex VBPtrType;
880
  uint64_t VBPtrOffset;
881
  uint64_t VTableIndex;
882
};
883
884
/// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
885
/// together. The first will end in an LF_INDEX record that points to the next.
886
class ListContinuationRecord : public TypeRecord {
887
public:
888
  ListContinuationRecord() = default;
889
4
  explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
890
  ListContinuationRecord(TypeIndex ContinuationIndex)
891
      : TypeRecord(TypeRecordKind::ListContinuation),
892
        ContinuationIndex(ContinuationIndex) {}
893
894
4
  TypeIndex getContinuationIndex() const { return ContinuationIndex; }
895
896
  TypeIndex ContinuationIndex;
897
};
898
899
// LF_PRECOMP
900
class PrecompRecord : public TypeRecord {
901
public:
902
  PrecompRecord() = default;
903
5
  explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
904
905
1
  uint32_t getStartTypeIndex() const { return StartTypeIndex; }
906
1
  uint32_t getTypesCount() const { return TypesCount; }
907
1
  uint32_t getSignature() const { return Signature; }
908
1
  StringRef getPrecompFilePath() const { return PrecompFilePath; }
909
910
  uint32_t StartTypeIndex;
911
  uint32_t TypesCount;
912
  uint32_t Signature;
913
  StringRef PrecompFilePath;
914
};
915
916
// LF_ENDPRECOMP
917
class EndPrecompRecord : public TypeRecord {
918
public:
919
  EndPrecompRecord() = default;
920
5
  explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
921
922
1
  uint32_t getSignature() const { return Signature; }
923
924
  uint32_t Signature;
925
};
926
} // end namespace codeview
927
} // end namespace llvm
928
929
#endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H