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:
parent
26fcd8455c
commit
30e5cd51f8
@ -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
|
@ -42,12 +42,12 @@ public:
|
||||
/// 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 @@ public:
|
||||
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<TypeRecordKind>(LeafEnum); \
|
||||
#define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \
|
||||
case EnumName: { \
|
||||
TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
|
||||
auto Result = ClassName::deserialize(RK, LeafData); \
|
||||
if (Result.getError()) \
|
||||
return parseError(); \
|
||||
@ -118,9 +115,9 @@ public:
|
||||
// continue parsing past an unknown member type.
|
||||
visitUnknownMember(Leaf);
|
||||
return parseError();
|
||||
#define MEMBER_RECORD(ClassName, LeafEnum) \
|
||||
case LeafEnum: { \
|
||||
TypeRecordKind RK = static_cast<TypeRecordKind>(LeafEnum); \
|
||||
#define MEMBER_RECORD(EnumName, EnumVal, ClassName, PrintName) \
|
||||
case EnumName: { \
|
||||
TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
|
||||
auto Result = ClassName::deserialize(RK, FieldData); \
|
||||
if (Result.getError()) \
|
||||
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
|
||||
/// record parsing cannot recover from an unknown member record, so this
|
||||
/// method is only called at most once per field list record.
|
||||
|
@ -384,8 +384,8 @@ enum class PointerToMemberRepresentation : uint16_t {
|
||||
/// 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 {
|
||||
|
@ -993,32 +993,38 @@ private:
|
||||
};
|
||||
|
||||
// LF_METHODLIST
|
||||
class MethodListRecord : public TypeRecord {
|
||||
class MethodOverloadListRecord : 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) {}
|
||||
MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
|
||||
: TypeRecord(TypeRecordKind::MethodList), MethodsRef(Methods) {}
|
||||
MethodOverloadListRecord(std::vector<OneMethodRecord> &Methods)
|
||||
: TypeRecord(TypeRecordKind::MethodList), Methods(Methods) {}
|
||||
|
||||
static ErrorOr<MethodListRecord> deserialize(TypeRecordKind Kind,
|
||||
static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
|
||||
ArrayRef<uint8_t> &Data) {
|
||||
const Layout *L = nullptr;
|
||||
int32_t VFTableOffset = 0;
|
||||
CV_DESERIALIZE(Data, L, CV_CONDITIONAL_FIELD(
|
||||
VFTableOffset, L->Attrs.isIntroducedVirtual()));
|
||||
std::vector<OneMethodRecord> 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();
|
||||
MethodOptions Options = L->Attrs.getFlags();
|
||||
MethodKind MethKind = L->Attrs.getMethodKind();
|
||||
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; }
|
||||
MethodKind getMethodKind() const { return Kind; }
|
||||
MethodOptions getOptions() const { return Options; }
|
||||
MemberAccess getAccess() const { return Access; }
|
||||
int32_t getVFTableOffset() const { return VFTableOffset; }
|
||||
ArrayRef<OneMethodRecord> getMethods() const {
|
||||
if (!MethodsRef.empty())
|
||||
return MethodsRef;
|
||||
return Methods;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Layout {
|
||||
@ -1030,11 +1036,8 @@ private:
|
||||
// VFTableOffset: int32_t offset in vftable
|
||||
};
|
||||
|
||||
TypeIndex Type;
|
||||
MethodKind Kind;
|
||||
MethodOptions Options;
|
||||
MemberAccess Access;
|
||||
int32_t VFTableOffset;
|
||||
ArrayRef<OneMethodRecord> MethodsRef;
|
||||
std::vector<OneMethodRecord> Methods;
|
||||
};
|
||||
|
||||
/// For method overload sets. LF_METHOD
|
||||
|
@ -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.
|
||||
#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(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(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)
|
||||
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(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)
|
||||
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(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.
|
||||
|
||||
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
|
||||
|
@ -65,8 +65,8 @@ static const EnumEntry<SimpleTypeKind> SimpleTypeNames[] = {
|
||||
};
|
||||
|
||||
static const EnumEntry<TypeLeafKind> 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 @@ public:
|
||||
: 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<uint8_t> LeafData);
|
||||
|
||||
void visitUnknownMember(TypeLeafKind Leaf);
|
||||
|
||||
void visitTypeBegin(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData);
|
||||
@ -242,9 +239,10 @@ private:
|
||||
|
||||
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 @@ void CVTypeDumperImpl::visitMemberFunctionRecord(TypeLeafKind Leaf,
|
||||
Name = CVTD.saveName(TypeName);
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitMethodList(TypeLeafKind Leaf,
|
||||
ArrayRef<uint8_t> LeafData) {
|
||||
while (!LeafData.empty()) {
|
||||
auto Method =
|
||||
MethodListRecord::deserialize(TypeRecordKind::MethodList, LeafData);
|
||||
if (Method)
|
||||
return;
|
||||
const MethodListRecord &M = *Method;
|
||||
|
||||
void CVTypeDumperImpl::visitMethodOverloadListRecord(TypeLeafKind Leaf,
|
||||
MethodOverloadListRecord &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());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user