Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/CodeView.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,23 @@ enum class ClassOptions : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ClassOptions)

enum class ClassOptions2 : uint32_t {
None = 0x0000,
Packed = 0x0001,
HasConstructorOrDestructor = 0x0002,
HasOverloadedOperator = 0x0004,
Nested = 0x0008,
ContainsNestedClass = 0x0010,
HasOverloadedAssignmentOperator = 0x0020,
HasConversionOperator = 0x0040,
ForwardReference = 0x0080,
Scoped = 0x0100,
HasUniqueName = 0x0200,
Sealed = 0x0400,
Intrinsic = 0x2000
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ClassOptions2)

enum class FrameProcedureOptions : uint32_t {
None = 0x00000000,
HasAlloca = 0x00000001,
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/CodeViewTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList)

TYPE_RECORD(LF_ARRAY, 0x1503, Array)
TYPE_RECORD(LF_CLASS, 0x1504, Class)
TYPE_RECORD(LF_CLASS2, 0x1608, Class2)
TYPE_RECORD_ALIAS(LF_STRUCTURE, 0x1505, Struct, Class)
TYPE_RECORD_ALIAS(LF_STRUCTURE2, 0x1609, Struct2, Class2)
TYPE_RECORD_ALIAS(LF_INTERFACE, 0x1519, Interface, Class)
TYPE_RECORD_ALIAS(LF_INTERFACE2, 0x160b, Interface2, Class2)
TYPE_RECORD(LF_UNION, 0x1506, Union)
TYPE_RECORD(LF_ENUM, 0x1507, Enum)
TYPE_RECORD(LF_TYPESERVER2, 0x1515, TypeServer2)
Expand Down
83 changes: 83 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,89 @@ class ClassRecord : public TagRecord {
uint64_t Size = 0;
};

class Tag2Record : public TypeRecord {
protected:
Tag2Record() = default;
explicit Tag2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
Tag2Record(TypeRecordKind Kind, ClassOptions2 Options,
TypeIndex FieldList, StringRef Name, StringRef UniqueName)
: TypeRecord(Kind), Options(Options),
FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}

public:
static const int HfaKindShift = 11;
static const int HfaKindMask = 0x1800;
static const int WinRTKindShift = 14;
static const int WinRTKindMask = 0xC000;

bool hasUniqueName() const {
return (getOptions() & ClassOptions2::HasUniqueName) != ClassOptions2::None;
}

bool isNested() const {
return (getOptions() & ClassOptions2::Nested) != ClassOptions2::None;
}

bool isForwardRef() const {
return (getOptions() & ClassOptions2::ForwardReference) !=
ClassOptions2::None;
}

bool containsNestedClass() const {
return (getOptions() & ClassOptions2::ContainsNestedClass) !=
ClassOptions2::None;
}

bool isScoped() const {
return (getOptions() & ClassOptions2::Scoped) != ClassOptions2::None;
}

ClassOptions2 getOptions() const { return Options; }
TypeIndex getFieldList() const { return FieldList; }
StringRef getName() const { return Name; }
StringRef getUniqueName() const { return UniqueName; }

ClassOptions2 Options = ClassOptions2::None;
TypeIndex FieldList;
StringRef Name;
StringRef UniqueName;
};

// LF_CLASS2, LF_STRUCTURE2, LF_INTERFACE2
class Class2Record : public Tag2Record {
public:
Class2Record() = default;
explicit Class2Record(TypeRecordKind Kind) : Tag2Record(Kind) {}
Class2Record(TypeRecordKind Kind, ClassOptions2 Options,
TypeIndex FieldList, TypeIndex DerivationList,
TypeIndex VTableShape, uint64_t Size, StringRef Name,
StringRef UniqueName)
: Tag2Record(Kind, Options, FieldList, Name, UniqueName),
DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {}

HfaKind getHfa() const {
uint16_t Value = static_cast<uint16_t>(Options);
Value = (Value & HfaKindMask) >> HfaKindShift;
return static_cast<HfaKind>(Value);
}

WindowsRTClassKind getWinRTKind() const {
uint16_t Value = static_cast<uint16_t>(Options);
Value = (Value & WinRTKindMask) >> WinRTKindShift;
return static_cast<WindowsRTClassKind>(Value);
}

TypeIndex getDerivationList() const { return DerivationList; }
TypeIndex getVTableShape() const { return VTableShape; }
uint64_t getCount() const { return Count; }
uint64_t getSize() const { return Size; }

TypeIndex DerivationList;
TypeIndex VTableShape;
uint64_t Count = 0;
uint64_t Size = 0;
};

// LF_UNION
struct UnionRecord : public TagRecord {
UnionRecord() = default;
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/TypeRecordHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ inline bool isAggregate(CVType CVT) {
case LF_STRUCTURE:
case LF_CLASS:
case LF_INTERFACE:
case LF_STRUCTURE2:
case LF_CLASS2:
case LF_INTERFACE2:
case LF_UNION:
return true;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class LVTypeVisitor final : public TypeVisitorCallbacks {

Error visitKnownRecord(CVType &Record, BuildInfoRecord &Args) override;
Error visitKnownRecord(CVType &Record, ClassRecord &Class) override;
Error visitKnownRecord(CVType &Record, Class2Record &Class) override;
Error visitKnownRecord(CVType &Record, EnumRecord &Enum) override;
Error visitKnownRecord(CVType &Record, FuncIdRecord &Func) override;
Error visitKnownRecord(CVType &Record, ProcedureRecord &Proc) override;
Expand Down Expand Up @@ -378,6 +379,8 @@ class LVLogicalVisitor final {
LVElement *Element);
Error visitKnownRecord(CVType &Record, ClassRecord &Class, TypeIndex TI,
LVElement *Element);
Error visitKnownRecord(CVType &Record, Class2Record &Class, TypeIndex TI,
LVElement *Element);
Error visitKnownRecord(CVType &Record, EnumRecord &Enum, TypeIndex TI,
LVElement *Element);
Error visitKnownRecord(CVType &Record, FieldListRecord &FieldList,
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class NativeTypeUDT : public NativeRawSymbol {
NativeTypeUDT(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI,
codeview::ClassRecord Class);

NativeTypeUDT(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI,
codeview::Class2Record Class);

NativeTypeUDT(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI,
codeview::UnionRecord Union);

Expand Down Expand Up @@ -64,9 +67,11 @@ class NativeTypeUDT : public NativeRawSymbol {
codeview::TypeIndex Index;

std::optional<codeview::ClassRecord> Class;
std::optional<codeview::Class2Record> Class2;
std::optional<codeview::UnionRecord> Union;
NativeTypeUDT *UnmodifiedType = nullptr;
codeview::TagRecord *Tag = nullptr;
codeview::Tag2Record *Tag2 = nullptr;
std::optional<codeview::ModifierRecord> Modifiers;
};

Expand Down
20 changes: 19 additions & 1 deletion llvm/include/llvm/DebugInfo/PDB/Native/TpiHashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ struct TagRecordHash {
: FullRecordHash(Full), ForwardDeclHash(Forward), Class(std::move(CR)) {
State = 0;
}

explicit TagRecordHash(codeview::Class2Record CR, uint32_t Full,
uint32_t Forward)
: FullRecordHash(Full), ForwardDeclHash(Forward), Class2(std::move(CR)) {
State = 3;
}
explicit TagRecordHash(codeview::EnumRecord ER, uint32_t Full,
uint32_t Forward)
: FullRecordHash(Full), ForwardDeclHash(Forward), Enum(std::move(ER)) {
Expand All @@ -39,6 +43,11 @@ struct TagRecordHash {
uint32_t FullRecordHash;
uint32_t ForwardDeclHash;

bool isTag2Record() const
{
return State == 3 ? true : false;
}

codeview::TagRecord &getRecord() {
switch (State) {
case 0:
Expand All @@ -51,9 +60,18 @@ struct TagRecordHash {
llvm_unreachable("unreachable!");
}

codeview::Tag2Record &getTag2Record() {
switch (State) {
case 3:
return Class2;
}
llvm_unreachable("unreachable!");
}

private:
union {
codeview::ClassRecord Class;
codeview::Class2Record Class2;
codeview::EnumRecord Enum;
codeview::UnionRecord Union;
};
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/DebugInfo/CodeView/EnumTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,21 @@ static const EnumEntry<uint16_t> ClassOptionNames[] = {
CV_ENUM_CLASS_ENT(ClassOptions, Intrinsic),
};

static const EnumEntry<uint32_t> ClassOption2Names[] = {
CV_ENUM_CLASS_ENT(ClassOptions2, Packed),
CV_ENUM_CLASS_ENT(ClassOptions2, HasConstructorOrDestructor),
CV_ENUM_CLASS_ENT(ClassOptions2, HasOverloadedOperator),
CV_ENUM_CLASS_ENT(ClassOptions2, Nested),
CV_ENUM_CLASS_ENT(ClassOptions2, ContainsNestedClass),
CV_ENUM_CLASS_ENT(ClassOptions2, HasOverloadedAssignmentOperator),
CV_ENUM_CLASS_ENT(ClassOptions2, HasConversionOperator),
CV_ENUM_CLASS_ENT(ClassOptions2, ForwardReference),
CV_ENUM_CLASS_ENT(ClassOptions2, Scoped),
CV_ENUM_CLASS_ENT(ClassOptions2, HasUniqueName),
CV_ENUM_CLASS_ENT(ClassOptions2, Sealed),
CV_ENUM_CLASS_ENT(ClassOptions2, Intrinsic),
};

static const EnumEntry<uint8_t> MemberAccessNames[] = {
CV_ENUM_CLASS_ENT(MemberAccess, None),
CV_ENUM_CLASS_ENT(MemberAccess, Private),
Expand Down Expand Up @@ -533,6 +548,10 @@ ArrayRef<EnumEntry<uint16_t>> getClassOptionNames() {
return ArrayRef(ClassOptionNames);
}

ArrayRef<EnumEntry<uint32_t>> getClassOption2Names() {
return ArrayRef(ClassOption2Names);
}

ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames() {
return ArrayRef(MemberAccessNames);
}
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/DebugInfo/CodeView/RecordName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, Class2Record &Class) {
Name = Class.getName();
return Error::success();
}

Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
Name = Union.getName();
return Error::success();
Expand Down
28 changes: 28 additions & 0 deletions llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ static const EnumEntry<uint16_t> ClassOptionNames[] = {
ENUM_ENTRY(ClassOptions, Intrinsic),
};

static const EnumEntry<uint32_t> ClassOption2Names[] = {
ENUM_ENTRY(ClassOptions2, Packed),
ENUM_ENTRY(ClassOptions2, HasConstructorOrDestructor),
ENUM_ENTRY(ClassOptions2, HasOverloadedOperator),
ENUM_ENTRY(ClassOptions2, Nested),
ENUM_ENTRY(ClassOptions2, ContainsNestedClass),
ENUM_ENTRY(ClassOptions2, HasOverloadedAssignmentOperator),
ENUM_ENTRY(ClassOptions2, HasConversionOperator),
ENUM_ENTRY(ClassOptions2, ForwardReference),
ENUM_ENTRY(ClassOptions2, Scoped),
ENUM_ENTRY(ClassOptions2, HasUniqueName),
ENUM_ENTRY(ClassOptions2, Sealed),
ENUM_ENTRY(ClassOptions2, Intrinsic),
};

static const EnumEntry<uint8_t> MemberAccessNames[] = {
ENUM_ENTRY(MemberAccess, None), ENUM_ENTRY(MemberAccess, Private),
ENUM_ENTRY(MemberAccess, Protected), ENUM_ENTRY(MemberAccess, Public),
Expand Down Expand Up @@ -257,6 +272,19 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
return Error::success();
}

Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, Class2Record &Class) {
uint32_t Props = static_cast<uint32_t>(Class.getOptions());
W->printFlags("Properties", Props, ArrayRef(ClassOption2Names));
printTypeIndex("FieldList", Class.getFieldList());
printTypeIndex("DerivedFrom", Class.getDerivationList());
printTypeIndex("VShape", Class.getVTableShape());
W->printNumber("SizeOf", Class.getSize());
W->printString("Name", Class.getName());
if (Props & uint32_t(ClassOptions2::HasUniqueName))
W->printString("LinkageName", Class.getUniqueName());
return Error::success();
}

Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
uint16_t Props = static_cast<uint16_t>(Union.getOptions());
W->printNumber("MemberCount", Union.getMemberCount());
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ static void discoverTypeIndices(ArrayRef<uint8_t> Content, TypeLeafKind Kind,
case TypeLeafKind::LF_INTERFACE:
Refs.push_back({TiRefKind::TypeRef, 4, 3});
break;
case TypeLeafKind::LF_CLASS2:
case TypeLeafKind::LF_STRUCTURE2:
case TypeLeafKind::LF_INTERFACE2:
Refs.push_back({TiRefKind::TypeRef, 4, 3});
break;
case TypeLeafKind::LF_UNION:
Refs.push_back({TiRefKind::TypeRef, 4, 1});
break;
Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ template <typename RecordT> static ClassOptions getUdtOptions(CVType CVT) {
consumeError(std::move(EC));
return ClassOptions::None;
}
return Record.getOptions();
return (ClassOptions)Record.getOptions();
}

bool llvm::codeview::isUdtForwardRef(CVType CVT) {
Expand All @@ -32,6 +32,11 @@ bool llvm::codeview::isUdtForwardRef(CVType CVT) {
case LF_INTERFACE:
UdtOptions = getUdtOptions<ClassRecord>(std::move(CVT));
break;
case LF_STRUCTURE2:
case LF_CLASS2:
case LF_INTERFACE2:
UdtOptions = getUdtOptions<Class2Record>(std::move(CVT));
break;
case LF_ENUM:
UdtOptions = getUdtOptions<EnumRecord>(std::move(CVT));
break;
Expand Down Expand Up @@ -174,6 +179,10 @@ uint64_t llvm::codeview::getSizeInBytesForTypeRecord(CVType CVT) {
case LF_CLASS:
case LF_INTERFACE:
return getUdtSize<ClassRecord>(std::move(CVT));
case LF_STRUCTURE2:
case LF_CLASS2:
case LF_INTERFACE2:
return getUdtSize<Class2Record>(std::move(CVT));
case LF_UNION:
return getUdtSize<UnionRecord>(std::move(CVT));
default:
Expand Down
20 changes: 20 additions & 0 deletions llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,26 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) {
return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, Class2Record &Record) {
assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE2) ||
(CVR.kind() == TypeLeafKind::LF_CLASS2));

std::string PropertiesNames =
getFlagNames(IO, static_cast<uint16_t>(Record.Options),
ArrayRef(getClassOptionNames()));
//error(IO.mapInteger(Record.MemberCount, "MemberCount"));
error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
error(IO.mapInteger(Record.FieldList, "FieldList"));
error(IO.mapInteger(Record.DerivationList, "DerivedFrom"));
error(IO.mapInteger(Record.VTableShape, "VShape"));
error(IO.mapEncodedInteger(Record.Count, "Count"));
error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
Record.hasUniqueName()));

return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
std::string PropertiesNames =
getFlagNames(IO, static_cast<uint16_t>(Record.Options),
Expand Down
Loading
Loading