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