mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[codeview] Align class and print names of types
Summary: This way we can get rid of one of the fields in the .def file. Reviewers: llvm-commits Subscribers: zturner Differential Revision: http://reviews.llvm.org/D20251 llvm-svn: 269461
This commit is contained in:
parent
72e0542f2c
commit
c52abd22d5
@ -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(EnumName, EnumVal, ClassName, PrintName) \
|
||||
void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {}
|
||||
#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(EnumName, EnumVal, ClassName, PrintName)
|
||||
#define TYPE_RECORD(EnumName, EnumVal, Name) \
|
||||
void visit##Name(TypeLeafKind LeafType, Name##Record &Record) {}
|
||||
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
|
||||
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
|
||||
void visit##Name(TypeLeafKind LeafType, Name##Record &Record) {}
|
||||
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
|
||||
#include "TypeRecords.def"
|
||||
|
||||
void visitTypeRecord(const TypeIterator::Record &Record) {
|
||||
@ -62,15 +62,18 @@ public:
|
||||
case LF_FIELDLIST:
|
||||
DerivedThis->visitFieldList(Record.Type, LeafData);
|
||||
break;
|
||||
#define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \
|
||||
#define TYPE_RECORD(EnumName, EnumVal, Name) \
|
||||
case EnumName: { \
|
||||
TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
|
||||
auto Result = ClassName::deserialize(RK, LeafData); \
|
||||
auto Result = Name##Record::deserialize(RK, LeafData); \
|
||||
if (Result.getError()) \
|
||||
return parseError(); \
|
||||
DerivedThis->visit##ClassName(Record.Type, *Result); \
|
||||
DerivedThis->visit##Name(Record.Type, *Result); \
|
||||
break; \
|
||||
}
|
||||
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
|
||||
TYPE_RECORD(EnumVal, EnumVal, AliasName)
|
||||
#define MEMBER_RECORD(EnumName, EnumVal, Name)
|
||||
#include "TypeRecords.def"
|
||||
}
|
||||
DerivedThis->visitTypeEnd(Record.Type, RecordData);
|
||||
@ -118,15 +121,17 @@ public:
|
||||
// continue parsing past an unknown member type.
|
||||
visitUnknownMember(Leaf);
|
||||
return parseError();
|
||||
#define MEMBER_RECORD(EnumName, EnumVal, ClassName, PrintName) \
|
||||
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
|
||||
case EnumName: { \
|
||||
TypeRecordKind RK = static_cast<TypeRecordKind>(EnumName); \
|
||||
auto Result = ClassName::deserialize(RK, FieldData); \
|
||||
auto Result = Name##Record::deserialize(RK, FieldData); \
|
||||
if (Result.getError()) \
|
||||
return parseError(); \
|
||||
static_cast<Derived *>(this)->visit##ClassName(Leaf, *Result); \
|
||||
static_cast<Derived *>(this)->visit##Name(Leaf, *Result); \
|
||||
break; \
|
||||
}
|
||||
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
|
||||
MEMBER_RECORD(EnumVal, EnumVal, AliasName)
|
||||
#include "TypeRecords.def"
|
||||
}
|
||||
FieldData = skipPadding(FieldData);
|
||||
|
@ -383,88 +383,22 @@ 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 class TypeRecordKind : uint16_t {
|
||||
#define TYPE_RECORD(lf_ename, value, name) name = value,
|
||||
#include "TypeRecords.def"
|
||||
// FIXME: Add serialization support
|
||||
FieldList = 0x1203,
|
||||
BitField = 0x1205,
|
||||
};
|
||||
|
||||
/// Duplicate copy of the above enum, but using the official CV names. Useful
|
||||
/// for reference purposes and when dealing with unknown record types.
|
||||
enum TypeLeafKind : uint16_t {
|
||||
#define CV_TYPE(name, val) name = val,
|
||||
#include "TypeRecords.def"
|
||||
};
|
||||
|
||||
enum class TypeRecordKind : uint16_t {
|
||||
None = 0,
|
||||
|
||||
VirtualTableShape = 0x000a,
|
||||
Label = 0x000e,
|
||||
EndPrecompiledHeader = 0x0014,
|
||||
|
||||
Modifier = 0x1001,
|
||||
Pointer = 0x1002,
|
||||
Procedure = 0x1008,
|
||||
MemberFunction = 0x1009,
|
||||
|
||||
Oem = 0x100f,
|
||||
Oem2 = 0x1011,
|
||||
|
||||
ArgumentList = 0x1201,
|
||||
FieldList = 0x1203,
|
||||
BitField = 0x1205,
|
||||
MethodList = 0x1206,
|
||||
|
||||
BaseClass = 0x1400,
|
||||
VirtualBaseClass = 0x1401,
|
||||
IndirectVirtualBaseClass = 0x1402,
|
||||
Index = 0x1404,
|
||||
VirtualFunctionTablePointer = 0x1409,
|
||||
|
||||
Enumerate = 0x1502,
|
||||
Array = 0x1503,
|
||||
Class = 0x1504,
|
||||
Structure = 0x1505,
|
||||
Union = 0x1506,
|
||||
Enum = 0x1507,
|
||||
Alias = 0x150a,
|
||||
Member = 0x150d,
|
||||
StaticMember = 0x150e,
|
||||
OverloadedMethod = 0x150f,
|
||||
NestedType = 0x1510,
|
||||
OneMethod = 0x1511,
|
||||
TypeServer2 = 0x1515,
|
||||
VirtualFunctionTable = 0x151d,
|
||||
|
||||
FunctionId = 0x1601,
|
||||
MemberFunctionId = 0x1602,
|
||||
BuildInfo = 0x1603,
|
||||
SubstringList = 0x1604,
|
||||
StringId = 0x1605,
|
||||
UdtSourceLine = 0x1606,
|
||||
|
||||
SByte = 0x8000,
|
||||
Int16 = 0x8001,
|
||||
UInt16 = 0x8002,
|
||||
Int32 = 0x8003,
|
||||
UInt32 = 0x8004,
|
||||
Single = 0x8005,
|
||||
Double = 0x8006,
|
||||
Float80 = 0x8007,
|
||||
Float128 = 0x8008,
|
||||
Int64 = 0x8009,
|
||||
UInt64 = 0x800a,
|
||||
Float48 = 0x800b,
|
||||
Complex32 = 0x800c,
|
||||
Complex64 = 0x800d,
|
||||
Complex80 = 0x800e,
|
||||
Complex128 = 0x800f,
|
||||
VarString = 0x8010,
|
||||
|
||||
Int128 = 0x8017,
|
||||
UInt128 = 0x8018,
|
||||
|
||||
Decimal = 0x8019,
|
||||
Date = 0x801a,
|
||||
Utf8String = 0x801b,
|
||||
|
||||
Float16 = 0x801c
|
||||
};
|
||||
|
||||
enum class VirtualTableSlotKind : uint8_t {
|
||||
enum class VFTableSlotKind : uint8_t {
|
||||
Near16 = 0x00,
|
||||
Far16 = 0x01,
|
||||
This = 0x02,
|
||||
|
@ -244,20 +244,20 @@ private:
|
||||
};
|
||||
|
||||
// LF_MFUNC_ID
|
||||
class MemberFunctionIdRecord : public TypeRecord {
|
||||
class MemberFuncIdRecord : public TypeRecord {
|
||||
public:
|
||||
MemberFunctionIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
|
||||
MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
|
||||
StringRef Name)
|
||||
: TypeRecord(TypeRecordKind::MemberFunctionId), ClassType(ClassType),
|
||||
: TypeRecord(TypeRecordKind::MemberFuncId), ClassType(ClassType),
|
||||
FunctionType(FunctionType), Name(Name) {}
|
||||
|
||||
static ErrorOr<MemberFunctionIdRecord> deserialize(TypeRecordKind Kind,
|
||||
static ErrorOr<MemberFuncIdRecord> deserialize(TypeRecordKind Kind,
|
||||
ArrayRef<uint8_t> &Data) {
|
||||
const Layout *L = nullptr;
|
||||
StringRef Name;
|
||||
CV_DESERIALIZE(Data, L, Name);
|
||||
|
||||
return MemberFunctionIdRecord(L->ClassType, L->FunctionType, Name);
|
||||
return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name);
|
||||
}
|
||||
|
||||
TypeIndex getClassType() const { return ClassType; }
|
||||
@ -276,22 +276,21 @@ private:
|
||||
};
|
||||
|
||||
// LF_ARGLIST, LF_SUBSTR_LIST
|
||||
class StringListRecord : public TypeRecord {
|
||||
class ArgListRecord : public TypeRecord {
|
||||
public:
|
||||
StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
|
||||
ArgListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
|
||||
: TypeRecord(Kind), StringIndices(Indices) {}
|
||||
|
||||
static ErrorOr<StringListRecord> deserialize(TypeRecordKind Kind,
|
||||
static ErrorOr<ArgListRecord> deserialize(TypeRecordKind Kind,
|
||||
ArrayRef<uint8_t> &Data) {
|
||||
if (Kind != TypeRecordKind::SubstringList &&
|
||||
Kind != TypeRecordKind::ArgumentList)
|
||||
if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList)
|
||||
return std::make_error_code(std::errc::illegal_byte_sequence);
|
||||
|
||||
const Layout *L = nullptr;
|
||||
ArrayRef<TypeIndex> Indices;
|
||||
CV_DESERIALIZE(Data, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
|
||||
|
||||
return StringListRecord(Kind, Indices);
|
||||
return ArgListRecord(Kind, Indices);
|
||||
}
|
||||
|
||||
ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
|
||||
@ -656,7 +655,7 @@ private:
|
||||
TypeIndex UnderlyingType;
|
||||
};
|
||||
|
||||
class BitFieldRecord : TypeRecord {
|
||||
class BitFieldRecord : public TypeRecord {
|
||||
public:
|
||||
BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset)
|
||||
: TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize),
|
||||
@ -673,20 +672,20 @@ private:
|
||||
};
|
||||
|
||||
// LF_VTSHAPE
|
||||
class VirtualTableShapeRecord : TypeRecord {
|
||||
class VFTableShapeRecord : public TypeRecord {
|
||||
public:
|
||||
explicit VirtualTableShapeRecord(ArrayRef<VirtualTableSlotKind> Slots)
|
||||
: TypeRecord(TypeRecordKind::VirtualTableShape), SlotsRef(Slots) {}
|
||||
explicit VirtualTableShapeRecord(std::vector<VirtualTableSlotKind> Slots)
|
||||
: TypeRecord(TypeRecordKind::VirtualTableShape), Slots(Slots) {}
|
||||
explicit VFTableShapeRecord(ArrayRef<VFTableSlotKind> Slots)
|
||||
: TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {}
|
||||
explicit VFTableShapeRecord(std::vector<VFTableSlotKind> Slots)
|
||||
: TypeRecord(TypeRecordKind::VFTableShape), Slots(Slots) {}
|
||||
|
||||
static ErrorOr<VirtualTableShapeRecord> deserialize(TypeRecordKind Kind,
|
||||
static ErrorOr<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
|
||||
ArrayRef<uint8_t> &Data) {
|
||||
const Layout *L = nullptr;
|
||||
if (auto EC = consumeObject(Data, L))
|
||||
return EC;
|
||||
|
||||
std::vector<VirtualTableSlotKind> Slots;
|
||||
std::vector<VFTableSlotKind> Slots;
|
||||
uint16_t Count = L->VFEntryCount;
|
||||
while (Count > 0) {
|
||||
if (Data.empty())
|
||||
@ -694,19 +693,19 @@ public:
|
||||
|
||||
// Process up to 2 nibbles at a time (if there are at least 2 remaining)
|
||||
uint8_t Value = Data[0] & 0x0F;
|
||||
Slots.push_back(static_cast<VirtualTableSlotKind>(Value));
|
||||
Slots.push_back(static_cast<VFTableSlotKind>(Value));
|
||||
if (--Count > 0) {
|
||||
Value = (Data[0] & 0xF0) >> 4;
|
||||
Slots.push_back(static_cast<VirtualTableSlotKind>(Value));
|
||||
Slots.push_back(static_cast<VFTableSlotKind>(Value));
|
||||
--Count;
|
||||
}
|
||||
Data = Data.slice(1);
|
||||
}
|
||||
|
||||
return VirtualTableShapeRecord(Slots);
|
||||
return VFTableShapeRecord(Slots);
|
||||
}
|
||||
|
||||
ArrayRef<VirtualTableSlotKind> getSlots() const {
|
||||
ArrayRef<VFTableSlotKind> getSlots() const {
|
||||
if (!SlotsRef.empty())
|
||||
return SlotsRef;
|
||||
return Slots;
|
||||
@ -723,12 +722,12 @@ private:
|
||||
};
|
||||
|
||||
private:
|
||||
ArrayRef<VirtualTableSlotKind> SlotsRef;
|
||||
std::vector<VirtualTableSlotKind> Slots;
|
||||
ArrayRef<VFTableSlotKind> SlotsRef;
|
||||
std::vector<VFTableSlotKind> Slots;
|
||||
};
|
||||
|
||||
// LF_TYPESERVER2
|
||||
class TypeServer2Record : TypeRecord {
|
||||
class TypeServer2Record : public TypeRecord {
|
||||
public:
|
||||
TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
|
||||
: TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
|
||||
@ -794,7 +793,7 @@ private:
|
||||
class FuncIdRecord : public TypeRecord {
|
||||
public:
|
||||
FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
|
||||
: TypeRecord(TypeRecordKind::FunctionId), ParentScope(ParentScope),
|
||||
: TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope),
|
||||
FunctionType(FunctionType), Name(Name) {}
|
||||
|
||||
static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
|
||||
@ -881,30 +880,30 @@ private:
|
||||
};
|
||||
|
||||
// LF_VFTABLE
|
||||
class VirtualTableRecord : public TypeRecord {
|
||||
class VFTableRecord : public TypeRecord {
|
||||
public:
|
||||
VirtualTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
|
||||
uint32_t VFPtrOffset, StringRef Name,
|
||||
ArrayRef<StringRef> Methods)
|
||||
: TypeRecord(TypeRecordKind::VirtualFunctionTable),
|
||||
VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
|
||||
uint32_t VFPtrOffset, StringRef Name,
|
||||
ArrayRef<StringRef> Methods)
|
||||
: TypeRecord(TypeRecordKind::VFTable),
|
||||
CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
|
||||
VFPtrOffset(VFPtrOffset), Name(Name), MethodNamesRef(Methods) {}
|
||||
VirtualTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
|
||||
uint32_t VFPtrOffset, StringRef Name,
|
||||
const std::vector<StringRef> &Methods)
|
||||
: TypeRecord(TypeRecordKind::VirtualFunctionTable),
|
||||
VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
|
||||
uint32_t VFPtrOffset, StringRef Name,
|
||||
const std::vector<StringRef> &Methods)
|
||||
: TypeRecord(TypeRecordKind::VFTable),
|
||||
CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
|
||||
VFPtrOffset(VFPtrOffset), Name(Name), MethodNames(Methods) {}
|
||||
|
||||
static ErrorOr<VirtualTableRecord> deserialize(TypeRecordKind Kind,
|
||||
ArrayRef<uint8_t> &Data) {
|
||||
static ErrorOr<VFTableRecord> deserialize(TypeRecordKind Kind,
|
||||
ArrayRef<uint8_t> &Data) {
|
||||
const Layout *L = nullptr;
|
||||
StringRef Name;
|
||||
std::vector<StringRef> Names;
|
||||
CV_DESERIALIZE(Data, L, Name, CV_ARRAY_FIELD_TAIL(Names));
|
||||
|
||||
return VirtualTableRecord(L->CompleteClass, L->OverriddenVFTable,
|
||||
L->VFPtrOffset, Name, Names);
|
||||
return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset,
|
||||
Name, Names);
|
||||
}
|
||||
|
||||
TypeIndex getCompleteClass() const { return CompleteClass; }
|
||||
@ -996,9 +995,9 @@ private:
|
||||
class MethodOverloadListRecord : public TypeRecord {
|
||||
public:
|
||||
MethodOverloadListRecord(ArrayRef<OneMethodRecord> Methods)
|
||||
: TypeRecord(TypeRecordKind::MethodList), MethodsRef(Methods) {}
|
||||
: TypeRecord(TypeRecordKind::MethodOverloadList), MethodsRef(Methods) {}
|
||||
MethodOverloadListRecord(std::vector<OneMethodRecord> &Methods)
|
||||
: TypeRecord(TypeRecordKind::MethodList), Methods(Methods) {}
|
||||
: TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {}
|
||||
|
||||
static ErrorOr<MethodOverloadListRecord> deserialize(TypeRecordKind Kind,
|
||||
ArrayRef<uint8_t> &Data) {
|
||||
@ -1078,7 +1077,7 @@ class DataMemberRecord : public TypeRecord {
|
||||
public:
|
||||
DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
|
||||
StringRef Name)
|
||||
: TypeRecord(TypeRecordKind::Member), Access(Access), Type(Type),
|
||||
: TypeRecord(TypeRecordKind::DataMember), Access(Access), Type(Type),
|
||||
FieldOffset(Offset), Name(Name) {}
|
||||
|
||||
static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
|
||||
@ -1114,8 +1113,8 @@ private:
|
||||
class StaticDataMemberRecord : public TypeRecord {
|
||||
public:
|
||||
StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
|
||||
: TypeRecord(TypeRecordKind::StaticMember), Access(Access), Type(Type),
|
||||
Name(Name) {}
|
||||
: TypeRecord(TypeRecordKind::StaticDataMember), Access(Access),
|
||||
Type(Type), Name(Name) {}
|
||||
|
||||
static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
|
||||
ArrayRef<uint8_t> &Data) {
|
||||
@ -1146,7 +1145,7 @@ private:
|
||||
class EnumeratorRecord : public TypeRecord {
|
||||
public:
|
||||
EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
|
||||
: TypeRecord(TypeRecordKind::Enumerate), Access(Access), Value(Value),
|
||||
: TypeRecord(TypeRecordKind::Enumerator), Access(Access), Value(Value),
|
||||
Name(Name) {}
|
||||
|
||||
static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
|
||||
@ -1176,17 +1175,17 @@ private:
|
||||
};
|
||||
|
||||
// LF_VFUNCTAB
|
||||
class VirtualFunctionPointerRecord : public TypeRecord {
|
||||
class VFPtrRecord : public TypeRecord {
|
||||
public:
|
||||
VirtualFunctionPointerRecord(TypeIndex Type)
|
||||
: TypeRecord(TypeRecordKind::VirtualFunctionTablePointer), Type(Type) {}
|
||||
static ErrorOr<VirtualFunctionPointerRecord>
|
||||
VFPtrRecord(TypeIndex Type)
|
||||
: TypeRecord(TypeRecordKind::VFPtr), Type(Type) {}
|
||||
static ErrorOr<VFPtrRecord>
|
||||
deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
|
||||
const Layout *L = nullptr;
|
||||
if (auto EC = consumeObject(Data, L))
|
||||
return EC;
|
||||
|
||||
return VirtualFunctionPointerRecord(L->Type);
|
||||
return VFPtrRecord(L->Type);
|
||||
}
|
||||
|
||||
TypeIndex getType() const { return Type; }
|
||||
|
@ -15,67 +15,72 @@
|
||||
// If the type is known, then we have a record describing it in TypeRecord.h.
|
||||
|
||||
#ifndef CV_TYPE
|
||||
#define CV_TYPE(ename, value)
|
||||
#define CV_TYPE(lf_ename, value)
|
||||
#endif
|
||||
|
||||
// If the type is known, then we have a record describing it in TypeRecord.h.
|
||||
#ifndef TYPE_RECORD
|
||||
#define TYPE_RECORD(ename, value, class_name, print_name) CV_TYPE(ename, value)
|
||||
#define TYPE_RECORD(lf_ename, value, name) CV_TYPE(lf_ename, value)
|
||||
#endif
|
||||
|
||||
#ifndef TYPE_RECORD_ALIAS
|
||||
#define TYPE_RECORD_ALIAS(ename, value, class_name, print_name) TYPE_RECORD(ename, value, class_name, print_name)
|
||||
#define TYPE_RECORD_ALIAS(lf_ename, value, name, alias_name) \
|
||||
TYPE_RECORD(lf_ename, value, name)
|
||||
#endif
|
||||
|
||||
#ifndef MEMBER_RECORD
|
||||
#define MEMBER_RECORD(ename, value, class_name, print_name) TYPE_RECORD(ename, value, class_name, print_name)
|
||||
#define MEMBER_RECORD(lf_ename, value, name) TYPE_RECORD(lf_ename, value, name)
|
||||
#endif
|
||||
|
||||
#ifndef MEMBER_RECORD_ALIAS
|
||||
#define MEMBER_RECORD_ALIAS(ename, value, class_name, print_name) MEMBER_RECORD(ename, value, class_name, print_name)
|
||||
#define MEMBER_RECORD_ALIAS(lf_ename, value, name, alias_name) \
|
||||
MEMBER_RECORD(lf_ename, value, 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_POINTER, 0x1002, Pointer)
|
||||
TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier)
|
||||
TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure)
|
||||
TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction)
|
||||
TYPE_RECORD(LF_ARGLIST, 0x1201, 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)
|
||||
TYPE_RECORD(LF_ARRAY, 0x1503, Array)
|
||||
TYPE_RECORD(LF_CLASS, 0x1504, Class)
|
||||
TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, Struct, Class)
|
||||
TYPE_RECORD_ALIAS(LF_INTERFACE, 0x1519, Interface, Class)
|
||||
TYPE_RECORD(LF_UNION, 0x1506, Union)
|
||||
TYPE_RECORD(LF_ENUM, 0x1507, Enum)
|
||||
TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2)
|
||||
TYPE_RECORD(LF_VFTABLE, 0x151d, VFTable)
|
||||
TYPE_RECORD(LF_VTSHAPE, 0x000a, VFTableShape)
|
||||
|
||||
// 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_BCLASS, 0x1400, BaseClass)
|
||||
MEMBER_RECORD_ALIAS(LF_BINTERFACE, 0x151a, BaseInterface, BaseClass)
|
||||
|
||||
MEMBER_RECORD(LF_VBCLASS, 0x1401, VirtualBaseClassRecord, VirtualBaseClass)
|
||||
MEMBER_RECORD_ALIAS(LF_IVBCLASS, 0x1402, VirtualBaseClassRecord, VirtualBaseClass)
|
||||
MEMBER_RECORD(LF_VBCLASS, 0x1401, VirtualBaseClass)
|
||||
MEMBER_RECORD_ALIAS(LF_IVBCLASS, 0x1402, IndirectVirtualBaseClass,
|
||||
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)
|
||||
MEMBER_RECORD(LF_VFUNCTAB, 0x1409, VFPtr)
|
||||
MEMBER_RECORD(LF_STMEMBER, 0x150e, StaticDataMember)
|
||||
MEMBER_RECORD(LF_METHOD, 0x150f, OverloadedMethod)
|
||||
MEMBER_RECORD(LF_MEMBER, 0x150d, DataMember)
|
||||
MEMBER_RECORD(LF_NESTTYPE, 0x1510, NestedType)
|
||||
MEMBER_RECORD(LF_ONEMETHOD, 0x1511, OneMethod)
|
||||
MEMBER_RECORD(LF_ENUMERATE, 0x1502, 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_FUNC_ID, 0x1601, FuncId)
|
||||
TYPE_RECORD(LF_MFUNC_ID, 0x1602, MemberFuncId)
|
||||
TYPE_RECORD(LF_BUILDINFO, 0x1603, BuildInfo)
|
||||
// FIXME: We reuse the structure of ArgListRecord for substring lists, but it
|
||||
// makes for confusing dumper output.
|
||||
TYPE_RECORD_ALIAS(LF_SUBSTR_LIST, 0x1604, StringList, ArgList)
|
||||
TYPE_RECORD(LF_STRING_ID, 0x1605, StringId)
|
||||
TYPE_RECORD(LF_UDT_SRC_LINE, 0x1606, UdtSourceLine)
|
||||
|
||||
TYPE_RECORD(LF_METHODLIST, 0x1206, MethodOverloadListRecord, MethodListEntry)
|
||||
TYPE_RECORD(LF_METHODLIST, 0x1206, MethodOverloadList)
|
||||
|
||||
|
||||
// 16 bit type records.
|
||||
|
@ -40,14 +40,14 @@ public:
|
||||
TypeIndex writeModifier(const ModifierRecord &Record);
|
||||
TypeIndex writeProcedure(const ProcedureRecord &Record);
|
||||
TypeIndex writeMemberFunction(const MemberFunctionRecord &Record);
|
||||
TypeIndex writeArgumentList(const StringListRecord &Record);
|
||||
TypeIndex writeArgList(const ArgListRecord &Record);
|
||||
TypeIndex writeRecord(TypeRecordBuilder &builder);
|
||||
TypeIndex writePointer(const PointerRecord &Record);
|
||||
TypeIndex writeArray(const ArrayRecord &Record);
|
||||
TypeIndex writeClass(const ClassRecord &Record);
|
||||
TypeIndex writeEnum(const EnumRecord &Record);
|
||||
TypeIndex writeBitField(const BitFieldRecord &Record);
|
||||
TypeIndex writeVirtualTableShape(const VirtualTableShapeRecord &Record);
|
||||
TypeIndex writeVFTableShape(const VFTableShapeRecord &Record);
|
||||
|
||||
TypeIndex writeFieldList(FieldListRecordBuilder &FieldList);
|
||||
TypeIndex writeMethodList(MethodListRecordBuilder &MethodList);
|
||||
|
@ -263,7 +263,7 @@ void CodeViewDebug::emitTypeInformation() {
|
||||
// type here.
|
||||
unsigned ArgListIndex = getNextTypeIndex();
|
||||
OS.AddComment("Type record length");
|
||||
OS.EmitIntValue(StringListRecord::getLayoutSize(), 2);
|
||||
OS.EmitIntValue(ArgListRecord::getLayoutSize(), 2);
|
||||
OS.AddComment("Leaf type: LF_ARGLIST");
|
||||
OS.EmitIntValue(LF_ARGLIST, 2);
|
||||
OS.AddComment("Number of arguments");
|
||||
|
@ -31,7 +31,7 @@ void FieldListRecordBuilder::writeEnumerate(MemberAccess Access, uint64_t Value,
|
||||
StringRef Name) {
|
||||
TypeRecordBuilder &Builder = getBuilder();
|
||||
|
||||
Builder.writeTypeRecordKind(TypeRecordKind::Enumerate);
|
||||
Builder.writeTypeRecordKind(TypeRecordKind::Enumerator);
|
||||
Builder.writeUInt16(static_cast<uint16_t>(Access));
|
||||
Builder.writeEncodedUnsignedInteger(Value);
|
||||
Builder.writeNullTerminatedString(Name);
|
||||
@ -43,7 +43,7 @@ void FieldListRecordBuilder::writeMember(MemberAccess Access, TypeIndex Type,
|
||||
uint64_t Offset, StringRef Name) {
|
||||
TypeRecordBuilder &Builder = getBuilder();
|
||||
|
||||
Builder.writeTypeRecordKind(TypeRecordKind::Member);
|
||||
Builder.writeTypeRecordKind(TypeRecordKind::DataMember);
|
||||
Builder.writeUInt16(static_cast<uint16_t>(Access));
|
||||
Builder.writeTypeIndex(Type);
|
||||
Builder.writeEncodedUnsignedInteger(Offset);
|
||||
@ -114,7 +114,7 @@ void FieldListRecordBuilder::writeStaticMember(MemberAccess Access,
|
||||
TypeIndex Type, StringRef Name) {
|
||||
TypeRecordBuilder &Builder = getBuilder();
|
||||
|
||||
Builder.writeTypeRecordKind(TypeRecordKind::StaticMember);
|
||||
Builder.writeTypeRecordKind(TypeRecordKind::StaticDataMember);
|
||||
Builder.writeUInt16(static_cast<uint16_t>(Access));
|
||||
Builder.writeTypeIndex(Type);
|
||||
Builder.writeNullTerminatedString(Name);
|
||||
@ -157,9 +157,9 @@ void FieldListRecordBuilder::writeVirtualBaseClass(
|
||||
void FieldListRecordBuilder::writeVirtualFunctionTablePointer(TypeIndex Type) {
|
||||
TypeRecordBuilder &Builder = getBuilder();
|
||||
|
||||
Builder.writeTypeRecordKind(TypeRecordKind::VirtualFunctionTablePointer);
|
||||
Builder.writeTypeRecordKind(TypeRecordKind::VFPtr);
|
||||
Builder.writeUInt16(0);
|
||||
Builder.writeTypeIndex(Type);
|
||||
|
||||
finishSubRecord();
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ using namespace llvm;
|
||||
using namespace codeview;
|
||||
|
||||
MethodListRecordBuilder::MethodListRecordBuilder()
|
||||
: ListRecordBuilder(TypeRecordKind::MethodList) {}
|
||||
: ListRecordBuilder(TypeRecordKind::MethodOverloadList) {}
|
||||
|
||||
void MethodListRecordBuilder::writeMethod(MemberAccess Access, MethodKind Kind,
|
||||
MethodOptions Options, TypeIndex Type,
|
||||
|
@ -200,12 +200,12 @@ public:
|
||||
: CVTD(CVTD), W(W), PrintRecordBytes(PrintRecordBytes) {}
|
||||
|
||||
/// CVTypeVisitor overrides.
|
||||
#define TYPE_RECORD(EnumName, EnumVal, ClassName, PrintName) \
|
||||
void visit##ClassName(TypeLeafKind LeafType, ClassName &Record);
|
||||
#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(EnumName, EnumVal, ClassName, PrintName)
|
||||
#define TYPE_RECORD(EnumName, EnumVal, Name) \
|
||||
void visit##Name(TypeLeafKind LeafType, Name##Record &Record);
|
||||
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
|
||||
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
|
||||
void visit##Name(TypeLeafKind LeafType, Name##Record &Record);
|
||||
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
|
||||
|
||||
void visitUnknownMember(TypeLeafKind Leaf);
|
||||
@ -239,9 +239,9 @@ private:
|
||||
|
||||
static StringRef getLeafTypeName(TypeLeafKind LT) {
|
||||
switch (LT) {
|
||||
#define TYPE_RECORD(ename, value, class_name, print_name) \
|
||||
#define TYPE_RECORD(ename, value, name) \
|
||||
case ename: \
|
||||
return #print_name;
|
||||
return #name;
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecords.def"
|
||||
default:
|
||||
break;
|
||||
@ -273,15 +273,14 @@ void CVTypeDumperImpl::visitTypeEnd(TypeLeafKind Leaf,
|
||||
W.startLine() << "}\n";
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitStringIdRecord(TypeLeafKind Leaf,
|
||||
void CVTypeDumperImpl::visitStringId(TypeLeafKind Leaf,
|
||||
StringIdRecord &String) {
|
||||
printTypeIndex("Id", String.getId());
|
||||
W.printString("StringData", String.getString());
|
||||
// Put this in CVUDTNames so it gets printed with LF_UDT_SRC_LINE.
|
||||
Name = String.getString();
|
||||
}
|
||||
void CVTypeDumperImpl::visitStringListRecord(TypeLeafKind Leaf,
|
||||
StringListRecord &Args) {
|
||||
void CVTypeDumperImpl::visitArgList(TypeLeafKind Leaf, ArgListRecord &Args) {
|
||||
auto Indices = Args.getIndices();
|
||||
uint32_t Size = Indices.size();
|
||||
W.printNumber("NumArgs", Size);
|
||||
@ -298,7 +297,7 @@ void CVTypeDumperImpl::visitStringListRecord(TypeLeafKind Leaf,
|
||||
Name = CVTD.saveName(TypeName);
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitClassRecord(TypeLeafKind Leaf, ClassRecord &Class) {
|
||||
void CVTypeDumperImpl::visitClass(TypeLeafKind Leaf, ClassRecord &Class) {
|
||||
uint16_t Props = static_cast<uint16_t>(Class.getOptions());
|
||||
W.printNumber("MemberCount", Class.getMemberCount());
|
||||
W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
|
||||
@ -312,7 +311,7 @@ void CVTypeDumperImpl::visitClassRecord(TypeLeafKind Leaf, ClassRecord &Class) {
|
||||
Name = Class.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitUnionRecord(TypeLeafKind Leaf, UnionRecord &Union) {
|
||||
void CVTypeDumperImpl::visitUnion(TypeLeafKind Leaf, UnionRecord &Union) {
|
||||
uint16_t Props = static_cast<uint16_t>(Union.getOptions());
|
||||
W.printNumber("MemberCount", Union.getMemberCount());
|
||||
W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
|
||||
@ -324,7 +323,7 @@ void CVTypeDumperImpl::visitUnionRecord(TypeLeafKind Leaf, UnionRecord &Union) {
|
||||
Name = Union.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitEnumRecord(TypeLeafKind Leaf, EnumRecord &Enum) {
|
||||
void CVTypeDumperImpl::visitEnum(TypeLeafKind Leaf, EnumRecord &Enum) {
|
||||
W.printNumber("NumEnumerators", Enum.getMemberCount());
|
||||
W.printFlags("Properties", uint16_t(Enum.getOptions()),
|
||||
makeArrayRef(ClassOptionNames));
|
||||
@ -334,7 +333,7 @@ void CVTypeDumperImpl::visitEnumRecord(TypeLeafKind Leaf, EnumRecord &Enum) {
|
||||
Name = Enum.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitArrayRecord(TypeLeafKind Leaf, ArrayRecord &AT) {
|
||||
void CVTypeDumperImpl::visitArray(TypeLeafKind Leaf, ArrayRecord &AT) {
|
||||
printTypeIndex("ElementType", AT.getElementType());
|
||||
printTypeIndex("IndexType", AT.getIndexType());
|
||||
W.printNumber("SizeOf", AT.getSize());
|
||||
@ -342,8 +341,7 @@ void CVTypeDumperImpl::visitArrayRecord(TypeLeafKind Leaf, ArrayRecord &AT) {
|
||||
Name = AT.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitVirtualTableRecord(TypeLeafKind Leaf,
|
||||
VirtualTableRecord &VFT) {
|
||||
void CVTypeDumperImpl::visitVFTable(TypeLeafKind Leaf, VFTableRecord &VFT) {
|
||||
printTypeIndex("CompleteClass", VFT.getCompleteClass());
|
||||
printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
|
||||
W.printHex("VFPtrOffset", VFT.getVFPtrOffset());
|
||||
@ -353,16 +351,16 @@ void CVTypeDumperImpl::visitVirtualTableRecord(TypeLeafKind Leaf,
|
||||
Name = VFT.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitMemberFunctionIdRecord(TypeLeafKind Leaf,
|
||||
MemberFunctionIdRecord &Id) {
|
||||
void CVTypeDumperImpl::visitMemberFuncId(TypeLeafKind Leaf,
|
||||
MemberFuncIdRecord &Id) {
|
||||
printTypeIndex("ClassType", Id.getClassType());
|
||||
printTypeIndex("FunctionType", Id.getFunctionType());
|
||||
W.printString("Name", Id.getName());
|
||||
Name = Id.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitProcedureRecord(TypeLeafKind Leaf,
|
||||
ProcedureRecord &Proc) {
|
||||
void CVTypeDumperImpl::visitProcedure(TypeLeafKind Leaf,
|
||||
ProcedureRecord &Proc) {
|
||||
printTypeIndex("ReturnType", Proc.getReturnType());
|
||||
W.printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
|
||||
makeArrayRef(CallingConventions));
|
||||
@ -379,8 +377,8 @@ void CVTypeDumperImpl::visitProcedureRecord(TypeLeafKind Leaf,
|
||||
Name = CVTD.saveName(TypeName);
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitMemberFunctionRecord(TypeLeafKind Leaf,
|
||||
MemberFunctionRecord &MF) {
|
||||
void CVTypeDumperImpl::visitMemberFunction(TypeLeafKind Leaf,
|
||||
MemberFunctionRecord &MF) {
|
||||
printTypeIndex("ReturnType", MF.getReturnType());
|
||||
printTypeIndex("ClassType", MF.getClassType());
|
||||
printTypeIndex("ThisType", MF.getThisType());
|
||||
@ -403,8 +401,8 @@ void CVTypeDumperImpl::visitMemberFunctionRecord(TypeLeafKind Leaf,
|
||||
Name = CVTD.saveName(TypeName);
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitMethodOverloadListRecord(TypeLeafKind Leaf,
|
||||
MethodOverloadListRecord &MethodList) {
|
||||
void CVTypeDumperImpl::visitMethodOverloadList(
|
||||
TypeLeafKind Leaf, MethodOverloadListRecord &MethodList) {
|
||||
for (auto &M : MethodList.getMethods()) {
|
||||
ListScope S(W, "Method");
|
||||
printMemberAttributes(M.getAccess(), M.getKind(), M.getOptions());
|
||||
@ -414,24 +412,22 @@ void CVTypeDumperImpl::visitMethodOverloadListRecord(TypeLeafKind Leaf,
|
||||
}
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitFuncIdRecord(TypeLeafKind Leaf,
|
||||
FuncIdRecord &Func) {
|
||||
void CVTypeDumperImpl::visitFuncId(TypeLeafKind Leaf, FuncIdRecord &Func) {
|
||||
printTypeIndex("ParentScope", Func.getParentScope());
|
||||
printTypeIndex("FunctionType", Func.getFunctionType());
|
||||
W.printString("Name", Func.getName());
|
||||
Name = Func.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitTypeServer2Record(TypeLeafKind Leaf,
|
||||
TypeServer2Record &TS) {
|
||||
void CVTypeDumperImpl::visitTypeServer2(TypeLeafKind Leaf,
|
||||
TypeServer2Record &TS) {
|
||||
W.printBinary("Signature", TS.getGuid());
|
||||
W.printNumber("Age", TS.getAge());
|
||||
W.printString("Name", TS.getName());
|
||||
Name = TS.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitPointerRecord(TypeLeafKind Leaf,
|
||||
PointerRecord &Ptr) {
|
||||
void CVTypeDumperImpl::visitPointer(TypeLeafKind Leaf, PointerRecord &Ptr) {
|
||||
printTypeIndex("PointeeType", Ptr.getReferentType());
|
||||
W.printHex("PointerAttributes", uint32_t(Ptr.getOptions()));
|
||||
W.printEnum("PtrType", unsigned(Ptr.getPointerKind()),
|
||||
@ -479,8 +475,7 @@ void CVTypeDumperImpl::visitPointerRecord(TypeLeafKind Leaf,
|
||||
}
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitModifierRecord(TypeLeafKind Leaf,
|
||||
ModifierRecord &Mod) {
|
||||
void CVTypeDumperImpl::visitModifier(TypeLeafKind Leaf, ModifierRecord &Mod) {
|
||||
uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
|
||||
printTypeIndex("ModifiedType", Mod.getModifiedType());
|
||||
W.printFlags("Modifiers", Mods, makeArrayRef(TypeModifierNames));
|
||||
@ -497,20 +492,20 @@ void CVTypeDumperImpl::visitModifierRecord(TypeLeafKind Leaf,
|
||||
Name = CVTD.saveName(TypeName);
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitVirtualTableShapeRecord(
|
||||
TypeLeafKind Leaf, VirtualTableShapeRecord &Shape) {
|
||||
void CVTypeDumperImpl::visitVFTableShape(TypeLeafKind Leaf,
|
||||
VFTableShapeRecord &Shape) {
|
||||
W.printNumber("VFEntryCount", Shape.getEntryCount());
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitUdtSourceLineRecord(TypeLeafKind Leaf,
|
||||
UdtSourceLineRecord &Line) {
|
||||
void CVTypeDumperImpl::visitUdtSourceLine(TypeLeafKind Leaf,
|
||||
UdtSourceLineRecord &Line) {
|
||||
printTypeIndex("UDT", Line.getUDT());
|
||||
printTypeIndex("SourceFile", Line.getSourceFile());
|
||||
W.printNumber("LineNumber", Line.getLineNumber());
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitBuildInfoRecord(TypeLeafKind Leaf,
|
||||
BuildInfoRecord &Args) {
|
||||
void CVTypeDumperImpl::visitBuildInfo(TypeLeafKind Leaf,
|
||||
BuildInfoRecord &Args) {
|
||||
W.printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
|
||||
|
||||
ListScope Arguments(W, "Arguments");
|
||||
@ -542,16 +537,16 @@ void CVTypeDumperImpl::visitUnknownMember(TypeLeafKind Leaf) {
|
||||
W.printHex("UnknownMember", unsigned(Leaf));
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitNestedTypeRecord(TypeLeafKind Leaf,
|
||||
NestedTypeRecord &Nested) {
|
||||
void CVTypeDumperImpl::visitNestedType(TypeLeafKind Leaf,
|
||||
NestedTypeRecord &Nested) {
|
||||
DictScope S(W, "NestedType");
|
||||
printTypeIndex("Type", Nested.getNestedType());
|
||||
W.printString("Name", Nested.getName());
|
||||
Name = Nested.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitOneMethodRecord(TypeLeafKind Leaf,
|
||||
OneMethodRecord &Method) {
|
||||
void CVTypeDumperImpl::visitOneMethod(TypeLeafKind Leaf,
|
||||
OneMethodRecord &Method) {
|
||||
DictScope S(W, "OneMethod");
|
||||
MethodKind K = Method.getKind();
|
||||
printMemberAttributes(Method.getAccess(), K, Method.getOptions());
|
||||
@ -563,8 +558,8 @@ void CVTypeDumperImpl::visitOneMethodRecord(TypeLeafKind Leaf,
|
||||
Name = Method.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitOverloadedMethodRecord(
|
||||
TypeLeafKind Leaf, OverloadedMethodRecord &Method) {
|
||||
void CVTypeDumperImpl::visitOverloadedMethod(TypeLeafKind Leaf,
|
||||
OverloadedMethodRecord &Method) {
|
||||
DictScope S(W, "OverloadedMethod");
|
||||
W.printHex("MethodCount", Method.getNumOverloads());
|
||||
printTypeIndex("MethodListIndex", Method.getMethodList());
|
||||
@ -572,8 +567,8 @@ void CVTypeDumperImpl::visitOverloadedMethodRecord(
|
||||
Name = Method.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitDataMemberRecord(TypeLeafKind Leaf,
|
||||
DataMemberRecord &Field) {
|
||||
void CVTypeDumperImpl::visitDataMember(TypeLeafKind Leaf,
|
||||
DataMemberRecord &Field) {
|
||||
DictScope S(W, "DataMember");
|
||||
printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
|
||||
MethodOptions::None);
|
||||
@ -583,8 +578,8 @@ void CVTypeDumperImpl::visitDataMemberRecord(TypeLeafKind Leaf,
|
||||
Name = Field.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitStaticDataMemberRecord(
|
||||
TypeLeafKind Leaf, StaticDataMemberRecord &Field) {
|
||||
void CVTypeDumperImpl::visitStaticDataMember(TypeLeafKind Leaf,
|
||||
StaticDataMemberRecord &Field) {
|
||||
DictScope S(W, "StaticDataMember");
|
||||
printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
|
||||
MethodOptions::None);
|
||||
@ -593,14 +588,13 @@ void CVTypeDumperImpl::visitStaticDataMemberRecord(
|
||||
Name = Field.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitVirtualFunctionPointerRecord(
|
||||
TypeLeafKind Leaf, VirtualFunctionPointerRecord &VFTable) {
|
||||
DictScope S(W, "VirtualFunctionPointer");
|
||||
void CVTypeDumperImpl::visitVFPtr(TypeLeafKind Leaf, VFPtrRecord &VFTable) {
|
||||
DictScope S(W, "VFPtr");
|
||||
printTypeIndex("Type", VFTable.getType());
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitEnumeratorRecord(TypeLeafKind Leaf,
|
||||
EnumeratorRecord &Enum) {
|
||||
void CVTypeDumperImpl::visitEnumerator(TypeLeafKind Leaf,
|
||||
EnumeratorRecord &Enum) {
|
||||
DictScope S(W, "Enumerator");
|
||||
printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
|
||||
MethodOptions::None);
|
||||
@ -609,8 +603,8 @@ void CVTypeDumperImpl::visitEnumeratorRecord(TypeLeafKind Leaf,
|
||||
Name = Enum.getName();
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitBaseClassRecord(TypeLeafKind Leaf,
|
||||
BaseClassRecord &Base) {
|
||||
void CVTypeDumperImpl::visitBaseClass(TypeLeafKind Leaf,
|
||||
BaseClassRecord &Base) {
|
||||
DictScope S(W, "BaseClass");
|
||||
printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
|
||||
MethodOptions::None);
|
||||
@ -618,8 +612,8 @@ void CVTypeDumperImpl::visitBaseClassRecord(TypeLeafKind Leaf,
|
||||
W.printHex("BaseOffset", Base.getBaseOffset());
|
||||
}
|
||||
|
||||
void CVTypeDumperImpl::visitVirtualBaseClassRecord(
|
||||
TypeLeafKind Leaf, VirtualBaseClassRecord &Base) {
|
||||
void CVTypeDumperImpl::visitVirtualBaseClass(TypeLeafKind Leaf,
|
||||
VirtualBaseClassRecord &Base) {
|
||||
DictScope S(W, "VirtualBaseClass");
|
||||
printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
|
||||
MethodOptions::None);
|
||||
|
@ -60,33 +60,33 @@ void TypeRecordBuilder::writeEncodedInteger(int64_t Value) {
|
||||
void TypeRecordBuilder::writeEncodedSignedInteger(int64_t Value) {
|
||||
if (Value >= std::numeric_limits<int8_t>::min() &&
|
||||
Value <= std::numeric_limits<int8_t>::max()) {
|
||||
writeUInt16(static_cast<uint16_t>(TypeRecordKind::SByte));
|
||||
writeUInt16(LF_CHAR);
|
||||
writeInt16(static_cast<int8_t>(Value));
|
||||
} else if (Value >= std::numeric_limits<int16_t>::min() &&
|
||||
Value <= std::numeric_limits<int16_t>::max()) {
|
||||
writeUInt16(static_cast<uint16_t>(TypeRecordKind::Int16));
|
||||
writeUInt16(LF_SHORT);
|
||||
writeInt16(static_cast<int16_t>(Value));
|
||||
} else if (Value >= std::numeric_limits<int32_t>::min() &&
|
||||
Value <= std::numeric_limits<int32_t>::max()) {
|
||||
writeUInt16(static_cast<uint32_t>(TypeRecordKind::Int32));
|
||||
writeUInt16(LF_LONG);
|
||||
writeInt32(static_cast<int32_t>(Value));
|
||||
} else {
|
||||
writeUInt16(static_cast<uint16_t>(TypeRecordKind::Int64));
|
||||
writeUInt16(LF_QUADWORD);
|
||||
writeInt64(Value);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeRecordBuilder::writeEncodedUnsignedInteger(uint64_t Value) {
|
||||
if (Value < static_cast<uint16_t>(TypeRecordKind::SByte)) {
|
||||
if (Value < LF_CHAR) {
|
||||
writeUInt16(static_cast<uint16_t>(Value));
|
||||
} else if (Value <= std::numeric_limits<uint16_t>::max()) {
|
||||
writeUInt16(static_cast<uint16_t>(TypeRecordKind::UInt16));
|
||||
writeUInt16(LF_USHORT);
|
||||
writeUInt16(static_cast<uint16_t>(Value));
|
||||
} else if (Value <= std::numeric_limits<uint32_t>::max()) {
|
||||
writeUInt16(static_cast<uint16_t>(TypeRecordKind::UInt32));
|
||||
writeUInt16(LF_ULONG);
|
||||
writeUInt32(static_cast<uint32_t>(Value));
|
||||
} else {
|
||||
writeUInt16(static_cast<uint16_t>(TypeRecordKind::UInt64));
|
||||
writeUInt16(LF_UQUADWORD);
|
||||
writeUInt64(Value);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ TypeTableBuilder::TypeTableBuilder() {}
|
||||
TypeTableBuilder::~TypeTableBuilder() {}
|
||||
|
||||
TypeIndex TypeTableBuilder::writeModifier(const ModifierRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::Modifier);
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
Builder.writeTypeIndex(Record.getModifiedType());
|
||||
Builder.writeUInt16(static_cast<uint16_t>(Record.getModifiers()));
|
||||
@ -31,7 +31,7 @@ TypeIndex TypeTableBuilder::writeModifier(const ModifierRecord &Record) {
|
||||
}
|
||||
|
||||
TypeIndex TypeTableBuilder::writeProcedure(const ProcedureRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::Procedure);
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
Builder.writeTypeIndex(Record.getReturnType());
|
||||
Builder.writeUInt8(static_cast<uint8_t>(Record.getCallConv()));
|
||||
@ -44,7 +44,7 @@ TypeIndex TypeTableBuilder::writeProcedure(const ProcedureRecord &Record) {
|
||||
|
||||
TypeIndex
|
||||
TypeTableBuilder::writeMemberFunction(const MemberFunctionRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::MemberFunction);
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
Builder.writeTypeIndex(Record.getReturnType());
|
||||
Builder.writeTypeIndex(Record.getClassType());
|
||||
@ -58,8 +58,8 @@ TypeTableBuilder::writeMemberFunction(const MemberFunctionRecord &Record) {
|
||||
return writeRecord(Builder);
|
||||
}
|
||||
|
||||
TypeIndex TypeTableBuilder::writeArgumentList(const StringListRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::ArgumentList);
|
||||
TypeIndex TypeTableBuilder::writeArgList(const ArgListRecord &Record) {
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
Builder.writeUInt32(Record.getIndices().size());
|
||||
for (TypeIndex TI : Record.getIndices()) {
|
||||
@ -70,7 +70,7 @@ TypeIndex TypeTableBuilder::writeArgumentList(const StringListRecord &Record) {
|
||||
}
|
||||
|
||||
TypeIndex TypeTableBuilder::writePointer(const PointerRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::Pointer);
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
Builder.writeTypeIndex(Record.getReferentType());
|
||||
uint32_t flags = static_cast<uint32_t>(Record.getOptions()) |
|
||||
@ -91,7 +91,7 @@ TypeIndex TypeTableBuilder::writePointer(const PointerRecord &Record) {
|
||||
}
|
||||
|
||||
TypeIndex TypeTableBuilder::writeArray(const ArrayRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::Array);
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
Builder.writeTypeIndex(Record.getElementType());
|
||||
Builder.writeTypeIndex(Record.getIndexType());
|
||||
@ -102,7 +102,7 @@ TypeIndex TypeTableBuilder::writeArray(const ArrayRecord &Record) {
|
||||
}
|
||||
|
||||
TypeIndex TypeTableBuilder::writeClass(const ClassRecord &Record) {
|
||||
assert((Record.getKind() == TypeRecordKind::Structure) ||
|
||||
assert((Record.getKind() == TypeRecordKind::Struct) ||
|
||||
(Record.getKind() == TypeRecordKind::Class) ||
|
||||
(Record.getKind() == TypeRecordKind::Union));
|
||||
|
||||
@ -129,7 +129,7 @@ TypeIndex TypeTableBuilder::writeClass(const ClassRecord &Record) {
|
||||
}
|
||||
|
||||
TypeIndex TypeTableBuilder::writeEnum(const EnumRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::Enum);
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
Builder.writeUInt16(Record.getMemberCount());
|
||||
Builder.writeUInt16(static_cast<uint16_t>(Record.getOptions()));
|
||||
@ -145,7 +145,7 @@ TypeIndex TypeTableBuilder::writeEnum(const EnumRecord &Record) {
|
||||
}
|
||||
|
||||
TypeIndex TypeTableBuilder::writeBitField(const BitFieldRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::BitField);
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
Builder.writeTypeIndex(Record.getType());
|
||||
Builder.writeUInt8(Record.getBitSize());
|
||||
@ -154,11 +154,11 @@ TypeIndex TypeTableBuilder::writeBitField(const BitFieldRecord &Record) {
|
||||
return writeRecord(Builder);
|
||||
}
|
||||
|
||||
TypeIndex TypeTableBuilder::writeVirtualTableShape(
|
||||
const VirtualTableShapeRecord &Record) {
|
||||
TypeRecordBuilder Builder(TypeRecordKind::VirtualTableShape);
|
||||
TypeIndex
|
||||
TypeTableBuilder::writeVFTableShape(const VFTableShapeRecord &Record) {
|
||||
TypeRecordBuilder Builder(Record.getKind());
|
||||
|
||||
ArrayRef<VirtualTableSlotKind> Slots = Record.getSlots();
|
||||
ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
|
||||
|
||||
Builder.writeUInt16(Slots.size());
|
||||
for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) {
|
||||
|
@ -76,7 +76,7 @@
|
||||
; OBJ: TypeLeafKind: LF_ARGLIST (0x1201)
|
||||
; OBJ: NumArgs: 0
|
||||
; OBJ: }
|
||||
; OBJ: ProcedureType (0x1001) {
|
||||
; OBJ: Procedure (0x1001) {
|
||||
; OBJ: TypeLeafKind: LF_PROCEDURE (0x1008)
|
||||
; OBJ: ReturnType: void (0x3)
|
||||
; OBJ: NumParameters: 0
|
||||
|
@ -257,7 +257,7 @@
|
||||
; EMPTY-NEXT: )
|
||||
; EMPTY-NEXT: }
|
||||
; EMPTY-NEXT: {
|
||||
; EMPTY-NEXT: ProcedureType (0x1001) {
|
||||
; EMPTY-NEXT: Procedure (0x1001) {
|
||||
; EMPTY-NEXT: TypeLeafKind: LF_PROCEDURE (0x1008)
|
||||
; EMPTY-NEXT: ReturnType: int (0x74)
|
||||
; EMPTY-NEXT: CallingConvention: NearC (0x0)
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
RUN: llvm-readobj -codeview %p/Inputs/codeview-vftable.obj.coff | FileCheck %s
|
||||
|
||||
CHECK: VFTableType (0x10F0) {
|
||||
CHECK: VFTable (0x10F0) {
|
||||
CHECK-NEXT: TypeLeafKind: LF_VFTABLE (0x151D)
|
||||
CHECK-NEXT: CompleteClass: A
|
||||
CHECK-NEXT: OverriddenVFTable: 0x0
|
||||
@ -27,7 +27,7 @@ CHECK-NEXT: VFPtrOffset: 0x0
|
||||
CHECK-NEXT: VFTableName: ??_7A@@6B@
|
||||
CHECK-NEXT: MethodName: ?f@A@@UEAAXXZ
|
||||
CHECK-NEXT: }
|
||||
CHECK-NEXT: VFTableType (0x10F1) {
|
||||
CHECK-NEXT: VFTable (0x10F1) {
|
||||
CHECK-NEXT: TypeLeafKind: LF_VFTABLE (0x151D)
|
||||
CHECK-NEXT: CompleteClass: B
|
||||
CHECK-NEXT: OverriddenVFTable: ??_7A@@6B@ (0x10F0)
|
||||
@ -36,7 +36,7 @@ CHECK-NEXT: VFTableName: ??_7B@@6B@
|
||||
CHECK-NEXT: MethodName: ?f@B@@UEAAXXZ
|
||||
CHECK-NEXT: MethodName: ?g@B@@UEAAXXZ
|
||||
CHECK-NEXT: }
|
||||
CHECK-NEXT: VFTableType (0x10F2) {
|
||||
CHECK-NEXT: VFTable (0x10F2) {
|
||||
CHECK-NEXT: TypeLeafKind: LF_VFTABLE (0x151D)
|
||||
CHECK-NEXT: CompleteClass: C
|
||||
CHECK-NEXT: OverriddenVFTable: ??_7B@@6B@ (0x10F1)
|
||||
|
Loading…
Reference in New Issue
Block a user