1 //===- TypeRecord.h ---------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
11 #define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
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"
32 using support::little32_t;
33 using support::ulittle16_t;
34 using support::ulittle32_t;
36 using CVType = CVRecord<TypeLeafKind>;
37 using RemappedType = RemappedRecord<TypeLeafKind>;
39 struct CVMemberRecord {
41 ArrayRef<uint8_t> Data;
43 using CVTypeArray = VarStreamArray<CVType>;
44 using CVTypeRange = iterator_range<CVTypeArray::Iterator>;
46 /// Equvalent to CV_fldattr_t in cvinfo.h.
47 struct MemberAttributes {
54 MemberAttributes() = default;
56 explicit MemberAttributes(MemberAccess Access)
57 : Attrs(static_cast<uint16_t>(Access)) {}
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);
65 /// Get the access specifier. Valid for any kind of member.
66 MemberAccess getAccess() const {
67 return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
70 /// Indicates if a method is defined with friend, virtual, static, etc.
71 MethodKind getMethodKind() const {
73 (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
77 /// Get the flags that are not included in access control or method
79 MethodOptions getFlags() const {
82 ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
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;
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;
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 {
104 MemberPointerInfo() = default;
106 MemberPointerInfo(TypeIndex ContainingType,
107 PointerToMemberRepresentation Representation)
108 : ContainingType(ContainingType), Representation(Representation) {}
110 TypeIndex getContainingType() const { return ContainingType; }
111 PointerToMemberRepresentation getRepresentation() const {
112 return Representation;
115 TypeIndex ContainingType;
116 PointerToMemberRepresentation Representation;
121 TypeRecord() = default;
122 explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
125 TypeRecordKind getKind() const { return Kind; }
131 class ModifierRecord : public TypeRecord {
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) {}
139 TypeIndex getModifiedType() const { return ModifiedType; }
140 ModifierOptions getModifiers() const { return Modifiers; }
142 TypeIndex ModifiedType;
143 ModifierOptions Modifiers;
147 class ProcedureRecord : public TypeRecord {
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) {}
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; }
164 TypeIndex ReturnType;
165 CallingConvention CallConv;
166 FunctionOptions Options;
167 uint16_t ParameterCount;
168 TypeIndex ArgumentList;
172 class MemberFunctionRecord : public TypeRecord {
174 MemberFunctionRecord() = default;
175 explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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) {}
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; }
196 TypeIndex ReturnType;
199 CallingConvention CallConv;
200 FunctionOptions Options;
201 uint16_t ParameterCount;
202 TypeIndex ArgumentList;
203 int32_t ThisPointerAdjustment;
207 class LabelRecord : public TypeRecord {
209 LabelRecord() = default;
210 explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
212 LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
218 class MemberFuncIdRecord : public TypeRecord {
220 MemberFuncIdRecord() = default;
221 explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
222 MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
224 : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
225 FunctionType(FunctionType), Name(Name) {}
227 TypeIndex getClassType() const { return ClassType; }
228 TypeIndex getFunctionType() const { return FunctionType; }
229 StringRef getName() const { return Name; }
232 TypeIndex FunctionType;
237 class ArgListRecord : public TypeRecord {
239 ArgListRecord() = default;
240 explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
242 ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
243 : TypeRecord(Kind), ArgIndices(Indices) {}
245 ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
247 std::vector<TypeIndex> ArgIndices;
251 class StringListRecord : public TypeRecord {
253 StringListRecord() = default;
254 explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
256 StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
257 : TypeRecord(Kind), StringIndices(Indices) {}
259 ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
261 std::vector<TypeIndex> StringIndices;
265 class PointerRecord : public TypeRecord {
267 static const uint32_t PointerKindShift = 0;
268 static const uint32_t PointerKindMask = 0x1F;
270 static const uint32_t PointerModeShift = 5;
271 static const uint32_t PointerModeMask = 0x07;
273 static const uint32_t PointerOptionMask = 0xFF;
275 static const uint32_t PointerSizeShift = 13;
276 static const uint32_t PointerSizeMask = 0xFF;
278 PointerRecord() = default;
279 explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
281 PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
282 : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
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)) {}
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) {}
295 TypeIndex getReferentType() const { return ReferentType; }
297 PointerKind getPointerKind() const {
298 return static_cast<PointerKind>((Attrs >> PointerKindShift) &
302 PointerMode getMode() const {
303 return static_cast<PointerMode>((Attrs >> PointerModeShift) &
307 PointerOptions getOptions() const {
308 return static_cast<PointerOptions>(Attrs);
311 uint8_t getSize() const {
312 return (Attrs >> PointerSizeShift) & PointerSizeMask;
315 MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
317 bool isPointerToMember() const {
318 return getMode() == PointerMode::PointerToDataMember ||
319 getMode() == PointerMode::PointerToMemberFunction;
322 bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
323 bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
325 bool isVolatile() const {
326 return !!(Attrs & uint32_t(PointerOptions::Volatile));
329 bool isUnaligned() const {
330 return !!(Attrs & uint32_t(PointerOptions::Unaligned));
333 bool isRestrict() const {
334 return !!(Attrs & uint32_t(PointerOptions::Restrict));
337 TypeIndex ReferentType;
339 Optional<MemberPointerInfo> MemberInfo;
341 void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
343 Attrs = calcAttrs(PK, PM, PO, Size);
347 static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
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);
359 class NestedTypeRecord : public TypeRecord {
361 NestedTypeRecord() = default;
362 explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
363 NestedTypeRecord(TypeIndex Type, StringRef Name)
364 : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
366 TypeIndex getNestedType() const { return Type; }
367 StringRef getName() const { return Name; }
374 class FieldListRecord : public TypeRecord {
376 FieldListRecord() = default;
377 explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
378 explicit FieldListRecord(ArrayRef<uint8_t> Data)
379 : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
381 ArrayRef<uint8_t> Data;
385 class ArrayRecord : public TypeRecord {
387 ArrayRecord() = default;
388 explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
389 ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
391 : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
392 IndexType(IndexType), Size(Size), Name(Name) {}
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; }
399 TypeIndex ElementType;
405 class TagRecord : public TypeRecord {
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) {}
415 static const int HfaKindShift = 11;
416 static const int HfaKindMask = 0x1800;
417 static const int WinRTKindShift = 14;
418 static const int WinRTKindMask = 0xC000;
420 bool hasUniqueName() const {
421 return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
424 bool isNested() const {
425 return (Options & ClassOptions::Nested) != ClassOptions::None;
428 bool isForwardRef() const {
429 return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
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; }
438 uint16_t MemberCount;
439 ClassOptions Options;
442 StringRef UniqueName;
445 // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
446 class ClassRecord : public TagRecord {
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) {}
457 HfaKind getHfa() const {
458 uint16_t Value = static_cast<uint16_t>(Options);
459 Value = (Value & HfaKindMask) >> HfaKindShift;
460 return static_cast<HfaKind>(Value);
463 WindowsRTClassKind getWinRTKind() const {
464 uint16_t Value = static_cast<uint16_t>(Options);
465 Value = (Value & WinRTKindMask) >> WinRTKindShift;
466 return static_cast<WindowsRTClassKind>(Value);
469 TypeIndex getDerivationList() const { return DerivationList; }
470 TypeIndex getVTableShape() const { return VTableShape; }
471 uint64_t getSize() const { return Size; }
473 TypeIndex DerivationList;
474 TypeIndex VTableShape;
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,
488 HfaKind getHfa() const {
489 uint16_t Value = static_cast<uint16_t>(Options);
490 Value = (Value & HfaKindMask) >> HfaKindShift;
491 return static_cast<HfaKind>(Value);
494 uint64_t getSize() const { return Size; }
500 class EnumRecord : public TagRecord {
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,
508 UnderlyingType(UnderlyingType) {}
510 TypeIndex getUnderlyingType() const { return UnderlyingType; }
512 TypeIndex UnderlyingType;
516 class BitFieldRecord : public TypeRecord {
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) {}
524 TypeIndex getType() const { return Type; }
525 uint8_t getBitOffset() const { return BitOffset; }
526 uint8_t getBitSize() const { return BitSize; }
534 class VFTableShapeRecord : public TypeRecord {
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)) {}
543 ArrayRef<VFTableSlotKind> getSlots() const {
544 if (!SlotsRef.empty())
549 uint32_t getEntryCount() const { return getSlots().size(); }
551 ArrayRef<VFTableSlotKind> SlotsRef;
552 std::vector<VFTableSlotKind> Slots;
556 class TypeServer2Record : public TypeRecord {
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);
566 const GUID &getGuid() const { return Guid; }
567 uint32_t getAge() const { return Age; }
568 StringRef getName() const { return Name; }
576 class StringIdRecord : public TypeRecord {
578 StringIdRecord() = default;
579 explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
580 StringIdRecord(TypeIndex Id, StringRef String)
581 : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
583 TypeIndex getId() const { return Id; }
584 StringRef getString() const { return String; }
591 class FuncIdRecord : public TypeRecord {
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) {}
599 TypeIndex getParentScope() const { return ParentScope; }
600 TypeIndex getFunctionType() const { return FunctionType; }
601 StringRef getName() const { return Name; }
603 TypeIndex ParentScope;
604 TypeIndex FunctionType;
609 class UdtSourceLineRecord : public TypeRecord {
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) {}
617 TypeIndex getUDT() const { return UDT; }
618 TypeIndex getSourceFile() const { return SourceFile; }
619 uint32_t getLineNumber() const { return LineNumber; }
622 TypeIndex SourceFile;
626 // LF_UDT_MOD_SRC_LINE
627 class UdtModSourceLineRecord : public TypeRecord {
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) {}
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; }
642 TypeIndex SourceFile;
648 class BuildInfoRecord : public TypeRecord {
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()) {}
656 ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
658 SmallVector<TypeIndex, 4> ArgIndices;
662 class VFTableRecord : public TypeRecord {
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());
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(); }
680 ArrayRef<StringRef> getMethodNames() const {
681 return makeArrayRef(MethodNames).drop_front();
684 TypeIndex CompleteClass;
685 TypeIndex OverriddenVFTable;
686 uint32_t VFPtrOffset;
687 std::vector<StringRef> MethodNames;
691 class OneMethodRecord : public TypeRecord {
693 OneMethodRecord() = default;
694 explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
695 OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
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) {}
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; }
711 bool isIntroducingVirtual() const {
712 return getMethodKind() == MethodKind::IntroducingVirtual ||
713 getMethodKind() == MethodKind::PureIntroducingVirtual;
717 MemberAttributes Attrs;
718 int32_t VFTableOffset;
723 class MethodOverloadListRecord : public TypeRecord {
725 MethodOverloadListRecord() = default;
726 explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
727 MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
728 : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
730 ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
732 std::vector<OneMethodRecord> Methods;
735 /// For method overload sets. LF_METHOD
736 class OverloadedMethodRecord : public TypeRecord {
738 OverloadedMethodRecord() = default;
739 explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
740 OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
742 : TypeRecord(TypeRecordKind::OverloadedMethod),
743 NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
745 uint16_t getNumOverloads() const { return NumOverloads; }
746 TypeIndex getMethodList() const { return MethodList; }
747 StringRef getName() const { return Name; }
749 uint16_t NumOverloads;
750 TypeIndex MethodList;
755 class DataMemberRecord : public TypeRecord {
757 DataMemberRecord() = default;
758 explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
759 DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
761 : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
762 FieldOffset(Offset), Name(Name) {}
763 DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
765 : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
766 FieldOffset(Offset), Name(Name) {}
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; }
773 MemberAttributes Attrs;
775 uint64_t FieldOffset;
780 class StaticDataMemberRecord : public TypeRecord {
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),
787 StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
788 : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
791 MemberAccess getAccess() const { return Attrs.getAccess(); }
792 TypeIndex getType() const { return Type; }
793 StringRef getName() const { return Name; }
795 MemberAttributes Attrs;
801 class EnumeratorRecord : public TypeRecord {
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) {}
812 MemberAccess getAccess() const { return Attrs.getAccess(); }
813 APSInt getValue() const { return Value; }
814 StringRef getName() const { return Name; }
816 MemberAttributes Attrs;
822 class VFPtrRecord : public TypeRecord {
824 VFPtrRecord() = default;
825 explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
826 VFPtrRecord(TypeIndex Type)
827 : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
829 TypeIndex getType() const { return Type; }
834 // LF_BCLASS, LF_BINTERFACE
835 class BaseClassRecord : public TypeRecord {
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),
842 BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
843 : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
846 MemberAccess getAccess() const { return Attrs.getAccess(); }
847 TypeIndex getBaseType() const { return Type; }
848 uint64_t getBaseOffset() const { return Offset; }
850 MemberAttributes Attrs;
855 // LF_VBCLASS, LF_IVBCLASS
856 class VirtualBaseClassRecord : public TypeRecord {
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) {}
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; }
877 MemberAttributes Attrs;
880 uint64_t VBPtrOffset;
881 uint64_t VTableIndex;
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 {
888 ListContinuationRecord() = default;
889 explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
890 ListContinuationRecord(TypeIndex ContinuationIndex)
891 : TypeRecord(TypeRecordKind::ListContinuation),
892 ContinuationIndex(ContinuationIndex) {}
894 TypeIndex getContinuationIndex() const { return ContinuationIndex; }
896 TypeIndex ContinuationIndex;
900 class PrecompRecord : public TypeRecord {
902 PrecompRecord() = default;
903 explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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; }
910 uint32_t StartTypeIndex;
913 StringRef PrecompFilePath;
917 class EndPrecompRecord : public TypeRecord {
919 EndPrecompRecord() = default;
920 explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
922 uint32_t getSignature() const { return Signature; }
926 } // end namespace codeview
927 } // end namespace llvm
929 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H