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