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 TypeIndex ReferentType;
335 Optional<MemberPointerInfo> MemberInfo;
337 void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
339 Attrs = calcAttrs(PK, PM, PO, Size);
343 static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
346 A |= static_cast<uint32_t>(PK);
347 A |= static_cast<uint32_t>(PO);
348 A |= (static_cast<uint32_t>(PM) << PointerModeShift);
349 A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
355 class NestedTypeRecord : public TypeRecord {
357 NestedTypeRecord() = default;
358 explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
359 NestedTypeRecord(TypeIndex Type, StringRef Name)
360 : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
362 TypeIndex getNestedType() const { return Type; }
363 StringRef getName() const { return Name; }
370 class FieldListRecord : public TypeRecord {
372 FieldListRecord() = default;
373 explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
374 explicit FieldListRecord(ArrayRef<uint8_t> Data)
375 : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
377 ArrayRef<uint8_t> Data;
381 class ArrayRecord : public TypeRecord {
383 ArrayRecord() = default;
384 explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
385 ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
387 : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
388 IndexType(IndexType), Size(Size), Name(Name) {}
390 TypeIndex getElementType() const { return ElementType; }
391 TypeIndex getIndexType() const { return IndexType; }
392 uint64_t getSize() const { return Size; }
393 StringRef getName() const { return Name; }
395 TypeIndex ElementType;
401 class TagRecord : public TypeRecord {
403 TagRecord() = default;
404 explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
405 TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
406 TypeIndex FieldList, StringRef Name, StringRef UniqueName)
407 : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
408 FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
411 static const int HfaKindShift = 11;
412 static const int HfaKindMask = 0x1800;
413 static const int WinRTKindShift = 14;
414 static const int WinRTKindMask = 0xC000;
416 bool hasUniqueName() const {
417 return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
420 bool isNested() const {
421 return (Options & ClassOptions::Nested) != ClassOptions::None;
424 bool isForwardRef() const {
425 return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
428 uint16_t getMemberCount() const { return MemberCount; }
429 ClassOptions getOptions() const { return Options; }
430 TypeIndex getFieldList() const { return FieldList; }
431 StringRef getName() const { return Name; }
432 StringRef getUniqueName() const { return UniqueName; }
434 uint16_t MemberCount;
435 ClassOptions Options;
438 StringRef UniqueName;
441 // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
442 class ClassRecord : public TagRecord {
444 ClassRecord() = default;
445 explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
446 ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
447 TypeIndex FieldList, TypeIndex DerivationList,
448 TypeIndex VTableShape, uint64_t Size, StringRef Name,
449 StringRef UniqueName)
450 : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
451 DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
453 HfaKind getHfa() const {
454 uint16_t Value = static_cast<uint16_t>(Options);
455 Value = (Value & HfaKindMask) >> HfaKindShift;
456 return static_cast<HfaKind>(Value);
459 WindowsRTClassKind getWinRTKind() const {
460 uint16_t Value = static_cast<uint16_t>(Options);
461 Value = (Value & WinRTKindMask) >> WinRTKindShift;
462 return static_cast<WindowsRTClassKind>(Value);
465 TypeIndex getDerivationList() const { return DerivationList; }
466 TypeIndex getVTableShape() const { return VTableShape; }
467 uint64_t getSize() const { return Size; }
469 TypeIndex DerivationList;
470 TypeIndex VTableShape;
475 struct UnionRecord : public TagRecord {
476 UnionRecord() = default;
477 explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
478 UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
479 uint64_t Size, StringRef Name, StringRef UniqueName)
480 : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
484 HfaKind getHfa() const {
485 uint16_t Value = static_cast<uint16_t>(Options);
486 Value = (Value & HfaKindMask) >> HfaKindShift;
487 return static_cast<HfaKind>(Value);
490 uint64_t getSize() const { return Size; }
496 class EnumRecord : public TagRecord {
498 EnumRecord() = default;
499 explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
500 EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
501 StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
502 : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
504 UnderlyingType(UnderlyingType) {}
506 TypeIndex getUnderlyingType() const { return UnderlyingType; }
508 TypeIndex UnderlyingType;
512 class BitFieldRecord : public TypeRecord {
514 BitFieldRecord() = default;
515 explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
516 BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
517 : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
518 BitOffset(BitOffset) {}
520 TypeIndex getType() const { return Type; }
521 uint8_t getBitOffset() const { return BitOffset; }
522 uint8_t getBitSize() const { return BitSize; }
530 class VFTableShapeRecord : public TypeRecord {
532 VFTableShapeRecord() = default;
533 explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
534 explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
535 : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
536 explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
537 : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
539 ArrayRef<VFTableSlotKind> getSlots() const {
540 if (!SlotsRef.empty())
545 uint32_t getEntryCount() const { return getSlots().size(); }
547 ArrayRef<VFTableSlotKind> SlotsRef;
548 std::vector<VFTableSlotKind> Slots;
552 class TypeServer2Record : public TypeRecord {
554 TypeServer2Record() = default;
555 explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
556 TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
557 : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
558 assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
559 ::memcpy(Guid.Guid, GuidStr.data(), 16);
562 const GUID &getGuid() const { return Guid; }
563 uint32_t getAge() const { return Age; }
564 StringRef getName() const { return Name; }
572 class StringIdRecord : public TypeRecord {
574 StringIdRecord() = default;
575 explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
576 StringIdRecord(TypeIndex Id, StringRef String)
577 : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
579 TypeIndex getId() const { return Id; }
580 StringRef getString() const { return String; }
587 class FuncIdRecord : public TypeRecord {
589 FuncIdRecord() = default;
590 explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
591 FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
592 : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
593 FunctionType(FunctionType), Name(Name) {}
595 TypeIndex getParentScope() const { return ParentScope; }
596 TypeIndex getFunctionType() const { return FunctionType; }
597 StringRef getName() const { return Name; }
599 TypeIndex ParentScope;
600 TypeIndex FunctionType;
605 class UdtSourceLineRecord : public TypeRecord {
607 UdtSourceLineRecord() = default;
608 explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
609 UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
610 : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
611 SourceFile(SourceFile), LineNumber(LineNumber) {}
613 TypeIndex getUDT() const { return UDT; }
614 TypeIndex getSourceFile() const { return SourceFile; }
615 uint32_t getLineNumber() const { return LineNumber; }
618 TypeIndex SourceFile;
622 // LF_UDT_MOD_SRC_LINE
623 class UdtModSourceLineRecord : public TypeRecord {
625 UdtModSourceLineRecord() = default;
626 explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
627 UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
628 uint32_t LineNumber, uint16_t Module)
629 : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
630 SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
632 TypeIndex getUDT() const { return UDT; }
633 TypeIndex getSourceFile() const { return SourceFile; }
634 uint32_t getLineNumber() const { return LineNumber; }
635 uint16_t getModule() const { return Module; }
638 TypeIndex SourceFile;
644 class BuildInfoRecord : public TypeRecord {
646 BuildInfoRecord() = default;
647 explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
648 BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
649 : TypeRecord(TypeRecordKind::BuildInfo),
650 ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
652 ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
654 SmallVector<TypeIndex, 4> ArgIndices;
658 class VFTableRecord : public TypeRecord {
660 VFTableRecord() = default;
661 explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
662 VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
663 uint32_t VFPtrOffset, StringRef Name,
664 ArrayRef<StringRef> Methods)
665 : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
666 OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
667 MethodNames.push_back(Name);
668 MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
671 TypeIndex getCompleteClass() const { return CompleteClass; }
672 TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
673 uint32_t getVFPtrOffset() const { return VFPtrOffset; }
674 StringRef getName() const { return makeArrayRef(MethodNames).front(); }
676 ArrayRef<StringRef> getMethodNames() const {
677 return makeArrayRef(MethodNames).drop_front();
680 TypeIndex CompleteClass;
681 TypeIndex OverriddenVFTable;
682 uint32_t VFPtrOffset;
683 std::vector<StringRef> MethodNames;
687 class OneMethodRecord : public TypeRecord {
689 OneMethodRecord() = default;
690 explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
691 OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
693 : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
694 VFTableOffset(VFTableOffset), Name(Name) {}
695 OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
696 MethodOptions Options, int32_t VFTableOffset, StringRef Name)
697 : TypeRecord(TypeRecordKind::OneMethod), Type(Type),
698 Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
700 TypeIndex getType() const { return Type; }
701 MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
702 MethodOptions getOptions() const { return Attrs.getFlags(); }
703 MemberAccess getAccess() const { return Attrs.getAccess(); }
704 int32_t getVFTableOffset() const { return VFTableOffset; }
705 StringRef getName() const { return Name; }
707 bool isIntroducingVirtual() const {
708 return getMethodKind() == MethodKind::IntroducingVirtual ||
709 getMethodKind() == MethodKind::PureIntroducingVirtual;
713 MemberAttributes Attrs;
714 int32_t VFTableOffset;
719 class MethodOverloadListRecord : public TypeRecord {
721 MethodOverloadListRecord() = default;
722 explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
723 MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
724 : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
726 ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
728 std::vector<OneMethodRecord> Methods;
731 /// For method overload sets. LF_METHOD
732 class OverloadedMethodRecord : public TypeRecord {
734 OverloadedMethodRecord() = default;
735 explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
736 OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
738 : TypeRecord(TypeRecordKind::OverloadedMethod),
739 NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
741 uint16_t getNumOverloads() const { return NumOverloads; }
742 TypeIndex getMethodList() const { return MethodList; }
743 StringRef getName() const { return Name; }
745 uint16_t NumOverloads;
746 TypeIndex MethodList;
751 class DataMemberRecord : public TypeRecord {
753 DataMemberRecord() = default;
754 explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
755 DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
757 : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
758 FieldOffset(Offset), Name(Name) {}
759 DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
761 : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
762 FieldOffset(Offset), Name(Name) {}
764 MemberAccess getAccess() const { return Attrs.getAccess(); }
765 TypeIndex getType() const { return Type; }
766 uint64_t getFieldOffset() const { return FieldOffset; }
767 StringRef getName() const { return Name; }
769 MemberAttributes Attrs;
771 uint64_t FieldOffset;
776 class StaticDataMemberRecord : public TypeRecord {
778 StaticDataMemberRecord() = default;
779 explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
780 StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
781 : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
783 StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
784 : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
787 MemberAccess getAccess() const { return Attrs.getAccess(); }
788 TypeIndex getType() const { return Type; }
789 StringRef getName() const { return Name; }
791 MemberAttributes Attrs;
797 class EnumeratorRecord : public TypeRecord {
799 EnumeratorRecord() = default;
800 explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
801 EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
802 : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
803 Value(std::move(Value)), Name(Name) {}
804 EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
805 : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
806 Value(std::move(Value)), Name(Name) {}
808 MemberAccess getAccess() const { return Attrs.getAccess(); }
809 APSInt getValue() const { return Value; }
810 StringRef getName() const { return Name; }
812 MemberAttributes Attrs;
818 class VFPtrRecord : public TypeRecord {
820 VFPtrRecord() = default;
821 explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
822 VFPtrRecord(TypeIndex Type)
823 : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
825 TypeIndex getType() const { return Type; }
830 // LF_BCLASS, LF_BINTERFACE
831 class BaseClassRecord : public TypeRecord {
833 BaseClassRecord() = default;
834 explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
835 BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
836 : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
838 BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
839 : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
842 MemberAccess getAccess() const { return Attrs.getAccess(); }
843 TypeIndex getBaseType() const { return Type; }
844 uint64_t getBaseOffset() const { return Offset; }
846 MemberAttributes Attrs;
851 // LF_VBCLASS, LF_IVBCLASS
852 class VirtualBaseClassRecord : public TypeRecord {
854 VirtualBaseClassRecord() = default;
855 explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
856 VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
857 TypeIndex BaseType, TypeIndex VBPtrType,
858 uint64_t Offset, uint64_t Index)
859 : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
860 VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
861 VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
862 TypeIndex BaseType, TypeIndex VBPtrType,
863 uint64_t Offset, uint64_t Index)
864 : TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
865 VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
867 MemberAccess getAccess() const { return Attrs.getAccess(); }
868 TypeIndex getBaseType() const { return BaseType; }
869 TypeIndex getVBPtrType() const { return VBPtrType; }
870 uint64_t getVBPtrOffset() const { return VBPtrOffset; }
871 uint64_t getVTableIndex() const { return VTableIndex; }
873 MemberAttributes Attrs;
876 uint64_t VBPtrOffset;
877 uint64_t VTableIndex;
880 /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
881 /// together. The first will end in an LF_INDEX record that points to the next.
882 class ListContinuationRecord : public TypeRecord {
884 ListContinuationRecord() = default;
885 explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
886 ListContinuationRecord(TypeIndex ContinuationIndex)
887 : TypeRecord(TypeRecordKind::ListContinuation),
888 ContinuationIndex(ContinuationIndex) {}
890 TypeIndex getContinuationIndex() const { return ContinuationIndex; }
892 TypeIndex ContinuationIndex;
895 } // end namespace codeview
896 } // end namespace llvm
898 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H