]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / DebugInfo / CodeView / TypeRecord.h
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
56   explicit MemberAttributes(MemberAccess Access)
57       : Attrs(static_cast<uint16_t>(Access)) {}
58
59   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.
66   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.
71   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.
79   MethodOptions getFlags() const {
80     return MethodOptions(
81         unsigned(Attrs) &
82         ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
83   }
84
85   /// Is this method virtual.
86   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.
93   bool isIntroducedVirtual() const {
94     auto MP = getMethodKind();
95     return MP == MethodKind::IntroducingVirtual ||
96            MP == MethodKind::PureIntroducingVirtual;
97   }
98
99   /// Is this method static.
100   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
111   MemberPointerInfo(TypeIndex ContainingType,
112                     PointerToMemberRepresentation Representation)
113       : ContainingType(ContainingType), Representation(Representation) {}
114
115   TypeIndex getContainingType() const { return ContainingType; }
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;
127   explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
128
129 public:
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;
139   explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
140   ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
141       : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
142         Modifiers(Modifiers) {}
143
144   TypeIndex getModifiedType() const { return ModifiedType; }
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;
155   explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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
163   TypeIndex getReturnType() const { return ReturnType; }
164   CallingConvention getCallConv() const { return CallConv; }
165   FunctionOptions getOptions() const { return Options; }
166   uint16_t getParameterCount() const { return ParameterCount; }
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;
180   explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
181
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
192   TypeIndex getReturnType() const { return ReturnType; }
193   TypeIndex getClassType() const { return ClassType; }
194   TypeIndex getThisType() const { return ThisType; }
195   CallingConvention getCallConv() const { return CallConv; }
196   FunctionOptions getOptions() const { return Options; }
197   uint16_t getParameterCount() const { return ParameterCount; }
198   TypeIndex getArgumentList() const { return ArgumentList; }
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;
215   explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
216
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;
226   explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
227   MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
228                          StringRef Name)
229       : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
230         FunctionType(FunctionType), Name(Name) {}
231
232   TypeIndex getClassType() const { return ClassType; }
233   TypeIndex getFunctionType() const { return FunctionType; }
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;
245   explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
246
247   ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
248       : TypeRecord(Kind), ArgIndices(Indices) {}
249
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;
259   explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
260
261   StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
262       : TypeRecord(Kind), StringIndices(Indices) {}
263
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;
288   explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
289
290   PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
291       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
292         Attrs(Attrs) {}
293
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
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
304   TypeIndex getReferentType() const { return ReferentType; }
305
306   PointerKind getPointerKind() const {
307     return static_cast<PointerKind>((Attrs >> PointerKindShift) &
308                                     PointerKindMask);
309   }
310
311   PointerMode getMode() const {
312     return static_cast<PointerMode>((Attrs >> PointerModeShift) &
313                                     PointerModeMask);
314   }
315
316   PointerOptions getOptions() const {
317     return static_cast<PointerOptions>(Attrs & PointerOptionMask);
318   }
319
320   uint8_t getSize() const {
321     return (Attrs >> PointerSizeShift) & PointerSizeMask;
322   }
323
324   MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
325
326   bool isPointerToMember() const {
327     return getMode() == PointerMode::PointerToDataMember ||
328            getMode() == PointerMode::PointerToMemberFunction;
329   }
330
331   bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
332   bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
333
334   bool isVolatile() const {
335     return !!(Attrs & uint32_t(PointerOptions::Volatile));
336   }
337
338   bool isUnaligned() const {
339     return !!(Attrs & uint32_t(PointerOptions::Unaligned));
340   }
341
342   bool isRestrict() const {
343     return !!(Attrs & uint32_t(PointerOptions::Restrict));
344   }
345
346   bool isLValueReferenceThisPtr() const {
347     return !!(Attrs & uint32_t(PointerOptions::LValueRefThisPointer));
348   }
349
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
358   void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
359                 uint8_t Size) {
360     Attrs = calcAttrs(PK, PM, PO, Size);
361   }
362
363 private:
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;
379   explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
380   NestedTypeRecord(TypeIndex Type, StringRef Name)
381       : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
382
383   TypeIndex getNestedType() const { return Type; }
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;
394   explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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;
405   explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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
411   TypeIndex getElementType() const { return ElementType; }
412   TypeIndex getIndexType() const { return IndexType; }
413   uint64_t getSize() const { return Size; }
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;
425   explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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
437   bool hasUniqueName() const {
438     return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
439   }
440
441   bool isNested() const {
442     return (Options & ClassOptions::Nested) != ClassOptions::None;
443   }
444
445   bool isForwardRef() const {
446     return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
447   }
448
449   bool containsNestedClass() const {
450     return (Options & ClassOptions::ContainsNestedClass) != ClassOptions::None;
451   }
452
453   bool isScoped() const {
454     return (Options & ClassOptions::Scoped) != ClassOptions::None;
455   }
456
457   uint16_t getMemberCount() const { return MemberCount; }
458   ClassOptions getOptions() const { return Options; }
459   TypeIndex getFieldList() const { return FieldList; }
460   StringRef getName() const { return Name; }
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;
474   explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
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
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
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
494   TypeIndex getDerivationList() const { return DerivationList; }
495   TypeIndex getVTableShape() const { return VTableShape; }
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;
506   explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
507   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
513   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
519   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;
528   explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
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
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;
544   explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
545   BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
546       : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
547         BitOffset(BitOffset) {}
548
549   TypeIndex getType() const { return Type; }
550   uint8_t getBitOffset() const { return BitOffset; }
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;
562   explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
563   explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
564       : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
565   explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
566       : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
567
568   ArrayRef<VFTableSlotKind> getSlots() const {
569     if (!SlotsRef.empty())
570       return SlotsRef;
571     return Slots;
572   }
573
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;
584   explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
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
591   const GUID &getGuid() const { return Guid; }
592   uint32_t getAge() const { return Age; }
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;
604   explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
605   StringIdRecord(TypeIndex Id, StringRef String)
606       : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
607
608   TypeIndex getId() const { return Id; }
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;
619   explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
620   FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
621       : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
622         FunctionType(FunctionType), Name(Name) {}
623
624   TypeIndex getParentScope() const { return ParentScope; }
625   TypeIndex getFunctionType() const { return FunctionType; }
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;
637   explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
638   UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
639       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
640         SourceFile(SourceFile), LineNumber(LineNumber) {}
641
642   TypeIndex getUDT() const { return UDT; }
643   TypeIndex getSourceFile() const { return SourceFile; }
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;
655   explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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
661   TypeIndex getUDT() const { return UDT; }
662   TypeIndex getSourceFile() const { return SourceFile; }
663   uint32_t getLineNumber() const { return LineNumber; }
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;
676   explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
677   BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
678       : TypeRecord(TypeRecordKind::BuildInfo),
679         ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
680
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;
700   explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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
710   TypeIndex getCompleteClass() const { return CompleteClass; }
711   TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
712   uint32_t getVFPtrOffset() const { return VFPtrOffset; }
713   StringRef getName() const { return makeArrayRef(MethodNames).front(); }
714
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;
729   explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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) {}
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
739   TypeIndex getType() const { return Type; }
740   MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
741   MethodOptions getOptions() const { return Attrs.getFlags(); }
742   MemberAccess getAccess() const { return Attrs.getAccess(); }
743   int32_t getVFTableOffset() const { return VFTableOffset; }
744   StringRef getName() const { return Name; }
745
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;
761   explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
762   MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
763       : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
764
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;
774   explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
775   OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
776                          StringRef Name)
777       : TypeRecord(TypeRecordKind::OverloadedMethod),
778         NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
779
780   uint16_t getNumOverloads() const { return NumOverloads; }
781   TypeIndex getMethodList() const { return MethodList; }
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;
793   explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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) {}
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
803   MemberAccess getAccess() const { return Attrs.getAccess(); }
804   TypeIndex getType() const { return Type; }
805   uint64_t getFieldOffset() const { return FieldOffset; }
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;
818   explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
819   StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
820       : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
821         Name(Name) {}
822   StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
823       : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
824         Name(Name) {}
825
826   MemberAccess getAccess() const { return Attrs.getAccess(); }
827   TypeIndex getType() const { return Type; }
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;
839   explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
840   EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
841       : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
842         Value(std::move(Value)), Name(Name) {}
843   EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
844       : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
845         Value(std::move(Value)), Name(Name) {}
846
847   MemberAccess getAccess() const { return Attrs.getAccess(); }
848   APSInt getValue() const { return Value; }
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;
860   explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
861   VFPtrRecord(TypeIndex Type)
862       : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
863
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;
873   explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
874   BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
875       : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
876         Offset(Offset) {}
877   BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
878       : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
879         Offset(Offset) {}
880
881   MemberAccess getAccess() const { return Attrs.getAccess(); }
882   TypeIndex getBaseType() const { return Type; }
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;
894   explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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) {}
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
906   MemberAccess getAccess() const { return Attrs.getAccess(); }
907   TypeIndex getBaseType() const { return BaseType; }
908   TypeIndex getVBPtrType() const { return VBPtrType; }
909   uint64_t getVBPtrOffset() const { return VBPtrOffset; }
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;
924   explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
925   ListContinuationRecord(TypeIndex ContinuationIndex)
926       : TypeRecord(TypeRecordKind::ListContinuation),
927         ContinuationIndex(ContinuationIndex) {}
928
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;
938   explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
939
940   uint32_t getStartTypeIndex() const { return StartTypeIndex; }
941   uint32_t getTypesCount() const { return TypesCount; }
942   uint32_t getSignature() const { return Signature; }
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;
955   explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
956
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