1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

Get rid of CVLeafTypes.def and combine with TypeRecords.def

This merges the functionality of the macros in `CVLeafTypes.def` and the
macros in `TypeRecords.def` into a single set of macros.

Differential Revision: http://reviews.llvm.org/D20190
Reviewed By: rnk, amccarth

llvm-svn: 269316
This commit is contained in:
Zachary Turner 2016-05-12 17:45:51 +00:00
parent 26fcd8455c
commit 30e5cd51f8
6 changed files with 263 additions and 324 deletions

View File

@ -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

View File

@ -42,12 +42,12 @@ public:
/// expected to consume the trailing bytes used by the field. /// expected to consume the trailing bytes used by the field.
/// FIXME: Make the visitor interpret the trailing bytes so that clients don't /// FIXME: Make the visitor interpret the trailing bytes so that clients don't
/// need to. /// need to.
#define TYPE_RECORD(ClassName, LeafEnum) \ #define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \
void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {} void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {}
#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) #define TYPE_RECORD_ALIAS(EnumName, EnumVal, ClassName, PrintName)
#define MEMBER_RECORD(ClassName, LeafEnum) \ #define MEMBER_RECORD(EnumName, EnumVal, ClassName, PrintName) \
void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {} void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {}
#define MEMBER_RECORD_ALIAS(ClassName, LeafEnum) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, ClassName, PrintName)
#include "TypeRecords.def" #include "TypeRecords.def"
void visitTypeRecord(const TypeIterator::Record &Record) { void visitTypeRecord(const TypeIterator::Record &Record) {
@ -62,12 +62,9 @@ public:
case LF_FIELDLIST: case LF_FIELDLIST:
DerivedThis->visitFieldList(Record.Type, LeafData); DerivedThis->visitFieldList(Record.Type, LeafData);
break; break;
case LF_METHODLIST: #define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \
DerivedThis->visitMethodList(Record.Type, LeafData); case EnumName: { \
break; TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
#define TYPE_RECORD(ClassName, LeafEnum) \
case LeafEnum: { \
TypeRecordKind RK = static_cast<TypeRecordKind>(LeafEnum); \
auto Result = ClassName::deserialize(RK, LeafData); \ auto Result = ClassName::deserialize(RK, LeafData); \
if (Result.getError()) \ if (Result.getError()) \
return parseError(); \ return parseError(); \
@ -118,9 +115,9 @@ public:
// continue parsing past an unknown member type. // continue parsing past an unknown member type.
visitUnknownMember(Leaf); visitUnknownMember(Leaf);
return parseError(); return parseError();
#define MEMBER_RECORD(ClassName, LeafEnum) \ #define MEMBER_RECORD(EnumName, EnumVal, ClassName, PrintName) \
case LeafEnum: { \ case EnumName: { \
TypeRecordKind RK = static_cast<TypeRecordKind>(LeafEnum); \ TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
auto Result = ClassName::deserialize(RK, FieldData); \ auto Result = ClassName::deserialize(RK, FieldData); \
if (Result.getError()) \ if (Result.getError()) \
return parseError(); \ return parseError(); \
@ -133,12 +130,6 @@ public:
} }
} }
/// 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<uint8_t> LeafData) {}
/// Action to take on unknown members. By default, they are ignored. Member /// Action to take on unknown members. By default, they are ignored. Member
/// record parsing cannot recover from an unknown member record, so this /// record parsing cannot recover from an unknown member record, so this
/// method is only called at most once per field list record. /// method is only called at most once per field list record.

View File

@ -384,8 +384,8 @@ enum class PointerToMemberRepresentation : uint16_t {
/// Distinguishes individual records in .debug$T section or PDB type stream. The /// Distinguishes individual records in .debug$T section or PDB type stream. The
/// documentation and headers talk about this as the "leaf" type. /// documentation and headers talk about this as the "leaf" type.
enum TypeLeafKind : uint16_t { enum TypeLeafKind : uint16_t {
#define LEAF_TYPE(name, val) name = val, #define CV_TYPE(name, val) name = val,
#include "CVLeafTypes.def" #include "TypeRecords.def"
}; };
enum class TypeRecordKind : uint16_t { enum class TypeRecordKind : uint16_t {

View File

@ -993,32 +993,38 @@ private:
}; };
// LF_METHODLIST // LF_METHODLIST
class MethodListRecord : public TypeRecord { class MethodOverloadListRecord : public TypeRecord {
public: public:
MethodListRecord(TypeIndex Type, MethodKind Kind, MethodOptions Options, MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
MemberAccess Access, int32_t VFTableOffset) : TypeRecord(TypeRecordKind::MethodList), MethodsRef(Methods) {}
: TypeRecord(TypeRecordKind::MethodList), Type(Type), Kind(Kind), MethodOverloadListRecord(std::vector<OneMethodRecord> &Methods)
Options(Options), Access(Access), VFTableOffset(VFTableOffset) {} : TypeRecord(TypeRecordKind::MethodList), Methods(Methods) {}
static ErrorOr<MethodListRecord> deserialize(TypeRecordKind Kind, static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
ArrayRef<uint8_t> &Data) { ArrayRef<uint8_t> &Data) {
const Layout *L = nullptr; std::vector<OneMethodRecord> Methods;
int32_t VFTableOffset = 0; while (!Data.empty()) {
CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD( const Layout *L = nullptr;
VFTableOffset, L->Attrs.isIntroducedVirtual())); int32_t VFTableOffset = 0;
CV_DESERIALIZE(
Data, L,
CV_CONDITIONAL_FIELD(VFTableOffset, L->Attrs.isIntroducedVirtual()));
MethodOptions Options = L->Attrs.getFlags(); MethodOptions Options = L->Attrs.getFlags();
MethodKind MethKind = L->Attrs.getMethodKind(); MethodKind MethKind = L->Attrs.getMethodKind();
MemberAccess Access = L->Attrs.getAccess(); MemberAccess Access = L->Attrs.getAccess();
return MethodListRecord(L->Type, MethKind, Options, Access, VFTableOffset); Methods.emplace_back(L->Type, MethKind, Options, Access, VFTableOffset,
StringRef());
}
return MethodOverloadListRecord(Methods);
} }
TypeIndex getType() const { return Type; } ArrayRef<OneMethodRecord> getMethods() const {
MethodKind getMethodKind() const { return Kind; } if (!MethodsRef.empty())
MethodOptions getOptions() const { return Options; } return MethodsRef;
MemberAccess getAccess() const { return Access; } return Methods;
int32_t getVFTableOffset() const { return VFTableOffset; } }
private: private:
struct Layout { struct Layout {
@ -1030,11 +1036,8 @@ private:
// VFTableOffset: int32_t offset in vftable // VFTableOffset: int32_t offset in vftable
}; };
TypeIndex Type; ArrayRef<OneMethodRecord> MethodsRef;
MethodKind Kind; std::vector<OneMethodRecord> Methods;
MethodOptions Options;
MemberAccess Access;
int32_t VFTableOffset;
}; };
/// For method overload sets. LF_METHOD /// For method overload sets. LF_METHOD

View File

@ -12,63 +12,234 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// 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. // If the type is known, then we have a record describing it in TypeRecord.h.
#ifndef TYPE_RECORD #ifndef TYPE_RECORD
#define TYPE_RECORD(ClassName, LeafEnum) #define TYPE_RECORD(ename, value, class_name, print_name) CV_TYPE(ename, value)
#endif #endif
#ifndef TYPE_RECORD_ALIAS #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 #endif
#ifndef MEMBER_RECORD #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 #endif
#ifndef MEMBER_RECORD_ALIAS #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 #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(PointerRecord, LF_POINTER) TYPE_RECORD(LF_ARRAY, 0x1503, ArrayRecord, ArrayType)
TYPE_RECORD(ModifierRecord, LF_MODIFIER) TYPE_RECORD(LF_CLASS, 0x1504, ClassRecord, ClassType)
TYPE_RECORD(ProcedureRecord, LF_PROCEDURE) TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, ClassRecord, ClassType)
TYPE_RECORD(MemberFunctionRecord, LF_MFUNCTION) TYPE_RECORD_ALIAS(LF_INTERFACE, 0x1519, ClassRecord, ClassType)
TYPE_RECORD(StringListRecord, LF_ARGLIST) TYPE_RECORD(LF_UNION, 0x1506, UnionRecord, UnionType)
TYPE_RECORD(LF_ENUM, 0x1507, EnumRecord, EnumType)
TYPE_RECORD(ArrayRecord, LF_ARRAY) TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2Record, TypeServer2)
TYPE_RECORD(ClassRecord, LF_CLASS) TYPE_RECORD(LF_VFTABLE, 0x151d, VirtualTableRecord, VFTableType)
TYPE_RECORD_ALIAS(ClassRecord, LF_STRUCTURE) TYPE_RECORD(LF_VTSHAPE, 0x000a, VirtualTableShapeRecord, VTableShape)
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)
// Member type records. These are generally not length prefixed, and appear // Member type records. These are generally not length prefixed, and appear
// inside of a field list record. // inside of a field list record.
MEMBER_RECORD(BaseClassRecord, LF_BCLASS) MEMBER_RECORD(LF_BCLASS, 0x1400, BaseClassRecord, BaseClass)
MEMBER_RECORD_ALIAS(BaseClassRecord, LF_BINTERFACE) MEMBER_RECORD_ALIAS(LF_BINTERFACE, 0x151a, BaseClassRecord, BaseClass)
MEMBER_RECORD(VirtualBaseClassRecord, LF_VBCLASS)
MEMBER_RECORD_ALIAS(VirtualBaseClassRecord, LF_IVBCLASS) MEMBER_RECORD(LF_VBCLASS, 0x1401, VirtualBaseClassRecord, VirtualBaseClass)
MEMBER_RECORD(VirtualFunctionPointerRecord, LF_VFUNCTAB) MEMBER_RECORD_ALIAS(LF_IVBCLASS, 0x1402, VirtualBaseClassRecord, VirtualBaseClass)
MEMBER_RECORD(StaticDataMemberRecord, LF_STMEMBER)
MEMBER_RECORD(OverloadedMethodRecord, LF_METHOD) MEMBER_RECORD(LF_VFUNCTAB, 0x1409, VirtualFunctionPointerRecord, VirtualFunctionPointer)
MEMBER_RECORD(DataMemberRecord, LF_MEMBER) MEMBER_RECORD(LF_STMEMBER, 0x150e, StaticDataMemberRecord, StaticDataMember)
MEMBER_RECORD(NestedTypeRecord, LF_NESTTYPE) MEMBER_RECORD(LF_METHOD, 0x150f, OverloadedMethodRecord, OverloadedMethod)
MEMBER_RECORD(OneMethodRecord, LF_ONEMETHOD) MEMBER_RECORD(LF_MEMBER, 0x150d, DataMemberRecord, DataMember)
MEMBER_RECORD(EnumeratorRecord, LF_ENUMERATE) 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(LF_METHODLIST, 0x1206, MethodOverloadListRecord, MethodListEntry)
// 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.
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. // ID leaf records. Subsequent leaf types may be referenced from .debug$S.
TYPE_RECORD(FuncIdRecord, LF_FUNC_ID) CV_TYPE(LF_UDT_MOD_SRC_LINE, 0x1607)
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)
// 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
#undef TYPE_RECORD_ALIAS #undef TYPE_RECORD_ALIAS
#undef MEMBER_RECORD #undef MEMBER_RECORD

View File

@ -65,8 +65,8 @@ static const EnumEntry<SimpleTypeKind> SimpleTypeNames[] = {
}; };
static const EnumEntry<TypeLeafKind> LeafTypeNames[] = { static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
#define LEAF_TYPE(enum, val) { #enum, enum }, #define CV_TYPE(enum, val) {#enum, enum},
#include "llvm/DebugInfo/CodeView/CVLeafTypes.def" #include "llvm/DebugInfo/CodeView/TypeRecords.def"
}; };
#define ENUM_ENTRY(enum_class, enum) \ #define ENUM_ENTRY(enum_class, enum) \
@ -200,17 +200,14 @@ public:
: CVTD(CVTD), W(W), PrintRecordBytes(PrintRecordBytes) {} : CVTD(CVTD), W(W), PrintRecordBytes(PrintRecordBytes) {}
/// CVTypeVisitor overrides. /// CVTypeVisitor overrides.
#define TYPE_RECORD(ClassName, LeafEnum) \ #define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \
void visit##ClassName(TypeLeafKind LeafType, ClassName &Record); void visit##ClassName(TypeLeafKind LeafType, ClassName &Record);
#define TYPE_RECORD_ALIAS(ClassName, LeafEnum) #define TYPE_RECORD_ALIAS(EnumName, EnumVal, ClassName, PrintName)
#define MEMBER_RECORD(ClassName, LeafEnum) \ #define MEMBER_RECORD(EnumName, EnumVal, ClassName, PrintName) \
void visit##ClassName(TypeLeafKind LeafType, ClassName &Record); 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" #include "llvm/DebugInfo/CodeView/TypeRecords.def"
/// Method overload lists are a special case.
void visitMethodList(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData);
void visitUnknownMember(TypeLeafKind Leaf); void visitUnknownMember(TypeLeafKind Leaf);
void visitTypeBegin(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData); void visitTypeBegin(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData);
@ -242,9 +239,10 @@ private:
static StringRef getLeafTypeName(TypeLeafKind LT) { static StringRef getLeafTypeName(TypeLeafKind LT) {
switch (LT) { switch (LT) {
#define KNOWN_TYPE(LeafName, Value, ClassName) \ #define TYPE_RECORD(ename, value, class_name, print_name) \
case LeafName: return #ClassName; case ename: \
#include "llvm/DebugInfo/CodeView/CVLeafTypes.def" return #print_name;
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
default: default:
break; break;
} }
@ -405,21 +403,14 @@ void CVTypeDumperImpl::visitMemberFunctionRecord(TypeLeafKind Leaf,
Name = CVTD.saveName(TypeName); Name = CVTD.saveName(TypeName);
} }
void CVTypeDumperImpl::visitMethodList(TypeLeafKind Leaf, void CVTypeDumperImpl::visitMethodOverloadListRecord(TypeLeafKind Leaf,
ArrayRef<uint8_t> LeafData) { MethodOverloadListRecord &MethodList) {
while (!LeafData.empty()) { for (auto &M : MethodList.getMethods()) {
auto Method =
MethodListRecord::deserialize(TypeRecordKind::MethodList, LeafData);
if (Method)
return;
const MethodListRecord &M = *Method;
ListScope S(W, "Method"); ListScope S(W, "Method");
printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions()); printMemberAttributes(M.getAccess(), M.getKind(), M.getOptions());
printTypeIndex("Type", Method->getType()); printTypeIndex("Type", M.getType());
if (Method->getMethodKind() == MethodKind::IntroducingVirtual || if (M.isIntroducingVirtual())
Method->getMethodKind() == MethodKind::PureIntroducingVirtual) W.printHex("VFTableOffset", M.getVFTableOffset());
W.printHex("VFTableOffset", Method->getVFTableOffset());
} }
} }