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 KNOWN_TYPE(EnumName, EnumVal, ClassName, PrintName) \ void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {} -#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) -#define MEMBER_RECORD(ClassName, LeafEnum) \ +#define KNOWN_TYPE_ALIAS(EnumName, EnumVal, ClassName, PrintName) +#define MEMBER_TYPE(EnumName, EnumVal, ClassName, PrintName) \ void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {} -#define MEMBER_RECORD_ALIAS(ClassName, LeafEnum) +#define MEMBER_TYPE_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 KNOWN_TYPE(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_TYPE(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 @@ -385,7 +385,7 @@ /// documentation and headers talk about this as the "leaf" type. enum TypeLeafKind : uint16_t { #define LEAF_TYPE(name, val) name = val, -#include "CVLeafTypes.def" +#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, 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, + 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,63 +13,234 @@ //===----------------------------------------------------------------------===// // If the type is known, then we have a record describing it in TypeRecord.h. -#ifndef TYPE_RECORD -#define TYPE_RECORD(ClassName, LeafEnum) + +#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, print_name) LEAF_TYPE(ename, value) #endif -#ifndef TYPE_RECORD_ALIAS -#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) TYPE_RECORD(ClassName, LeafEnum) +#ifndef KNOWN_TYPE_ALIAS +#define KNOWN_TYPE_ALIAS(ename, value, class_name, print_name) KNOWN_TYPE(ename, value, class_name, print_name) #endif -#ifndef MEMBER_RECORD -#define MEMBER_RECORD(ClassName, LeafEnum) TYPE_RECORD(ClassName, LeafEnum) +#ifndef MEMBER_TYPE +#define MEMBER_TYPE(ename, value, class_name, print_name) KNOWN_TYPE(ename, value, class_name, print_name) #endif -#ifndef MEMBER_RECORD_ALIAS -#define MEMBER_RECORD_ALIAS(ClassName, LeafEnum) MEMBER_RECORD(ClassName, LeafEnum) +#ifndef MEMBER_TYPE_ALIAS +#define MEMBER_TYPE_ALIAS(ename, value, class_name, print_name) MEMBER_TYPE(ename, value, class_name, print_name) #endif +KNOWN_TYPE(LF_POINTER, 0x1002, PointerRecord, PointerType) +KNOWN_TYPE(LF_MODIFIER, 0x1001, ModifierRecord, TypeModifier) +KNOWN_TYPE(LF_PROCEDURE, 0x1008, ProcedureRecord, ProcedureType) +KNOWN_TYPE(LF_MFUNCTION, 0x1009, MemberFunctionRecord, MemberFunctionType) +KNOWN_TYPE(LF_ARGLIST, 0x1201, StringListRecord, ArgList) + +KNOWN_TYPE(LF_ARRAY, 0x1503, ArrayRecord, ArrayType) +KNOWN_TYPE(LF_CLASS, 0x1504, ClassRecord, ClassType) +KNOWN_TYPE_ALIAS(LF_STRUCTURE, 0x1505, ClassRecord, ClassType) +KNOWN_TYPE_ALIAS(LF_INTERFACE, 0x1519, ClassRecord, ClassType) +KNOWN_TYPE(LF_UNION, 0x1506, UnionRecord, UnionType) +KNOWN_TYPE(LF_ENUM, 0x1507, EnumRecord, EnumType) +KNOWN_TYPE(LF_TYPESERVER2, 0x1515, TypeServer2Record, TypeServer2) +KNOWN_TYPE(LF_VFTABLE, 0x151d, VirtualTableRecord, VFTableType) +KNOWN_TYPE(LF_VTSHAPE, 0x000a, VirtualTableShapeRecord, VTableShape) + +// Member type records. These are generally not length prefixed, and appear +// inside of a field list record. +MEMBER_TYPE(LF_BCLASS, 0x1400, BaseClassRecord, BaseClass) +MEMBER_TYPE_ALIAS(LF_BINTERFACE, 0x151a, BaseClassRecord, BaseClass) + +MEMBER_TYPE(LF_VBCLASS, 0x1401, VirtualBaseClassRecord, VirtualBaseClass) +MEMBER_TYPE_ALIAS(LF_IVBCLASS, 0x1402, VirtualBaseClassRecord, VirtualBaseClass) + +MEMBER_TYPE(LF_VFUNCTAB, 0x1409, VirtualFunctionPointerRecord, VirtualFunctionPointer) +MEMBER_TYPE(LF_STMEMBER, 0x150e, StaticDataMemberRecord, StaticDataMember) +MEMBER_TYPE(LF_METHOD, 0x150f, OverloadedMethodRecord, OverloadedMethod) +MEMBER_TYPE(LF_MEMBER, 0x150d, DataMemberRecord, DataMember) +MEMBER_TYPE(LF_NESTTYPE, 0x1510, NestedTypeRecord, NestedType) +MEMBER_TYPE(LF_ONEMETHOD, 0x1511, OneMethodRecord, OneMethod) +MEMBER_TYPE(LF_ENUMERATE, 0x1502, EnumeratorRecord, Enumerator) + +// ID leaf records. Subsequent leaf types may be referenced from .debug$S. +KNOWN_TYPE(LF_FUNC_ID, 0x1601, FuncIdRecord, FuncId) +KNOWN_TYPE(LF_MFUNC_ID, 0x1602, MemberFunctionIdRecord, MemberFuncId) +KNOWN_TYPE(LF_BUILDINFO, 0x1603, BuildInfoRecord, BuildInfo) +KNOWN_TYPE_ALIAS(LF_SUBSTR_LIST, 0x1604, StringListRecord, ArgList) +KNOWN_TYPE(LF_STRING_ID, 0x1605, StringIdRecord, StringId) +KNOWN_TYPE(LF_UDT_SRC_LINE, 0x1606, UdtSourceLineRecord, UDTSrcLine) + +KNOWN_TYPE(LF_METHODLIST, 0x1206, MethodListRecord, MethodListEntry) + + +// 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) +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) -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) +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) +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) -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) +LEAF_TYPE(LF_SKIP, 0x1200) +LEAF_TYPE(LF_DEFARG_ST, 0x1202) +LEAF_TYPE(LF_FIELDLIST, 0x1203) +LEAF_TYPE(LF_DERIVED, 0x1204) +LEAF_TYPE(LF_BITFIELD, 0x1205) +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. -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) +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) +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) +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) +LEAF_TYPE(LF_NESTTYPEEX, 0x1512) +LEAF_TYPE(LF_MEMBERMODIFY, 0x1513) +LEAF_TYPE(LF_MANAGED, 0x1514) +LEAF_TYPE(LF_STRIDED_ARRAY, 0x1516) +LEAF_TYPE(LF_HLSL, 0x1517) +LEAF_TYPE(LF_MODIFIER_EX, 0x1518) +LEAF_TYPE(LF_VECTOR, 0x151b) +LEAF_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) - -#undef TYPE_RECORD -#undef TYPE_RECORD_ALIAS -#undef MEMBER_RECORD -#undef MEMBER_RECORD_ALIAS +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 LEAF_TYPE +#undef KNOWN_TYPE +#undef KNOWN_TYPE_ALIAS +#undef MEMBER_TYPE +#undef MEMBER_TYPE_ALIAS Index: lib/DebugInfo/CodeView/TypeDumper.cpp =================================================================== --- lib/DebugInfo/CodeView/TypeDumper.cpp +++ lib/DebugInfo/CodeView/TypeDumper.cpp @@ -66,7 +66,7 @@ static const EnumEntry LeafTypeNames[] = { #define LEAF_TYPE(enum, val) { #enum, enum }, -#include "llvm/DebugInfo/CodeView/CVLeafTypes.def" +#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 KNOWN_TYPE(EnumName, EnumVal, ClassName, PrintName) \ void visit##ClassName(TypeLeafKind LeafType, ClassName &Record); -#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) -#define MEMBER_RECORD(ClassName, LeafEnum) \ +#define KNOWN_TYPE_ALIAS(EnumName, EnumVal, ClassName, PrintName) +#define MEMBER_TYPE(EnumName, EnumVal, ClassName, PrintName) \ void visit##ClassName(TypeLeafKind LeafType, ClassName &Record); -#define MEMBER_RECORD_ALIAS(ClassName, LeafEnum) +#define MEMBER_TYPE_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 KNOWN_TYPE(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()); } }