1 //===- TypeRecord.h ---------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
10 #define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
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"
31 using support::little32_t;
32 using support::ulittle16_t;
33 using support::ulittle32_t;
35 using CVType = CVRecord<TypeLeafKind>;
36 using RemappedType = RemappedRecord<TypeLeafKind>;
38 struct CVMemberRecord {
40 ArrayRef<uint8_t> Data;
42 using CVTypeArray = VarStreamArray<CVType>;
43 using CVTypeRange = iterator_range<CVTypeArray::Iterator>;
45 /// Equvalent to CV_fldattr_t in cvinfo.h.
46 struct MemberAttributes {
53 MemberAttributes() = default;
55 explicit MemberAttributes(MemberAccess Access)
56 : Attrs(static_cast<uint16_t>(Access)) {}
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);
64 /// Get the access specifier. Valid for any kind of member.
65 MemberAccess getAccess() const {
66 return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
69 /// Indicates if a method is defined with friend, virtual, static, etc.
70 MethodKind getMethodKind() const {
72 (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >>
76 /// Get the flags that are not included in access control or method
78 MethodOptions getFlags() const {
81 ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
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;
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;
98 /// Is this method static.
99 bool isStatic() const {
100 return getMethodKind() == MethodKind::Static;
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 {
108 MemberPointerInfo() = default;
110 MemberPointerInfo(TypeIndex ContainingType,
111 PointerToMemberRepresentation Representation)
112 : ContainingType(ContainingType), Representation(Representation) {}
114 TypeIndex getContainingType() const { return ContainingType; }
115 PointerToMemberRepresentation getRepresentation() const {
116 return Representation;
119 TypeIndex ContainingType;
120 PointerToMemberRepresentation Representation;
125 TypeRecord() = default;
126 explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
129 TypeRecordKind getKind() const { return Kind; }
135 class ModifierRecord : public TypeRecord {
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) {}
143 TypeIndex getModifiedType() const { return ModifiedType; }
144 ModifierOptions getModifiers() const { return Modifiers; }
146 TypeIndex ModifiedType;
147 ModifierOptions Modifiers;
151 class ProcedureRecord : public TypeRecord {
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) {}
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; }
168 TypeIndex ReturnType;
169 CallingConvention CallConv;
170 FunctionOptions Options;
171 uint16_t ParameterCount;
172 TypeIndex ArgumentList;
176 class MemberFunctionRecord : public TypeRecord {
178 MemberFunctionRecord() = default;
179 explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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) {}
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; }
200 TypeIndex ReturnType;
203 CallingConvention CallConv;
204 FunctionOptions Options;
205 uint16_t ParameterCount;
206 TypeIndex ArgumentList;
207 int32_t ThisPointerAdjustment;
211 class LabelRecord : public TypeRecord {
213 LabelRecord() = default;
214 explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
216 LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {}
222 class MemberFuncIdRecord : public TypeRecord {
224 MemberFuncIdRecord() = default;
225 explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
226 MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
228 : TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
229 FunctionType(FunctionType), Name(Name) {}
231 TypeIndex getClassType() const { return ClassType; }
232 TypeIndex getFunctionType() const { return FunctionType; }
233 StringRef getName() const { return Name; }
236 TypeIndex FunctionType;
241 class ArgListRecord : public TypeRecord {
243 ArgListRecord() = default;
244 explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
246 ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
247 : TypeRecord(Kind), ArgIndices(Indices) {}
249 ArrayRef<TypeIndex> getIndices() const { return ArgIndices; }
251 std::vector<TypeIndex> ArgIndices;
255 class StringListRecord : public TypeRecord {
257 StringListRecord() = default;
258 explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
260 StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
261 : TypeRecord(Kind), StringIndices(Indices) {}
263 ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
265 std::vector<TypeIndex> StringIndices;
269 class PointerRecord : public TypeRecord {
271 // ---------------------------XXXXX
272 static const uint32_t PointerKindShift = 0;
273 static const uint32_t PointerKindMask = 0x1F;
275 // ------------------------XXX-----
276 static const uint32_t PointerModeShift = 5;
277 static const uint32_t PointerModeMask = 0x07;
279 // ----------XXX------XXXXX--------
280 static const uint32_t PointerOptionMask = 0x381f00;
282 // -------------XXXXXX------------
283 static const uint32_t PointerSizeShift = 13;
284 static const uint32_t PointerSizeMask = 0xFF;
286 PointerRecord() = default;
287 explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
289 PointerRecord(TypeIndex ReferentType, uint32_t Attrs)
290 : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
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)) {}
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) {}
303 TypeIndex getReferentType() const { return ReferentType; }
305 PointerKind getPointerKind() const {
306 return static_cast<PointerKind>((Attrs >> PointerKindShift) &
310 PointerMode getMode() const {
311 return static_cast<PointerMode>((Attrs >> PointerModeShift) &
315 PointerOptions getOptions() const {
316 return static_cast<PointerOptions>(Attrs & PointerOptionMask);
319 uint8_t getSize() const {
320 return (Attrs >> PointerSizeShift) & PointerSizeMask;
323 MemberPointerInfo getMemberInfo() const { return *MemberInfo; }
325 bool isPointerToMember() const {
326 return getMode() == PointerMode::PointerToDataMember ||
327 getMode() == PointerMode::PointerToMemberFunction;
330 bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); }
331 bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); }
333 bool isVolatile() const {
334 return !!(Attrs & uint32_t(PointerOptions::Volatile));
337 bool isUnaligned() const {
338 return !!(Attrs & uint32_t(PointerOptions::Unaligned));
341 bool isRestrict() const {
342 return !!(Attrs & uint32_t(PointerOptions::Restrict));
345 bool isLValueReferenceThisPtr() const {
346 return !!(Attrs & uint32_t(PointerOptions::LValueRefThisPointer));
349 bool isRValueReferenceThisPtr() const {
350 return !!(Attrs & uint32_t(PointerOptions::RValueRefThisPointer));
353 TypeIndex ReferentType;
355 Optional<MemberPointerInfo> MemberInfo;
357 void setAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
359 Attrs = calcAttrs(PK, PM, PO, Size);
363 static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO,
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);
375 class NestedTypeRecord : public TypeRecord {
377 NestedTypeRecord() = default;
378 explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
379 NestedTypeRecord(TypeIndex Type, StringRef Name)
380 : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
382 TypeIndex getNestedType() const { return Type; }
383 StringRef getName() const { return Name; }
390 class FieldListRecord : public TypeRecord {
392 FieldListRecord() = default;
393 explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
394 explicit FieldListRecord(ArrayRef<uint8_t> Data)
395 : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}
397 ArrayRef<uint8_t> Data;
401 class ArrayRecord : public TypeRecord {
403 ArrayRecord() = default;
404 explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
405 ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
407 : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
408 IndexType(IndexType), Size(Size), Name(Name) {}
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; }
415 TypeIndex ElementType;
421 class TagRecord : public TypeRecord {
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) {}
431 static const int HfaKindShift = 11;
432 static const int HfaKindMask = 0x1800;
433 static const int WinRTKindShift = 14;
434 static const int WinRTKindMask = 0xC000;
436 bool hasUniqueName() const {
437 return (Options & ClassOptions::HasUniqueName) != ClassOptions::None;
440 bool isNested() const {
441 return (Options & ClassOptions::Nested) != ClassOptions::None;
444 bool isForwardRef() const {
445 return (Options & ClassOptions::ForwardReference) != ClassOptions::None;
448 bool containsNestedClass() const {
449 return (Options & ClassOptions::ContainsNestedClass) != ClassOptions::None;
452 bool isScoped() const {
453 return (Options & ClassOptions::Scoped) != ClassOptions::None;
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; }
462 uint16_t MemberCount;
463 ClassOptions Options;
466 StringRef UniqueName;
469 // LF_CLASS, LF_STRUCTURE, LF_INTERFACE
470 class ClassRecord : public TagRecord {
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) {}
481 HfaKind getHfa() const {
482 uint16_t Value = static_cast<uint16_t>(Options);
483 Value = (Value & HfaKindMask) >> HfaKindShift;
484 return static_cast<HfaKind>(Value);
487 WindowsRTClassKind getWinRTKind() const {
488 uint16_t Value = static_cast<uint16_t>(Options);
489 Value = (Value & WinRTKindMask) >> WinRTKindShift;
490 return static_cast<WindowsRTClassKind>(Value);
493 TypeIndex getDerivationList() const { return DerivationList; }
494 TypeIndex getVTableShape() const { return VTableShape; }
495 uint64_t getSize() const { return Size; }
497 TypeIndex DerivationList;
498 TypeIndex VTableShape;
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,
512 HfaKind getHfa() const {
513 uint16_t Value = static_cast<uint16_t>(Options);
514 Value = (Value & HfaKindMask) >> HfaKindShift;
515 return static_cast<HfaKind>(Value);
518 uint64_t getSize() const { return Size; }
524 class EnumRecord : public TagRecord {
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,
532 UnderlyingType(UnderlyingType) {}
534 TypeIndex getUnderlyingType() const { return UnderlyingType; }
536 TypeIndex UnderlyingType;
540 class BitFieldRecord : public TypeRecord {
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) {}
548 TypeIndex getType() const { return Type; }
549 uint8_t getBitOffset() const { return BitOffset; }
550 uint8_t getBitSize() const { return BitSize; }
558 class VFTableShapeRecord : public TypeRecord {
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)) {}
567 ArrayRef<VFTableSlotKind> getSlots() const {
568 if (!SlotsRef.empty())
573 uint32_t getEntryCount() const { return getSlots().size(); }
575 ArrayRef<VFTableSlotKind> SlotsRef;
576 std::vector<VFTableSlotKind> Slots;
580 class TypeServer2Record : public TypeRecord {
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);
590 const GUID &getGuid() const { return Guid; }
591 uint32_t getAge() const { return Age; }
592 StringRef getName() const { return Name; }
600 class StringIdRecord : public TypeRecord {
602 StringIdRecord() = default;
603 explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
604 StringIdRecord(TypeIndex Id, StringRef String)
605 : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
607 TypeIndex getId() const { return Id; }
608 StringRef getString() const { return String; }
615 class FuncIdRecord : public TypeRecord {
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) {}
623 TypeIndex getParentScope() const { return ParentScope; }
624 TypeIndex getFunctionType() const { return FunctionType; }
625 StringRef getName() const { return Name; }
627 TypeIndex ParentScope;
628 TypeIndex FunctionType;
633 class UdtSourceLineRecord : public TypeRecord {
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) {}
641 TypeIndex getUDT() const { return UDT; }
642 TypeIndex getSourceFile() const { return SourceFile; }
643 uint32_t getLineNumber() const { return LineNumber; }
646 TypeIndex SourceFile;
650 // LF_UDT_MOD_SRC_LINE
651 class UdtModSourceLineRecord : public TypeRecord {
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) {}
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; }
666 TypeIndex SourceFile;
672 class BuildInfoRecord : public TypeRecord {
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()) {}
680 ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
682 /// Indices of known build info arguments.
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)
692 SmallVector<TypeIndex, MaxArgs> ArgIndices;
696 class VFTableRecord : public TypeRecord {
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());
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(); }
714 ArrayRef<StringRef> getMethodNames() const {
715 return makeArrayRef(MethodNames).drop_front();
718 TypeIndex CompleteClass;
719 TypeIndex OverriddenVFTable;
720 uint32_t VFPtrOffset;
721 std::vector<StringRef> MethodNames;
725 class OneMethodRecord : public TypeRecord {
727 OneMethodRecord() = default;
728 explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
729 OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset,
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) {}
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; }
745 bool isIntroducingVirtual() const {
746 return getMethodKind() == MethodKind::IntroducingVirtual ||
747 getMethodKind() == MethodKind::PureIntroducingVirtual;
751 MemberAttributes Attrs;
752 int32_t VFTableOffset;
757 class MethodOverloadListRecord : public TypeRecord {
759 MethodOverloadListRecord() = default;
760 explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
761 MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
762 : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
764 ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
766 std::vector<OneMethodRecord> Methods;
769 /// For method overload sets. LF_METHOD
770 class OverloadedMethodRecord : public TypeRecord {
772 OverloadedMethodRecord() = default;
773 explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
774 OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
776 : TypeRecord(TypeRecordKind::OverloadedMethod),
777 NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
779 uint16_t getNumOverloads() const { return NumOverloads; }
780 TypeIndex getMethodList() const { return MethodList; }
781 StringRef getName() const { return Name; }
783 uint16_t NumOverloads;
784 TypeIndex MethodList;
789 class DataMemberRecord : public TypeRecord {
791 DataMemberRecord() = default;
792 explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
793 DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset,
795 : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type),
796 FieldOffset(Offset), Name(Name) {}
797 DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
799 : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type),
800 FieldOffset(Offset), Name(Name) {}
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; }
807 MemberAttributes Attrs;
809 uint64_t FieldOffset;
814 class StaticDataMemberRecord : public TypeRecord {
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),
821 StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
822 : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type),
825 MemberAccess getAccess() const { return Attrs.getAccess(); }
826 TypeIndex getType() const { return Type; }
827 StringRef getName() const { return Name; }
829 MemberAttributes Attrs;
835 class EnumeratorRecord : public TypeRecord {
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) {}
846 MemberAccess getAccess() const { return Attrs.getAccess(); }
847 APSInt getValue() const { return Value; }
848 StringRef getName() const { return Name; }
850 MemberAttributes Attrs;
856 class VFPtrRecord : public TypeRecord {
858 VFPtrRecord() = default;
859 explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
860 VFPtrRecord(TypeIndex Type)
861 : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
863 TypeIndex getType() const { return Type; }
868 // LF_BCLASS, LF_BINTERFACE
869 class BaseClassRecord : public TypeRecord {
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),
876 BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
877 : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type),
880 MemberAccess getAccess() const { return Attrs.getAccess(); }
881 TypeIndex getBaseType() const { return Type; }
882 uint64_t getBaseOffset() const { return Offset; }
884 MemberAttributes Attrs;
889 // LF_VBCLASS, LF_IVBCLASS
890 class VirtualBaseClassRecord : public TypeRecord {
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) {}
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; }
911 MemberAttributes Attrs;
914 uint64_t VBPtrOffset;
915 uint64_t VTableIndex;
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 {
922 ListContinuationRecord() = default;
923 explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
924 ListContinuationRecord(TypeIndex ContinuationIndex)
925 : TypeRecord(TypeRecordKind::ListContinuation),
926 ContinuationIndex(ContinuationIndex) {}
928 TypeIndex getContinuationIndex() const { return ContinuationIndex; }
930 TypeIndex ContinuationIndex;
934 class PrecompRecord : public TypeRecord {
936 PrecompRecord() = default;
937 explicit PrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
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; }
944 uint32_t StartTypeIndex;
947 StringRef PrecompFilePath;
951 class EndPrecompRecord : public TypeRecord {
953 EndPrecompRecord() = default;
954 explicit EndPrecompRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}
956 uint32_t getSignature() const { return Signature; }
961 } // end namespace codeview
962 } // end namespace llvm
964 #endif // LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H