Index: include/llvm/DebugInfo/CodeView/CVLeafTypes.def =================================================================== --- include/llvm/DebugInfo/CodeView/CVLeafTypes.def +++ /dev/null @@ -1,217 +0,0 @@ -//===-- CVLeafTypes.def - All CodeView leaf types ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// See LEAF_ENUM_e in cvinfo.h. This should match the constants there. -// -//===----------------------------------------------------------------------===// - -#ifndef LEAF_TYPE -#define LEAF_TYPE(ename, value) -#endif - -// If the type is known, then we have a record describing it in TypeRecord.h. -#ifndef KNOWN_TYPE -#define KNOWN_TYPE(ename, value, class_name) LEAF_TYPE(ename, value) -#endif - -// 16 bit type records. -LEAF_TYPE(LF_MODIFIER_16t, 0x0001) -LEAF_TYPE(LF_POINTER_16t, 0x0002) -LEAF_TYPE(LF_ARRAY_16t, 0x0003) -LEAF_TYPE(LF_CLASS_16t, 0x0004) -LEAF_TYPE(LF_STRUCTURE_16t, 0x0005) -LEAF_TYPE(LF_UNION_16t, 0x0006) -LEAF_TYPE(LF_ENUM_16t, 0x0007) -LEAF_TYPE(LF_PROCEDURE_16t, 0x0008) -LEAF_TYPE(LF_MFUNCTION_16t, 0x0009) -KNOWN_TYPE(LF_VTSHAPE, 0x000a, VTableShape) -LEAF_TYPE(LF_COBOL0_16t, 0x000b) -LEAF_TYPE(LF_COBOL1, 0x000c) -LEAF_TYPE(LF_BARRAY_16t, 0x000d) -LEAF_TYPE(LF_LABEL, 0x000e) -LEAF_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL -LEAF_TYPE(LF_NOTTRAN, 0x0010) -LEAF_TYPE(LF_DIMARRAY_16t, 0x0011) -LEAF_TYPE(LF_VFTPATH_16t, 0x0012) -LEAF_TYPE(LF_PRECOMP_16t, 0x0013) -LEAF_TYPE(LF_ENDPRECOMP, 0x0014) -LEAF_TYPE(LF_OEM_16t, 0x0015) -LEAF_TYPE(LF_TYPESERVER_ST, 0x0016) - -LEAF_TYPE(LF_SKIP_16t, 0x0200) -LEAF_TYPE(LF_ARGLIST_16t, 0x0201) -LEAF_TYPE(LF_DEFARG_16t, 0x0202) -LEAF_TYPE(LF_LIST, 0x0203) -LEAF_TYPE(LF_FIELDLIST_16t, 0x0204) -LEAF_TYPE(LF_DERIVED_16t, 0x0205) -LEAF_TYPE(LF_BITFIELD_16t, 0x0206) -LEAF_TYPE(LF_METHODLIST_16t, 0x0207) -LEAF_TYPE(LF_DIMCONU_16t, 0x0208) -LEAF_TYPE(LF_DIMCONLU_16t, 0x0209) -LEAF_TYPE(LF_DIMVARU_16t, 0x020a) -LEAF_TYPE(LF_DIMVARLU_16t, 0x020b) -LEAF_TYPE(LF_REFSYM, 0x020c) - -// 16 bit member types. Generally not length prefixed. -LEAF_TYPE(LF_BCLASS_16t, 0x0400) -LEAF_TYPE(LF_VBCLASS_16t, 0x0401) -LEAF_TYPE(LF_IVBCLASS_16t, 0x0402) -LEAF_TYPE(LF_ENUMERATE_ST, 0x0403) -LEAF_TYPE(LF_FRIENDFCN_16t, 0x0404) -LEAF_TYPE(LF_INDEX_16t, 0x0405) -LEAF_TYPE(LF_MEMBER_16t, 0x0406) -LEAF_TYPE(LF_STMEMBER_16t, 0x0407) -LEAF_TYPE(LF_METHOD_16t, 0x0408) -LEAF_TYPE(LF_NESTTYPE_16t, 0x0409) -LEAF_TYPE(LF_VFUNCTAB_16t, 0x040a) -LEAF_TYPE(LF_FRIENDCLS_16t, 0x040b) -LEAF_TYPE(LF_ONEMETHOD_16t, 0x040c) -LEAF_TYPE(LF_VFUNCOFF_16t, 0x040d) - -LEAF_TYPE(LF_TI16_MAX, 0x1000) - -KNOWN_TYPE(LF_MODIFIER, 0x1001, TypeModifier) -KNOWN_TYPE(LF_POINTER, 0x1002, PointerType) -LEAF_TYPE(LF_ARRAY_ST, 0x1003) -LEAF_TYPE(LF_CLASS_ST, 0x1004) -LEAF_TYPE(LF_STRUCTURE_ST, 0x1005) -LEAF_TYPE(LF_UNION_ST, 0x1006) -LEAF_TYPE(LF_ENUM_ST, 0x1007) -KNOWN_TYPE(LF_PROCEDURE, 0x1008, ProcedureType) -KNOWN_TYPE(LF_MFUNCTION, 0x1009, MemberFunctionType) -LEAF_TYPE(LF_COBOL0, 0x100a) -LEAF_TYPE(LF_BARRAY, 0x100b) -LEAF_TYPE(LF_DIMARRAY_ST, 0x100c) -LEAF_TYPE(LF_VFTPATH, 0x100d) -LEAF_TYPE(LF_PRECOMP_ST, 0x100e) -LEAF_TYPE(LF_OEM, 0x100f) -LEAF_TYPE(LF_ALIAS_ST, 0x1010) -LEAF_TYPE(LF_OEM2, 0x1011) - -LEAF_TYPE(LF_SKIP, 0x1200) -KNOWN_TYPE(LF_ARGLIST, 0x1201, ArgList) -LEAF_TYPE(LF_DEFARG_ST, 0x1202) -LEAF_TYPE(LF_FIELDLIST, 0x1203) -LEAF_TYPE(LF_DERIVED, 0x1204) -LEAF_TYPE(LF_BITFIELD, 0x1205) -KNOWN_TYPE(LF_METHODLIST, 0x1206, MethodListEntry) -LEAF_TYPE(LF_DIMCONU, 0x1207) -LEAF_TYPE(LF_DIMCONLU, 0x1208) -LEAF_TYPE(LF_DIMVARU, 0x1209) -LEAF_TYPE(LF_DIMVARLU, 0x120a) - -// Member type records. These are generally not length prefixed, and appear -// inside of a field list record. -KNOWN_TYPE(LF_BCLASS, 0x1400, BaseClass) -KNOWN_TYPE(LF_VBCLASS, 0x1401, VirtualBaseClass) -KNOWN_TYPE(LF_IVBCLASS, 0x1402, VirtualBaseClass) -LEAF_TYPE(LF_FRIENDFCN_ST, 0x1403) -LEAF_TYPE(LF_INDEX, 0x1404) -LEAF_TYPE(LF_MEMBER_ST, 0x1405) -LEAF_TYPE(LF_STMEMBER_ST, 0x1406) -LEAF_TYPE(LF_METHOD_ST, 0x1407) -LEAF_TYPE(LF_NESTTYPE_ST, 0x1408) -KNOWN_TYPE(LF_VFUNCTAB, 0x1409, VirtualFunctionPointer) -LEAF_TYPE(LF_FRIENDCLS, 0x140a) -LEAF_TYPE(LF_ONEMETHOD_ST, 0x140b) -LEAF_TYPE(LF_VFUNCOFF, 0x140c) -LEAF_TYPE(LF_NESTTYPEEX_ST, 0x140d) -LEAF_TYPE(LF_MEMBERMODIFY_ST, 0x140e) -LEAF_TYPE(LF_MANAGED_ST, 0x140f) - -LEAF_TYPE(LF_ST_MAX, 0x1500) -LEAF_TYPE(LF_TYPESERVER, 0x1501) -KNOWN_TYPE(LF_ENUMERATE, 0x1502, Enumerator) -KNOWN_TYPE(LF_ARRAY, 0x1503, ArrayType) -KNOWN_TYPE(LF_CLASS, 0x1504, ClassType) -KNOWN_TYPE(LF_STRUCTURE, 0x1505, ClassType) -KNOWN_TYPE(LF_UNION, 0x1506, UnionType) -KNOWN_TYPE(LF_ENUM, 0x1507, EnumType) -LEAF_TYPE(LF_DIMARRAY, 0x1508) -LEAF_TYPE(LF_PRECOMP, 0x1509) -LEAF_TYPE(LF_ALIAS, 0x150a) -LEAF_TYPE(LF_DEFARG, 0x150b) -LEAF_TYPE(LF_FRIENDFCN, 0x150c) -KNOWN_TYPE(LF_MEMBER, 0x150d, DataMember) -KNOWN_TYPE(LF_STMEMBER, 0x150e, StaticDataMember) -KNOWN_TYPE(LF_METHOD, 0x150f, OverloadedMethod) -KNOWN_TYPE(LF_NESTTYPE, 0x1510, NestedType) -KNOWN_TYPE(LF_ONEMETHOD, 0x1511, OneMethod) -LEAF_TYPE(LF_NESTTYPEEX, 0x1512) -LEAF_TYPE(LF_MEMBERMODIFY, 0x1513) -LEAF_TYPE(LF_MANAGED, 0x1514) -KNOWN_TYPE(LF_TYPESERVER2, 0x1515, TypeServer2) -LEAF_TYPE(LF_STRIDED_ARRAY, 0x1516) -LEAF_TYPE(LF_HLSL, 0x1517) -LEAF_TYPE(LF_MODIFIER_EX, 0x1518) -KNOWN_TYPE(LF_INTERFACE, 0x1519, ClassType) -KNOWN_TYPE(LF_BINTERFACE, 0x151a, BaseClass) -LEAF_TYPE(LF_VECTOR, 0x151b) -LEAF_TYPE(LF_MATRIX, 0x151c) -KNOWN_TYPE(LF_VFTABLE, 0x151d, VFTableType) - -// ID leaf records. Subsequent leaf types may be referenced from .debug$S. - -KNOWN_TYPE(LF_FUNC_ID, 0x1601, FuncId) -KNOWN_TYPE(LF_MFUNC_ID, 0x1602, MemberFuncId) -KNOWN_TYPE(LF_BUILDINFO, 0x1603, BuildInfo) -KNOWN_TYPE(LF_SUBSTR_LIST, 0x1604, ArgList) -KNOWN_TYPE(LF_STRING_ID, 0x1605, StringId) -KNOWN_TYPE(LF_UDT_SRC_LINE, 0x1606, UDTSrcLine) -LEAF_TYPE(LF_UDT_MOD_SRC_LINE, 0x1607) - -// Numeric leaf types. These are generally contained in other records, and not -// encountered in the main type stream. - -LEAF_TYPE(LF_NUMERIC, 0x8000) -LEAF_TYPE(LF_CHAR, 0x8000) -LEAF_TYPE(LF_SHORT, 0x8001) -LEAF_TYPE(LF_USHORT, 0x8002) -LEAF_TYPE(LF_LONG, 0x8003) -LEAF_TYPE(LF_ULONG, 0x8004) -LEAF_TYPE(LF_REAL32, 0x8005) -LEAF_TYPE(LF_REAL64, 0x8006) -LEAF_TYPE(LF_REAL80, 0x8007) -LEAF_TYPE(LF_REAL128, 0x8008) -LEAF_TYPE(LF_QUADWORD, 0x8009) -LEAF_TYPE(LF_UQUADWORD, 0x800a) -LEAF_TYPE(LF_REAL48, 0x800b) -LEAF_TYPE(LF_COMPLEX32, 0x800c) -LEAF_TYPE(LF_COMPLEX64, 0x800d) -LEAF_TYPE(LF_COMPLEX80, 0x800e) -LEAF_TYPE(LF_COMPLEX128, 0x800f) -LEAF_TYPE(LF_VARSTRING, 0x8010) -LEAF_TYPE(LF_OCTWORD, 0x8017) -LEAF_TYPE(LF_UOCTWORD, 0x8018) -LEAF_TYPE(LF_DECIMAL, 0x8019) -LEAF_TYPE(LF_DATE, 0x801a) -LEAF_TYPE(LF_UTF8STRING, 0x801b) -LEAF_TYPE(LF_REAL16, 0x801c) - -// Padding bytes. These are emitted into alignment bytes in the type stream. - -LEAF_TYPE(LF_PAD0, 0xf0) -LEAF_TYPE(LF_PAD1, 0xf1) -LEAF_TYPE(LF_PAD2, 0xf2) -LEAF_TYPE(LF_PAD3, 0xf3) -LEAF_TYPE(LF_PAD4, 0xf4) -LEAF_TYPE(LF_PAD5, 0xf5) -LEAF_TYPE(LF_PAD6, 0xf6) -LEAF_TYPE(LF_PAD7, 0xf7) -LEAF_TYPE(LF_PAD8, 0xf8) -LEAF_TYPE(LF_PAD9, 0xf9) -LEAF_TYPE(LF_PAD10, 0xfa) -LEAF_TYPE(LF_PAD11, 0xfb) -LEAF_TYPE(LF_PAD12, 0xfc) -LEAF_TYPE(LF_PAD13, 0xfd) -LEAF_TYPE(LF_PAD14, 0xfe) -LEAF_TYPE(LF_PAD15, 0xff) - -#undef KNOWN_TYPE -#undef LEAF_TYPE Index: include/llvm/DebugInfo/CodeView/CVTypeVisitor.h =================================================================== --- include/llvm/DebugInfo/CodeView/CVTypeVisitor.h +++ include/llvm/DebugInfo/CodeView/CVTypeVisitor.h @@ -42,12 +42,12 @@ /// expected to consume the trailing bytes used by the field. /// FIXME: Make the visitor interpret the trailing bytes so that clients don't /// need to. -#define TYPE_RECORD(ClassName, LeafEnum) \ +#define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \ void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {} -#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) -#define MEMBER_RECORD(ClassName, LeafEnum) \ +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, ClassName, PrintName) +#define MEMBER_RECORD(EnumName, EnumVal, ClassName, PrintName) \ void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {} -#define MEMBER_RECORD_ALIAS(ClassName, LeafEnum) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, ClassName, PrintName) #include "TypeRecords.def" void visitTypeRecord(const TypeIterator::Record &Record) { @@ -62,12 +62,9 @@ case LF_FIELDLIST: DerivedThis->visitFieldList(Record.Type, LeafData); break; - case LF_METHODLIST: - DerivedThis->visitMethodList(Record.Type, LeafData); - break; -#define TYPE_RECORD(ClassName, LeafEnum) \ - case LeafEnum: { \ - TypeRecordKind RK = static_cast(LeafEnum); \ +#define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \ + case EnumName: { \ + TypeRecordKind RK = static_cast(EnumName); \ auto Result = ClassName::deserialize(RK, LeafData); \ if (Result.getError()) \ return parseError(); \ @@ -118,9 +115,9 @@ // continue parsing past an unknown member type. visitUnknownMember(Leaf); return parseError(); -#define MEMBER_RECORD(ClassName, LeafEnum) \ - case LeafEnum: { \ - TypeRecordKind RK = static_cast(LeafEnum); \ +#define MEMBER_RECORD(EnumName, EnumVal, ClassName, PrintName) \ + case EnumName: { \ + TypeRecordKind RK = static_cast(EnumName); \ auto Result = ClassName::deserialize(RK, FieldData); \ if (Result.getError()) \ return parseError(); \ @@ -133,12 +130,6 @@ } } - /// Action to take on method overload lists, which do not have a common record - /// prefix. The LeafData is composed of MethodListEntry objects, each of which - /// may have a trailing 32-bit vftable offset. - /// FIXME: Hoist this complexity into the visitor. - void visitMethodList(TypeLeafKind Leaf, ArrayRef LeafData) {} - /// Action to take on unknown members. By default, they are ignored. Member /// record parsing cannot recover from an unknown member record, so this /// method is only called at most once per field list record. Index: include/llvm/DebugInfo/CodeView/CodeView.h =================================================================== --- include/llvm/DebugInfo/CodeView/CodeView.h +++ include/llvm/DebugInfo/CodeView/CodeView.h @@ -384,8 +384,8 @@ /// Distinguishes individual records in .debug$T section or PDB type stream. The /// documentation and headers talk about this as the "leaf" type. enum TypeLeafKind : uint16_t { -#define LEAF_TYPE(name, val) name = val, -#include "CVLeafTypes.def" +#define CV_TYPE(name, val) name = val, +#include "TypeRecords.def" }; enum class TypeRecordKind : uint16_t { Index: include/llvm/DebugInfo/CodeView/TypeRecord.h =================================================================== --- include/llvm/DebugInfo/CodeView/TypeRecord.h +++ include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -995,30 +995,36 @@ // LF_METHODLIST class MethodListRecord : public TypeRecord { public: - MethodListRecord(TypeIndex Type, MethodKind Kind, MethodOptions Options, - MemberAccess Access, int32_t VFTableOffset) - : TypeRecord(TypeRecordKind::MethodList), Type(Type), Kind(Kind), - Options(Options), Access(Access), VFTableOffset(VFTableOffset) {} + MethodListRecord(ArrayRef Methods) + : TypeRecord(TypeRecordKind::MethodList), MethodsRef(Methods) {} + MethodListRecord(std::vector &Methods) + : TypeRecord(TypeRecordKind::MethodList), Methods(Methods) {} static ErrorOr deserialize(TypeRecordKind Kind, ArrayRef &Data) { - const Layout *L = nullptr; - int32_t VFTableOffset = 0; - CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD( - VFTableOffset, L->Attrs.isIntroducedVirtual())); - - MethodOptions Options = L->Attrs.getFlags(); - MethodKind MethKind = L->Attrs.getMethodKind(); - MemberAccess Access = L->Attrs.getAccess(); - - return MethodListRecord(L->Type, MethKind, Options, Access, VFTableOffset); + std::vector Methods; + while (!Data.empty()) { + const Layout *L = nullptr; + int32_t VFTableOffset = 0; + CV_DESERIALIZE( + Data, L, + CV_CONDITIONAL_FIELD(VFTableOffset, L->Attrs.isIntroducedVirtual())); + + MethodOptions Options = L->Attrs.getFlags(); + MethodKind MethKind = L->Attrs.getMethodKind(); + MemberAccess Access = L->Attrs.getAccess(); + + Methods.emplace_back(L->Type, MethKind, Options, Access, VFTableOffset, + StringRef()); + } + return MethodListRecord(Methods); } - TypeIndex getType() const { return Type; } - MethodKind getMethodKind() const { return Kind; } - MethodOptions getOptions() const { return Options; } - MemberAccess getAccess() const { return Access; } - int32_t getVFTableOffset() const { return VFTableOffset; } + ArrayRef getMethods() const { + if (!MethodsRef.empty()) + return MethodsRef; + return Methods; + } private: struct Layout { @@ -1030,11 +1036,8 @@ // VFTableOffset: int32_t offset in vftable }; - TypeIndex Type; - MethodKind Kind; - MethodOptions Options; - MemberAccess Access; - int32_t VFTableOffset; + ArrayRef MethodsRef; + std::vector Methods; }; /// For method overload sets. LF_METHOD Index: include/llvm/DebugInfo/CodeView/TypeRecords.def =================================================================== --- include/llvm/DebugInfo/CodeView/TypeRecords.def +++ include/llvm/DebugInfo/CodeView/TypeRecords.def @@ -13,62 +13,233 @@ //===----------------------------------------------------------------------===// // If the type is known, then we have a record describing it in TypeRecord.h. + +#ifndef CV_TYPE +#define CV_TYPE(ename, value) +#endif + +// If the type is known, then we have a record describing it in TypeRecord.h. #ifndef TYPE_RECORD -#define TYPE_RECORD(ClassName, LeafEnum) +#define TYPE_RECORD(ename, value, class_name, print_name) CV_TYPE(ename, value) #endif #ifndef TYPE_RECORD_ALIAS -#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) TYPE_RECORD(ClassName, LeafEnum) +#define TYPE_RECORD_ALIAS(ename, value, class_name, print_name) TYPE_RECORD(ename, value, class_name, print_name) #endif #ifndef MEMBER_RECORD -#define MEMBER_RECORD(ClassName, LeafEnum) TYPE_RECORD(ClassName, LeafEnum) +#define MEMBER_RECORD(ename, value, class_name, print_name) TYPE_RECORD(ename, value, class_name, print_name) #endif #ifndef MEMBER_RECORD_ALIAS -#define MEMBER_RECORD_ALIAS(ClassName, LeafEnum) MEMBER_RECORD(ClassName, LeafEnum) +#define MEMBER_RECORD_ALIAS(ename, value, class_name, print_name) MEMBER_RECORD(ename, value, class_name, print_name) #endif +TYPE_RECORD(LF_POINTER, 0x1002, PointerRecord, PointerType) +TYPE_RECORD(LF_MODIFIER, 0x1001, ModifierRecord, TypeModifier) +TYPE_RECORD(LF_PROCEDURE, 0x1008, ProcedureRecord, ProcedureType) +TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunctionRecord, MemberFunctionType) +TYPE_RECORD(LF_ARGLIST, 0x1201, StringListRecord, ArgList) + +TYPE_RECORD(LF_ARRAY, 0x1503, ArrayRecord, ArrayType) +TYPE_RECORD(LF_CLASS, 0x1504, ClassRecord, ClassType) +TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, ClassRecord, ClassType) +TYPE_RECORD_ALIAS(LF_INTERFACE, 0x1519, ClassRecord, ClassType) +TYPE_RECORD(LF_UNION, 0x1506, UnionRecord, UnionType) +TYPE_RECORD(LF_ENUM, 0x1507, EnumRecord, EnumType) +TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2Record, TypeServer2) +TYPE_RECORD(LF_VFTABLE, 0x151d, VirtualTableRecord, VFTableType) +TYPE_RECORD(LF_VTSHAPE, 0x000a, VirtualTableShapeRecord, VTableShape) + +// Member type records. These are generally not length prefixed, and appear +// inside of a field list record. +MEMBER_RECORD(LF_BCLASS, 0x1400, BaseClassRecord, BaseClass) +MEMBER_RECORD_ALIAS(LF_BINTERFACE, 0x151a, BaseClassRecord, BaseClass) + +MEMBER_RECORD(LF_VBCLASS, 0x1401, VirtualBaseClassRecord, VirtualBaseClass) +MEMBER_RECORD_ALIAS(LF_IVBCLASS, 0x1402, VirtualBaseClassRecord, VirtualBaseClass) + +MEMBER_RECORD(LF_VFUNCTAB, 0x1409, VirtualFunctionPointerRecord, VirtualFunctionPointer) +MEMBER_RECORD(LF_STMEMBER, 0x150e, StaticDataMemberRecord, StaticDataMember) +MEMBER_RECORD(LF_METHOD, 0x150f, OverloadedMethodRecord, OverloadedMethod) +MEMBER_RECORD(LF_MEMBER, 0x150d, DataMemberRecord, DataMember) +MEMBER_RECORD(LF_NESTTYPE, 0x1510, NestedTypeRecord, NestedType) +MEMBER_RECORD(LF_ONEMETHOD, 0x1511, OneMethodRecord, OneMethod) +MEMBER_RECORD(LF_ENUMERATE, 0x1502, EnumeratorRecord, Enumerator) + +// ID leaf records. Subsequent leaf types may be referenced from .debug$S. +TYPE_RECORD(LF_FUNC_ID, 0x1601, FuncIdRecord, FuncId) +TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFunctionIdRecord, MemberFuncId) +TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfoRecord, BuildInfo) +TYPE_RECORD_ALIAS(LF_SUBSTR_LIST, 0x1604, StringListRecord, ArgList) +TYPE_RECORD(LF_STRING_ID, 0x1605, StringIdRecord, StringId) +TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLineRecord, UDTSrcLine) -TYPE_RECORD(PointerRecord, LF_POINTER) -TYPE_RECORD(ModifierRecord, LF_MODIFIER) -TYPE_RECORD(ProcedureRecord, LF_PROCEDURE) -TYPE_RECORD(MemberFunctionRecord, LF_MFUNCTION) -TYPE_RECORD(StringListRecord, LF_ARGLIST) +TYPE_RECORD(LF_METHODLIST, 0x1206, MethodListRecord, MethodListEntry) -TYPE_RECORD(ArrayRecord, LF_ARRAY) -TYPE_RECORD(ClassRecord, LF_CLASS) -TYPE_RECORD_ALIAS(ClassRecord, LF_STRUCTURE) -TYPE_RECORD_ALIAS(ClassRecord, LF_INTERFACE) -TYPE_RECORD(UnionRecord, LF_UNION) -TYPE_RECORD(EnumRecord, LF_ENUM) -TYPE_RECORD(TypeServer2Record, LF_TYPESERVER2) -TYPE_RECORD(VirtualTableRecord, LF_VFTABLE) -TYPE_RECORD(VirtualTableShapeRecord, LF_VTSHAPE) + +// 16 bit type records. +CV_TYPE(LF_MODIFIER_16t, 0x0001) +CV_TYPE(LF_POINTER_16t, 0x0002) +CV_TYPE(LF_ARRAY_16t, 0x0003) +CV_TYPE(LF_CLASS_16t, 0x0004) +CV_TYPE(LF_STRUCTURE_16t, 0x0005) +CV_TYPE(LF_UNION_16t, 0x0006) +CV_TYPE(LF_ENUM_16t, 0x0007) +CV_TYPE(LF_PROCEDURE_16t, 0x0008) +CV_TYPE(LF_MFUNCTION_16t, 0x0009) +CV_TYPE(LF_COBOL0_16t, 0x000b) +CV_TYPE(LF_COBOL1, 0x000c) +CV_TYPE(LF_BARRAY_16t, 0x000d) +CV_TYPE(LF_LABEL, 0x000e) +CV_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL +CV_TYPE(LF_NOTTRAN, 0x0010) +CV_TYPE(LF_DIMARRAY_16t, 0x0011) +CV_TYPE(LF_VFTPATH_16t, 0x0012) +CV_TYPE(LF_PRECOMP_16t, 0x0013) +CV_TYPE(LF_ENDPRECOMP, 0x0014) +CV_TYPE(LF_OEM_16t, 0x0015) +CV_TYPE(LF_TYPESERVER_ST, 0x0016) + +CV_TYPE(LF_SKIP_16t, 0x0200) +CV_TYPE(LF_ARGLIST_16t, 0x0201) +CV_TYPE(LF_DEFARG_16t, 0x0202) +CV_TYPE(LF_LIST, 0x0203) +CV_TYPE(LF_FIELDLIST_16t, 0x0204) +CV_TYPE(LF_DERIVED_16t, 0x0205) +CV_TYPE(LF_BITFIELD_16t, 0x0206) +CV_TYPE(LF_METHODLIST_16t, 0x0207) +CV_TYPE(LF_DIMCONU_16t, 0x0208) +CV_TYPE(LF_DIMCONLU_16t, 0x0209) +CV_TYPE(LF_DIMVARU_16t, 0x020a) +CV_TYPE(LF_DIMVARLU_16t, 0x020b) +CV_TYPE(LF_REFSYM, 0x020c) + +// 16 bit member types. Generally not length prefixed. +CV_TYPE(LF_BCLASS_16t, 0x0400) +CV_TYPE(LF_VBCLASS_16t, 0x0401) +CV_TYPE(LF_IVBCLASS_16t, 0x0402) +CV_TYPE(LF_ENUMERATE_ST, 0x0403) +CV_TYPE(LF_FRIENDFCN_16t, 0x0404) +CV_TYPE(LF_INDEX_16t, 0x0405) +CV_TYPE(LF_MEMBER_16t, 0x0406) +CV_TYPE(LF_STMEMBER_16t, 0x0407) +CV_TYPE(LF_METHOD_16t, 0x0408) +CV_TYPE(LF_NESTTYPE_16t, 0x0409) +CV_TYPE(LF_VFUNCTAB_16t, 0x040a) +CV_TYPE(LF_FRIENDCLS_16t, 0x040b) +CV_TYPE(LF_ONEMETHOD_16t, 0x040c) +CV_TYPE(LF_VFUNCOFF_16t, 0x040d) + +CV_TYPE(LF_TI16_MAX, 0x1000) + +CV_TYPE(LF_ARRAY_ST, 0x1003) +CV_TYPE(LF_CLASS_ST, 0x1004) +CV_TYPE(LF_STRUCTURE_ST, 0x1005) +CV_TYPE(LF_UNION_ST, 0x1006) +CV_TYPE(LF_ENUM_ST, 0x1007) +CV_TYPE(LF_COBOL0, 0x100a) +CV_TYPE(LF_BARRAY, 0x100b) +CV_TYPE(LF_DIMARRAY_ST, 0x100c) +CV_TYPE(LF_VFTPATH, 0x100d) +CV_TYPE(LF_PRECOMP_ST, 0x100e) +CV_TYPE(LF_OEM, 0x100f) +CV_TYPE(LF_ALIAS_ST, 0x1010) +CV_TYPE(LF_OEM2, 0x1011) + +CV_TYPE(LF_SKIP, 0x1200) +CV_TYPE(LF_DEFARG_ST, 0x1202) +CV_TYPE(LF_FIELDLIST, 0x1203) +CV_TYPE(LF_DERIVED, 0x1204) +CV_TYPE(LF_BITFIELD, 0x1205) +CV_TYPE(LF_DIMCONU, 0x1207) +CV_TYPE(LF_DIMCONLU, 0x1208) +CV_TYPE(LF_DIMVARU, 0x1209) +CV_TYPE(LF_DIMVARLU, 0x120a) // Member type records. These are generally not length prefixed, and appear // inside of a field list record. -MEMBER_RECORD(BaseClassRecord, LF_BCLASS) -MEMBER_RECORD_ALIAS(BaseClassRecord, LF_BINTERFACE) -MEMBER_RECORD(VirtualBaseClassRecord, LF_VBCLASS) -MEMBER_RECORD_ALIAS(VirtualBaseClassRecord, LF_IVBCLASS) -MEMBER_RECORD(VirtualFunctionPointerRecord, LF_VFUNCTAB) -MEMBER_RECORD(StaticDataMemberRecord, LF_STMEMBER) -MEMBER_RECORD(OverloadedMethodRecord, LF_METHOD) -MEMBER_RECORD(DataMemberRecord, LF_MEMBER) -MEMBER_RECORD(NestedTypeRecord, LF_NESTTYPE) -MEMBER_RECORD(OneMethodRecord, LF_ONEMETHOD) -MEMBER_RECORD(EnumeratorRecord, LF_ENUMERATE) +CV_TYPE(LF_FRIENDFCN_ST, 0x1403) +CV_TYPE(LF_INDEX, 0x1404) +CV_TYPE(LF_MEMBER_ST, 0x1405) +CV_TYPE(LF_STMEMBER_ST, 0x1406) +CV_TYPE(LF_METHOD_ST, 0x1407) +CV_TYPE(LF_NESTTYPE_ST, 0x1408) +CV_TYPE(LF_FRIENDCLS, 0x140a) +CV_TYPE(LF_ONEMETHOD_ST, 0x140b) +CV_TYPE(LF_VFUNCOFF, 0x140c) +CV_TYPE(LF_NESTTYPEEX_ST, 0x140d) +CV_TYPE(LF_MEMBERMODIFY_ST, 0x140e) +CV_TYPE(LF_MANAGED_ST, 0x140f) + +CV_TYPE(LF_ST_MAX, 0x1500) +CV_TYPE(LF_TYPESERVER, 0x1501) +CV_TYPE(LF_DIMARRAY, 0x1508) +CV_TYPE(LF_PRECOMP, 0x1509) +CV_TYPE(LF_ALIAS, 0x150a) +CV_TYPE(LF_DEFARG, 0x150b) +CV_TYPE(LF_FRIENDFCN, 0x150c) +CV_TYPE(LF_NESTTYPEEX, 0x1512) +CV_TYPE(LF_MEMBERMODIFY, 0x1513) +CV_TYPE(LF_MANAGED, 0x1514) +CV_TYPE(LF_STRIDED_ARRAY, 0x1516) +CV_TYPE(LF_HLSL, 0x1517) +CV_TYPE(LF_MODIFIER_EX, 0x1518) +CV_TYPE(LF_VECTOR, 0x151b) +CV_TYPE(LF_MATRIX, 0x151c) // ID leaf records. Subsequent leaf types may be referenced from .debug$S. -TYPE_RECORD(FuncIdRecord, LF_FUNC_ID) -TYPE_RECORD(MemberFunctionIdRecord, LF_MFUNC_ID) -TYPE_RECORD(BuildInfoRecord, LF_BUILDINFO) -TYPE_RECORD_ALIAS(StringListRecord, LF_SUBSTR_LIST) -TYPE_RECORD(StringIdRecord, LF_STRING_ID) -TYPE_RECORD(UdtSourceLineRecord, LF_UDT_SRC_LINE) +CV_TYPE(LF_UDT_MOD_SRC_LINE, 0x1607) + +// Numeric leaf types. These are generally contained in other records, and not +// encountered in the main type stream. + +CV_TYPE(LF_NUMERIC, 0x8000) +CV_TYPE(LF_CHAR, 0x8000) +CV_TYPE(LF_SHORT, 0x8001) +CV_TYPE(LF_USHORT, 0x8002) +CV_TYPE(LF_LONG, 0x8003) +CV_TYPE(LF_ULONG, 0x8004) +CV_TYPE(LF_REAL32, 0x8005) +CV_TYPE(LF_REAL64, 0x8006) +CV_TYPE(LF_REAL80, 0x8007) +CV_TYPE(LF_REAL128, 0x8008) +CV_TYPE(LF_QUADWORD, 0x8009) +CV_TYPE(LF_UQUADWORD, 0x800a) +CV_TYPE(LF_REAL48, 0x800b) +CV_TYPE(LF_COMPLEX32, 0x800c) +CV_TYPE(LF_COMPLEX64, 0x800d) +CV_TYPE(LF_COMPLEX80, 0x800e) +CV_TYPE(LF_COMPLEX128, 0x800f) +CV_TYPE(LF_VARSTRING, 0x8010) +CV_TYPE(LF_OCTWORD, 0x8017) +CV_TYPE(LF_UOCTWORD, 0x8018) +CV_TYPE(LF_DECIMAL, 0x8019) +CV_TYPE(LF_DATE, 0x801a) +CV_TYPE(LF_UTF8STRING, 0x801b) +CV_TYPE(LF_REAL16, 0x801c) + +// Padding bytes. These are emitted into alignment bytes in the type stream. + +CV_TYPE(LF_PAD0, 0xf0) +CV_TYPE(LF_PAD1, 0xf1) +CV_TYPE(LF_PAD2, 0xf2) +CV_TYPE(LF_PAD3, 0xf3) +CV_TYPE(LF_PAD4, 0xf4) +CV_TYPE(LF_PAD5, 0xf5) +CV_TYPE(LF_PAD6, 0xf6) +CV_TYPE(LF_PAD7, 0xf7) +CV_TYPE(LF_PAD8, 0xf8) +CV_TYPE(LF_PAD9, 0xf9) +CV_TYPE(LF_PAD10, 0xfa) +CV_TYPE(LF_PAD11, 0xfb) +CV_TYPE(LF_PAD12, 0xfc) +CV_TYPE(LF_PAD13, 0xfd) +CV_TYPE(LF_PAD14, 0xfe) +CV_TYPE(LF_PAD15, 0xff) +#undef CV_TYPE #undef TYPE_RECORD #undef TYPE_RECORD_ALIAS #undef MEMBER_RECORD Index: lib/DebugInfo/CodeView/TypeDumper.cpp =================================================================== --- lib/DebugInfo/CodeView/TypeDumper.cpp +++ lib/DebugInfo/CodeView/TypeDumper.cpp @@ -65,8 +65,8 @@ }; static const EnumEntry LeafTypeNames[] = { -#define LEAF_TYPE(enum, val) { #enum, enum }, -#include "llvm/DebugInfo/CodeView/CVLeafTypes.def" +#define CV_TYPE(enum, val) {#enum, enum}, +#include "llvm/DebugInfo/CodeView/TypeRecords.def" }; #define ENUM_ENTRY(enum_class, enum) \ @@ -200,17 +200,14 @@ : CVTD(CVTD), W(W), PrintRecordBytes(PrintRecordBytes) {} /// CVTypeVisitor overrides. -#define TYPE_RECORD(ClassName, LeafEnum) \ +#define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \ void visit##ClassName(TypeLeafKind LeafType, ClassName &Record); -#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) -#define MEMBER_RECORD(ClassName, LeafEnum) \ +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, ClassName, PrintName) +#define MEMBER_RECORD(EnumName, EnumVal, ClassName, PrintName) \ void visit##ClassName(TypeLeafKind LeafType, ClassName &Record); -#define MEMBER_RECORD_ALIAS(ClassName, LeafEnum) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, ClassName, PrintName) #include "llvm/DebugInfo/CodeView/TypeRecords.def" - /// Method overload lists are a special case. - void visitMethodList(TypeLeafKind Leaf, ArrayRef LeafData); - void visitUnknownMember(TypeLeafKind Leaf); void visitTypeBegin(TypeLeafKind Leaf, ArrayRef LeafData); @@ -242,9 +239,10 @@ static StringRef getLeafTypeName(TypeLeafKind LT) { switch (LT) { -#define KNOWN_TYPE(LeafName, Value, ClassName) \ - case LeafName: return #ClassName; -#include "llvm/DebugInfo/CodeView/CVLeafTypes.def" +#define TYPE_RECORD(ename, value, class_name, print_name) \ + case ename: \ + return #print_name; +#include "llvm/DebugInfo/CodeView/TypeRecords.def" default: break; } @@ -405,21 +403,14 @@ Name = CVTD.saveName(TypeName); } -void CVTypeDumperImpl::visitMethodList(TypeLeafKind Leaf, - ArrayRef LeafData) { - while (!LeafData.empty()) { - auto Method = - MethodListRecord::deserialize(TypeRecordKind::MethodList, LeafData); - if (Method) - return; - const MethodListRecord &M = *Method; - +void CVTypeDumperImpl::visitMethodListRecord(TypeLeafKind Leaf, + MethodListRecord &MethodList) { + for (auto &M : MethodList.getMethods()) { ListScope S(W, "Method"); - printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions()); - printTypeIndex("Type", Method->getType()); - if (Method->getMethodKind() == MethodKind::IntroducingVirtual || - Method->getMethodKind() == MethodKind::PureIntroducingVirtual) - W.printHex("VFTableOffset", Method->getVFTableOffset()); + printMemberAttributes(M.getAccess(), M.getKind(), M.getOptions()); + printTypeIndex("Type", M.getType()); + if (M.isIntroducingVirtual()) + W.printHex("VFTableOffset", M.getVFTableOffset()); } }