]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
Merge clang 7.0.1 and several follow-up changes
[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
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   MemberPointerInfo() = default;
105
106   MemberPointerInfo(TypeIndex ContainingType,
107                     PointerToMemberRepresentation Representation)
108       : ContainingType(ContainingType), Representation(Representation) {}
109
110   TypeIndex getContainingType() const { return ContainingType; }
111   PointerToMemberRepresentation getRepresentation() const {
112     return Representation;
113   }
114
115   TypeIndex ContainingType;
116   PointerToMemberRepresentation Representation;
117 };
118
119 class TypeRecord {
120 protected:
121   TypeRecord() = default;
122   explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
123
124 public:
125   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   explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
135   ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
136       : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
137         Modifiers(Modifiers) {}
138
139   TypeIndex getModifiedType() const { return ModifiedType; }
140   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   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         ArgumentList(ArgumentList) {}
157
158   TypeIndex getReturnType() const { return ReturnType; }
159   CallingConvention getCallConv() const { return CallConv; }
160   FunctionOptions getOptions() const { return Options; }
161   uint16_t getParameterCount() const { return ParameterCount; }
162   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   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         ThisPointerAdjustment(ThisPointerAdjustment) {}
186
187   TypeIndex getReturnType() const { return ReturnType; }
188   TypeIndex getClassType() const { return ClassType; }
189   TypeIndex getThisType() const { return ThisType; }
190   CallingConvention getCallConv() const { return CallConv; }
191   FunctionOptions getOptions() const { return Options; }
192   uint16_t getParameterCount() const { return ParameterCount; }
193   TypeIndex getArgumentList() const { return ArgumentList; }
194   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   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   explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
222   MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
223                          StringRef Name)
224       : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
225         FunctionType(FunctionType), Name(Name) {}
226
227   TypeIndex getClassType() const { return ClassType; }
228   TypeIndex getFunctionType() const { return FunctionType; }
229   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   explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
241
242   ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
243       : TypeRecord(Kind), ArgIndices(Indices) {}
244
245   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   explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
255
256   StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
257       : TypeRecord(Kind), StringIndices(Indices) {}
258
259   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   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         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         Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
294
295   TypeIndex getReferentType() const { return ReferentType; }
296
297   PointerKind getPointerKind() const {
298     return static_cast<PointerKind>((Attrs >> PointerKindShift) &
299                                     PointerKindMask);
300   }
301
302   PointerMode getMode() const {
303     return static_cast<PointerMode>((Attrs >> PointerModeShift) &
304                                     PointerModeMask);
305   }
306
307   PointerOptions getOptions() const {
308     return static_cast<PointerOptions>(Attrs);
309   }
310
311   uint8_t getSize() const {
312     return (Attrs >> PointerSizeShift) & PointerSizeMask;
313   }
314
315   MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
316
317   bool isPointerToMember() const {
318     return getMode() == PointerMode::PointerToDataMember ||
319            getMode() == PointerMode::PointerToMemberFunction;
320   }
321
322   bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
323   bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
324
325   bool isVolatile() const {
326     return !!(Attrs & uint32_t(PointerOptions::Volatile));
327   }
328
329   bool isUnaligned() const {
330     return !!(Attrs & uint32_t(PointerOptions::Unaligned));
331   }
332
333   bool isRestrict() const {
334     return !!(Attrs & uint32_t(PointerOptions::Restrict));
335   }
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                             uint8_t Size) {
349     uint32_t A = 0;
350     A |= static_cast<uint32_t>(PK);
351     A |= static_cast<uint32_t>(PO);
352     A |= (static_cast<uint32_t>(PM) << PointerModeShift);
353     A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
354     return A;
355   }
356 };
357
358 // LF_NESTTYPE
359 class NestedTypeRecord : public TypeRecord {
360 public:
361   NestedTypeRecord() = default;
362   explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
363   NestedTypeRecord(TypeIndex Type, StringRef Name)
364       : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
365
366   TypeIndex getNestedType() const { return Type; }
367   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   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   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         IndexType(IndexType), Size(Size), Name(Name) {}
393
394   TypeIndex getElementType() const { return ElementType; }
395   TypeIndex getIndexType() const { return IndexType; }
396   uint64_t getSize() const { return Size; }
397   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   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         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   bool hasUniqueName() const {
421     return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
422   }
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   uint16_t getMemberCount() const { return MemberCount; }
433   ClassOptions getOptions() const { return Options; }
434   TypeIndex getFieldList() const { return FieldList; }
435   StringRef getName() const { return Name; }
436   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   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         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   TypeIndex getDerivationList() const { return DerivationList; }
470   TypeIndex getVTableShape() const { return VTableShape; }
471   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   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         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   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   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         UnderlyingType(UnderlyingType) {}
509
510   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   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         BitOffset(BitOffset) {}
523
524   TypeIndex getType() const { return Type; }
525   uint8_t getBitOffset() const { return BitOffset; }
526   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   explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
538   explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
539       : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
540   explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
541       : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
542
543   ArrayRef<VFTableSlotKind> getSlots() const {
544     if (!SlotsRef.empty())
545       return SlotsRef;
546     return Slots;
547   }
548
549   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   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   const GUID &getGuid() const { return Guid; }
567   uint32_t getAge() const { return Age; }
568   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   explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
580   StringIdRecord(TypeIndex Id, StringRef String)
581       : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
582
583   TypeIndex getId() const { return Id; }
584   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   explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
595   FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
596       : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
597         FunctionType(FunctionType), Name(Name) {}
598
599   TypeIndex getParentScope() const { return ParentScope; }
600   TypeIndex getFunctionType() const { return FunctionType; }
601   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   explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
613   UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
614       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
615         SourceFile(SourceFile), LineNumber(LineNumber) {}
616
617   TypeIndex getUDT() const { return UDT; }
618   TypeIndex getSourceFile() const { return SourceFile; }
619   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   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   TypeIndex getUDT() const { return UDT; }
637   TypeIndex getSourceFile() const { return SourceFile; }
638   uint32_t getLineNumber() const { return LineNumber; }
639   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   explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
652   BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
653       : TypeRecord(TypeRecordKind::BuildInfo),
654         ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
655
656   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   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   TypeIndex getCompleteClass() const { return CompleteClass; }
676   TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
677   uint32_t getVFPtrOffset() const { return VFPtrOffset; }
678   StringRef getName() const { return makeArrayRef(MethodNames).front(); }
679
680   ArrayRef<StringRef> getMethodNames() const {
681     return makeArrayRef(MethodNames).drop_front();
682   }
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   OneMethodRecord() = default;
694   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         Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
703
704   TypeIndex getType() const { return Type; }
705   MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
706   MethodOptions getOptions() const { return Attrs.getFlags(); }
707   MemberAccess getAccess() const { return Attrs.getAccess(); }
708   int32_t getVFTableOffset() const { return VFTableOffset; }
709   StringRef getName() const { return Name; }
710
711   bool isIntroducingVirtual() const {
712     return getMethodKind() == MethodKind::IntroducingVirtual ||
713            getMethodKind() == MethodKind::PureIntroducingVirtual;
714   }
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   explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
727   MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
728       : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
729
730   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   explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
740   OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
741                          StringRef Name)
742       : TypeRecord(TypeRecordKind::OverloadedMethod),
743         NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
744
745   uint16_t getNumOverloads() const { return NumOverloads; }
746   TypeIndex getMethodList() const { return MethodList; }
747   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   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         FieldOffset(Offset), Name(Name) {}
767
768   MemberAccess getAccess() const { return Attrs.getAccess(); }
769   TypeIndex getType() const { return Type; }
770   uint64_t getFieldOffset() const { return FieldOffset; }
771   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   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         Name(Name) {}
790
791   MemberAccess getAccess() const { return Attrs.getAccess(); }
792   TypeIndex getType() const { return Type; }
793   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   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         Value(std::move(Value)), Name(Name) {}
811
812   MemberAccess getAccess() const { return Attrs.getAccess(); }
813   APSInt getValue() const { return Value; }
814   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   explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
826   VFPtrRecord(TypeIndex Type)
827       : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
828
829   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   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         Offset(Offset) {}
845
846   MemberAccess getAccess() const { return Attrs.getAccess(); }
847   TypeIndex getBaseType() const { return Type; }
848   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   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         VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
870
871   MemberAccess getAccess() const { return Attrs.getAccess(); }
872   TypeIndex getBaseType() const { return BaseType; }
873   TypeIndex getVBPtrType() const { return VBPtrType; }
874   uint64_t getVBPtrOffset() const { return VBPtrOffset; }
875   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   explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
890   ListContinuationRecord(TypeIndex ContinuationIndex)
891       : TypeRecord(TypeRecordKind::ListContinuation),
892         ContinuationIndex(ContinuationIndex) {}
893
894   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   explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
904
905   uint32_t getStartTypeIndex() const { return StartTypeIndex; }
906   uint32_t getTypesCount() const { return TypesCount; }
907   uint32_t getSignature() const { return Signature; }
908   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   explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
921
922   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