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;
99 /// Is this method static.
100 bool isStatic() const {
101 return getMethodKind() == MethodKind::Static;
105 // Does not correspond to any tag, this is the tail of an LF_POINTER record
106 // if it represents a member pointer.
107 class MemberPointerInfo {
109 MemberPointerInfo() = default;
111 MemberPointerInfo(TypeIndex ContainingType,
112 PointerToMemberRepresentation Representation)
113 : ContainingType(ContainingType), Representation(Representation) {}
115 TypeIndex getContainingType() const { return ContainingType; }
116 PointerToMemberRepresentation getRepresentation() const {
117 return Representation;
120 TypeIndex ContainingType;
121 PointerToMemberRepresentation Representation;
126 TypeRecord() = default;
127 explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
130 TypeRecordKind getKind() const { return Kind; }
136 class ModifierRecord : public TypeRecord {
138 ModifierRecord() = default;
139 explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
140 ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
141 : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
142 Modifiers(Modifiers) {}
144 TypeIndex getModifiedType() const { return ModifiedType; }
145 ModifierOptions getModifiers() const { return Modifiers; }
147 TypeIndex ModifiedType;
148 ModifierOptions Modifiers;
152 class ProcedureRecord : public TypeRecord {
154 ProcedureRecord() = default;
155 explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
156 ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
157 FunctionOptions Options, uint16_t ParameterCount,
158 TypeIndex ArgumentList)
159 : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType),
160 CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
161 ArgumentList(ArgumentList) {}
163 TypeIndex getReturnType() const { return ReturnType; }
164 CallingConvention getCallConv() const { return CallConv; }
165 FunctionOptions getOptions() const { return Options; }
166 uint16_t getParameterCount() const { return ParameterCount; }
167 TypeIndex getArgumentList() const { return ArgumentList; }
169 TypeIndex ReturnType;
170 CallingConvention CallConv;
171 FunctionOptions Options;
172 uint16_t ParameterCount;
173 TypeIndex ArgumentList;
177 class MemberFunctionRecord : public TypeRecord {
179 MemberFunctionRecord() = default;
180 explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
182 MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
183 TypeIndex ThisType, CallingConvention CallConv,
184 FunctionOptions Options, uint16_t ParameterCount,
185 TypeIndex ArgumentList, int32_t ThisPointerAdjustment)
186 : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType),
187 ClassType(ClassType), ThisType(ThisType), CallConv(CallConv),
188 Options(Options), ParameterCount(ParameterCount),
189 ArgumentList(ArgumentList),
190 ThisPointerAdjustment(ThisPointerAdjustment) {}
192 TypeIndex getReturnType() const { return ReturnType; }
193 TypeIndex getClassType() const { return ClassType; }
194 TypeIndex getThisType() const { return ThisType; }
195 CallingConvention getCallConv() const { return CallConv; }
196 FunctionOptions getOptions() const { return Options; }
197 uint16_t getParameterCount() const { return ParameterCount; }
198 TypeIndex getArgumentList() const { return ArgumentList; }
199 int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
201 TypeIndex ReturnType;
204 CallingConvention CallConv;
205 FunctionOptions Options;
206 uint16_t ParameterCount;
207 TypeIndex ArgumentList;
208 int32_t ThisPointerAdjustment;
212 class LabelRecord : public TypeRecord {
214 LabelRecord() = default;
215 explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
217 LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
223 class MemberFuncIdRecord : public TypeRecord {
225 MemberFuncIdRecord() = default;
226 explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
227 MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
229 : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
230 FunctionType(FunctionType), Name(Name) {}
232 TypeIndex getClassType() const { return ClassType; }
233 TypeIndex getFunctionType() const { return FunctionType; }
234 StringRef getName() const { return Name; }
237 TypeIndex FunctionType;
242 class ArgListRecord : public TypeRecord {
244 ArgListRecord() = default;
245 explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
247 ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
248 : TypeRecord(Kind), ArgIndices(Indices) {}
250 ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
252 std::vector<TypeIndex> ArgIndices;
256 class StringListRecord : public TypeRecord {
258 StringListRecord() = default;
259 explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
261 StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
262 : TypeRecord(Kind), StringIndices(Indices) {}
264 ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
266 std::vector<TypeIndex> StringIndices;
270 class PointerRecord : public TypeRecord {
272 // ---------------------------XXXXX
273 static const uint32_t PointerKindShift = 0;
274 static const uint32_t PointerKindMask = 0x1F;
276 // ------------------------XXX-----
277 static const uint32_t PointerModeShift = 5;
278 static const uint32_t PointerModeMask = 0x07;
280 // ----------XXX------XXXXX--------
281 static const uint32_t PointerOptionMask = 0x381f00;
283 // -------------XXXXXX------------
284 static const uint32_t PointerSizeShift = 13;
285 static const uint32_t PointerSizeMask = 0xFF;
287 PointerRecord() = default;
288 explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
290 PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
291 : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
294 PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
295 PointerOptions PO, uint8_t Size)
296 : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
297 Attrs(calcAttrs(PK, PM, PO, Size)) {}
299 PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM,
300 PointerOptions PO, uint8_t Size, const MemberPointerInfo &MPI)
301 : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
302 Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(MPI) {}
304 TypeIndex getReferentType() const { return ReferentType; }
306 PointerKind getPointerKind() const {
307 return static_cast<PointerKind>((Attrs >> PointerKindShift) &
311 PointerMode getMode() const {
312 return static_cast<PointerMode>((Attrs >> PointerModeShift) &
316 PointerOptions getOptions() const {
317 return static_cast<PointerOptions>(Attrs & PointerOptionMask);
320 uint8_t getSize() const {
321 return (Attrs >> PointerSizeShift) & PointerSizeMask;
324 MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
326 bool isPointerToMember() const {
327 return getMode() == PointerMode::PointerToDataMember ||
328 getMode() == PointerMode::PointerToMemberFunction;
331 bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
332 bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
334 bool isVolatile() const {
335 return !!(Attrs & uint32_t(PointerOptions::Volatile));
338 bool isUnaligned() const {
339 return !!(Attrs & uint32_t(PointerOptions::Unaligned));
342 bool isRestrict() const {
343 return !!(Attrs & uint32_t(PointerOptions::Restrict));
346 bool isLValueReferenceThisPtr() const {
347 return !!(Attrs & uint32_t(PointerOptions::LValueRefThisPointer));
350 bool isRValueReferenceThisPtr() const {
351 return !!(Attrs & uint32_t(PointerOptions::RValueRefThisPointer));
354 TypeIndex ReferentType;
356 Optional<MemberPointerInfo> MemberInfo;
358 void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
360 Attrs = calcAttrs(PK, PM, PO, Size);
364 static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
367 A |= static_cast<uint32_t>(PK);
368 A |= static_cast<uint32_t>(PO);
369 A |= (static_cast<uint32_t>(PM) << PointerModeShift);
370 A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
376 class NestedTypeRecord : public TypeRecord {
378 NestedTypeRecord() = default;
379 explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
380 NestedTypeRecord(TypeIndex Type, StringRef Name)
381 : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
383 TypeIndex getNestedType() const { return Type; }
384 StringRef getName() const { return Name; }
391 class FieldListRecord : public TypeRecord {
393 FieldListRecord() = default;
394 explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
395 explicit FieldListRecord(ArrayRef<uint8_t> Data)
396 : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
398 ArrayRef<uint8_t> Data;
402 class ArrayRecord : public TypeRecord {
404 ArrayRecord() = default;
405 explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
406 ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
408 : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
409 IndexType(IndexType), Size(Size), Name(Name) {}
411 TypeIndex getElementType() const { return ElementType; }
412 TypeIndex getIndexType() const { return IndexType; }
413 uint64_t getSize() const { return Size; }
414 StringRef getName() const { return Name; }
416 TypeIndex ElementType;
422 class TagRecord : public TypeRecord {
424 TagRecord() = default;
425 explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
426 TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
427 TypeIndex FieldList, StringRef Name, StringRef UniqueName)
428 : TypeRecord(Kind), MemberCount(MemberCount), Options(Options),
429 FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
432 static const int HfaKindShift = 11;
433 static const int HfaKindMask = 0x1800;
434 static const int WinRTKindShift = 14;
435 static const int WinRTKindMask = 0xC000;
437 bool hasUniqueName() const {
438 return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
441 bool isNested() const {
442 return (Options & ClassOptions::Nested) != ClassOptions::None;
445 bool isForwardRef() const {
446 return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
449 bool containsNestedClass() const {
450 return (Options & ClassOptions::ContainsNestedClass) != ClassOptions::None;
453 bool isScoped() const {
454 return (Options & ClassOptions::Scoped) != ClassOptions::None;
457 uint16_t getMemberCount() const { return MemberCount; }
458 ClassOptions getOptions() const { return Options; }
459 TypeIndex getFieldList() const { return FieldList; }
460 StringRef getName() const { return Name; }
461 StringRef getUniqueName() const { return UniqueName; }
463 uint16_t MemberCount;
464 ClassOptions Options;
467 StringRef UniqueName;
470 // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
471 class ClassRecord : public TagRecord {
473 ClassRecord() = default;
474 explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
475 ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options,
476 TypeIndex FieldList, TypeIndex DerivationList,
477 TypeIndex VTableShape, uint64_t Size, StringRef Name,
478 StringRef UniqueName)
479 : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
480 DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}
482 HfaKind getHfa() const {
483 uint16_t Value = static_cast<uint16_t>(Options);
484 Value = (Value & HfaKindMask) >> HfaKindShift;
485 return static_cast<HfaKind>(Value);
488 WindowsRTClassKind getWinRTKind() const {
489 uint16_t Value = static_cast<uint16_t>(Options);
490 Value = (Value & WinRTKindMask) >> WinRTKindShift;
491 return static_cast<WindowsRTClassKind>(Value);
494 TypeIndex getDerivationList() const { return DerivationList; }
495 TypeIndex getVTableShape() const { return VTableShape; }
496 uint64_t getSize() const { return Size; }
498 TypeIndex DerivationList;
499 TypeIndex VTableShape;
504 struct UnionRecord : public TagRecord {
505 UnionRecord() = default;
506 explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
507 UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
508 uint64_t Size, StringRef Name, StringRef UniqueName)
509 : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
513 HfaKind getHfa() const {
514 uint16_t Value = static_cast<uint16_t>(Options);
515 Value = (Value & HfaKindMask) >> HfaKindShift;
516 return static_cast<HfaKind>(Value);
519 uint64_t getSize() const { return Size; }
525 class EnumRecord : public TagRecord {
527 EnumRecord() = default;
528 explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {}
529 EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
530 StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType)
531 : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name,
533 UnderlyingType(UnderlyingType) {}
535 TypeIndex getUnderlyingType() const { return UnderlyingType; }
537 TypeIndex UnderlyingType;
541 class BitFieldRecord : public TypeRecord {
543 BitFieldRecord() = default;
544 explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
545 BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
546 : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
547 BitOffset(BitOffset) {}
549 TypeIndex getType() const { return Type; }
550 uint8_t getBitOffset() const { return BitOffset; }
551 uint8_t getBitSize() const { return BitSize; }
559 class VFTableShapeRecord : public TypeRecord {
561 VFTableShapeRecord() = default;
562 explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
563 explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
564 : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
565 explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
566 : TypeRecord(TypeRecordKind::VFTableShape), Slots(std::move(Slots)) {}
568 ArrayRef<VFTableSlotKind> getSlots() const {
569 if (!SlotsRef.empty())
574 uint32_t getEntryCount() const { return getSlots().size(); }
576 ArrayRef<VFTableSlotKind> SlotsRef;
577 std::vector<VFTableSlotKind> Slots;
581 class TypeServer2Record : public TypeRecord {
583 TypeServer2Record() = default;
584 explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
585 TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
586 : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
587 assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
588 ::memcpy(Guid.Guid, GuidStr.data(), 16);
591 const GUID &getGuid() const { return Guid; }
592 uint32_t getAge() const { return Age; }
593 StringRef getName() const { return Name; }
601 class StringIdRecord : public TypeRecord {
603 StringIdRecord() = default;
604 explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
605 StringIdRecord(TypeIndex Id, StringRef String)
606 : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
608 TypeIndex getId() const { return Id; }
609 StringRef getString() const { return String; }
616 class FuncIdRecord : public TypeRecord {
618 FuncIdRecord() = default;
619 explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
620 FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
621 : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
622 FunctionType(FunctionType), Name(Name) {}
624 TypeIndex getParentScope() const { return ParentScope; }
625 TypeIndex getFunctionType() const { return FunctionType; }
626 StringRef getName() const { return Name; }
628 TypeIndex ParentScope;
629 TypeIndex FunctionType;
634 class UdtSourceLineRecord : public TypeRecord {
636 UdtSourceLineRecord() = default;
637 explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
638 UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
639 : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
640 SourceFile(SourceFile), LineNumber(LineNumber) {}
642 TypeIndex getUDT() const { return UDT; }
643 TypeIndex getSourceFile() const { return SourceFile; }
644 uint32_t getLineNumber() const { return LineNumber; }
647 TypeIndex SourceFile;
651 // LF_UDT_MOD_SRC_LINE
652 class UdtModSourceLineRecord : public TypeRecord {
654 UdtModSourceLineRecord() = default;
655 explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
656 UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile,
657 uint32_t LineNumber, uint16_t Module)
658 : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
659 SourceFile(SourceFile), LineNumber(LineNumber), Module(Module) {}
661 TypeIndex getUDT() const { return UDT; }
662 TypeIndex getSourceFile() const { return SourceFile; }
663 uint32_t getLineNumber() const { return LineNumber; }
664 uint16_t getModule() const { return Module; }
667 TypeIndex SourceFile;
673 class BuildInfoRecord : public TypeRecord {
675 BuildInfoRecord() = default;
676 explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
677 BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
678 : TypeRecord(TypeRecordKind::BuildInfo),
679 ArgIndices(ArgIndices.begin(), ArgIndices.end()) {}
681 ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
683 /// Indices of known build info arguments.
685 CurrentDirectory, ///< Absolute CWD path
686 BuildTool, ///< Absolute compiler path
687 SourceFile, ///< Path to main source file, relative or absolute
688 TypeServerPDB, ///< Absolute path of type server PDB (/Fd)
689 CommandLine, ///< Full canonical command line (maybe -cc1)
693 SmallVector<TypeIndex, MaxArgs> ArgIndices;
697 class VFTableRecord : public TypeRecord {
699 VFTableRecord() = default;
700 explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
701 VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
702 uint32_t VFPtrOffset, StringRef Name,
703 ArrayRef<StringRef> Methods)
704 : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass),
705 OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) {
706 MethodNames.push_back(Name);
707 MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end());
710 TypeIndex getCompleteClass() const { return CompleteClass; }
711 TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
712 uint32_t getVFPtrOffset() const { return VFPtrOffset; }
713 StringRef getName() const { return makeArrayRef(MethodNames).front(); }
715 ArrayRef<StringRef> getMethodNames() const {
716 return makeArrayRef(MethodNames).drop_front();
719 TypeIndex CompleteClass;
720 TypeIndex OverriddenVFTable;
721 uint32_t VFPtrOffset;
722 std::vector<StringRef> MethodNames;
726 class OneMethodRecord : public TypeRecord {
728 OneMethodRecord() = default;
729 explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
730 OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
732 : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs),
733 VFTableOffset(VFTableOffset), Name(Name) {}
734 OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind MK,
735 MethodOptions Options, int32_t VFTableOffset, StringRef Name)
736 : TypeRecord(TypeRecordKind::OneMethod), Type(Type),
737 Attrs(Access, MK, Options), VFTableOffset(VFTableOffset), Name(Name) {}
739 TypeIndex getType() const { return Type; }
740 MethodKind getMethodKind() const { return Attrs.getMethodKind(); }
741 MethodOptions getOptions() const { return Attrs.getFlags(); }
742 MemberAccess getAccess() const { return Attrs.getAccess(); }
743 int32_t getVFTableOffset() const { return VFTableOffset; }
744 StringRef getName() const { return Name; }
746 bool isIntroducingVirtual() const {
747 return getMethodKind() == MethodKind::IntroducingVirtual ||
748 getMethodKind() == MethodKind::PureIntroducingVirtual;
752 MemberAttributes Attrs;
753 int32_t VFTableOffset;
758 class MethodOverloadListRecord : public TypeRecord {
760 MethodOverloadListRecord() = default;
761 explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
762 MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
763 : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
765 ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
767 std::vector<OneMethodRecord> Methods;
770 /// For method overload sets. LF_METHOD
771 class OverloadedMethodRecord : public TypeRecord {
773 OverloadedMethodRecord() = default;
774 explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
775 OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
777 : TypeRecord(TypeRecordKind::OverloadedMethod),
778 NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
780 uint16_t getNumOverloads() const { return NumOverloads; }
781 TypeIndex getMethodList() const { return MethodList; }
782 StringRef getName() const { return Name; }
784 uint16_t NumOverloads;
785 TypeIndex MethodList;
790 class DataMemberRecord : public TypeRecord {
792 DataMemberRecord() = default;
793 explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
794 DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
796 : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
797 FieldOffset(Offset), Name(Name) {}
798 DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
800 : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
801 FieldOffset(Offset), Name(Name) {}
803 MemberAccess getAccess() const { return Attrs.getAccess(); }
804 TypeIndex getType() const { return Type; }
805 uint64_t getFieldOffset() const { return FieldOffset; }
806 StringRef getName() const { return Name; }
808 MemberAttributes Attrs;
810 uint64_t FieldOffset;
815 class StaticDataMemberRecord : public TypeRecord {
817 StaticDataMemberRecord() = default;
818 explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
819 StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name)
820 : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type),
822 StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
823 : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
826 MemberAccess getAccess() const { return Attrs.getAccess(); }
827 TypeIndex getType() const { return Type; }
828 StringRef getName() const { return Name; }
830 MemberAttributes Attrs;
836 class EnumeratorRecord : public TypeRecord {
838 EnumeratorRecord() = default;
839 explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
840 EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name)
841 : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs),
842 Value(std::move(Value)), Name(Name) {}
843 EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
844 : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access),
845 Value(std::move(Value)), Name(Name) {}
847 MemberAccess getAccess() const { return Attrs.getAccess(); }
848 APSInt getValue() const { return Value; }
849 StringRef getName() const { return Name; }
851 MemberAttributes Attrs;
857 class VFPtrRecord : public TypeRecord {
859 VFPtrRecord() = default;
860 explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
861 VFPtrRecord(TypeIndex Type)
862 : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
864 TypeIndex getType() const { return Type; }
869 // LF_BCLASS, LF_BINTERFACE
870 class BaseClassRecord : public TypeRecord {
872 BaseClassRecord() = default;
873 explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
874 BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset)
875 : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type),
877 BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
878 : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
881 MemberAccess getAccess() const { return Attrs.getAccess(); }
882 TypeIndex getBaseType() const { return Type; }
883 uint64_t getBaseOffset() const { return Offset; }
885 MemberAttributes Attrs;
890 // LF_VBCLASS, LF_IVBCLASS
891 class VirtualBaseClassRecord : public TypeRecord {
893 VirtualBaseClassRecord() = default;
894 explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
895 VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs,
896 TypeIndex BaseType, TypeIndex VBPtrType,
897 uint64_t Offset, uint64_t Index)
898 : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType),
899 VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
900 VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access,
901 TypeIndex BaseType, TypeIndex VBPtrType,
902 uint64_t Offset, uint64_t Index)
903 : TypeRecord(Kind), Attrs(Access), BaseType(BaseType),
904 VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {}
906 MemberAccess getAccess() const { return Attrs.getAccess(); }
907 TypeIndex getBaseType() const { return BaseType; }
908 TypeIndex getVBPtrType() const { return VBPtrType; }
909 uint64_t getVBPtrOffset() const { return VBPtrOffset; }
910 uint64_t getVTableIndex() const { return VTableIndex; }
912 MemberAttributes Attrs;
915 uint64_t VBPtrOffset;
916 uint64_t VTableIndex;
919 /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records
920 /// together. The first will end in an LF_INDEX record that points to the next.
921 class ListContinuationRecord : public TypeRecord {
923 ListContinuationRecord() = default;
924 explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
925 ListContinuationRecord(TypeIndex ContinuationIndex)
926 : TypeRecord(TypeRecordKind::ListContinuation),
927 ContinuationIndex(ContinuationIndex) {}
929 TypeIndex getContinuationIndex() const { return ContinuationIndex; }
931 TypeIndex ContinuationIndex;
935 class PrecompRecord : public TypeRecord {
937 PrecompRecord() = default;
938 explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
940 uint32_t getStartTypeIndex() const { return StartTypeIndex; }
941 uint32_t getTypesCount() const { return TypesCount; }
942 uint32_t getSignature() const { return Signature; }
943 StringRef getPrecompFilePath() const { return PrecompFilePath; }
945 uint32_t StartTypeIndex;
948 StringRef PrecompFilePath;
952 class EndPrecompRecord : public TypeRecord {
954 EndPrecompRecord() = default;
955 explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
957 uint32_t getSignature() const { return Signature; }
962 } // end namespace codeview
963 } // end namespace llvm
965 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H