]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304149, and update
[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/DebugInfo/CodeView/CVRecord.h"
19 #include "llvm/DebugInfo/CodeView/CodeView.h"
20 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
21 #include "llvm/Support/BinaryStreamArray.h"
22 #include "llvm/Support/Endian.h"
23 #include <algorithm>
24 #include <cstdint>
25 #include <vector>
26
27 namespace llvm {
28
29 class BinaryStreamReader;
30
31 namespace codeview {
32
33 using support::little32_t;
34 using support::ulittle16_t;
35 using support::ulittle32_t;
36
37 typedef CVRecord<TypeLeafKind> CVType;
38 typedef RemappedRecord<TypeLeafKind> RemappedType;
39
40 struct CVMemberRecord {
41   TypeLeafKind Kind;
42   ArrayRef<uint8_t> Data;
43 };
44 typedef VarStreamArray<CVType> CVTypeArray;
45 typedef iterator_range<CVTypeArray::Iterator> CVTypeRange;
46
47 /// Equvalent to CV_fldattr_t in cvinfo.h.
48 struct MemberAttributes {
49   uint16_t Attrs = 0;
50   enum {
51     MethodKindShift = 2,
52   };
53   MemberAttributes() = default;
54
55   explicit MemberAttributes(MemberAccess Access)
56       : Attrs(static_cast<uint16_t>(Access)) {}
57
58   MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
59     Attrs = static_cast<uint16_t>(Access);
60     Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
61     Attrs |= static_cast<uint16_t>(Flags);
62   }
63
64   /// Get the access specifier. Valid for any kind of member.
65   MemberAccess getAccess() const {
66     return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
67   }
68
69   /// Indicates if a method is defined with friend, virtual, static, etc.
70   MethodKind getMethodKind() const {
71     return MethodKind(
72         (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
73         MethodKindShift);
74   }
75
76   /// Get the flags that are not included in access control or method
77   /// properties.
78   MethodOptions getFlags() const {
79     return MethodOptions(
80         unsigned(Attrs) &
81         ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
82   }
83
84   /// Is this method virtual.
85   bool isVirtual() const {
86     auto MP = getMethodKind();
87     return MP != MethodKind::Vanilla && MP != MethodKind::Friend &&
88            MP != MethodKind::Static;
89   }
90
91   /// Does this member introduce a new virtual method.
92   bool isIntroducedVirtual() const {
93     auto MP = getMethodKind();
94     return MP == MethodKind::IntroducingVirtual ||
95            MP == MethodKind::PureIntroducingVirtual;
96   }
97 };
98
99 // Does not correspond to any tag, this is the tail of an LF_POINTER record
100 // if it represents a member pointer.
101 class MemberPointerInfo {
102 public:
103   MemberPointerInfo() = default;
104
105   MemberPointerInfo(TypeIndex ContainingType,
106                     PointerToMemberRepresentation Representation)
107       : ContainingType(ContainingType), Representation(Representation) {}
108
109   TypeIndex getContainingType() const { return ContainingType; }
110   PointerToMemberRepresentation getRepresentation() const {
111     return Representation;
112   }
113
114   TypeIndex ContainingType;
115   PointerToMemberRepresentation Representation;
116 };
117
118 class TypeRecord {
119 protected:
120   TypeRecord() = default;
121   explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
122
123 public:
124   TypeRecordKind getKind() const { return Kind; }
125
126 private:
127   TypeRecordKind Kind;
128 };
129
130 // LF_MODIFIER
131 class ModifierRecord : public TypeRecord {
132 public:
133   explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
134   ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
135       : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
136         Modifiers(Modifiers) {}
137
138   TypeIndex getModifiedType() const { return ModifiedType; }
139   ModifierOptions getModifiers() const { return Modifiers; }
140
141   TypeIndex ModifiedType;
142   ModifierOptions Modifiers;
143 };
144
145 // LF_PROCEDURE
146 class ProcedureRecord : public TypeRecord {
147 public:
148   explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
149   ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
150                   FunctionOptions Options, uint16_t ParameterCount,
151                   TypeIndex ArgumentList)
152       : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType),
153         CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
154         ArgumentList(ArgumentList) {}
155
156   TypeIndex getReturnType() const { return ReturnType; }
157   CallingConvention getCallConv() const { return CallConv; }
158   FunctionOptions getOptions() const { return Options; }
159   uint16_t getParameterCount() const { return ParameterCount; }
160   TypeIndex getArgumentList() const { return ArgumentList; }
161
162   TypeIndex ReturnType;
163   CallingConvention CallConv;
164   FunctionOptions Options;
165   uint16_t ParameterCount;
166   TypeIndex ArgumentList;
167 };
168
169 // LF_MFUNCTION
170 class MemberFunctionRecord : public TypeRecord {
171 public:
172   explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
173
174   MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
175                        TypeIndex ThisType, CallingConvention CallConv,
176                        FunctionOptions Options, uint16_t ParameterCount,
177                        TypeIndex ArgumentList, int32_t ThisPointerAdjustment)
178       : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType),
179         ClassType(ClassType), ThisType(ThisType), CallConv(CallConv),
180         Options(Options), ParameterCount(ParameterCount),
181         ArgumentList(ArgumentList),
182         ThisPointerAdjustment(ThisPointerAdjustment) {}
183
184   TypeIndex getReturnType() const { return ReturnType; }
185   TypeIndex getClassType() const { return ClassType; }
186   TypeIndex getThisType() const { return ThisType; }
187   CallingConvention getCallConv() const { return CallConv; }
188   FunctionOptions getOptions() const { return Options; }
189   uint16_t getParameterCount() const { return ParameterCount; }
190   TypeIndex getArgumentList() const { return ArgumentList; }
191   int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
192
193   TypeIndex ReturnType;
194   TypeIndex ClassType;
195   TypeIndex ThisType;
196   CallingConvention CallConv;
197   FunctionOptions Options;
198   uint16_t ParameterCount;
199   TypeIndex ArgumentList;
200   int32_t ThisPointerAdjustment;
201 };
202
203 // LF_LABEL
204 class LabelRecord : public TypeRecord {
205 public:
206   explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
207
208   LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
209
210   LabelType Mode;
211 };
212
213 // LF_MFUNC_ID
214 class MemberFuncIdRecord : public TypeRecord {
215 public:
216   explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
217   MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
218                          StringRef Name)
219       : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
220         FunctionType(FunctionType), Name(Name) {}
221
222   TypeIndex getClassType() const { return ClassType; }
223   TypeIndex getFunctionType() const { return FunctionType; }
224   StringRef getName() const { return Name; }
225   TypeIndex ClassType;
226   TypeIndex FunctionType;
227   StringRef Name;
228 };
229
230 // LF_ARGLIST
231 class ArgListRecord : public TypeRecord {
232 public:
233   explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
234
235   ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
236       : TypeRecord(Kind), ArgIndices(Indices) {}
237
238   ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
239
240   std::vector<TypeIndex> ArgIndices;
241 };
242
243 // LF_SUBSTR_LIST
244 class StringListRecord : public TypeRecord {
245 public:
246   explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
247
248   StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
249       : TypeRecord(Kind), StringIndices(Indices) {}
250
251   ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
252
253   std::vector<TypeIndex> StringIndices;
254 };
255
256 // LF_POINTER
257 class PointerRecord : public TypeRecord {
258 public:
259   static const uint32_t PointerKindShift = 0;
260   static const uint32_t PointerKindMask = 0x1F;
261
262   static const uint32_t PointerModeShift = 5;
263   static const uint32_t PointerModeMask = 0x07;
264
265   static const uint32_t PointerOptionMask = 0xFF;
266
267   static const uint32_t PointerSizeShift = 13;
268   static const uint32_t PointerSizeMask = 0xFF;
269
270   explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
271
272   PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
273       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
274         Attrs(Attrs) {}
275
276   PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
277                 PointerOptions PO, uint8_t Size)
278       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
279         Attrs(calcAttrs(PK, PM, PO, Size)) {}
280
281   PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
282                 PointerOptions PO, uint8_t Size, const MemberPointerInfo &MPI)
283       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
284         Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
285
286   TypeIndex getReferentType() const { return ReferentType; }
287
288   PointerKind getPointerKind() const {
289     return static_cast<PointerKind>((Attrs >> PointerKindShift) &
290                                     PointerKindMask);
291   }
292
293   PointerMode getMode() const {
294     return static_cast<PointerMode>((Attrs >> PointerModeShift) &
295                                     PointerModeMask);
296   }
297
298   PointerOptions getOptions() const {
299     return static_cast<PointerOptions>(Attrs);
300   }
301
302   uint8_t getSize() const {
303     return (Attrs >> PointerSizeShift) & PointerSizeMask;
304   }
305
306   MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
307
308   bool isPointerToMember() const {
309     return getMode() == PointerMode::PointerToDataMember ||
310            getMode() == PointerMode::PointerToMemberFunction;
311   }
312
313   bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
314   bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
315
316   bool isVolatile() const {
317     return !!(Attrs & uint32_t(PointerOptions::Volatile));
318   }
319
320   bool isUnaligned() const {
321     return !!(Attrs & uint32_t(PointerOptions::Unaligned));
322   }
323
324   TypeIndex ReferentType;
325   uint32_t Attrs;
326
327   Optional<MemberPointerInfo> MemberInfo;
328
329 private:
330   static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
331                             uint8_t Size) {
332     uint32_t A = 0;
333     A |= static_cast<uint32_t>(PK);
334     A |= static_cast<uint32_t>(PO);
335     A |= (static_cast<uint32_t>(PM) << PointerModeShift);
336     A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
337     return A;
338   }
339 };
340
341 // LF_NESTTYPE
342 class NestedTypeRecord : public TypeRecord {
343 public:
344   explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
345   NestedTypeRecord(TypeIndex Type, StringRef Name)
346       : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
347
348   TypeIndex getNestedType() const { return Type; }
349   StringRef getName() const { return Name; }
350
351   TypeIndex Type;
352   StringRef Name;
353 };
354
355 // LF_FIELDLIST
356 class FieldListRecord : public TypeRecord {
357 public:
358   explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
359   explicit FieldListRecord(ArrayRef<uint8_t> Data)
360       : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
361
362   ArrayRef<uint8_t> Data;
363 };
364
365 // LF_ARRAY
366 class ArrayRecord : public TypeRecord {
367 public:
368   explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
369   ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
370               StringRef Name)
371       : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
372         IndexType(IndexType), Size(Size), Name(Name) {}
373
374   TypeIndex getElementType() const { return ElementType; }
375   TypeIndex getIndexType() const { return IndexType; }
376   uint64_t getSize() const { return Size; }
377   StringRef getName() const { return Name; }
378
379   TypeIndex ElementType;
380   TypeIndex IndexType;
381   uint64_t Size;
382   StringRef Name;
383 };
384
385 class TagRecord : public TypeRecord {
386 protected:
387   explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
388   TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
389             TypeIndex FieldList, StringRef Name, StringRef UniqueName)
390       : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
391         FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
392
393 public:
394   static const int HfaKindShift = 11;
395   static const int HfaKindMask = 0x1800;
396   static const int WinRTKindShift = 14;
397   static const int WinRTKindMask = 0xC000;
398
399   bool hasUniqueName() const {
400     return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
401   }
402
403   uint16_t getMemberCount() const { return MemberCount; }
404   ClassOptions getOptions() const { return Options; }
405   TypeIndex getFieldList() const { return FieldList; }
406   StringRef getName() const { return Name; }
407   StringRef getUniqueName() const { return UniqueName; }
408
409   uint16_t MemberCount;
410   ClassOptions Options;
411   TypeIndex FieldList;
412   StringRef Name;
413   StringRef UniqueName;
414 };
415
416 // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
417 class ClassRecord : public TagRecord {
418 public:
419   explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
420   ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
421               TypeIndex FieldList, TypeIndex DerivationList,
422               TypeIndex VTableShape, uint64_t Size, StringRef Name,
423               StringRef UniqueName)
424       : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
425         DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
426
427   HfaKind getHfa() const {
428     uint16_t Value = static_cast<uint16_t>(Options);
429     Value = (Value & HfaKindMask) >> HfaKindShift;
430     return static_cast<HfaKind>(Value);
431   }
432
433   WindowsRTClassKind getWinRTKind() const {
434     uint16_t Value = static_cast<uint16_t>(Options);
435     Value = (Value & WinRTKindMask) >> WinRTKindShift;
436     return static_cast<WindowsRTClassKind>(Value);
437   }
438
439   TypeIndex getDerivationList() const { return DerivationList; }
440   TypeIndex getVTableShape() const { return VTableShape; }
441   uint64_t getSize() const { return Size; }
442
443   TypeIndex DerivationList;
444   TypeIndex VTableShape;
445   uint64_t Size;
446 };
447
448 // LF_UNION
449 struct UnionRecord : public TagRecord {
450   explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
451   UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
452               uint64_t Size, StringRef Name, StringRef UniqueName)
453       : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
454                   UniqueName),
455         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   uint64_t getSize() const { return Size; }
464
465   uint64_t Size;
466 };
467
468 // LF_ENUM
469 class EnumRecord : public TagRecord {
470 public:
471   explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
472   EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
473              StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
474       : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
475                   UniqueName),
476         UnderlyingType(UnderlyingType) {}
477
478   TypeIndex getUnderlyingType() const { return UnderlyingType; }
479   TypeIndex UnderlyingType;
480 };
481
482 // LF_BITFIELD
483 class BitFieldRecord : public TypeRecord {
484 public:
485   explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
486   BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
487       : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
488         BitOffset(BitOffset) {}
489
490   TypeIndex getType() const { return Type; }
491   uint8_t getBitOffset() const { return BitOffset; }
492   uint8_t getBitSize() const { return BitSize; }
493   TypeIndex Type;
494   uint8_t BitSize;
495   uint8_t BitOffset;
496 };
497
498 // LF_VTSHAPE
499 class VFTableShapeRecord : public TypeRecord {
500 public:
501   explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
502   explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
503       : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
504   explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
505       : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
506
507   ArrayRef<VFTableSlotKind> getSlots() const {
508     if (!SlotsRef.empty())
509       return SlotsRef;
510     return Slots;
511   }
512
513   uint32_t getEntryCount() const { return getSlots().size(); }
514   ArrayRef<VFTableSlotKind> SlotsRef;
515   std::vector<VFTableSlotKind> Slots;
516 };
517
518 // LF_TYPESERVER2
519 class TypeServer2Record : public TypeRecord {
520 public:
521   explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
522   TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
523       : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
524         Name(Name) {}
525
526   StringRef getGuid() const { return Guid; }
527
528   uint32_t getAge() const { return Age; }
529
530   StringRef getName() const { return Name; }
531
532   StringRef Guid;
533   uint32_t Age;
534   StringRef Name;
535 };
536
537 // LF_STRING_ID
538 class StringIdRecord : public TypeRecord {
539 public:
540   explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
541   StringIdRecord(TypeIndex Id, StringRef String)
542       : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
543
544   TypeIndex getId() const { return Id; }
545
546   StringRef getString() const { return String; }
547   TypeIndex Id;
548   StringRef String;
549 };
550
551 // LF_FUNC_ID
552 class FuncIdRecord : public TypeRecord {
553 public:
554   explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
555   FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
556       : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
557         FunctionType(FunctionType), Name(Name) {}
558
559   TypeIndex getParentScope() const { return ParentScope; }
560
561   TypeIndex getFunctionType() const { return FunctionType; }
562
563   StringRef getName() const { return Name; }
564
565   TypeIndex ParentScope;
566   TypeIndex FunctionType;
567   StringRef Name;
568 };
569
570 // LF_UDT_SRC_LINE
571 class UdtSourceLineRecord : public TypeRecord {
572 public:
573   explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
574   UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
575       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
576         SourceFile(SourceFile), LineNumber(LineNumber) {}
577
578   TypeIndex getUDT() const { return UDT; }
579   TypeIndex getSourceFile() const { return SourceFile; }
580   uint32_t getLineNumber() const { return LineNumber; }
581
582   TypeIndex UDT;
583   TypeIndex SourceFile;
584   uint32_t LineNumber;
585 };
586
587 // LF_UDT_MOD_SRC_LINE
588 class UdtModSourceLineRecord : public TypeRecord {
589 public:
590   explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
591   UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
592                          uint32_t LineNumber, uint16_t Module)
593       : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
594         SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
595
596   TypeIndex getUDT() const { return UDT; }
597   TypeIndex getSourceFile() const { return SourceFile; }
598   uint32_t getLineNumber() const { return LineNumber; }
599   uint16_t getModule() const { return Module; }
600
601   TypeIndex UDT;
602   TypeIndex SourceFile;
603   uint32_t LineNumber;
604   uint16_t Module;
605 };
606
607 // LF_BUILDINFO
608 class BuildInfoRecord : public TypeRecord {
609 public:
610   explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
611   BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
612       : TypeRecord(TypeRecordKind::BuildInfo),
613         ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
614
615   ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
616   SmallVector<TypeIndex, 4> ArgIndices;
617 };
618
619 // LF_VFTABLE
620 class VFTableRecord : public TypeRecord {
621 public:
622   explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
623   VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
624                 uint32_t VFPtrOffset, StringRef Name,
625                 ArrayRef<StringRef> Methods)
626       : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
627         OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
628     MethodNames.push_back(Name);
629     MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
630   }
631
632   TypeIndex getCompleteClass() const { return CompleteClass; }
633   TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
634   uint32_t getVFPtrOffset() const { return VFPtrOffset; }
635   StringRef getName() const { return makeArrayRef(MethodNames).front(); }
636   ArrayRef<StringRef> getMethodNames() const {
637     return makeArrayRef(MethodNames).drop_front();
638   }
639
640   TypeIndex CompleteClass;
641   TypeIndex OverriddenVFTable;
642   uint32_t VFPtrOffset;
643   std::vector<StringRef> MethodNames;
644 };
645
646 // LF_ONEMETHOD
647 class OneMethodRecord : public TypeRecord {
648 public:
649   OneMethodRecord() : TypeRecord(TypeRecordKind::OneMethod) {}
650   explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
651   OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
652                   StringRef Name)
653       : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
654         VFTableOffset(VFTableOffset), Name(Name) {}
655   OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
656                   MethodOptions Options, int32_t VFTableOffset, StringRef Name)
657       : TypeRecord(TypeRecordKind::OneMethod), Type(Type),
658         Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
659
660   TypeIndex getType() const { return Type; }
661   MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
662   MethodOptions getOptions() const { return Attrs.getFlags(); }
663   MemberAccess getAccess() const { return Attrs.getAccess(); }
664   int32_t getVFTableOffset() const { return VFTableOffset; }
665   StringRef getName() const { return Name; }
666
667   bool isIntroducingVirtual() const {
668     return getMethodKind() == MethodKind::IntroducingVirtual ||
669            getMethodKind() == MethodKind::PureIntroducingVirtual;
670   }
671
672   TypeIndex Type;
673   MemberAttributes Attrs;
674   int32_t VFTableOffset;
675   StringRef Name;
676 };
677
678 // LF_METHODLIST
679 class MethodOverloadListRecord : public TypeRecord {
680 public:
681   explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
682   MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
683       : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
684
685   ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
686   std::vector<OneMethodRecord> Methods;
687 };
688
689 /// For method overload sets.  LF_METHOD
690 class OverloadedMethodRecord : public TypeRecord {
691 public:
692   explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
693   OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
694                          StringRef Name)
695       : TypeRecord(TypeRecordKind::OverloadedMethod),
696         NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
697
698   uint16_t getNumOverloads() const { return NumOverloads; }
699   TypeIndex getMethodList() const { return MethodList; }
700   StringRef getName() const { return Name; }
701   uint16_t NumOverloads;
702   TypeIndex MethodList;
703   StringRef Name;
704 };
705
706 // LF_MEMBER
707 class DataMemberRecord : public TypeRecord {
708 public:
709   explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
710   DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
711                    StringRef Name)
712       : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
713         FieldOffset(Offset), Name(Name) {}
714   DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
715                    StringRef Name)
716       : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
717         FieldOffset(Offset), Name(Name) {}
718
719   MemberAccess getAccess() const { return Attrs.getAccess(); }
720   TypeIndex getType() const { return Type; }
721   uint64_t getFieldOffset() const { return FieldOffset; }
722   StringRef getName() const { return Name; }
723
724   MemberAttributes Attrs;
725   TypeIndex Type;
726   uint64_t FieldOffset;
727   StringRef Name;
728 };
729
730 // LF_STMEMBER
731 class StaticDataMemberRecord : public TypeRecord {
732 public:
733   explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
734   StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
735       : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
736         Name(Name) {}
737   StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
738       : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
739         Name(Name) {}
740
741   MemberAccess getAccess() const { return Attrs.getAccess(); }
742   TypeIndex getType() const { return Type; }
743   StringRef getName() const { return Name; }
744
745   MemberAttributes Attrs;
746   TypeIndex Type;
747   StringRef Name;
748 };
749
750 // LF_ENUMERATE
751 class EnumeratorRecord : public TypeRecord {
752 public:
753   explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
754   EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
755       : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
756         Value(std::move(Value)), Name(Name) {}
757   EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
758       : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
759         Value(std::move(Value)), Name(Name) {}
760
761   MemberAccess getAccess() const { return Attrs.getAccess(); }
762   APSInt getValue() const { return Value; }
763   StringRef getName() const { return Name; }
764
765   MemberAttributes Attrs;
766   APSInt Value;
767   StringRef Name;
768 };
769
770 // LF_VFUNCTAB
771 class VFPtrRecord : public TypeRecord {
772 public:
773   explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
774   VFPtrRecord(TypeIndex Type)
775       : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
776
777   TypeIndex getType() const { return Type; }
778
779   TypeIndex Type;
780 };
781
782 // LF_BCLASS, LF_BINTERFACE
783 class BaseClassRecord : public TypeRecord {
784 public:
785   explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
786   BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
787       : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
788         Offset(Offset) {}
789   BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
790       : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
791         Offset(Offset) {}
792
793   MemberAccess getAccess() const { return Attrs.getAccess(); }
794   TypeIndex getBaseType() const { return Type; }
795   uint64_t getBaseOffset() const { return Offset; }
796
797   MemberAttributes Attrs;
798   TypeIndex Type;
799   uint64_t Offset;
800 };
801
802 // LF_VBCLASS, LF_IVBCLASS
803 class VirtualBaseClassRecord : public TypeRecord {
804 public:
805   explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
806   VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
807                          TypeIndex BaseType, TypeIndex VBPtrType,
808                          uint64_t Offset, uint64_t Index)
809       : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
810         VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
811   VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
812                          TypeIndex BaseType, TypeIndex VBPtrType,
813                          uint64_t Offset, uint64_t Index)
814       : TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
815         VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
816
817   MemberAccess getAccess() const { return Attrs.getAccess(); }
818   TypeIndex getBaseType() const { return BaseType; }
819   TypeIndex getVBPtrType() const { return VBPtrType; }
820   uint64_t getVBPtrOffset() const { return VBPtrOffset; }
821   uint64_t getVTableIndex() const { return VTableIndex; }
822
823   MemberAttributes Attrs;
824   TypeIndex BaseType;
825   TypeIndex VBPtrType;
826   uint64_t VBPtrOffset;
827   uint64_t VTableIndex;
828 };
829
830 /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
831 /// together. The first will end in an LF_INDEX record that points to the next.
832 class ListContinuationRecord : public TypeRecord {
833 public:
834   explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
835   ListContinuationRecord(TypeIndex ContinuationIndex)
836       : TypeRecord(TypeRecordKind::ListContinuation),
837         ContinuationIndex(ContinuationIndex) {}
838
839   TypeIndex getContinuationIndex() const { return ContinuationIndex; }
840
841   TypeIndex ContinuationIndex;
842 };
843
844 } // end namespace codeview
845
846 } // end namespace llvm
847
848 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H