diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index 3316e71916e..4e8c8feb7a1 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -6,6 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// +// Defines constants and basic types describing CodeView debug information. +// +//===----------------------------------------------------------------------===// #ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H #define LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H @@ -22,28 +26,28 @@ namespace codeview { /// 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" +#include "CodeViewTypes.def" }; /// 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" +#include "CodeViewTypes.def" }; /// Distinguishes individual records in the Symbols subsection of a .debug$S /// section. Equivalent to SYM_ENUM_e in cvinfo.h. enum class SymbolRecordKind : uint16_t { #define SYMBOL_RECORD(lf_ename, value, name) name = value, -#include "CVSymbolTypes.def" +#include "CodeViewSymbols.def" }; /// Duplicate copy of the above enum, but using the official CV names. Useful /// for reference purposes and when dealing with unknown record types. enum SymbolKind : uint16_t { #define CV_SYMBOL(name, val) name = val, -#include "CVSymbolTypes.def" +#include "CodeViewSymbols.def" }; #define CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(Class) \ @@ -280,7 +284,7 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions) /// Equivalent to CV_LABEL_TYPE_e. enum class LabelType : uint16_t { Near = 0x0, - Far = 0x4, + Far = 0x4, }; /// Equivalent to CV_modifier_t. diff --git a/include/llvm/DebugInfo/CodeView/CVSymbolTypes.def b/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def similarity index 100% rename from include/llvm/DebugInfo/CodeView/CVSymbolTypes.def rename to include/llvm/DebugInfo/CodeView/CodeViewSymbols.def diff --git a/include/llvm/DebugInfo/CodeView/TypeRecords.def b/include/llvm/DebugInfo/CodeView/CodeViewTypes.def similarity index 100% rename from include/llvm/DebugInfo/CodeView/TypeRecords.def rename to include/llvm/DebugInfo/CodeView/CodeViewTypes.def diff --git a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h index c1a5152930f..a2592e56279 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h @@ -54,7 +54,7 @@ public: return visitKnownRecordImpl(CVR, Record); \ } #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" private: template Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) { diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h b/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h index 0a1837a0d93..5d072a3b272 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecordMapping.h @@ -29,7 +29,7 @@ public: #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ Error visitKnownRecord(CVSymbol &CVR, Name &Record) override; #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" private: Optional Kind; diff --git a/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/include/llvm/DebugInfo/CodeView/SymbolSerializer.h index f2e99bd8332..ec16a23495f 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolSerializer.h +++ b/include/llvm/DebugInfo/CodeView/SymbolSerializer.h @@ -55,7 +55,7 @@ public: return visitKnownRecordImpl(CVR, Record); \ } #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" private: template diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h index 96a93bf7e57..5f4205bd6e0 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h +++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h @@ -59,7 +59,7 @@ public: return Error::success(); \ } #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" private: std::vector Pipeline; diff --git a/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h b/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h index aaa9d2e85e1..2ef7eabdaa9 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h +++ b/include/llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h @@ -39,7 +39,7 @@ public: return Error::success(); \ } #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h index c064e19a7e9..77dbc91a7d3 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h +++ b/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h @@ -39,7 +39,7 @@ public: Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override; #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" private: StringRef getTypeName(TypeIndex Index) const; diff --git a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h index a9c5cf42fc5..965cdfd85f4 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -41,6 +41,7 @@ public: TypeDeserializer() = default; template static Error deserializeAs(CVType &CVT, T &Record) { + Record.Kind = static_cast(CVT.kind()); MappingInfo I(CVT.content()); if (auto EC = I.Mapping.visitTypeBegin(CVT)) return EC; @@ -75,7 +76,7 @@ public: #define MEMBER_RECORD(EnumName, EnumVal, Name) #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" private: template @@ -127,7 +128,7 @@ public: } #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" private: template diff --git a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h index 65b3a33e654..afb8b363636 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h +++ b/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h @@ -58,7 +58,7 @@ public: Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override; #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" private: void printMemberAttributes(MemberAttributes Attrs); diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 92745ebfcde..3a64a437aa4 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -123,13 +123,13 @@ protected: public: TypeRecordKind getKind() const { return Kind; } -private: TypeRecordKind Kind; }; // LF_MODIFIER class ModifierRecord : public TypeRecord { public: + ModifierRecord() = default; explicit ModifierRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers) : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType), @@ -145,6 +145,7 @@ public: // LF_PROCEDURE class ProcedureRecord : public TypeRecord { public: + ProcedureRecord() = default; explicit ProcedureRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv, FunctionOptions Options, uint16_t ParameterCount, @@ -169,6 +170,7 @@ public: // LF_MFUNCTION class MemberFunctionRecord : public TypeRecord { public: + MemberFunctionRecord() = default; explicit MemberFunctionRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType, @@ -203,6 +205,7 @@ public: // LF_LABEL class LabelRecord : public TypeRecord { public: + LabelRecord() = default; explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {} @@ -213,6 +216,7 @@ public: // LF_MFUNC_ID class MemberFuncIdRecord : public TypeRecord { public: + MemberFuncIdRecord() = default; explicit MemberFuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} MemberFuncIdRecord(TypeIndex ClassType, TypeIndex FunctionType, StringRef Name) @@ -230,6 +234,7 @@ public: // LF_ARGLIST class ArgListRecord : public TypeRecord { public: + ArgListRecord() = default; explicit ArgListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} ArgListRecord(TypeRecordKind Kind, ArrayRef Indices) @@ -243,6 +248,7 @@ public: // LF_SUBSTR_LIST class StringListRecord : public TypeRecord { public: + StringListRecord() = default; explicit StringListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} StringListRecord(TypeRecordKind Kind, ArrayRef Indices) @@ -267,6 +273,7 @@ public: static const uint32_t PointerSizeShift = 13; static const uint32_t PointerSizeMask = 0xFF; + PointerRecord() = default; explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} PointerRecord(TypeIndex ReferentType, uint32_t Attrs) @@ -341,6 +348,7 @@ private: // LF_NESTTYPE class NestedTypeRecord : public TypeRecord { public: + NestedTypeRecord() = default; explicit NestedTypeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} NestedTypeRecord(TypeIndex Type, StringRef Name) : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {} @@ -355,6 +363,7 @@ public: // LF_FIELDLIST class FieldListRecord : public TypeRecord { public: + FieldListRecord() = default; explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} explicit FieldListRecord(ArrayRef Data) : TypeRecord(TypeRecordKind::FieldList), Data(Data) {} @@ -365,6 +374,7 @@ public: // LF_ARRAY class ArrayRecord : public TypeRecord { public: + ArrayRecord() = default; explicit ArrayRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size, StringRef Name) @@ -384,6 +394,7 @@ public: class TagRecord : public TypeRecord { protected: + TagRecord() = default; explicit TagRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList, StringRef Name, StringRef UniqueName) @@ -416,6 +427,7 @@ public: // LF_CLASS, LF_STRUCTURE, LF_INTERFACE class ClassRecord : public TagRecord { public: + ClassRecord() = default; explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {} ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList, TypeIndex DerivationList, @@ -447,6 +459,7 @@ public: // LF_UNION struct UnionRecord : public TagRecord { + UnionRecord() = default; explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {} UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList, uint64_t Size, StringRef Name, StringRef UniqueName) @@ -468,6 +481,7 @@ struct UnionRecord : public TagRecord { // LF_ENUM class EnumRecord : public TagRecord { public: + EnumRecord() = default; explicit EnumRecord(TypeRecordKind Kind) : TagRecord(Kind) {} EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList, StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType) @@ -482,6 +496,7 @@ public: // LF_BITFIELD class BitFieldRecord : public TypeRecord { public: + BitFieldRecord() = default; explicit BitFieldRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset) : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize), @@ -498,6 +513,7 @@ public: // LF_VTSHAPE class VFTableShapeRecord : public TypeRecord { public: + VFTableShapeRecord() = default; explicit VFTableShapeRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} explicit VFTableShapeRecord(ArrayRef Slots) : TypeRecord(TypeRecordKind::VFTableShape), SlotsRef(Slots) {} @@ -518,6 +534,7 @@ public: // LF_TYPESERVER2 class TypeServer2Record : public TypeRecord { public: + TypeServer2Record() = default; explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {} TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name) : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age), @@ -537,6 +554,7 @@ public: // LF_STRING_ID class StringIdRecord : public TypeRecord { public: + StringIdRecord() = default; explicit StringIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} StringIdRecord(TypeIndex Id, StringRef String) : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {} @@ -551,6 +569,7 @@ public: // LF_FUNC_ID class FuncIdRecord : public TypeRecord { public: + FuncIdRecord() = default; explicit FuncIdRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name) : TypeRecord(TypeRecordKind::FuncId), ParentScope(ParentScope), @@ -570,6 +589,7 @@ public: // LF_UDT_SRC_LINE class UdtSourceLineRecord : public TypeRecord { public: + UdtSourceLineRecord() = default; explicit UdtSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber) : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT), @@ -587,6 +607,7 @@ public: // LF_UDT_MOD_SRC_LINE class UdtModSourceLineRecord : public TypeRecord { public: + UdtModSourceLineRecord() = default; explicit UdtModSourceLineRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} UdtModSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber, uint16_t Module) @@ -607,6 +628,7 @@ public: // LF_BUILDINFO class BuildInfoRecord : public TypeRecord { public: + BuildInfoRecord() = default; explicit BuildInfoRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} BuildInfoRecord(ArrayRef ArgIndices) : TypeRecord(TypeRecordKind::BuildInfo), @@ -619,6 +641,7 @@ public: // LF_VFTABLE class VFTableRecord : public TypeRecord { public: + VFTableRecord() = default; explicit VFTableRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable, uint32_t VFPtrOffset, StringRef Name, @@ -646,7 +669,7 @@ public: // LF_ONEMETHOD class OneMethodRecord : public TypeRecord { public: - OneMethodRecord() : TypeRecord(TypeRecordKind::OneMethod) {} + OneMethodRecord() = default; explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset, StringRef Name) @@ -678,6 +701,7 @@ public: // LF_METHODLIST class MethodOverloadListRecord : public TypeRecord { public: + MethodOverloadListRecord() = default; explicit MethodOverloadListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} MethodOverloadListRecord(ArrayRef Methods) : TypeRecord(TypeRecordKind::MethodOverloadList), Methods(Methods) {} @@ -689,6 +713,7 @@ public: /// For method overload sets. LF_METHOD class OverloadedMethodRecord : public TypeRecord { public: + OverloadedMethodRecord() = default; explicit OverloadedMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList, StringRef Name) @@ -706,6 +731,7 @@ public: // LF_MEMBER class DataMemberRecord : public TypeRecord { public: + DataMemberRecord() = default; explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset, StringRef Name) @@ -730,6 +756,7 @@ public: // LF_STMEMBER class StaticDataMemberRecord : public TypeRecord { public: + StaticDataMemberRecord() = default; explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name) : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type), @@ -750,6 +777,7 @@ public: // LF_ENUMERATE class EnumeratorRecord : public TypeRecord { public: + EnumeratorRecord() = default; explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name) : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs), @@ -770,6 +798,7 @@ public: // LF_VFUNCTAB class VFPtrRecord : public TypeRecord { public: + VFPtrRecord() = default; explicit VFPtrRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} VFPtrRecord(TypeIndex Type) : TypeRecord(TypeRecordKind::VFPtr), Type(Type) {} @@ -782,6 +811,7 @@ public: // LF_BCLASS, LF_BINTERFACE class BaseClassRecord : public TypeRecord { public: + BaseClassRecord() = default; explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset) : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type), @@ -802,6 +832,7 @@ public: // LF_VBCLASS, LF_IVBCLASS class VirtualBaseClassRecord : public TypeRecord { public: + VirtualBaseClassRecord() = default; explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs, TypeIndex BaseType, TypeIndex VBPtrType, @@ -831,6 +862,7 @@ public: /// together. The first will end in an LF_INDEX record that points to the next. class ListContinuationRecord : public TypeRecord { public: + ListContinuationRecord() = default; explicit ListContinuationRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} ListContinuationRecord(TypeIndex ContinuationIndex) : TypeRecord(TypeRecordKind::ListContinuation), diff --git a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h index 924ca0470fa..6156223b256 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h @@ -37,7 +37,7 @@ public: Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override; #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" private: Optional TypeKind; diff --git a/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/include/llvm/DebugInfo/CodeView/TypeSerializer.h index 435c43f7edc..1dee86a1da7 100644 --- a/include/llvm/DebugInfo/CodeView/TypeSerializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeSerializer.h @@ -106,7 +106,7 @@ public: return visitKnownMemberImpl(CVR, Record); \ } #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" private: template diff --git a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h index 7bdc9ecb20c..907ed1010e5 100644 --- a/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h +++ b/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h @@ -13,8 +13,8 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/CodeView/TypeSerializer.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/CodeView/TypeSerializer.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" #include diff --git a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h index ed48df33249..126fb8abb0d 100644 --- a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h +++ b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h @@ -94,7 +94,7 @@ public: } #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" private: template Error visitKnownRecordImpl(CVType &CVR, T &Record) { diff --git a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h index 0ea754deb42..d7a473306bc 100644 --- a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h +++ b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h @@ -58,7 +58,11 @@ public: #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +#undef TYPE_RECORD +#undef TYPE_RECORD_ALIAS +#undef MEMBER_RECORD +#undef MEMBER_RECORD_ALIAS }; } // end namespace codeview diff --git a/include/llvm/DebugInfo/PDB/Native/RawConstants.h b/include/llvm/DebugInfo/PDB/Native/RawConstants.h index f5d4df8feb2..e1bd86b2870 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawConstants.h +++ b/include/llvm/DebugInfo/PDB/Native/RawConstants.h @@ -12,7 +12,6 @@ #include "llvm/ADT/BitmaskEnum.h" #include "llvm/DebugInfo/CodeView/CodeView.h" - #include namespace llvm { diff --git a/include/llvm/DebugInfo/PDB/Native/TpiHashing.h b/include/llvm/DebugInfo/PDB/Native/TpiHashing.h index dd2698c354a..156abb59a6b 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiHashing.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiHashing.h @@ -38,7 +38,7 @@ public: #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD(EnumName, EnumVal, Name) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" private: template diff --git a/include/llvm/ObjectYAML/CodeViewYAML.h b/include/llvm/ObjectYAML/CodeViewYAML.h new file mode 100644 index 00000000000..d1eec305c58 --- /dev/null +++ b/include/llvm/ObjectYAML/CodeViewYAML.h @@ -0,0 +1,141 @@ +//===- CodeViewYAML.cpp - CodeView YAMLIO implementation ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECTYAML_CODEVIEWYAML_H +#define LLVM_OBJECTYAML_CODEVIEWYAML_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/CodeView/TypeSerializer.h" +#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/ObjectYAML/YAML.h" + +namespace llvm { +namespace CodeViewYAML { + +namespace detail { +struct MemberRecordBase; +struct LeafRecordBase; +} + +struct SourceLineEntry { + uint32_t Offset; + uint32_t LineStart; + uint32_t EndDelta; + bool IsStatement; +}; + +struct SourceColumnEntry { + uint16_t StartColumn; + uint16_t EndColumn; +}; + +struct SourceLineBlock { + StringRef FileName; + std::vector Lines; + std::vector Columns; +}; + +struct HexFormattedString { + std::vector Bytes; +}; + +struct SourceFileChecksumEntry { + StringRef FileName; + codeview::FileChecksumKind Kind; + HexFormattedString ChecksumBytes; +}; + +struct SourceLineInfo { + uint32_t RelocOffset; + uint32_t RelocSegment; + codeview::LineFlags Flags; + uint32_t CodeSize; + + std::vector Blocks; +}; + +struct InlineeSite { + uint32_t Inlinee; + StringRef FileName; + uint32_t SourceLineNum; + std::vector ExtraFiles; +}; + +struct InlineeInfo { + bool HasExtraFiles; + std::vector Sites; +}; + +struct SourceFileInfo { + std::vector FileChecksums; + std::vector LineFragments; + std::vector Inlinees; +}; + +struct MemberRecord { + std::shared_ptr Member; +}; + +struct LeafRecord { + std::shared_ptr Leaf; + + codeview::CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const; + static Expected fromCodeViewRecord(codeview::CVType Type); +}; + +} // namespace CodeViewYAML +} // namespace llvm + +LLVM_YAML_DECLARE_SCALAR_TRAITS(codeview::TypeIndex, false) +LLVM_YAML_DECLARE_SCALAR_TRAITS(CodeViewYAML::HexFormattedString, false) +LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false) + +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceColumnEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceFileChecksumEntry) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineInfo) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineBlock) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceFileInfo) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::InlineeInfo) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::InlineeSite) + +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::LeafRecord) +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::MemberRecord) + +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::TypeLeafKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::PointerToMemberRepresentation) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::VFTableSlotKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::CallingConvention) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::PointerKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::PointerMode) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::HfaKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::MemberAccess) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::MethodKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::WindowsRTClassKind) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::LabelType) +LLVM_YAML_DECLARE_ENUM_TRAITS(codeview::FileChecksumKind) + +LLVM_YAML_DECLARE_BITSET_TRAITS(codeview::PointerOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(codeview::LineFlags) +LLVM_YAML_DECLARE_BITSET_TRAITS(codeview::ModifierOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(codeview::FunctionOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(codeview::ClassOptions) +LLVM_YAML_DECLARE_BITSET_TRAITS(codeview::MethodOptions) + +LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::LeafRecord) +LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::MemberRecord) + +#endif diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index ffea679fab8..8949d69ce72 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -1606,6 +1606,44 @@ template struct StdMapStringCustomMappingTraitsImpl { } \ } +#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type) \ + namespace llvm { \ + namespace yaml { \ + template <> struct MappingTraits { \ + static void mapping(IO &IO, Type &Obj); \ + }; \ + } \ + } + +#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type) \ + namespace llvm { \ + namespace yaml { \ + template <> struct ScalarEnumerationTraits { \ + static void enumeration(IO &io, Type &Value); \ + }; \ + } \ + } + +#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type) \ + namespace llvm { \ + namespace yaml { \ + template <> struct ScalarBitSetTraits { \ + static void bitset(IO &IO, Type &Options); \ + }; \ + } \ + } + +#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote) \ + namespace llvm { \ + namespace yaml { \ + template <> struct ScalarTraits { \ + static void output(const Type &Value, void *ctx, llvm::raw_ostream &Out); \ + static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \ + static bool mustQuote(StringRef) { return MustQuote; } \ + }; \ + } \ + } + /// Utility for declaring that a std::vector of a particular type /// should be considered a YAML document list. #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \ diff --git a/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp index 4c78caf0347..d058f486497 100644 --- a/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp +++ b/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp @@ -46,7 +46,7 @@ Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) { } #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \ SYMBOL_RECORD(EnumVal, EnumVal, AliasName) -#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" } if (auto EC = Callbacks.visitSymbolEnd(Record)) diff --git a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp index 705b548141b..f0debd9e970 100644 --- a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp +++ b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp @@ -71,7 +71,7 @@ static Error visitMemberRecord(CVMemberRecord &Record, MEMBER_RECORD(EnumVal, EnumVal, AliasName) #define TYPE_RECORD(EnumName, EnumVal, Name) #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" } if (auto EC = Callbacks.visitMemberEnd(Record)) @@ -155,7 +155,7 @@ Error CVTypeVisitor::finishVisitation(CVType &Record) { TYPE_RECORD(EnumVal, EnumVal, AliasName) #define MEMBER_RECORD(EnumName, EnumVal, Name) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" } if (auto EC = Callbacks.visitTypeEnd(Record)) diff --git a/lib/DebugInfo/CodeView/EnumTables.cpp b/lib/DebugInfo/CodeView/EnumTables.cpp index 0441110c85e..01d8ccf2d31 100644 --- a/lib/DebugInfo/CodeView/EnumTables.cpp +++ b/lib/DebugInfo/CodeView/EnumTables.cpp @@ -20,13 +20,13 @@ using namespace codeview; static const EnumEntry SymbolTypeNames[] = { #define CV_SYMBOL(enum, val) {#enum, enum}, -#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" #undef CV_SYMBOL }; static const EnumEntry TypeLeafNames[] = { #define CV_TYPE(name, val) {#name, name}, -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" #undef CV_TYPE }; diff --git a/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp index 2f5a7d256c6..3d49a7198d1 100644 --- a/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -41,7 +41,7 @@ public: #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ Error visitKnownRecord(CVSymbol &CVR, Name &Record) override; #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" Error visitSymbolBegin(CVSymbol &Record) override; Error visitSymbolEnd(CVSymbol &Record) override; diff --git a/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp index 84f52a05581..04b0384d819 100644 --- a/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp +++ b/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp @@ -26,7 +26,7 @@ using namespace llvm::codeview; static const EnumEntry LeafTypeNames[] = { #define CV_TYPE(enum, val) {#enum, enum}, -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" }; #define ENUM_ENTRY(enum_class, enum) \ @@ -155,7 +155,7 @@ static StringRef getLeafTypeName(TypeLeafKind LT) { #define TYPE_RECORD(ename, value, name) \ case ename: \ return #name; -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" default: break; } diff --git a/lib/MC/MCCodeView.cpp b/lib/MC/MCCodeView.cpp index a0a0ef31227..6c9a4f9f982 100644 --- a/lib/MC/MCCodeView.cpp +++ b/lib/MC/MCCodeView.cpp @@ -12,11 +12,11 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCCodeView.h" -#include "llvm/MC/MCAsmLayout.h" #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCValue.h" diff --git a/lib/ObjectYAML/CMakeLists.txt b/lib/ObjectYAML/CMakeLists.txt index 37f8fd7bce1..237a409d70b 100644 --- a/lib/ObjectYAML/CMakeLists.txt +++ b/lib/ObjectYAML/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMObjectYAML + CodeViewYAML.cpp COFFYAML.cpp DWARFEmitter.cpp DWARFVisitor.cpp diff --git a/lib/ObjectYAML/CodeViewYAML.cpp b/lib/ObjectYAML/CodeViewYAML.cpp new file mode 100644 index 00000000000..9e0ab6f9869 --- /dev/null +++ b/lib/ObjectYAML/CodeViewYAML.cpp @@ -0,0 +1,759 @@ +//===- CodeViewYAML.cpp - CodeView YAMLIO implementation ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CodeViewYAML.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/CodeViewError.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::CodeViewYAML; +using namespace llvm::CodeViewYAML::detail; +using namespace llvm::yaml; + +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceFileChecksumEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceColumnEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineBlock) +LLVM_YAML_IS_SEQUENCE_VECTOR(SourceLineInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeSite) +LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord) +LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) +LLVM_YAML_IS_SEQUENCE_VECTOR(uint32_t) +LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind) +LLVM_YAML_IS_SEQUENCE_VECTOR(TypeIndex) + +LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::codeview::OneMethodRecord) +LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::codeview::MemberPointerInfo) + +namespace llvm { +namespace CodeViewYAML { +namespace detail { + +struct LeafRecordBase { + TypeLeafKind Kind; + explicit LeafRecordBase(TypeLeafKind K) : Kind(K) {} + + virtual ~LeafRecordBase() {} + virtual void map(yaml::IO &io) = 0; + virtual CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const = 0; + virtual Error fromCodeViewRecord(CVType Type) = 0; +}; + +template struct LeafRecordImpl : public LeafRecordBase { + explicit LeafRecordImpl(TypeLeafKind K) + : LeafRecordBase(K), Record(static_cast(K)) {} + + void map(yaml::IO &io) override; + + Error fromCodeViewRecord(CVType Type) override { + return TypeDeserializer::deserializeAs(Type, Record); + } + + CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const override { + TypeTableBuilder Table(Allocator); + Table.writeKnownType(Record); + return CVType(Kind, Table.records().front()); + } + + mutable T Record; +}; + +template <> struct LeafRecordImpl : public LeafRecordBase { + explicit LeafRecordImpl(TypeLeafKind K) : LeafRecordBase(K) {} + + void map(yaml::IO &io) override; + CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const override; + Error fromCodeViewRecord(CVType Type) override; + + std::vector Members; +}; + +struct MemberRecordBase { + TypeLeafKind Kind; + explicit MemberRecordBase(TypeLeafKind K) : Kind(K) {} + + virtual ~MemberRecordBase() {} + virtual void map(yaml::IO &io) = 0; + virtual void writeTo(FieldListRecordBuilder &FLRB) = 0; +}; + +template struct MemberRecordImpl : public MemberRecordBase { + explicit MemberRecordImpl(TypeLeafKind K) + : MemberRecordBase(K), Record(static_cast(K)) {} + void map(yaml::IO &io) override; + + void writeTo(FieldListRecordBuilder &FLRB) override { + FLRB.writeMemberType(Record); + } + + mutable T Record; +}; +} +} +} + +void ScalarTraits::output(const TypeIndex &S, void *, + llvm::raw_ostream &OS) { + OS << S.getIndex(); +} + +StringRef ScalarTraits::input(StringRef Scalar, void *Ctx, + TypeIndex &S) { + uint32_t I; + StringRef Result = ScalarTraits::input(Scalar, Ctx, I); + S.setIndex(I); + return Result; +} + +void ScalarTraits::output(const APSInt &S, void *, + llvm::raw_ostream &OS) { + S.print(OS, true); +} + +StringRef ScalarTraits::input(StringRef Scalar, void *Ctx, APSInt &S) { + S = APSInt(Scalar); + return ""; +} + +void ScalarEnumerationTraits::enumeration(IO &io, + TypeLeafKind &Value) { +#define CV_TYPE(name, val) io.enumCase(Value, #name, name); +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +#undef CV_TYPE +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, PointerToMemberRepresentation &Value) { + IO.enumCase(Value, "Unknown", PointerToMemberRepresentation::Unknown); + IO.enumCase(Value, "SingleInheritanceData", + PointerToMemberRepresentation::SingleInheritanceData); + IO.enumCase(Value, "MultipleInheritanceData", + PointerToMemberRepresentation::MultipleInheritanceData); + IO.enumCase(Value, "VirtualInheritanceData", + PointerToMemberRepresentation::VirtualInheritanceData); + IO.enumCase(Value, "GeneralData", PointerToMemberRepresentation::GeneralData); + IO.enumCase(Value, "SingleInheritanceFunction", + PointerToMemberRepresentation::SingleInheritanceFunction); + IO.enumCase(Value, "MultipleInheritanceFunction", + PointerToMemberRepresentation::MultipleInheritanceFunction); + IO.enumCase(Value, "VirtualInheritanceFunction", + PointerToMemberRepresentation::VirtualInheritanceFunction); + IO.enumCase(Value, "GeneralFunction", + PointerToMemberRepresentation::GeneralFunction); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, VFTableSlotKind &Kind) { + IO.enumCase(Kind, "Near16", VFTableSlotKind::Near16); + IO.enumCase(Kind, "Far16", VFTableSlotKind::Far16); + IO.enumCase(Kind, "This", VFTableSlotKind::This); + IO.enumCase(Kind, "Outer", VFTableSlotKind::Outer); + IO.enumCase(Kind, "Meta", VFTableSlotKind::Meta); + IO.enumCase(Kind, "Near", VFTableSlotKind::Near); + IO.enumCase(Kind, "Far", VFTableSlotKind::Far); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, CallingConvention &Value) { + IO.enumCase(Value, "NearC", CallingConvention::NearC); + IO.enumCase(Value, "FarC", CallingConvention::FarC); + IO.enumCase(Value, "NearPascal", CallingConvention::NearPascal); + IO.enumCase(Value, "FarPascal", CallingConvention::FarPascal); + IO.enumCase(Value, "NearFast", CallingConvention::NearFast); + IO.enumCase(Value, "FarFast", CallingConvention::FarFast); + IO.enumCase(Value, "NearStdCall", CallingConvention::NearStdCall); + IO.enumCase(Value, "FarStdCall", CallingConvention::FarStdCall); + IO.enumCase(Value, "NearSysCall", CallingConvention::NearSysCall); + IO.enumCase(Value, "FarSysCall", CallingConvention::FarSysCall); + IO.enumCase(Value, "ThisCall", CallingConvention::ThisCall); + IO.enumCase(Value, "MipsCall", CallingConvention::MipsCall); + IO.enumCase(Value, "Generic", CallingConvention::Generic); + IO.enumCase(Value, "AlphaCall", CallingConvention::AlphaCall); + IO.enumCase(Value, "PpcCall", CallingConvention::PpcCall); + IO.enumCase(Value, "SHCall", CallingConvention::SHCall); + IO.enumCase(Value, "ArmCall", CallingConvention::ArmCall); + IO.enumCase(Value, "AM33Call", CallingConvention::AM33Call); + IO.enumCase(Value, "TriCall", CallingConvention::TriCall); + IO.enumCase(Value, "SH5Call", CallingConvention::SH5Call); + IO.enumCase(Value, "M32RCall", CallingConvention::M32RCall); + IO.enumCase(Value, "ClrCall", CallingConvention::ClrCall); + IO.enumCase(Value, "Inline", CallingConvention::Inline); + IO.enumCase(Value, "NearVector", CallingConvention::NearVector); +} + +void ScalarEnumerationTraits::enumeration(IO &IO, + PointerKind &Kind) { + IO.enumCase(Kind, "Near16", PointerKind::Near16); + IO.enumCase(Kind, "Far16", PointerKind::Far16); + IO.enumCase(Kind, "Huge16", PointerKind::Huge16); + IO.enumCase(Kind, "BasedOnSegment", PointerKind::BasedOnSegment); + IO.enumCase(Kind, "BasedOnValue", PointerKind::BasedOnValue); + IO.enumCase(Kind, "BasedOnSegmentValue", PointerKind::BasedOnSegmentValue); + IO.enumCase(Kind, "BasedOnAddress", PointerKind::BasedOnAddress); + IO.enumCase(Kind, "BasedOnSegmentAddress", + PointerKind::BasedOnSegmentAddress); + IO.enumCase(Kind, "BasedOnType", PointerKind::BasedOnType); + IO.enumCase(Kind, "BasedOnSelf", PointerKind::BasedOnSelf); + IO.enumCase(Kind, "Near32", PointerKind::Near32); + IO.enumCase(Kind, "Far32", PointerKind::Far32); + IO.enumCase(Kind, "Near64", PointerKind::Near64); +} + +void ScalarEnumerationTraits::enumeration(IO &IO, + PointerMode &Mode) { + IO.enumCase(Mode, "Pointer", PointerMode::Pointer); + IO.enumCase(Mode, "LValueReference", PointerMode::LValueReference); + IO.enumCase(Mode, "PointerToDataMember", PointerMode::PointerToDataMember); + IO.enumCase(Mode, "PointerToMemberFunction", + PointerMode::PointerToMemberFunction); + IO.enumCase(Mode, "RValueReference", PointerMode::RValueReference); +} + +void ScalarEnumerationTraits::enumeration(IO &IO, HfaKind &Value) { + IO.enumCase(Value, "None", HfaKind::None); + IO.enumCase(Value, "Float", HfaKind::Float); + IO.enumCase(Value, "Double", HfaKind::Double); + IO.enumCase(Value, "Other", HfaKind::Other); +} + +void ScalarEnumerationTraits::enumeration(IO &IO, + MemberAccess &Access) { + IO.enumCase(Access, "None", MemberAccess::None); + IO.enumCase(Access, "Private", MemberAccess::Private); + IO.enumCase(Access, "Protected", MemberAccess::Protected); + IO.enumCase(Access, "Public", MemberAccess::Public); +} + +void ScalarEnumerationTraits::enumeration(IO &IO, + MethodKind &Kind) { + IO.enumCase(Kind, "Vanilla", MethodKind::Vanilla); + IO.enumCase(Kind, "Virtual", MethodKind::Virtual); + IO.enumCase(Kind, "Static", MethodKind::Static); + IO.enumCase(Kind, "Friend", MethodKind::Friend); + IO.enumCase(Kind, "IntroducingVirtual", MethodKind::IntroducingVirtual); + IO.enumCase(Kind, "PureVirtual", MethodKind::PureVirtual); + IO.enumCase(Kind, "PureIntroducingVirtual", + MethodKind::PureIntroducingVirtual); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, WindowsRTClassKind &Value) { + IO.enumCase(Value, "None", WindowsRTClassKind::None); + IO.enumCase(Value, "Ref", WindowsRTClassKind::RefClass); + IO.enumCase(Value, "Value", WindowsRTClassKind::ValueClass); + IO.enumCase(Value, "Interface", WindowsRTClassKind::Interface); +} + +void ScalarEnumerationTraits::enumeration(IO &IO, LabelType &Value) { + IO.enumCase(Value, "Near", LabelType::Near); + IO.enumCase(Value, "Far", LabelType::Far); +} + +void ScalarBitSetTraits::bitset(IO &IO, + PointerOptions &Options) { + IO.bitSetCase(Options, "None", PointerOptions::None); + IO.bitSetCase(Options, "Flat32", PointerOptions::Flat32); + IO.bitSetCase(Options, "Volatile", PointerOptions::Volatile); + IO.bitSetCase(Options, "Const", PointerOptions::Const); + IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned); + IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict); + IO.bitSetCase(Options, "WinRTSmartPointer", + PointerOptions::WinRTSmartPointer); +} + +void ScalarBitSetTraits::bitset(IO &IO, + ModifierOptions &Options) { + IO.bitSetCase(Options, "None", ModifierOptions::None); + IO.bitSetCase(Options, "Const", ModifierOptions::Const); + IO.bitSetCase(Options, "Volatile", ModifierOptions::Volatile); + IO.bitSetCase(Options, "Unaligned", ModifierOptions::Unaligned); +} + +void ScalarBitSetTraits::bitset(IO &IO, + FunctionOptions &Options) { + IO.bitSetCase(Options, "None", FunctionOptions::None); + IO.bitSetCase(Options, "CxxReturnUdt", FunctionOptions::CxxReturnUdt); + IO.bitSetCase(Options, "Constructor", FunctionOptions::Constructor); + IO.bitSetCase(Options, "ConstructorWithVirtualBases", + FunctionOptions::ConstructorWithVirtualBases); +} + +void ScalarBitSetTraits::bitset(IO &IO, ClassOptions &Options) { + IO.bitSetCase(Options, "None", ClassOptions::None); + IO.bitSetCase(Options, "HasConstructorOrDestructor", + ClassOptions::HasConstructorOrDestructor); + IO.bitSetCase(Options, "HasOverloadedOperator", + ClassOptions::HasOverloadedOperator); + IO.bitSetCase(Options, "Nested", ClassOptions::Nested); + IO.bitSetCase(Options, "ContainsNestedClass", + ClassOptions::ContainsNestedClass); + IO.bitSetCase(Options, "HasOverloadedAssignmentOperator", + ClassOptions::HasOverloadedAssignmentOperator); + IO.bitSetCase(Options, "HasConversionOperator", + ClassOptions::HasConversionOperator); + IO.bitSetCase(Options, "ForwardReference", ClassOptions::ForwardReference); + IO.bitSetCase(Options, "Scoped", ClassOptions::Scoped); + IO.bitSetCase(Options, "HasUniqueName", ClassOptions::HasUniqueName); + IO.bitSetCase(Options, "Sealed", ClassOptions::Sealed); + IO.bitSetCase(Options, "Intrinsic", ClassOptions::Intrinsic); +} + +void ScalarBitSetTraits::bitset(IO &IO, MethodOptions &Options) { + IO.bitSetCase(Options, "None", MethodOptions::None); + IO.bitSetCase(Options, "Pseudo", MethodOptions::Pseudo); + IO.bitSetCase(Options, "NoInherit", MethodOptions::NoInherit); + IO.bitSetCase(Options, "NoConstruct", MethodOptions::NoConstruct); + IO.bitSetCase(Options, "CompilerGenerated", MethodOptions::CompilerGenerated); + IO.bitSetCase(Options, "Sealed", MethodOptions::Sealed); +} + +void ScalarEnumerationTraits::enumeration( + IO &io, FileChecksumKind &Kind) { + io.enumCase(Kind, "None", FileChecksumKind::None); + io.enumCase(Kind, "MD5", FileChecksumKind::MD5); + io.enumCase(Kind, "SHA1", FileChecksumKind::SHA1); + io.enumCase(Kind, "SHA256", FileChecksumKind::SHA256); +} + +void ScalarBitSetTraits::bitset(IO &io, LineFlags &Flags) { + io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns); + io.enumFallback(Flags); +} + +void ScalarTraits::output(const HexFormattedString &Value, + void *ctx, raw_ostream &Out) { + StringRef Bytes(reinterpret_cast(Value.Bytes.data()), + Value.Bytes.size()); + Out << toHex(Bytes); +} + +StringRef ScalarTraits::input(StringRef Scalar, void *ctxt, + HexFormattedString &Value) { + std::string H = fromHex(Scalar); + Value.Bytes.assign(H.begin(), H.end()); + return StringRef(); +} + +void MappingTraits::mapping(IO &IO, SourceLineEntry &Obj) { + IO.mapRequired("Offset", Obj.Offset); + IO.mapRequired("LineStart", Obj.LineStart); + IO.mapRequired("IsStatement", Obj.IsStatement); + IO.mapRequired("EndDelta", Obj.EndDelta); +} + +void MappingTraits::mapping(IO &IO, SourceColumnEntry &Obj) { + IO.mapRequired("StartColumn", Obj.StartColumn); + IO.mapRequired("EndColumn", Obj.EndColumn); +} + +void MappingTraits::mapping(IO &IO, SourceLineBlock &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("Lines", Obj.Lines); + IO.mapRequired("Columns", Obj.Columns); +} + +void MappingTraits::mapping( + IO &IO, SourceFileChecksumEntry &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("Kind", Obj.Kind); + IO.mapRequired("Checksum", Obj.ChecksumBytes); +} + +void MappingTraits::mapping(IO &IO, SourceLineInfo &Obj) { + IO.mapRequired("CodeSize", Obj.CodeSize); + + IO.mapRequired("Flags", Obj.Flags); + IO.mapRequired("RelocOffset", Obj.RelocOffset); + IO.mapRequired("RelocSegment", Obj.RelocSegment); + IO.mapRequired("Blocks", Obj.Blocks); +} + +void MappingTraits::mapping(IO &IO, SourceFileInfo &Obj) { + IO.mapOptional("Checksums", Obj.FileChecksums); + IO.mapOptional("Lines", Obj.LineFragments); + IO.mapOptional("InlineeLines", Obj.Inlinees); +} + +void MappingTraits::mapping(IO &IO, InlineeSite &Obj) { + IO.mapRequired("FileName", Obj.FileName); + IO.mapRequired("LineNum", Obj.SourceLineNum); + IO.mapRequired("Inlinee", Obj.Inlinee); + IO.mapOptional("ExtraFiles", Obj.ExtraFiles); +} + +void MappingTraits::mapping(IO &IO, InlineeInfo &Obj) { + IO.mapRequired("HasExtraFiles", Obj.HasExtraFiles); + IO.mapRequired("Sites", Obj.Sites); +} + +void MappingTraits::mapping(IO &IO, MemberPointerInfo &MPI) { + IO.mapRequired("ContainingType", MPI.ContainingType); + IO.mapRequired("Representation", MPI.Representation); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ModifiedType", Record.ModifiedType); + IO.mapRequired("Modifiers", Record.Modifiers); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ReturnType", Record.ReturnType); + IO.mapRequired("CallConv", Record.CallConv); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("ParameterCount", Record.ParameterCount); + IO.mapRequired("ArgumentList", Record.ArgumentList); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ReturnType", Record.ReturnType); + IO.mapRequired("ClassType", Record.ClassType); + IO.mapRequired("ThisType", Record.ThisType); + IO.mapRequired("CallConv", Record.CallConv); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("ParameterCount", Record.ParameterCount); + IO.mapRequired("ArgumentList", Record.ArgumentList); + IO.mapRequired("ThisPointerAdjustment", Record.ThisPointerAdjustment); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("Mode", Record.Mode); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ClassType", Record.ClassType); + IO.mapRequired("FunctionType", Record.FunctionType); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ArgIndices", Record.ArgIndices); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("StringIndices", Record.StringIndices); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ReferentType", Record.ReferentType); + IO.mapRequired("Attrs", Record.Attrs); + IO.mapOptional("MemberInfo", Record.MemberInfo); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ElementType", Record.ElementType); + IO.mapRequired("IndexType", Record.IndexType); + IO.mapRequired("Size", Record.Size); + IO.mapRequired("Name", Record.Name); +} + +void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("FieldList", Members); +} + +namespace { +class MemberRecordConversionVisitor : public TypeVisitorCallbacks { +public: + explicit MemberRecordConversionVisitor(std::vector &Records) + : Records(Records) {} + +#define TYPE_RECORD(EnumName, EnumVal, Name) +#define MEMBER_RECORD(EnumName, EnumVal, Name) \ + Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \ + return visitKnownMemberImpl(Record); \ + } +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" +private: + template Error visitKnownMemberImpl(T &Record) { + TypeLeafKind K = static_cast(Record.getKind()); + auto Impl = std::make_shared>(K); + Impl->Record = Record; + Records.push_back(MemberRecord{Impl}); + return Error::success(); + } + + std::vector &Records; +}; +} + +Error LeafRecordImpl::fromCodeViewRecord(CVType Type) { + MemberRecordConversionVisitor V(Members); + return visitMemberRecordStream(Type.content(), V); +} + +CVType LeafRecordImpl::toCodeViewRecord( + BumpPtrAllocator &Allocator) const { + TypeTableBuilder TTB(Allocator); + FieldListRecordBuilder FLRB(TTB); + FLRB.begin(); + for (const auto &Member : Members) { + Member.Member->writeTo(FLRB); + } + FLRB.end(true); + return CVType(Kind, TTB.records().front()); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("MemberCount", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + + IO.mapRequired("DerivationList", Record.DerivationList); + IO.mapRequired("VTableShape", Record.VTableShape); + IO.mapRequired("Size", Record.Size); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("MemberCount", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + + IO.mapRequired("Size", Record.Size); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("NumEnumerators", Record.MemberCount); + IO.mapRequired("Options", Record.Options); + IO.mapRequired("FieldList", Record.FieldList); + IO.mapRequired("Name", Record.Name); + IO.mapRequired("UniqueName", Record.UniqueName); + + IO.mapRequired("UnderlyingType", Record.UnderlyingType); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("Type", Record.Type); + IO.mapRequired("BitSize", Record.BitSize); + IO.mapRequired("BitOffset", Record.BitOffset); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("Slots", Record.Slots); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("Guid", Record.Guid); + IO.mapRequired("Age", Record.Age); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("Id", Record.Id); + IO.mapRequired("String", Record.String); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ParentScope", Record.ParentScope); + IO.mapRequired("FunctionType", Record.FunctionType); + IO.mapRequired("Name", Record.Name); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("UDT", Record.UDT); + IO.mapRequired("SourceFile", Record.SourceFile); + IO.mapRequired("LineNumber", Record.LineNumber); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("UDT", Record.UDT); + IO.mapRequired("SourceFile", Record.SourceFile); + IO.mapRequired("LineNumber", Record.LineNumber); + IO.mapRequired("Module", Record.Module); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("ArgIndices", Record.ArgIndices); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("CompleteClass", Record.CompleteClass); + IO.mapRequired("OverriddenVFTable", Record.OverriddenVFTable); + IO.mapRequired("VFPtrOffset", Record.VFPtrOffset); + IO.mapRequired("MethodNames", Record.MethodNames); +} + +template <> void LeafRecordImpl::map(IO &IO) { + IO.mapRequired("Methods", Record.Methods); +} + +void MappingTraits::mapping(IO &io, OneMethodRecord &Record) { + io.mapRequired("Type", Record.Type); + io.mapRequired("Attrs", Record.Attrs.Attrs); + io.mapRequired("VFTableOffset", Record.VFTableOffset); + io.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl::map(IO &IO) { + MappingTraits::mapping(IO, Record); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("NumOverloads", Record.NumOverloads); + IO.mapRequired("MethodList", Record.MethodList); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("FieldOffset", Record.FieldOffset); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Value", Record.Value); + IO.mapRequired("Name", Record.Name); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("Type", Record.Type); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("Type", Record.Type); + IO.mapRequired("Offset", Record.Offset); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("Attrs", Record.Attrs.Attrs); + IO.mapRequired("BaseType", Record.BaseType); + IO.mapRequired("VBPtrType", Record.VBPtrType); + IO.mapRequired("VBPtrOffset", Record.VBPtrOffset); + IO.mapRequired("VTableIndex", Record.VTableIndex); +} + +template <> void MemberRecordImpl::map(IO &IO) { + IO.mapRequired("ContinuationIndex", Record.ContinuationIndex); +} + +template +static inline Expected fromCodeViewRecordImpl(CVType Type) { + LeafRecord Result; + + auto Impl = std::make_shared>(Type.kind()); + if (auto EC = Impl->fromCodeViewRecord(Type)) + return std::move(EC); + Result.Leaf = Impl; + return Result; +} + +Expected LeafRecord::fromCodeViewRecord(CVType Type) { +#define TYPE_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + return fromCodeViewRecordImpl(Type); +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + TYPE_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Type.kind()) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: { llvm_unreachable("Unknown leaf kind!"); } + } + return make_error(cv_error_code::corrupt_record); +} + +CVType LeafRecord::toCodeViewRecord(BumpPtrAllocator &Allocator) const { + return Leaf->toCodeViewRecord(Allocator); +} + +template <> struct MappingTraits { + static void mapping(IO &io, LeafRecordBase &Record) { Record.map(io); } +}; + +template +static void mapLeafRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, + LeafRecord &Obj) { + if (!IO.outputting()) + Obj.Leaf = std::make_shared>(Kind); + + if (Kind == LF_FIELDLIST) + Obj.Leaf->map(IO); + else + IO.mapRequired(Class, *Obj.Leaf); +} + +void MappingTraits::mapping(IO &IO, LeafRecord &Obj) { + TypeLeafKind Kind; + if (IO.outputting()) + Kind = Obj.Leaf->Kind; + IO.mapRequired("Kind", Kind); + +#define TYPE_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + mapLeafRecordImpl(IO, #ClassName, Kind, Obj); \ + break; +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + TYPE_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Kind) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: { llvm_unreachable("Unknown leaf kind!"); } + } +} + +template <> struct MappingTraits { + static void mapping(IO &io, MemberRecordBase &Record) { Record.map(io); } +}; + +template +static void mapMemberRecordImpl(IO &IO, const char *Class, TypeLeafKind Kind, + MemberRecord &Obj) { + if (!IO.outputting()) + Obj.Member = std::make_shared>(Kind); + + IO.mapRequired(Class, *Obj.Member); +} + +void MappingTraits::mapping(IO &IO, MemberRecord &Obj) { + TypeLeafKind Kind; + if (IO.outputting()) + Kind = Obj.Member->Kind; + IO.mapRequired("Kind", Kind); + +#define MEMBER_RECORD(EnumName, EnumVal, ClassName) \ + case EnumName: \ + mapMemberRecordImpl(IO, #ClassName, Kind, Obj); \ + break; +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ + MEMBER_RECORD(EnumName, EnumVal, ClassName) +#define TYPE_RECORD(EnumName, EnumVal, ClassName) +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) + switch (Kind) { +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + default: { llvm_unreachable("Unknown member kind!"); } + } +} diff --git a/lib/ObjectYAML/LLVMBuild.txt b/lib/ObjectYAML/LLVMBuild.txt index b8d1d2f1779..44657e916a9 100644 --- a/lib/ObjectYAML/LLVMBuild.txt +++ b/lib/ObjectYAML/LLVMBuild.txt @@ -11,4 +11,4 @@ type = Library name = ObjectYAML parent = Libraries -required_libraries = Support +required_libraries = Support DebugInfoCodeView diff --git a/tools/llvm-pdbdump/Analyze.cpp b/tools/llvm-pdbdump/Analyze.cpp index 3a026e5d245..b503cdcbf1e 100644 --- a/tools/llvm-pdbdump/Analyze.cpp +++ b/tools/llvm-pdbdump/Analyze.cpp @@ -35,7 +35,7 @@ static StringRef getLeafTypeName(TypeLeafKind LT) { #define TYPE_RECORD(ename, value, name) \ case ename: \ return #name; -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" default: break; } diff --git a/tools/llvm-pdbdump/CMakeLists.txt b/tools/llvm-pdbdump/CMakeLists.txt index 325e38c15ca..af6d2cb3406 100644 --- a/tools/llvm-pdbdump/CMakeLists.txt +++ b/tools/llvm-pdbdump/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS DebugInfoMSF DebugInfoPDB Object + ObjectYAML Support ) @@ -12,8 +13,6 @@ add_llvm_tool(llvm-pdbdump CompactTypeDumpVisitor.cpp Diff.cpp llvm-pdbdump.cpp - YamlSymbolDumper.cpp - YamlTypeDumper.cpp LinePrinter.cpp LLVMOutputStyle.cpp PdbYaml.cpp @@ -29,6 +28,7 @@ add_llvm_tool(llvm-pdbdump PrettyVariableDumper.cpp StreamUtil.cpp YAMLOutputStyle.cpp + YamlSymbolDumper.cpp ) if(LLVM_USE_SANITIZE_COVERAGE) diff --git a/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp b/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp index 3b609ae50c1..6dd54e0dbec 100644 --- a/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp +++ b/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp @@ -18,7 +18,7 @@ using namespace llvm::pdb; static const EnumEntry LeafTypeNames[] = { #define CV_TYPE(enum, val) {#enum, enum}, -#include "llvm/DebugInfo/CodeView/TypeRecords.def" +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" }; static StringRef getLeafName(TypeLeafKind K) { diff --git a/tools/llvm-pdbdump/PdbYaml.cpp b/tools/llvm-pdbdump/PdbYaml.cpp index dd32eca14c1..53213524321 100644 --- a/tools/llvm-pdbdump/PdbYaml.cpp +++ b/tools/llvm-pdbdump/PdbYaml.cpp @@ -9,9 +9,7 @@ #include "PdbYaml.h" -#include "YamlSerializationContext.h" #include "YamlSymbolDumper.h" -#include "YamlTypeDumper.h" #include "llvm/ADT/StringExtras.h" #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" @@ -22,6 +20,7 @@ #include "llvm/DebugInfo/CodeView/TypeSerializer.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/DebugInfo/PDB/Native/TpiHashing.h" #include "llvm/DebugInfo/PDB/PDBExtras.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" @@ -35,15 +34,7 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceFileChecksumEntry) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineEntry) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceColumnEntry) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineBlock) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineInfo) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbInlineeSite) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbInlineeInfo) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSymbolRecord) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiRecord) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList) LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::pdb::PdbRaw_FeatureSig) @@ -152,57 +143,18 @@ template <> struct ScalarEnumerationTraits { io.enumCase(Features, "VC140", PdbRaw_FeatureSig::VC140); } }; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &io, llvm::codeview::FileChecksumKind &Kind) { - io.enumCase(Kind, "None", llvm::codeview::FileChecksumKind::None); - io.enumCase(Kind, "MD5", llvm::codeview::FileChecksumKind::MD5); - io.enumCase(Kind, "SHA1", llvm::codeview::FileChecksumKind::SHA1); - io.enumCase(Kind, "SHA256", llvm::codeview::FileChecksumKind::SHA256); - } -}; - -template <> struct ScalarBitSetTraits { - static void bitset(IO &io, llvm::codeview::LineFlags &Flags) { - io.bitSetCase(Flags, "HasColumnInfo", llvm::codeview::LF_HaveColumns); - io.enumFallback(Flags); - } -}; } } -void ScalarTraits::output(const HexFormattedString &Value, - void *ctx, raw_ostream &Out) { - StringRef Bytes(reinterpret_cast(Value.Bytes.data()), - Value.Bytes.size()); - Out << toHex(Bytes); -} - -StringRef ScalarTraits::input(StringRef Scalar, void *ctxt, - HexFormattedString &Value) { - std::string H = fromHex(Scalar); - Value.Bytes.assign(H.begin(), H.end()); - return StringRef(); -} - void MappingTraits::mapping(IO &IO, PdbObject &Obj) { - // Create a single serialization context that will be passed through the - // entire process of serializing / deserializing a Tpi Stream. This is - // especially important when we are going from Pdb -> Yaml because we need - // to maintain state in a TypeTableBuilder across mappings, and at the end of - // the entire process, we need to have one TypeTableBuilder that has every - // record. - pdb::yaml::SerializationContext Context(IO, Obj.Allocator); - - IO.mapOptional("MSF", Obj.Headers); IO.mapOptional("StreamSizes", Obj.StreamSizes); IO.mapOptional("StreamMap", Obj.StreamMap); IO.mapOptional("StringTable", Obj.StringTable); IO.mapOptional("PdbStream", Obj.PdbStream); - IO.mapOptionalWithContext("DbiStream", Obj.DbiStream, Context); - IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Context); - IO.mapOptionalWithContext("IpiStream", Obj.IpiStream, Context); + IO.mapOptional("DbiStream", Obj.DbiStream); + IO.mapOptional("TpiStream", Obj.TpiStream); + IO.mapOptional("IpiStream", Obj.IpiStream); } void MappingTraits::mapping(IO &IO, MSFHeaders &Obj) { @@ -239,7 +191,7 @@ void MappingTraits::mapping(IO &IO, PdbInfoStream &Obj) { IO.mapOptional("Version", Obj.Version, PdbImplVC70); } -void MappingContextTraits::mapping(IO &IO, PdbDbiStream &Obj, pdb::yaml::SerializationContext &Context) { +void MappingTraits::mapping(IO &IO, PdbDbiStream &Obj) { IO.mapOptional("VerHeader", Obj.VerHeader, PdbDbiV70); IO.mapOptional("Age", Obj.Age, 1U); IO.mapOptional("BuildNumber", Obj.BuildNumber, uint16_t(0U)); @@ -247,13 +199,13 @@ void MappingContextTraits::mappin IO.mapOptional("PdbDllRbld", Obj.PdbDllRbld, uint16_t(0U)); IO.mapOptional("Flags", Obj.Flags, uint16_t(1U)); IO.mapOptional("MachineType", Obj.MachineType, PDB_Machine::x86); - IO.mapOptionalWithContext("Modules", Obj.ModInfos, Context); + IO.mapOptional("Modules", Obj.ModInfos); } -void MappingContextTraits::mapping( - IO &IO, pdb::yaml::PdbTpiStream &Obj, pdb::yaml::SerializationContext &Context) { +void MappingTraits::mapping(IO &IO, + pdb::yaml::PdbTpiStream &Obj) { IO.mapOptional("Version", Obj.Version, PdbTpiV80); - IO.mapRequired("Records", Obj.Records, Context); + IO.mapRequired("Records", Obj.Records); } void MappingTraits::mapping(IO &IO, @@ -262,9 +214,11 @@ void MappingTraits::mapping(IO &IO, IO.mapRequired("StreamNum", Obj.StreamNumber); } -void MappingContextTraits::mapping(IO &IO, PdbSymbolRecord &Obj, pdb::yaml::SerializationContext &Context) { +void MappingTraits::mapping(IO &IO, PdbSymbolRecord &Obj) { + BumpPtrAllocator *Alloc = + reinterpret_cast(IO.getContext()); codeview::SymbolVisitorCallbackPipeline Pipeline; - codeview::SymbolSerializer Serializer(Context.Allocator); + codeview::SymbolSerializer Serializer(*Alloc); codeview::SymbolDeserializer Deserializer(nullptr); codeview::yaml::YamlSymbolDumper Dumper(IO); @@ -283,113 +237,15 @@ void MappingContextTraits::map consumeError(Visitor.visitSymbolRecord(Obj.Record)); } -void MappingContextTraits::mapping(IO &IO, PdbModiStream &Obj, pdb::yaml::SerializationContext &Context) { +void MappingTraits::mapping(IO &IO, PdbModiStream &Obj) { IO.mapOptional("Signature", Obj.Signature, 4U); - IO.mapRequired("Records", Obj.Symbols, Context); + IO.mapRequired("Records", Obj.Symbols); } -void MappingContextTraits::mapping(IO &IO, PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context) { +void MappingTraits::mapping(IO &IO, PdbDbiModuleInfo &Obj) { IO.mapRequired("Module", Obj.Mod); IO.mapOptional("ObjFile", Obj.Obj, Obj.Mod); IO.mapOptional("SourceFiles", Obj.SourceFiles); - IO.mapOptionalWithContext("LineInfo", Obj.FileLineInfo, Context); - IO.mapOptionalWithContext("Modi", Obj.Modi, Context); -} - -void MappingContextTraits:: - mapping(IO &IO, PdbSourceLineEntry &Obj, - pdb::yaml::SerializationContext &Context) { - IO.mapRequired("Offset", Obj.Offset); - IO.mapRequired("LineStart", Obj.LineStart); - IO.mapRequired("IsStatement", Obj.IsStatement); - IO.mapRequired("EndDelta", Obj.EndDelta); -} - -void MappingContextTraits:: - mapping(IO &IO, PdbSourceColumnEntry &Obj, - pdb::yaml::SerializationContext &Context) { - IO.mapRequired("StartColumn", Obj.StartColumn); - IO.mapRequired("EndColumn", Obj.EndColumn); -} - -void MappingContextTraits:: - mapping(IO &IO, PdbSourceLineBlock &Obj, - pdb::yaml::SerializationContext &Context) { - IO.mapRequired("FileName", Obj.FileName); - IO.mapRequired("Lines", Obj.Lines, Context); - IO.mapRequired("Columns", Obj.Columns, Context); -} - -void MappingContextTraits:: - mapping(IO &IO, PdbSourceFileChecksumEntry &Obj, - pdb::yaml::SerializationContext &Context) { - IO.mapRequired("FileName", Obj.FileName); - IO.mapRequired("Kind", Obj.Kind); - IO.mapRequired("Checksum", Obj.ChecksumBytes); -} - -void MappingContextTraits:: - mapping(IO &IO, PdbSourceLineInfo &Obj, - pdb::yaml::SerializationContext &Context) { - IO.mapRequired("CodeSize", Obj.CodeSize); - - IO.mapRequired("Flags", Obj.Flags); - IO.mapRequired("RelocOffset", Obj.RelocOffset); - IO.mapRequired("RelocSegment", Obj.RelocSegment); - IO.mapRequired("Blocks", Obj.Blocks, Context); -} - -void MappingContextTraits:: - mapping(IO &IO, PdbSourceFileInfo &Obj, - pdb::yaml::SerializationContext &Context) { - IO.mapOptionalWithContext("Checksums", Obj.FileChecksums, Context); - IO.mapOptionalWithContext("Lines", Obj.LineFragments, Context); - IO.mapOptionalWithContext("InlineeLines", Obj.Inlinees, Context); -} - -void MappingContextTraits::mapping( - IO &IO, PdbInlineeSite &Obj, SerializationContext &Context) { - IO.mapRequired("FileName", Obj.FileName); - IO.mapRequired("LineNum", Obj.SourceLineNum); - IO.mapRequired("Inlinee", Obj.Inlinee); - IO.mapOptional("ExtraFiles", Obj.ExtraFiles); -} - -void MappingContextTraits::mapping( - IO &IO, PdbInlineeInfo &Obj, SerializationContext &Context) { - IO.mapRequired("HasExtraFiles", Obj.HasExtraFiles); - IO.mapRequired("Sites", Obj.Sites, Context); -} - -void MappingContextTraits:: - mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj, - pdb::yaml::SerializationContext &Context) { - if (IO.outputting()) { - // For PDB to Yaml, deserialize into a high level record type, then dump it. - consumeError(codeview::visitTypeRecord(Obj.Record, Context.Dumper)); - } else { - codeview::TypeVisitorCallbackPipeline Pipeline; - codeview::TypeSerializer Serializer(Context.Allocator); - pdb::TpiHashUpdater Hasher; - // For Yaml to PDB, extract from the high level record type, then write it - // to bytes. - - // This might be interpreted as a hack, but serializing FieldList - // sub-records requires having access to the same serializer being used by - // the FieldList itself. - Context.ActiveSerializer = &Serializer; - Pipeline.addCallbackToPipeline(Context.Dumper); - Pipeline.addCallbackToPipeline(Serializer); - Pipeline.addCallbackToPipeline(Hasher); - consumeError(codeview::visitTypeRecord(Obj.Record, Pipeline, - codeview::VDS_BytesExternal)); - } - - Context.ActiveSerializer = nullptr; + IO.mapOptional("LineInfo", Obj.FileLineInfo); + IO.mapOptional("Modi", Obj.Modi); } diff --git a/tools/llvm-pdbdump/PdbYaml.h b/tools/llvm-pdbdump/PdbYaml.h index 423845caeb3..f8c8850a86f 100644 --- a/tools/llvm-pdbdump/PdbYaml.h +++ b/tools/llvm-pdbdump/PdbYaml.h @@ -19,6 +19,7 @@ #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/ObjectYAML/CodeViewYAML.h" #include "llvm/Support/Endian.h" #include "llvm/Support/YAMLTraits.h" @@ -65,66 +66,11 @@ struct PdbModiStream { std::vector Symbols; }; -struct PdbSourceLineEntry { - uint32_t Offset; - uint32_t LineStart; - uint32_t EndDelta; - bool IsStatement; -}; - -struct PdbSourceColumnEntry { - uint16_t StartColumn; - uint16_t EndColumn; -}; - -struct PdbSourceLineBlock { - StringRef FileName; - std::vector Lines; - std::vector Columns; -}; - -struct HexFormattedString { - std::vector Bytes; -}; - -struct PdbSourceFileChecksumEntry { - StringRef FileName; - codeview::FileChecksumKind Kind; - HexFormattedString ChecksumBytes; -}; - -struct PdbSourceLineInfo { - uint32_t RelocOffset; - uint32_t RelocSegment; - codeview::LineFlags Flags; - uint32_t CodeSize; - - std::vector Blocks; -}; - -struct PdbInlineeSite { - codeview::TypeIndex Inlinee; - StringRef FileName; - uint32_t SourceLineNum; - std::vector ExtraFiles; -}; - -struct PdbInlineeInfo { - bool HasExtraFiles; - std::vector Sites; -}; - -struct PdbSourceFileInfo { - std::vector FileChecksums; - std::vector LineFragments; - std::vector Inlinees; -}; - struct PdbDbiModuleInfo { StringRef Obj; StringRef Mod; std::vector SourceFiles; - Optional FileLineInfo; + Optional FileLineInfo; Optional Modi; }; @@ -140,17 +86,9 @@ struct PdbDbiStream { std::vector ModInfos; }; -struct PdbTpiRecord { - codeview::CVType Record; -}; - -struct PdbTpiFieldListRecord { - codeview::CVMemberRecord Record; -}; - struct PdbTpiStream { PdbRaw_TpiVer Version = PdbTpiV80; - std::vector Records; + std::vector Records; }; struct PdbObject { @@ -172,126 +110,16 @@ struct PdbObject { } } -namespace llvm { -namespace yaml { - -template <> struct MappingTraits { - static void mapping(IO &IO, pdb::yaml::PdbObject &Obj); -}; - -template <> struct MappingTraits { - static void mapping(IO &IO, pdb::yaml::MSFHeaders &Obj); -}; - -template <> struct MappingTraits { - static void mapping(IO &IO, msf::SuperBlock &SB); -}; - -template <> struct MappingTraits { - static void mapping(IO &IO, pdb::yaml::StreamBlockList &SB); -}; - -template <> struct MappingTraits { - static void mapping(IO &IO, pdb::yaml::PdbInfoStream &Obj); -}; - -template <> struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbDbiStream &Obj, pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbTpiStream &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> struct MappingTraits { - static void mapping(IO &IO, pdb::yaml::NamedStreamMapping &Obj); -}; - -template <> struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbSymbolRecord &Obj, pdb::yaml::SerializationContext &Context); -}; - -template <> struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbModiStream &Obj, pdb::yaml::SerializationContext &Context); -}; - -template <> struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbSourceLineEntry &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbSourceColumnEntry &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbSourceLineBlock &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbSourceFileChecksumEntry &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> struct ScalarTraits { - static void output(const pdb::yaml::HexFormattedString &Value, void *ctx, - llvm::raw_ostream &Out); - static StringRef input(StringRef Scalar, void *ctxt, - pdb::yaml::HexFormattedString &Value); - static bool mustQuote(StringRef) { return false; } -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbSourceLineInfo &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbSourceFileInfo &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbInlineeInfo &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbInlineeSite &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj, - pdb::yaml::SerializationContext &Context); -}; -} -} +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbObject) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::MSFHeaders) +LLVM_YAML_DECLARE_MAPPING_TRAITS(msf::SuperBlock) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::StreamBlockList) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbInfoStream) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbDbiStream) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbTpiStream) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::NamedStreamMapping) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbSymbolRecord) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbModiStream) +LLVM_YAML_DECLARE_MAPPING_TRAITS(pdb::yaml::PdbDbiModuleInfo) #endif // LLVM_TOOLS_LLVMPDBDUMP_PDBYAML_H diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/tools/llvm-pdbdump/YAMLOutputStyle.cpp index 7aa68dee7d4..6173804c375 100644 --- a/tools/llvm-pdbdump/YAMLOutputStyle.cpp +++ b/tools/llvm-pdbdump/YAMLOutputStyle.cpp @@ -28,6 +28,7 @@ #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/ObjectYAML/CodeViewYAML.h" using namespace llvm; using namespace llvm::codeview; @@ -104,12 +105,12 @@ Error YAMLOutputStyle::dump() { namespace { class C13YamlVisitor : public C13DebugFragmentVisitor { public: - C13YamlVisitor(llvm::pdb::yaml::PdbSourceFileInfo &Info, PDBFile &F) + C13YamlVisitor(CodeViewYAML::SourceFileInfo &Info, PDBFile &F) : C13DebugFragmentVisitor(F), Info(Info) {} Error handleFileChecksums() override { for (const auto &C : *Checksums) { - llvm::pdb::yaml::PdbSourceFileChecksumEntry Entry; + CodeViewYAML::SourceFileChecksumEntry Entry; if (auto Result = getNameFromStringTable(C.FileNameOffset)) Entry.FileName = *Result; else @@ -143,7 +144,7 @@ public: return Result.takeError(); for (const auto &N : L.LineNumbers) { - llvm::pdb::yaml::PdbSourceLineEntry Line; + CodeViewYAML::SourceLineEntry Line; Line.Offset = N.Offset; codeview::LineInfo LI(N.Flags); Line.LineStart = LI.getStartLine(); @@ -154,7 +155,7 @@ public: if (LF.hasColumnInfo()) { for (const auto &C : L.Columns) { - llvm::pdb::yaml::PdbSourceColumnEntry Column; + CodeViewYAML::SourceColumnEntry Column; Column.StartColumn = C.StartColumn; Column.EndColumn = C.EndColumn; Block.Columns.push_back(Column); @@ -179,7 +180,7 @@ public: else return Result.takeError(); - Site.Inlinee = IL.Header->Inlinee; + Site.Inlinee = IL.Header->Inlinee.getIndex(); Site.SourceLineNum = IL.Header->SourceLineNum; if (ILF.hasExtraFiles()) { for (const auto &EF : IL.ExtraFiles) { @@ -195,17 +196,16 @@ public: } private: - - llvm::pdb::yaml::PdbSourceFileInfo &Info; + CodeViewYAML::SourceFileInfo &Info; }; } -Expected> +Expected> YAMLOutputStyle::getFileLineInfo(const pdb::ModuleDebugStreamRef &ModS) { if (!ModS.hasLineInfo()) return None; - yaml::PdbSourceFileInfo Info; + CodeViewYAML::SourceFileInfo Info; C13YamlVisitor Visitor(Info, File); if (auto EC = codeview::visitDebugSubsections(ModS.linesAndChecksums(), Visitor)) @@ -378,13 +378,10 @@ Error YAMLOutputStyle::dumpTpiStream() { Obj.TpiStream.emplace(); Obj.TpiStream->Version = TS.getTpiVersion(); for (auto &Record : TS.types(nullptr)) { - yaml::PdbTpiRecord R; - // It's not necessary to set R.RecordData here. That only exists as a - // way to have the `PdbTpiRecord` structure own the memory that `R.Record` - // references. In the case of reading an existing PDB though, that memory - // is owned by the backing stream. - R.Record = Record; - Obj.TpiStream->Records.push_back(R); + auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record); + if (!ExpectedRecord) + return ExpectedRecord.takeError(); + Obj.TpiStream->Records.push_back(*ExpectedRecord); } return Error::success(); @@ -402,9 +399,11 @@ Error YAMLOutputStyle::dumpIpiStream() { Obj.IpiStream.emplace(); Obj.IpiStream->Version = IS.getTpiVersion(); for (auto &Record : IS.types(nullptr)) { - yaml::PdbTpiRecord R; - R.Record = Record; - Obj.IpiStream->Records.push_back(R); + auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record); + if (!ExpectedRecord) + return ExpectedRecord.takeError(); + + Obj.IpiStream->Records.push_back(*ExpectedRecord); } return Error::success(); diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.h b/tools/llvm-pdbdump/YAMLOutputStyle.h index 068312aec45..6e4067c48f8 100644 --- a/tools/llvm-pdbdump/YAMLOutputStyle.h +++ b/tools/llvm-pdbdump/YAMLOutputStyle.h @@ -27,7 +27,7 @@ public: Error dump() override; private: - Expected> + Expected> getFileLineInfo(const pdb::ModuleDebugStreamRef &ModS); Error dumpStringTable(); diff --git a/tools/llvm-pdbdump/YamlSerializationContext.h b/tools/llvm-pdbdump/YamlSerializationContext.h deleted file mode 100644 index dcf29d249d6..00000000000 --- a/tools/llvm-pdbdump/YamlSerializationContext.h +++ /dev/null @@ -1,39 +0,0 @@ -//===- YamlSerializationContext.h ----------------------------- *- C++ --*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_LLVMPDBDUMP_YAMLSERIALIZATIONCONTEXT_H -#define LLVM_TOOLS_LLVMPDBDUMP_YAMLSERIALIZATIONCONTEXT_H - -#include "PdbYaml.h" -#include "YamlTypeDumper.h" -#include "llvm/Support/Allocator.h" - -namespace llvm { -namespace codeview { -class TypeSerializer; -} -namespace yaml { -class IO; -} - -namespace pdb { -namespace yaml { -struct SerializationContext { - explicit SerializationContext(llvm::yaml::IO &IO, BumpPtrAllocator &Allocator) - : Dumper(IO, *this), Allocator(Allocator) {} - - codeview::yaml::YamlTypeDumperCallbacks Dumper; - BumpPtrAllocator &Allocator; - codeview::TypeSerializer *ActiveSerializer = nullptr; -}; -} -} -} - -#endif \ No newline at end of file diff --git a/tools/llvm-pdbdump/YamlSymbolDumper.cpp b/tools/llvm-pdbdump/YamlSymbolDumper.cpp index 431bf404fb0..4d5a50146e0 100644 --- a/tools/llvm-pdbdump/YamlSymbolDumper.cpp +++ b/tools/llvm-pdbdump/YamlSymbolDumper.cpp @@ -9,7 +9,6 @@ #include "YamlSymbolDumper.h" #include "PdbYaml.h" -#include "YamlTypeDumper.h" #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" @@ -27,10 +26,10 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord) LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind) LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) LLVM_YAML_IS_SEQUENCE_VECTOR(CVType) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiFieldListRecord) namespace llvm { namespace yaml { + void ScalarEnumerationTraits::enumeration(IO &io, SymbolKind &Value) { auto SymbolNames = getSymbolTypeNames(); diff --git a/tools/llvm-pdbdump/YamlSymbolDumper.h b/tools/llvm-pdbdump/YamlSymbolDumper.h index 61e63f96719..55c0eaa87f5 100644 --- a/tools/llvm-pdbdump/YamlSymbolDumper.h +++ b/tools/llvm-pdbdump/YamlSymbolDumper.h @@ -34,7 +34,7 @@ public: return Error::success(); \ } #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" private: template @@ -59,7 +59,7 @@ template <> struct ScalarEnumerationTraits { static void mapping(IO &IO, codeview::Name &Obj); \ }; #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def" +#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" } } diff --git a/tools/llvm-pdbdump/YamlTypeDumper.cpp b/tools/llvm-pdbdump/YamlTypeDumper.cpp deleted file mode 100644 index beb70072095..00000000000 --- a/tools/llvm-pdbdump/YamlTypeDumper.cpp +++ /dev/null @@ -1,589 +0,0 @@ -//===- YamlTypeDumper.cpp ------------------------------------- *- C++ --*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "YamlTypeDumper.h" -#include "PdbYaml.h" -#include "YamlSerializationContext.h" - -#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" -#include "llvm/DebugInfo/CodeView/EnumTables.h" -#include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeSerializer.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" -#include "llvm/DebugInfo/PDB/Native/TpiHashing.h" - -using namespace llvm; -using namespace llvm::codeview; -using namespace llvm::codeview::yaml; - -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t) -LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord) -LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind) -LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) -LLVM_YAML_IS_SEQUENCE_VECTOR(CVType) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiFieldListRecord) - -namespace { -struct FieldListRecordSplitter : public TypeVisitorCallbacks { -public: - explicit FieldListRecordSplitter( - std::vector &Records) - : Records(Records) {} - -#define TYPE_RECORD(EnumName, EnumVal, Name) -#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#define MEMBER_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownMember(CVMemberRecord &CVT, Name##Record &Record) override { \ - visitKnownMemberImpl(CVT); \ - return Error::success(); \ - } -#include "llvm/DebugInfo/CodeView/TypeRecords.def" - -private: - void visitKnownMemberImpl(CVMemberRecord &CVT) { - llvm::pdb::yaml::PdbTpiFieldListRecord R; - R.Record = CVT; - Records.push_back(std::move(R)); - } - - std::vector &Records; -}; -} - -namespace llvm { -namespace yaml { -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, PointerToMemberRepresentation &Value) { - IO.enumCase(Value, "Unknown", PointerToMemberRepresentation::Unknown); - IO.enumCase(Value, "SingleInheritanceData", - PointerToMemberRepresentation::SingleInheritanceData); - IO.enumCase(Value, "MultipleInheritanceData", - PointerToMemberRepresentation::MultipleInheritanceData); - IO.enumCase(Value, "VirtualInheritanceData", - PointerToMemberRepresentation::VirtualInheritanceData); - IO.enumCase(Value, "GeneralData", - PointerToMemberRepresentation::GeneralData); - IO.enumCase(Value, "SingleInheritanceFunction", - PointerToMemberRepresentation::SingleInheritanceFunction); - IO.enumCase(Value, "MultipleInheritanceFunction", - PointerToMemberRepresentation::MultipleInheritanceFunction); - IO.enumCase(Value, "VirtualInheritanceFunction", - PointerToMemberRepresentation::VirtualInheritanceFunction); - IO.enumCase(Value, "GeneralFunction", - PointerToMemberRepresentation::GeneralFunction); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, VFTableSlotKind &Kind) { - IO.enumCase(Kind, "Near16", VFTableSlotKind::Near16); - IO.enumCase(Kind, "Far16", VFTableSlotKind::Far16); - IO.enumCase(Kind, "This", VFTableSlotKind::This); - IO.enumCase(Kind, "Outer", VFTableSlotKind::Outer); - IO.enumCase(Kind, "Meta", VFTableSlotKind::Meta); - IO.enumCase(Kind, "Near", VFTableSlotKind::Near); - IO.enumCase(Kind, "Far", VFTableSlotKind::Far); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, CallingConvention &Value) { - IO.enumCase(Value, "NearC", CallingConvention::NearC); - IO.enumCase(Value, "FarC", CallingConvention::FarC); - IO.enumCase(Value, "NearPascal", CallingConvention::NearPascal); - IO.enumCase(Value, "FarPascal", CallingConvention::FarPascal); - IO.enumCase(Value, "NearFast", CallingConvention::NearFast); - IO.enumCase(Value, "FarFast", CallingConvention::FarFast); - IO.enumCase(Value, "NearStdCall", CallingConvention::NearStdCall); - IO.enumCase(Value, "FarStdCall", CallingConvention::FarStdCall); - IO.enumCase(Value, "NearSysCall", CallingConvention::NearSysCall); - IO.enumCase(Value, "FarSysCall", CallingConvention::FarSysCall); - IO.enumCase(Value, "ThisCall", CallingConvention::ThisCall); - IO.enumCase(Value, "MipsCall", CallingConvention::MipsCall); - IO.enumCase(Value, "Generic", CallingConvention::Generic); - IO.enumCase(Value, "AlphaCall", CallingConvention::AlphaCall); - IO.enumCase(Value, "PpcCall", CallingConvention::PpcCall); - IO.enumCase(Value, "SHCall", CallingConvention::SHCall); - IO.enumCase(Value, "ArmCall", CallingConvention::ArmCall); - IO.enumCase(Value, "AM33Call", CallingConvention::AM33Call); - IO.enumCase(Value, "TriCall", CallingConvention::TriCall); - IO.enumCase(Value, "SH5Call", CallingConvention::SH5Call); - IO.enumCase(Value, "M32RCall", CallingConvention::M32RCall); - IO.enumCase(Value, "ClrCall", CallingConvention::ClrCall); - IO.enumCase(Value, "Inline", CallingConvention::Inline); - IO.enumCase(Value, "NearVector", CallingConvention::NearVector); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, PointerKind &Kind) { - IO.enumCase(Kind, "Near16", PointerKind::Near16); - IO.enumCase(Kind, "Far16", PointerKind::Far16); - IO.enumCase(Kind, "Huge16", PointerKind::Huge16); - IO.enumCase(Kind, "BasedOnSegment", PointerKind::BasedOnSegment); - IO.enumCase(Kind, "BasedOnValue", PointerKind::BasedOnValue); - IO.enumCase(Kind, "BasedOnSegmentValue", PointerKind::BasedOnSegmentValue); - IO.enumCase(Kind, "BasedOnAddress", PointerKind::BasedOnAddress); - IO.enumCase(Kind, "BasedOnSegmentAddress", - PointerKind::BasedOnSegmentAddress); - IO.enumCase(Kind, "BasedOnType", PointerKind::BasedOnType); - IO.enumCase(Kind, "BasedOnSelf", PointerKind::BasedOnSelf); - IO.enumCase(Kind, "Near32", PointerKind::Near32); - IO.enumCase(Kind, "Far32", PointerKind::Far32); - IO.enumCase(Kind, "Near64", PointerKind::Near64); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, PointerMode &Mode) { - IO.enumCase(Mode, "Pointer", PointerMode::Pointer); - IO.enumCase(Mode, "LValueReference", PointerMode::LValueReference); - IO.enumCase(Mode, "PointerToDataMember", PointerMode::PointerToDataMember); - IO.enumCase(Mode, "PointerToMemberFunction", - PointerMode::PointerToMemberFunction); - IO.enumCase(Mode, "RValueReference", PointerMode::RValueReference); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, HfaKind &Value) { - IO.enumCase(Value, "None", HfaKind::None); - IO.enumCase(Value, "Float", HfaKind::Float); - IO.enumCase(Value, "Double", HfaKind::Double); - IO.enumCase(Value, "Other", HfaKind::Other); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, MemberAccess &Access) { - IO.enumCase(Access, "None", MemberAccess::None); - IO.enumCase(Access, "Private", MemberAccess::Private); - IO.enumCase(Access, "Protected", MemberAccess::Protected); - IO.enumCase(Access, "Public", MemberAccess::Public); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, MethodKind &Kind) { - IO.enumCase(Kind, "Vanilla", MethodKind::Vanilla); - IO.enumCase(Kind, "Virtual", MethodKind::Virtual); - IO.enumCase(Kind, "Static", MethodKind::Static); - IO.enumCase(Kind, "Friend", MethodKind::Friend); - IO.enumCase(Kind, "IntroducingVirtual", MethodKind::IntroducingVirtual); - IO.enumCase(Kind, "PureVirtual", MethodKind::PureVirtual); - IO.enumCase(Kind, "PureIntroducingVirtual", - MethodKind::PureIntroducingVirtual); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, WindowsRTClassKind &Value) { - IO.enumCase(Value, "None", WindowsRTClassKind::None); - IO.enumCase(Value, "Ref", WindowsRTClassKind::RefClass); - IO.enumCase(Value, "Value", WindowsRTClassKind::ValueClass); - IO.enumCase(Value, "Interface", WindowsRTClassKind::Interface); - } -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, LabelType &Value) { - IO.enumCase(Value, "Near", LabelType::Near); - IO.enumCase(Value, "Far", LabelType::Far); - } -}; - -template <> struct ScalarBitSetTraits { - static void bitset(IO &IO, PointerOptions &Options) { - IO.bitSetCase(Options, "None", PointerOptions::None); - IO.bitSetCase(Options, "Flat32", PointerOptions::Flat32); - IO.bitSetCase(Options, "Volatile", PointerOptions::Volatile); - IO.bitSetCase(Options, "Const", PointerOptions::Const); - IO.bitSetCase(Options, "Unaligned", PointerOptions::Unaligned); - IO.bitSetCase(Options, "Restrict", PointerOptions::Restrict); - IO.bitSetCase(Options, "WinRTSmartPointer", - PointerOptions::WinRTSmartPointer); - } -}; - -template <> struct ScalarBitSetTraits { - static void bitset(IO &IO, ModifierOptions &Options) { - IO.bitSetCase(Options, "None", ModifierOptions::None); - IO.bitSetCase(Options, "Const", ModifierOptions::Const); - IO.bitSetCase(Options, "Volatile", ModifierOptions::Volatile); - IO.bitSetCase(Options, "Unaligned", ModifierOptions::Unaligned); - } -}; - -template <> struct ScalarBitSetTraits { - static void bitset(IO &IO, FunctionOptions &Options) { - IO.bitSetCase(Options, "None", FunctionOptions::None); - IO.bitSetCase(Options, "CxxReturnUdt", FunctionOptions::CxxReturnUdt); - IO.bitSetCase(Options, "Constructor", FunctionOptions::Constructor); - IO.bitSetCase(Options, "ConstructorWithVirtualBases", - FunctionOptions::ConstructorWithVirtualBases); - } -}; - -template <> struct ScalarBitSetTraits { - static void bitset(IO &IO, ClassOptions &Options) { - IO.bitSetCase(Options, "None", ClassOptions::None); - IO.bitSetCase(Options, "HasConstructorOrDestructor", - ClassOptions::HasConstructorOrDestructor); - IO.bitSetCase(Options, "HasOverloadedOperator", - ClassOptions::HasOverloadedOperator); - IO.bitSetCase(Options, "Nested", ClassOptions::Nested); - IO.bitSetCase(Options, "ContainsNestedClass", - ClassOptions::ContainsNestedClass); - IO.bitSetCase(Options, "HasOverloadedAssignmentOperator", - ClassOptions::HasOverloadedAssignmentOperator); - IO.bitSetCase(Options, "HasConversionOperator", - ClassOptions::HasConversionOperator); - IO.bitSetCase(Options, "ForwardReference", ClassOptions::ForwardReference); - IO.bitSetCase(Options, "Scoped", ClassOptions::Scoped); - IO.bitSetCase(Options, "HasUniqueName", ClassOptions::HasUniqueName); - IO.bitSetCase(Options, "Sealed", ClassOptions::Sealed); - IO.bitSetCase(Options, "Intrinsic", ClassOptions::Intrinsic); - } -}; - -template <> struct ScalarBitSetTraits { - static void bitset(IO &IO, MethodOptions &Options) { - IO.bitSetCase(Options, "None", MethodOptions::None); - IO.bitSetCase(Options, "Pseudo", MethodOptions::Pseudo); - IO.bitSetCase(Options, "NoInherit", MethodOptions::NoInherit); - IO.bitSetCase(Options, "NoConstruct", MethodOptions::NoConstruct); - IO.bitSetCase(Options, "CompilerGenerated", - MethodOptions::CompilerGenerated); - IO.bitSetCase(Options, "Sealed", MethodOptions::Sealed); - } -}; - -void ScalarTraits::output(const APSInt &S, void *, - llvm::raw_ostream &OS) { - S.print(OS, true); -} -StringRef ScalarTraits::input(StringRef Scalar, void *Ctx, APSInt &S) { - S = APSInt(Scalar); - return ""; -} - -bool ScalarTraits::mustQuote(StringRef Scalar) { return false; } - -void MappingContextTraits::mapping( - IO &IO, CVType &Record, pdb::yaml::SerializationContext &Context) { - if (IO.outputting()) - consumeError(codeview::visitTypeRecord(Record, Context.Dumper)); -} - -void MappingTraits::mapping(IO &IO, StringIdRecord &String) { - IO.mapRequired("Id", String.Id); - IO.mapRequired("String", String.String); -} - -void MappingTraits::mapping(IO &IO, ArgListRecord &Args) { - IO.mapRequired("ArgIndices", Args.ArgIndices); -} - -void MappingTraits::mapping(IO &IO, StringListRecord &Strings) { - IO.mapRequired("StringIndices", Strings.StringIndices); -} - -void MappingTraits::mapping(IO &IO, ClassRecord &Class) { - IO.mapRequired("MemberCount", Class.MemberCount); - IO.mapRequired("Options", Class.Options); - IO.mapRequired("FieldList", Class.FieldList); - IO.mapRequired("Name", Class.Name); - IO.mapRequired("UniqueName", Class.UniqueName); - IO.mapRequired("DerivationList", Class.DerivationList); - IO.mapRequired("VTableShape", Class.VTableShape); - IO.mapRequired("Size", Class.Size); -} - -void MappingTraits::mapping(IO &IO, UnionRecord &Union) { - IO.mapRequired("MemberCount", Union.MemberCount); - IO.mapRequired("Options", Union.Options); - IO.mapRequired("FieldList", Union.FieldList); - IO.mapRequired("Name", Union.Name); - IO.mapRequired("UniqueName", Union.UniqueName); - IO.mapRequired("Size", Union.Size); -} - -void MappingTraits::mapping(IO &IO, EnumRecord &Enum) { - IO.mapRequired("NumEnumerators", Enum.MemberCount); - IO.mapRequired("Options", Enum.Options); - IO.mapRequired("FieldList", Enum.FieldList); - IO.mapRequired("Name", Enum.Name); - IO.mapRequired("UniqueName", Enum.UniqueName); - IO.mapRequired("UnderlyingType", Enum.UnderlyingType); -} - -void MappingTraits::mapping(IO &IO, ArrayRecord &AT) { - IO.mapRequired("ElementType", AT.ElementType); - IO.mapRequired("IndexType", AT.IndexType); - IO.mapRequired("Size", AT.Size); - IO.mapRequired("Name", AT.Name); -} - -void MappingTraits::mapping(IO &IO, VFTableRecord &VFT) { - IO.mapRequired("CompleteClass", VFT.CompleteClass); - IO.mapRequired("OverriddenVFTable", VFT.OverriddenVFTable); - IO.mapRequired("VFPtrOffset", VFT.VFPtrOffset); - IO.mapRequired("MethodNames", VFT.MethodNames); -} - -void MappingTraits::mapping(IO &IO, - MemberFuncIdRecord &Id) { - IO.mapRequired("ClassType", Id.ClassType); - IO.mapRequired("FunctionType", Id.FunctionType); - IO.mapRequired("Name", Id.Name); -} - -void MappingTraits::mapping(IO &IO, ProcedureRecord &Proc) { - IO.mapRequired("ReturnType", Proc.ReturnType); - IO.mapRequired("CallConv", Proc.CallConv); - IO.mapRequired("Options", Proc.Options); - IO.mapRequired("ParameterCount", Proc.ParameterCount); - IO.mapRequired("ArgumentList", Proc.ArgumentList); -} - -void MappingTraits::mapping(IO &IO, - MemberFunctionRecord &MF) { - IO.mapRequired("ReturnType", MF.ReturnType); - IO.mapRequired("ClassType", MF.ClassType); - IO.mapRequired("ThisType", MF.ThisType); - IO.mapRequired("CallConv", MF.CallConv); - IO.mapRequired("Options", MF.Options); - IO.mapRequired("ParameterCount", MF.ParameterCount); - IO.mapRequired("ArgumentList", MF.ArgumentList); - IO.mapRequired("ThisPointerAdjustment", MF.ThisPointerAdjustment); -} - -void MappingTraits::mapping( - IO &IO, MethodOverloadListRecord &MethodList) { - IO.mapRequired("Methods", MethodList.Methods); -} - -void MappingTraits::mapping(IO &IO, FuncIdRecord &Func) { - IO.mapRequired("ParentScope", Func.ParentScope); - IO.mapRequired("FunctionType", Func.FunctionType); - IO.mapRequired("Name", Func.Name); -} - -void MappingTraits::mapping(IO &IO, TypeServer2Record &TS) { - IO.mapRequired("Guid", TS.Guid); - IO.mapRequired("Age", TS.Age); - IO.mapRequired("Name", TS.Name); -} - -void MappingTraits::mapping(IO &IO, PointerRecord &Ptr) { - IO.mapRequired("ReferentType", Ptr.ReferentType); - IO.mapRequired("Attrs", Ptr.Attrs); - IO.mapOptional("MemberInfo", Ptr.MemberInfo); -} - -void MappingTraits::mapping(IO &IO, MemberPointerInfo &MPI) { - IO.mapRequired("ContainingType", MPI.ContainingType); - IO.mapRequired("Representation", MPI.Representation); -} - -void MappingTraits::mapping(IO &IO, ModifierRecord &Mod) { - IO.mapRequired("ModifiedType", Mod.ModifiedType); - IO.mapRequired("Modifiers", Mod.Modifiers); -} - -void MappingTraits::mapping(IO &IO, BitFieldRecord &BitField) { - IO.mapRequired("Type", BitField.Type); - IO.mapRequired("BitSize", BitField.BitSize); - IO.mapRequired("BitOffset", BitField.BitOffset); -} - -void MappingTraits::mapping(IO &IO, - VFTableShapeRecord &Shape) { - IO.mapRequired("Slots", Shape.Slots); -} - -void MappingTraits::mapping(IO &IO, - UdtSourceLineRecord &Line) { - IO.mapRequired("UDT", Line.UDT); - IO.mapRequired("SourceFile", Line.SourceFile); - IO.mapRequired("LineNumber", Line.LineNumber); -} - -void MappingTraits::mapping( - IO &IO, UdtModSourceLineRecord &Line) { - IO.mapRequired("UDT", Line.UDT); - IO.mapRequired("SourceFile", Line.SourceFile); - IO.mapRequired("LineNumber", Line.LineNumber); - IO.mapRequired("Module", Line.Module); -} - -void MappingTraits::mapping(IO &IO, BuildInfoRecord &Args) { - IO.mapRequired("ArgIndices", Args.ArgIndices); -} - -void MappingTraits::mapping(IO &IO, LabelRecord &R) { - IO.mapRequired("Mode", R.Mode); -} - -void MappingTraits::mapping(IO &IO, - NestedTypeRecord &Nested) { - IO.mapRequired("Type", Nested.Type); - IO.mapRequired("Name", Nested.Name); -} - -void MappingTraits::mapping(IO &IO, OneMethodRecord &Method) { - IO.mapRequired("Type", Method.Type); - IO.mapRequired("Attrs", Method.Attrs.Attrs); - IO.mapRequired("VFTableOffset", Method.VFTableOffset); - IO.mapRequired("Name", Method.Name); -} - -void MappingTraits::mapping( - IO &IO, OverloadedMethodRecord &Method) { - IO.mapRequired("NumOverloads", Method.NumOverloads); - IO.mapRequired("MethodList", Method.MethodList); - IO.mapRequired("Name", Method.Name); -} - -void MappingTraits::mapping(IO &IO, DataMemberRecord &Field) { - IO.mapRequired("Attrs", Field.Attrs.Attrs); - IO.mapRequired("Type", Field.Type); - IO.mapRequired("FieldOffset", Field.FieldOffset); - IO.mapRequired("Name", Field.Name); -} - -void MappingTraits::mapping( - IO &IO, StaticDataMemberRecord &Field) { - IO.mapRequired("Attrs", Field.Attrs.Attrs); - IO.mapRequired("Type", Field.Type); - IO.mapRequired("Name", Field.Name); -} - -void MappingTraits::mapping(IO &IO, VFPtrRecord &VFTable) { - IO.mapRequired("Type", VFTable.Type); -} - -void MappingTraits::mapping(IO &IO, EnumeratorRecord &Enum) { - IO.mapRequired("Attrs", Enum.Attrs.Attrs); - IO.mapRequired("Value", Enum.Value); - IO.mapRequired("Name", Enum.Name); -} - -void MappingTraits::mapping(IO &IO, BaseClassRecord &Base) { - IO.mapRequired("Attrs", Base.Attrs.Attrs); - IO.mapRequired("Type", Base.Type); - IO.mapRequired("Offset", Base.Offset); -} - -void MappingTraits::mapping( - IO &IO, VirtualBaseClassRecord &Base) { - IO.mapRequired("Attrs", Base.Attrs.Attrs); - IO.mapRequired("BaseType", Base.BaseType); - IO.mapRequired("VBPtrType", Base.VBPtrType); - IO.mapRequired("VBPtrOffset", Base.VBPtrOffset); - IO.mapRequired("VTableIndex", Base.VTableIndex); -} - -void MappingTraits::mapping( - IO &IO, ListContinuationRecord &Cont) { - IO.mapRequired("ContinuationIndex", Cont.ContinuationIndex); -} - -void ScalarTraits::output(const codeview::TypeIndex &S, - void *, llvm::raw_ostream &OS) { - OS << S.getIndex(); -} -StringRef ScalarTraits::input(StringRef Scalar, void *Ctx, - codeview::TypeIndex &S) { - uint32_t I; - StringRef Result = ScalarTraits::input(Scalar, Ctx, I); - if (!Result.empty()) - return Result; - S = TypeIndex(I); - return ""; -} -bool ScalarTraits::mustQuote(StringRef Scalar) { - return false; -} - -void ScalarEnumerationTraits::enumeration(IO &io, - TypeLeafKind &Value) { - auto TypeLeafNames = getTypeLeafNames(); - for (const auto &E : TypeLeafNames) - io.enumCase(Value, E.Name.str().c_str(), E.Value); -} -} -} - -Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin( - CVType &CVR) { - YamlIO.mapRequired("Kind", CVR.Type); - return Error::success(); -} - -Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitMemberBegin( - CVMemberRecord &Record) { - YamlIO.mapRequired("Kind", Record.Kind); - return Error::success(); -} - -void llvm::codeview::yaml::YamlTypeDumperCallbacks::visitKnownRecordImpl( - const char *Name, CVType &CVR, FieldListRecord &FieldList) { - std::vector FieldListRecords; - if (YamlIO.outputting()) { - // If we are outputting, then `FieldList.Data` contains a huge chunk of data - // representing the serialized list of members. We need to split it up into - // individual CVType records where each record represents an individual - // member. This way, we can simply map the entire thing as a Yaml sequence, - // which will recurse back to the standard handler for top-level fields - // (top-level and member fields all have the exact same Yaml syntax so use - // the same parser). - FieldListRecordSplitter Splitter(FieldListRecords); - consumeError(codeview::visitMemberRecordStream(FieldList.Data, Splitter)); - } - // Note that if we're not outputting (i.e. Yaml -> PDB) the result of this - // mapping gets lost, as the records are simply stored in this locally scoped - // vector. What's important though is they are all sharing a single - // Serializer - // instance (in `Context.ActiveSerializer`), and that is building up a list of - // all the types. The fact that we need a throwaway vector here is just to - // appease the YAML API to treat this as a sequence and do this mapping once - // for each YAML Sequence element in the input Yaml stream. - YamlIO.mapRequired("FieldList", FieldListRecords, Context); -} - -namespace llvm { -namespace yaml { -template <> -struct MappingContextTraits { - static void mapping(IO &IO, pdb::yaml::PdbTpiFieldListRecord &Obj, - pdb::yaml::SerializationContext &Context) { - if (IO.outputting()) - consumeError(codeview::visitMemberRecord(Obj.Record, Context.Dumper)); - else { - // If we are not outputting, then the array contains no data starting out, - // and is instead populated from the sequence represented by the yaml -- - // again, using the same logic that we use for top-level records. - assert(Context.ActiveSerializer && "There is no active serializer!"); - codeview::TypeVisitorCallbackPipeline Pipeline; - pdb::TpiHashUpdater Hasher; - - Pipeline.addCallbackToPipeline(Context.Dumper); - Pipeline.addCallbackToPipeline(*Context.ActiveSerializer); - Pipeline.addCallbackToPipeline(Hasher); - consumeError( - codeview::visitMemberRecord(Obj.Record, Pipeline, VDS_BytesExternal)); - } - } -}; -} -} diff --git a/tools/llvm-pdbdump/YamlTypeDumper.h b/tools/llvm-pdbdump/YamlTypeDumper.h deleted file mode 100644 index 3f15ba0bf85..00000000000 --- a/tools/llvm-pdbdump/YamlTypeDumper.h +++ /dev/null @@ -1,116 +0,0 @@ -//===- YamlTypeDumper.h --------------------------------------- *- C++ --*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TOOLS_LLVMPDBDUMP_YAMLTYPEDUMPER_H -#define LLVM_TOOLS_LLVMPDBDUMP_YAMLTYPEDUMPER_H - -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" -#include "llvm/Support/YAMLTraits.h" - -namespace llvm { -namespace pdb { -namespace yaml { -struct SerializationContext; -} -} -namespace codeview { -namespace yaml { -class YamlTypeDumperCallbacks : public TypeVisitorCallbacks { -public: - YamlTypeDumperCallbacks(llvm::yaml::IO &IO, - llvm::pdb::yaml::SerializationContext &Context) - : YamlIO(IO), Context(Context) {} - - virtual Error visitTypeBegin(CVType &Record) override; - virtual Error visitMemberBegin(CVMemberRecord &Record) override; - -#define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownRecord(CVRecord &CVR, Name##Record &Record) \ - override { \ - visitKnownRecordImpl(#Name, CVR, Record); \ - return Error::success(); \ - } -#define MEMBER_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \ - visitKnownMemberImpl(#Name, Record); \ - return Error::success(); \ - } -#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/TypeRecords.def" - -private: - template void visitKnownMemberImpl(const char *Name, T &Record) { - YamlIO.mapRequired(Name, Record); - } - - template - void visitKnownRecordImpl(const char *Name, CVType &Type, T &Record) { - YamlIO.mapRequired(Name, Record); - } - - void visitKnownRecordImpl(const char *Name, CVType &CVR, - FieldListRecord &FieldList); - - llvm::yaml::IO &YamlIO; - llvm::pdb::yaml::SerializationContext &Context; -}; -} -} -namespace pdb { -namespace yaml { -struct SerializationContext; -} -} -} - -namespace llvm { -namespace yaml { - -template <> struct ScalarTraits { - static void output(const APSInt &S, void *, llvm::raw_ostream &OS); - static StringRef input(StringRef Scalar, void *Ctx, APSInt &S); - static bool mustQuote(StringRef Scalar); -}; - -template <> struct ScalarTraits { - static void output(const codeview::TypeIndex &S, void *, - llvm::raw_ostream &OS); - static StringRef input(StringRef Scalar, void *Ctx, codeview::TypeIndex &S); - static bool mustQuote(StringRef Scalar); -}; - -template <> struct MappingTraits { - static void mapping(IO &IO, codeview::MemberPointerInfo &Obj); -}; - -template <> -struct MappingContextTraits { - static void mapping(IO &IO, codeview::CVType &Obj, - pdb::yaml::SerializationContext &Context); -}; - -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &io, codeview::TypeLeafKind &Value); -}; - -#define TYPE_RECORD(EnumName, EnumVal, Name) \ - template <> struct MappingTraits { \ - static void mapping(IO &IO, codeview::Name##Record &Obj); \ - }; -#define MEMBER_RECORD(EnumName, EnumVal, Name) \ - TYPE_RECORD(EnumName, EnumVal, Name) -#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/TypeRecords.def" -} -} - -#endif diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index baba862ae66..b1f1ab1bba2 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -61,6 +61,7 @@ #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" +#include "llvm/ObjectYAML/CodeViewYAML.h" #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/COM.h" #include "llvm/Support/CommandLine.h" @@ -476,6 +477,7 @@ static void yamlToPdb(StringRef Path) { std::unique_ptr &Buffer = ErrorOrBuffer.get(); llvm::yaml::Input In(Buffer->getBuffer()); + In.setContext(&Allocator); pdb::yaml::PdbObject YamlObj(Allocator); In >> YamlObj; @@ -584,7 +586,7 @@ static void yamlToPdb(StringRef Path) { auto Inlinees = llvm::make_unique( ChecksumRef, Inlinee.HasExtraFiles); for (const auto &Site : Inlinee.Sites) { - Inlinees->addInlineSite(Site.Inlinee, Site.FileName, + Inlinees->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName, Site.SourceLineNum); if (!Inlinee.HasExtraFiles) continue; @@ -601,14 +603,18 @@ static void yamlToPdb(StringRef Path) { auto &TpiBuilder = Builder.getTpiBuilder(); const auto &Tpi = YamlObj.TpiStream.getValueOr(DefaultTpiStream); TpiBuilder.setVersionHeader(Tpi.Version); - for (const auto &R : Tpi.Records) - TpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash); + for (const auto &R : Tpi.Records) { + CVType Type = R.toCodeViewRecord(Allocator); + TpiBuilder.addTypeRecord(Type.RecordData, None); + } const auto &Ipi = YamlObj.IpiStream.getValueOr(DefaultIpiStream); auto &IpiBuilder = Builder.getIpiBuilder(); IpiBuilder.setVersionHeader(Ipi.Version); - for (const auto &R : Ipi.Records) - IpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash); + for (const auto &R : Ipi.Records) { + CVType Type = R.toCodeViewRecord(Allocator); + IpiBuilder.addTypeRecord(Type.RecordData, None); + } ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile)); }