From 68ca30aa362b18b755319022898494135be8acb1 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Fri, 9 Jun 2017 00:28:08 +0000 Subject: [CodeView] Support remaining debug subsection types This adds support for Symbols, StringTable, and FrameData subsection types. Even though these subsections rarely if ever appear in a PDB file (they are usually in object files), there's no theoretical reason why they *couldn't* appear in a PDB. The real issue though is that in order to add support for dumping and writing them (which will be useful for object files), we need a way to test them. And since there is no support for reading and writing them to / from object files yet, making PDB support them is the best way to both add support for the underlying format and add support for tests at the same time. Later, when we go to add support for reading / writing them from object files, we'll need only minimal changes in the underlying read/write code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305037 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ObjectYAML/CodeViewYAMLDebugSections.cpp | 311 +++++++++++++++++++++++++-- lib/ObjectYAML/CodeViewYAMLTypes.cpp | 28 +-- 2 files changed, 311 insertions(+), 28 deletions(-) (limited to 'lib/ObjectYAML') diff --git a/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp b/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp index baf98d1b083..3bcedd02d47 100644 --- a/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp +++ b/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp @@ -20,13 +20,17 @@ #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h" #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h" #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h" +#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" - +#include "llvm/DebugInfo/CodeView/SymbolSerializer.h" +#include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" +#include "llvm/Support/BinaryStreamWriter.h" using namespace llvm; using namespace llvm::codeview; using namespace llvm::CodeViewYAML; @@ -43,6 +47,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo) LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport) LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport) LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) +LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData) LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t) LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false) @@ -51,6 +56,7 @@ LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind) LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags) LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleExport) +LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLFrameData) LLVM_YAML_DECLARE_MAPPING_TRAITS(YAMLCrossModuleImport) LLVM_YAML_DECLARE_MAPPING_TRAITS(CrossModuleImportItem) LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry) @@ -69,7 +75,8 @@ struct YAMLSubsectionBase { virtual void map(IO &IO) = 0; virtual std::unique_ptr - toCodeViewSubsection(DebugStringTableSubsection *UseStrings, + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *UseStrings, DebugChecksumsSubsection *UseChecksums) const = 0; }; } @@ -83,7 +90,8 @@ struct YAMLChecksumsSubsection : public YAMLSubsectionBase { void map(IO &IO) override; std::unique_ptr - toCodeViewSubsection(DebugStringTableSubsection *Strings, + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *Strings, DebugChecksumsSubsection *Checksums) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, @@ -97,7 +105,8 @@ struct YAMLLinesSubsection : public YAMLSubsectionBase { void map(IO &IO) override; std::unique_ptr - toCodeViewSubsection(DebugStringTableSubsection *Strings, + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *Strings, DebugChecksumsSubsection *Checksums) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, @@ -113,7 +122,8 @@ struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase { void map(IO &IO) override; std::unique_ptr - toCodeViewSubsection(DebugStringTableSubsection *Strings, + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *Strings, DebugChecksumsSubsection *Checksums) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, @@ -129,7 +139,8 @@ struct YAMLCrossModuleExportsSubsection : public YAMLSubsectionBase { void map(IO &IO) override; std::unique_ptr - toCodeViewSubsection(DebugStringTableSubsection *Strings, + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *Strings, DebugChecksumsSubsection *Checksums) const override; static Expected> fromCodeViewSubsection(const DebugCrossModuleExportsSubsectionRef &Exports); @@ -143,7 +154,8 @@ struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase { void map(IO &IO) override; std::unique_ptr - toCodeViewSubsection(DebugStringTableSubsection *Strings, + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *Strings, DebugChecksumsSubsection *Checksums) const override; static Expected> fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, @@ -151,6 +163,51 @@ struct YAMLCrossModuleImportsSubsection : public YAMLSubsectionBase { std::vector Imports; }; + +struct YAMLSymbolsSubsection : public YAMLSubsectionBase { + YAMLSymbolsSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Symbols) {} + + void map(IO &IO) override; + std::unique_ptr + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const override; + static Expected> + fromCodeViewSubsection(const DebugSymbolsSubsectionRef &Symbols); + + std::vector Symbols; +}; + +struct YAMLStringTableSubsection : public YAMLSubsectionBase { + YAMLStringTableSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::StringTable) {} + + void map(IO &IO) override; + std::unique_ptr + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const override; + static Expected> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings); + + std::vector Strings; +}; + +struct YAMLFrameDataSubsection : public YAMLSubsectionBase { + YAMLFrameDataSubsection() + : YAMLSubsectionBase(DebugSubsectionKind::FrameData) {} + + void map(IO &IO) override; + std::unique_ptr + toCodeViewSubsection(BumpPtrAllocator &Allocator, + DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const override; + static Expected> + fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings, + const DebugFrameDataSubsectionRef &Frames); + + std::vector Frames; +}; } void ScalarBitSetTraits::bitset(IO &io, LineFlags &Flags) { @@ -223,6 +280,17 @@ void MappingTraits::mapping(IO &IO, InlineeSite &Obj) { IO.mapOptional("ExtraFiles", Obj.ExtraFiles); } +void MappingTraits::mapping(IO &IO, YAMLFrameData &Obj) { + IO.mapRequired("CodeSize", Obj.CodeSize); + IO.mapRequired("FrameFunc", Obj.FrameFunc); + IO.mapRequired("LocalSize", Obj.LocalSize); + IO.mapOptional("MaxStackSize", Obj.MaxStackSize); + IO.mapOptional("ParamsSize", Obj.ParamsSize); + IO.mapOptional("PrologSize", Obj.PrologSize); + IO.mapOptional("RvaStart", Obj.RvaStart); + IO.mapOptional("SavedRegsSize", Obj.SavedRegsSize); +} + void YAMLChecksumsSubsection::map(IO &IO) { IO.mapTag("!FileChecksums", true); IO.mapRequired("Checksums", Checksums); @@ -254,6 +322,21 @@ void YAMLCrossModuleImportsSubsection::map(IO &IO) { IO.mapOptional("Imports", Imports); } +void YAMLSymbolsSubsection::map(IO &IO) { + IO.mapTag("!Symbols", true); + IO.mapRequired("Records", Symbols); +} + +void YAMLStringTableSubsection::map(IO &IO) { + IO.mapTag("!StringTable", true); + IO.mapRequired("Strings", Strings); +} + +void YAMLFrameDataSubsection::map(IO &IO) { + IO.mapTag("!FrameData", true); + IO.mapRequired("Frames", Frames); +} + void MappingTraits::mapping( IO &IO, YAMLDebugSubsection &Subsection) { if (!IO.outputting()) { @@ -270,6 +353,12 @@ void MappingTraits::mapping( } else if (IO.mapTag("!CrossModuleImports")) { Subsection.Subsection = std::make_shared(); + } else if (IO.mapTag("!Symbols")) { + Subsection.Subsection = std::make_shared(); + } else if (IO.mapTag("!StringTable")) { + Subsection.Subsection = std::make_shared(); + } else if (IO.mapTag("!FrameData")) { + Subsection.Subsection = std::make_shared(); } else { llvm_unreachable("Unexpected subsection tag!"); } @@ -289,7 +378,7 @@ findChecksums(ArrayRef Subsections) { } std::unique_ptr YAMLChecksumsSubsection::toCodeViewSubsection( - DebugStringTableSubsection *UseStrings, + BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings, DebugChecksumsSubsection *UseChecksums) const { assert(UseStrings && !UseChecksums); auto Result = llvm::make_unique(*UseStrings); @@ -300,7 +389,7 @@ std::unique_ptr YAMLChecksumsSubsection::toCodeViewSubsection( } std::unique_ptr YAMLLinesSubsection::toCodeViewSubsection( - DebugStringTableSubsection *UseStrings, + BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings, DebugChecksumsSubsection *UseChecksums) const { assert(UseStrings && UseChecksums); auto Result = @@ -331,7 +420,7 @@ std::unique_ptr YAMLLinesSubsection::toCodeViewSubsection( std::unique_ptr YAMLInlineeLinesSubsection::toCodeViewSubsection( - DebugStringTableSubsection *UseStrings, + BumpPtrAllocator &Allocator, DebugStringTableSubsection *UseStrings, DebugChecksumsSubsection *UseChecksums) const { assert(UseChecksums); auto Result = llvm::make_unique( @@ -352,7 +441,7 @@ YAMLInlineeLinesSubsection::toCodeViewSubsection( std::unique_ptr YAMLCrossModuleExportsSubsection::toCodeViewSubsection( - DebugStringTableSubsection *Strings, + BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, DebugChecksumsSubsection *Checksums) const { auto Result = llvm::make_unique(); for (const auto &M : Exports) @@ -362,7 +451,7 @@ YAMLCrossModuleExportsSubsection::toCodeViewSubsection( std::unique_ptr YAMLCrossModuleImportsSubsection::toCodeViewSubsection( - DebugStringTableSubsection *Strings, + BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, DebugChecksumsSubsection *Checksums) const { auto Result = llvm::make_unique(*Strings); for (const auto &M : Imports) { @@ -372,6 +461,47 @@ YAMLCrossModuleImportsSubsection::toCodeViewSubsection( return llvm::cast(std::move(Result)); } +std::unique_ptr YAMLSymbolsSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const { + auto Result = llvm::make_unique(); + for (const auto &Sym : Symbols) + Result->addSymbol( + Sym.toCodeViewSymbol(Allocator, CodeViewContainer::ObjectFile)); + return std::move(Result); +} + +std::unique_ptr +YAMLStringTableSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const { + auto Result = llvm::make_unique(); + for (const auto &Str : this->Strings) + Result->insert(Str); + return std::move(Result); +} + +std::unique_ptr YAMLFrameDataSubsection::toCodeViewSubsection( + BumpPtrAllocator &Allocator, DebugStringTableSubsection *Strings, + DebugChecksumsSubsection *Checksums) const { + assert(Strings); + auto Result = llvm::make_unique(); + for (const auto &YF : Frames) { + codeview::FrameData F; + F.CodeSize = YF.CodeSize; + F.Flags = YF.Flags; + F.LocalSize = YF.LocalSize; + F.MaxStackSize = YF.MaxStackSize; + F.ParamsSize = YF.ParamsSize; + F.PrologSize = YF.PrologSize; + F.RvaStart = YF.RvaStart; + F.SavedRegsSize = YF.SavedRegsSize; + F.FrameFunc = Strings->insert(YF.FrameFunc); + Result->addFrameData(F); + } + return std::move(Result); +} + static Expected convertOneChecksum(const DebugStringTableSubsectionRef &Strings, const FileChecksumEntry &CS) { @@ -503,9 +633,74 @@ YAMLCrossModuleImportsSubsection::fromCodeViewSubsection( return Result; } +Expected> +YAMLSymbolsSubsection::fromCodeViewSubsection( + const DebugSymbolsSubsectionRef &Symbols) { + auto Result = std::make_shared(); + for (const auto &Sym : Symbols) { + auto S = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym); + if (!S) + return joinErrors(make_error( + cv_error_code::corrupt_record, + "Invalid CodeView Symbol Record in SymbolRecord " + "subsection of .debug$S while converting to YAML!"), + S.takeError()); + + Result->Symbols.push_back(*S); + } + return Result; +} + +Expected> +YAMLStringTableSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings) { + auto Result = std::make_shared(); + BinaryStreamReader Reader(Strings.getBuffer()); + StringRef S; + // First item is a single null string, skip it. + if (auto EC = Reader.readCString(S)) + return std::move(EC); + assert(S.empty()); + while (Reader.bytesRemaining() > 0) { + if (auto EC = Reader.readCString(S)) + return std::move(EC); + Result->Strings.push_back(S); + } + return Result; +} + +Expected> +YAMLFrameDataSubsection::fromCodeViewSubsection( + const DebugStringTableSubsectionRef &Strings, + const DebugFrameDataSubsectionRef &Frames) { + auto Result = std::make_shared(); + for (const auto &F : Frames) { + YAMLFrameData YF; + YF.CodeSize = F.CodeSize; + YF.Flags = F.Flags; + YF.LocalSize = F.LocalSize; + YF.MaxStackSize = F.MaxStackSize; + YF.ParamsSize = F.ParamsSize; + YF.PrologSize = F.PrologSize; + YF.RvaStart = F.RvaStart; + YF.SavedRegsSize = F.SavedRegsSize; + + auto ES = Strings.getString(F.FrameFunc); + if (!ES) + return joinErrors( + make_error( + cv_error_code::no_records, + "Could not find string for string id while mapping FrameData!"), + ES.takeError()); + YF.FrameFunc = *ES; + Result->Frames.push_back(YF); + } + return Result; +} + Expected>> -llvm::CodeViewYAML::convertSubsectionList( - ArrayRef Subsections, +llvm::CodeViewYAML::toCodeViewSubsectionList( + BumpPtrAllocator &Allocator, ArrayRef Subsections, DebugStringTableSubsection &Strings) { std::vector> Result; if (Subsections.empty()) @@ -514,7 +709,8 @@ llvm::CodeViewYAML::convertSubsectionList( auto Checksums = findChecksums(Subsections); std::unique_ptr ChecksumsBase; if (Checksums) - ChecksumsBase = Checksums->toCodeViewSubsection(&Strings, nullptr); + ChecksumsBase = + Checksums->toCodeViewSubsection(Allocator, &Strings, nullptr); DebugChecksumsSubsection *CS = static_cast(ChecksumsBase.get()); for (const auto &SS : Subsections) { @@ -524,7 +720,41 @@ llvm::CodeViewYAML::convertSubsectionList( if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) CVS = std::move(ChecksumsBase); else - CVS = SS.Subsection->toCodeViewSubsection(&Strings, CS); + CVS = SS.Subsection->toCodeViewSubsection(Allocator, &Strings, CS); + assert(CVS != nullptr); + Result.push_back(std::move(CVS)); + } + return std::move(Result); +} + +Expected>> +llvm::CodeViewYAML::toCodeViewSubsectionList( + BumpPtrAllocator &Allocator, ArrayRef Subsections, + std::unique_ptr &TakeStrings, + DebugStringTableSubsection *StringsRef) { + std::vector> Result; + if (Subsections.empty()) + return std::move(Result); + + auto Checksums = findChecksums(Subsections); + + std::unique_ptr ChecksumsBase; + if (Checksums) + ChecksumsBase = + Checksums->toCodeViewSubsection(Allocator, StringsRef, nullptr); + DebugChecksumsSubsection *CS = + static_cast(ChecksumsBase.get()); + for (const auto &SS : Subsections) { + // We've already converted the checksums and string table subsection, don't + // do it twice. + std::unique_ptr CVS; + if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) + CVS = std::move(ChecksumsBase); + else if (SS.Subsection->Kind == DebugSubsectionKind::StringTable) { + assert(TakeStrings && "No string table!"); + CVS = std::move(TakeStrings); + } else + CVS = SS.Subsection->toCodeViewSubsection(Allocator, StringsRef, CS); assert(CVS != nullptr); Result.push_back(std::move(CVS)); } @@ -546,6 +776,12 @@ struct SubsectionConversionVisitor : public DebugSubsectionVisitor { const DebugSubsectionState &State) override; Error visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &Inlinees, const DebugSubsectionState &State) override; + Error visitStringTable(DebugStringTableSubsectionRef &ST, + const DebugSubsectionState &State) override; + Error visitSymbols(DebugSymbolsSubsectionRef &Symbols, + const DebugSubsectionState &State) override; + Error visitFrameData(DebugFrameDataSubsectionRef &Symbols, + const DebugSubsectionState &State) override; YAMLDebugSubsection Subsection; }; @@ -607,6 +843,34 @@ Error SubsectionConversionVisitor::visitCrossModuleImports( Subsection.Subsection = *Result; return Error::success(); } + +Error SubsectionConversionVisitor::visitStringTable( + DebugStringTableSubsectionRef &Strings, const DebugSubsectionState &State) { + auto Result = YAMLStringTableSubsection::fromCodeViewSubsection(Strings); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitSymbols( + DebugSymbolsSubsectionRef &Symbols, const DebugSubsectionState &State) { + auto Result = YAMLSymbolsSubsection::fromCodeViewSubsection(Symbols); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} + +Error SubsectionConversionVisitor::visitFrameData( + DebugFrameDataSubsectionRef &Frames, const DebugSubsectionState &State) { + auto Result = + YAMLFrameDataSubsection::fromCodeViewSubsection(State.strings(), Frames); + if (!Result) + return Result.takeError(); + Subsection.Subsection = *Result; + return Error::success(); +} } Expected YAMLDebugSubsection::fromCodeViewSubection( @@ -620,3 +884,18 @@ Expected YAMLDebugSubsection::fromCodeViewSubection( return V.Subsection; } + +std::unique_ptr +llvm::CodeViewYAML::findStringTable(ArrayRef Sections) { + for (const auto &SS : Sections) { + if (SS.Subsection->Kind != DebugSubsectionKind::StringTable) + continue; + + // String Table doesn't use the allocator. + BumpPtrAllocator Allocator; + auto Result = + SS.Subsection->toCodeViewSubsection(Allocator, nullptr, nullptr); + return llvm::cast(std::move(Result)); + } + return nullptr; +} diff --git a/lib/ObjectYAML/CodeViewYAMLTypes.cpp b/lib/ObjectYAML/CodeViewYAMLTypes.cpp index 4e82a299a67..1302b0713d0 100644 --- a/lib/ObjectYAML/CodeViewYAMLTypes.cpp +++ b/lib/ObjectYAML/CodeViewYAMLTypes.cpp @@ -20,6 +20,7 @@ #include "llvm/DebugInfo/CodeView/EnumTables.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/Support/BinaryStreamWriter.h" using namespace llvm; using namespace llvm::codeview; @@ -66,7 +67,7 @@ struct LeafRecordBase { virtual ~LeafRecordBase() {} virtual void map(yaml::IO &io) = 0; - virtual CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const = 0; + virtual CVType toCodeViewRecord(TypeTableBuilder &TTB) const = 0; virtual Error fromCodeViewRecord(CVType Type) = 0; }; @@ -80,10 +81,9 @@ template struct LeafRecordImpl : public LeafRecordBase { return TypeDeserializer::deserializeAs(Type, Record); } - CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const override { - TypeTableBuilder Table(Allocator); - Table.writeKnownType(Record); - return CVType(Kind, Table.records().front()); + CVType toCodeViewRecord(TypeTableBuilder &TTB) const override { + TTB.writeKnownType(Record); + return CVType(Kind, TTB.records().back()); } mutable T Record; @@ -93,7 +93,7 @@ template <> struct LeafRecordImpl : public LeafRecordBase { explicit LeafRecordImpl(TypeLeafKind K) : LeafRecordBase(K) {} void map(yaml::IO &io) override; - CVType toCodeViewRecord(BumpPtrAllocator &Allocator) const override; + CVType toCodeViewRecord(TypeTableBuilder &TTB) const override; Error fromCodeViewRecord(CVType Type) override; std::vector Members; @@ -440,16 +440,15 @@ Error LeafRecordImpl::fromCodeViewRecord(CVType Type) { return visitMemberRecordStream(Type.content(), V); } -CVType LeafRecordImpl::toCodeViewRecord( - BumpPtrAllocator &Allocator) const { - TypeTableBuilder TTB(Allocator); +CVType +LeafRecordImpl::toCodeViewRecord(TypeTableBuilder &TTB) const { FieldListRecordBuilder FLRB(TTB); FLRB.begin(); for (const auto &Member : Members) { Member.Member->writeTo(FLRB); } FLRB.end(true); - return CVType(Kind, TTB.records().front()); + return CVType(Kind, TTB.records().back()); } void MappingTraits::mapping(IO &io, OneMethodRecord &Record) { @@ -634,8 +633,13 @@ Expected LeafRecord::fromCodeViewRecord(CVType Type) { return make_error(cv_error_code::corrupt_record); } -CVType LeafRecord::toCodeViewRecord(BumpPtrAllocator &Allocator) const { - return Leaf->toCodeViewRecord(Allocator); +CVType LeafRecord::toCodeViewRecord(BumpPtrAllocator &Alloc) const { + TypeTableBuilder TTB(Alloc); + return Leaf->toCodeViewRecord(TTB); +} + +CVType LeafRecord::toCodeViewRecord(TypeTableBuilder &TTB) const { + return Leaf->toCodeViewRecord(TTB); } namespace llvm { -- cgit v1.2.3