Index: lld/trunk/COFF/PDB.cpp =================================================================== --- lld/trunk/COFF/PDB.cpp +++ lld/trunk/COFF/PDB.cpp @@ -82,18 +82,40 @@ return Data.slice(4); } -// Merge .debug$T sections and returns it. -static std::vector mergeDebugT(SymbolTable *Symtab) { - ScopedPrinter W(outs()); +static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, + codeview::TypeTableBuilder &TypeTable, + std::vector &Data) { + // Start the TPI or IPI stream header. + TpiBuilder.setVersionHeader(pdb::PdbTpiV80); + + // Flatten the in memory type table. + // FIXME: Avoid this copy. + TypeTable.ForEachRecord([&](TypeIndex TI, ArrayRef Rec) { + Data.insert(Data.end(), Rec.begin(), Rec.end()); + }); + BinaryByteStream Stream(Data, support::little); + codeview::CVTypeArray Records; + BinaryStreamReader Reader(Stream); + if (auto EC = Reader.readArray(Records, Reader.getLength())) + fatal(EC, "Reader.readArray failed"); + for (const codeview::CVType &Rec : Records) + TpiBuilder.addTypeRecord(Rec); +} + +// Merge .debug$T sections into IpiData and TpiData. +static void mergeDebugT(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder, + std::vector &TpiData, + std::vector &IpiData) { // Visit all .debug$T sections to add them to Builder. - codeview::TypeTableBuilder Builder(BAlloc); + codeview::TypeTableBuilder IDTable(BAlloc); + codeview::TypeTableBuilder TypeTable(BAlloc); for (ObjectFile *File : Symtab->ObjectFiles) { ArrayRef Data = getDebugSection(File, ".debug$T"); if (Data.empty()) continue; - BinaryByteStream Stream(Data, llvm::support::little); + BinaryByteStream Stream(Data, support::little); codeview::CVTypeArray Types; BinaryStreamReader Reader(Stream); // Follow type servers. If the same type server is encountered more than @@ -104,16 +126,16 @@ Handler.addSearchPath(llvm::sys::path::parent_path(File->getName())); if (auto EC = Reader.readArray(Types, Reader.getLength())) fatal(EC, "Reader::readArray failed"); - if (auto Err = codeview::mergeTypeStreams(Builder, &Handler, Types)) + if (auto Err = + codeview::mergeTypeStreams(IDTable, TypeTable, &Handler, Types)) fatal(Err, "codeview::mergeTypeStreams failed"); } - // Construct section contents. - std::vector V; - Builder.ForEachRecord([&](TypeIndex TI, ArrayRef Rec) { - V.insert(V.end(), Rec.begin(), Rec.end()); - }); - return V; + // Construct TPI stream contents. + addTypeInfo(Builder.getTpiBuilder(), TypeTable, TpiData); + + // Construct IPI stream contents. + addTypeInfo(Builder.getIpiBuilder(), IDTable, IpiData); } static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) { @@ -159,17 +181,6 @@ } } -static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, - ArrayRef Data) { - BinaryByteStream Stream(Data, llvm::support::little); - codeview::CVTypeArray Records; - BinaryStreamReader Reader(Stream); - if (auto EC = Reader.readArray(Records, Reader.getLength())) - fatal(EC, "Reader.readArray failed"); - for (const codeview::CVType &Rec : Records) - TpiBuilder.addTypeRecord(Rec); -} - // Creates a PDB file. void coff::createPDB(StringRef Path, SymbolTable *Symtab, ArrayRef SectionTable, @@ -202,18 +213,9 @@ auto &DbiBuilder = Builder.getDbiBuilder(); DbiBuilder.setVersionHeader(pdb::PdbDbiV110); - // Add an empty TPI stream. - auto &TpiBuilder = Builder.getTpiBuilder(); - TpiBuilder.setVersionHeader(pdb::PdbTpiV80); std::vector TpiData; - if (Config->DebugPdb) { - TpiData = mergeDebugT(Symtab); - addTypeInfo(TpiBuilder, TpiData); - } - - // Add an empty IPI stream. - auto &IpiBuilder = Builder.getIpiBuilder(); - IpiBuilder.setVersionHeader(pdb::PdbTpiV80); + std::vector IpiData; + mergeDebugT(Symtab, Builder, TpiData, IpiData); // Add Section Contributions. std::vector Contribs = Index: lld/trunk/test/COFF/pdb.test =================================================================== --- lld/trunk/test/COFF/pdb.test +++ lld/trunk/test/COFF/pdb.test @@ -60,6 +60,9 @@ # CHECK-NEXT: Options: [ None ] # CHECK-NEXT: ParameterCount: 0 # CHECK-NEXT: ArgumentList: 4099 +# CHECK-NEXT: IpiStream: +# CHECK-NEXT: Version: VC80 +# CHECK-NEXT: Records: # CHECK-NEXT: - Kind: LF_FUNC_ID # CHECK-NEXT: FuncId: # CHECK-NEXT: ParentScope: 0 @@ -84,10 +87,10 @@ # CHECK-NEXT: String: '-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"' # CHECK-NEXT: - Kind: LF_SUBSTR_LIST # CHECK-NEXT: StringList: -# CHECK-NEXT: StringIndices: [ 4105 ] +# CHECK-NEXT: StringIndices: [ 4100 ] # CHECK-NEXT: - Kind: LF_STRING_ID # CHECK-NEXT: StringId: -# CHECK-NEXT: Id: 4106 +# CHECK-NEXT: Id: 4101 # CHECK-NEXT: String: ' -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X' # CHECK-NEXT: - Kind: LF_STRING_ID # CHECK-NEXT: StringId: @@ -99,17 +102,14 @@ # CHECK-NEXT: String: 'D:\b\vc140.pdb' # CHECK-NEXT: - Kind: LF_BUILDINFO # CHECK-NEXT: BuildInfo: -# CHECK-NEXT: ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ] +# CHECK-NEXT: ArgIndices: [ 4098, 4099, 4103, 4104, 4102 ] # CHECK-NEXT: - Kind: LF_STRING_ID # CHECK-NEXT: StringId: # CHECK-NEXT: Id: 0 # CHECK-NEXT: String: ret42-sub.c # CHECK-NEXT: - Kind: LF_BUILDINFO # CHECK-NEXT: BuildInfo: -# CHECK-NEXT: ArgIndices: [ 4103, 4104, 4111, 4109, 4107 ] -# CHECK-NEXT: IpiStream: -# CHECK-NEXT: Version: VC80 -# CHECK-NEXT: Records: +# CHECK-NEXT: ArgIndices: [ 4098, 4099, 4106, 4104, 4102 ] # RAW: FileHeaders { # RAW-NEXT: BlockSize: 4096 Index: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -21,8 +21,9 @@ class TypeServerHandler; /// Merges one type stream into another. Returns true on success. -Error mergeTypeStreams(TypeTableBuilder &DestStream, TypeServerHandler *Handler, - const CVTypeArray &Types); +Error mergeTypeStreams(TypeTableBuilder &DestIdStream, + TypeTableBuilder &DestTypeStream, + TypeServerHandler *Handler, const CVTypeArray &Types); } // end namespace codeview } // end namespace llvm Index: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -52,11 +52,17 @@ /// - If the type record already exists in the destination stream, discard it /// and update the type index map to forward the source type index to the /// existing destination type index. +/// +/// As an additional complication, type stream merging actually produces two +/// streams: an item (or IPI) stream and a type stream, as this is what is +/// actually stored in the final PDB. We choose which records go where by +/// looking at the record kind. class TypeStreamMerger : public TypeVisitorCallbacks { public: - TypeStreamMerger(TypeTableBuilder &DestStream, TypeServerHandler *Handler) - : DestStream(DestStream), FieldListBuilder(DestStream), Handler(Handler) { - } + TypeStreamMerger(TypeTableBuilder &DestIdStream, + TypeTableBuilder &DestTypeStream, TypeServerHandler *Handler) + : DestIdStream(DestIdStream), DestTypeStream(DestTypeStream), + FieldListBuilder(DestTypeStream), Handler(Handler) {} /// TypeVisitorCallbacks overrides. #define TYPE_RECORD(EnumName, EnumVal, Name) \ @@ -85,7 +91,18 @@ std::move(*LastError), llvm::make_error(cv_error_code::corrupt_record)); } - IndexMap.push_back(DestStream.writeKnownType(R)); + IndexMap.push_back(DestTypeStream.writeKnownType(R)); + return Error::success(); + } + + template + Error writeIdRecord(RecordType &R, bool RemapSuccess) { + if (!RemapSuccess) { + LastError = joinErrors( + std::move(*LastError), + llvm::make_error(cv_error_code::corrupt_record)); + } + IndexMap.push_back(DestIdStream.writeKnownType(R)); return Error::success(); } @@ -104,7 +121,8 @@ BumpPtrAllocator Allocator; - TypeTableBuilder &DestStream; + TypeTableBuilder &DestIdStream; + TypeTableBuilder &DestTypeStream; FieldListRecordBuilder FieldListBuilder; TypeServerHandler *Handler; @@ -158,6 +176,62 @@ return false; } +//----------------------------------------------------------------------------// +// Item records +//----------------------------------------------------------------------------// + +Error TypeStreamMerger::visitKnownRecord(CVType &, FuncIdRecord &R) { + bool Success = true; + Success &= remapIndex(R.ParentScope); + Success &= remapIndex(R.FunctionType); + return writeIdRecord(R, Success); +} + +Error TypeStreamMerger::visitKnownRecord(CVType &, MemberFuncIdRecord &R) { + bool Success = true; + Success &= remapIndex(R.ClassType); + Success &= remapIndex(R.FunctionType); + return writeIdRecord(R, Success); +} + +Error TypeStreamMerger::visitKnownRecord(CVType &, StringIdRecord &R) { + return writeIdRecord(R, remapIndex(R.Id)); +} + +Error TypeStreamMerger::visitKnownRecord(CVType &, StringListRecord &R) { + bool Success = true; + for (TypeIndex &Str : R.StringIndices) + Success &= remapIndex(Str); + return writeIdRecord(R, Success); +} + +Error TypeStreamMerger::visitKnownRecord(CVType &, BuildInfoRecord &R) { + bool Success = true; + for (TypeIndex &Arg : R.ArgIndices) + Success &= remapIndex(Arg); + return writeIdRecord(R, Success); +} + +Error TypeStreamMerger::visitKnownRecord(CVType &, UdtSourceLineRecord &R) { + bool Success = true; + Success &= remapIndex(R.UDT); + Success &= remapIndex(R.SourceFile); + // FIXME: Translate UdtSourceLineRecord into UdtModSourceLineRecords in the + // IPI stream. + return writeIdRecord(R, Success); +} + +Error TypeStreamMerger::visitKnownRecord(CVType &, UdtModSourceLineRecord &R) { + bool Success = true; + Success &= remapIndex(R.UDT); + Success &= remapIndex(R.SourceFile); + return writeIdRecord(R, Success); +} + +//----------------------------------------------------------------------------// +// Type records +//----------------------------------------------------------------------------// + Error TypeStreamMerger::visitKnownRecord(CVType &, ModifierRecord &R) { return writeRecord(R, remapIndex(R.ModifiedType)); } @@ -178,13 +252,6 @@ return writeRecord(R, Success); } -Error TypeStreamMerger::visitKnownRecord(CVType &, MemberFuncIdRecord &R) { - bool Success = true; - Success &= remapIndex(R.ClassType); - Success &= remapIndex(R.FunctionType); - return writeRecord(R, Success); -} - Error TypeStreamMerger::visitKnownRecord(CVType &, ArgListRecord &R) { bool Success = true; for (TypeIndex &Arg : R.ArgIndices) @@ -192,13 +259,6 @@ return writeRecord(R, Success); } -Error TypeStreamMerger::visitKnownRecord(CVType &, StringListRecord &R) { - bool Success = true; - for (TypeIndex &Str : R.StringIndices) - Success &= remapIndex(Str); - return writeRecord(R, Success); -} - Error TypeStreamMerger::visitKnownRecord(CVType &, PointerRecord &R) { bool Success = true; Success &= remapIndex(R.ReferentType); @@ -245,38 +305,6 @@ return writeRecord(R, true); } -Error TypeStreamMerger::visitKnownRecord(CVType &, StringIdRecord &R) { - return writeRecord(R, remapIndex(R.Id)); -} - -Error TypeStreamMerger::visitKnownRecord(CVType &, FuncIdRecord &R) { - bool Success = true; - Success &= remapIndex(R.ParentScope); - Success &= remapIndex(R.FunctionType); - return writeRecord(R, Success); -} - -Error TypeStreamMerger::visitKnownRecord(CVType &, UdtSourceLineRecord &R) { - bool Success = true; - Success &= remapIndex(R.UDT); - Success &= remapIndex(R.SourceFile); - return writeRecord(R, Success); -} - -Error TypeStreamMerger::visitKnownRecord(CVType &, UdtModSourceLineRecord &R) { - bool Success = true; - Success &= remapIndex(R.UDT); - Success &= remapIndex(R.SourceFile); - return writeRecord(R, Success); -} - -Error TypeStreamMerger::visitKnownRecord(CVType &, BuildInfoRecord &R) { - bool Success = true; - for (TypeIndex &Arg : R.ArgIndices) - Success &= remapIndex(Arg); - return writeRecord(R, Success); -} - Error TypeStreamMerger::visitKnownRecord(CVType &, VFTableRecord &R) { bool Success = true; Success &= remapIndex(R.CompleteClass); @@ -300,6 +328,10 @@ return Error::success(); } +//----------------------------------------------------------------------------// +// Member records +//----------------------------------------------------------------------------// + Error TypeStreamMerger::visitKnownMember(CVMemberRecord &, NestedTypeRecord &R) { return writeMember(R, remapIndex(R.Type)); @@ -381,8 +413,10 @@ return Ret; } -Error llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestStream, +Error llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestIdStream, + TypeTableBuilder &DestTypeStream, TypeServerHandler *Handler, const CVTypeArray &Types) { - return TypeStreamMerger(DestStream, Handler).mergeStream(Types); + return TypeStreamMerger(DestIdStream, DestTypeStream, Handler) + .mergeStream(Types); } Index: llvm/trunk/test/tools/llvm-readobj/codeview-merging.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/codeview-merging.test +++ llvm/trunk/test/tools/llvm-readobj/codeview-merging.test @@ -21,6 +21,15 @@ RUN: llvm-readobj -codeview %S/Inputs/codeview-merging-2.obj | FileCheck %s --check-prefix=OBJ2 RUN: llvm-readobj -codeview-merged-types %S/Inputs/codeview-merging-1.obj %S/Inputs/codeview-merging-2.obj | FileCheck %s +OBJ1: Procedure ({{.*}}) { +OBJ1-NEXT: TypeLeafKind: LF_PROCEDURE (0x1008) +OBJ1-NEXT: ReturnType: int (0x74) +OBJ1-NEXT: CallingConvention: NearC (0x0) +OBJ1-NEXT: FunctionOptions [ (0x0) +OBJ1-NEXT: ] +OBJ1-NEXT: NumParameters: 1 +OBJ1-NEXT: ArgListType: (A*) (0x1002) +OBJ1-NEXT: } OBJ1: FuncId (0x100D) { OBJ1-NEXT: TypeLeafKind: LF_FUNC_ID (0x1601) OBJ1-NEXT: ParentScope: 0x0 @@ -50,16 +59,55 @@ OBJ2-NEXT: } OBJ2-NOT: FuncId -CHECK: FuncId (0x100D) { +CHECK: MergedTypeStream [ +CHECK: Procedure ({{.*}}) { +CHECK-NEXT: TypeLeafKind: LF_PROCEDURE (0x1008) +CHECK-NEXT: ReturnType: int (0x74) +CHECK-NEXT: CallingConvention: NearC (0x0) +CHECK-NEXT: FunctionOptions [ (0x0) +CHECK-NEXT: ] +CHECK-NEXT: NumParameters: 1 +CHECK-NEXT: ArgListType: (A*) (0x1002) +CHECK-NEXT: } +CHECK: Struct (0x1007) { +CHECK-NEXT: TypeLeafKind: LF_STRUCTURE (0x1505) +CHECK-NEXT: MemberCount: 1 +CHECK-NEXT: Properties [ (0x200) +CHECK-NEXT: HasUniqueName (0x200) +CHECK-NEXT: ] +CHECK-NEXT: FieldList: (0x1006) +CHECK-NEXT: DerivedFrom: 0x0 +CHECK-NEXT: VShape: 0x0 +CHECK-NEXT: SizeOf: 8 +CHECK-NEXT: Name: B +CHECK-NEXT: LinkageName: .?AUB@@ +CHECK-NEXT: } +CHECK: ] + +CHECK: MergedIDStream [ +CHECK-NEXT: StringId (0x1000) { +CHECK-NEXT: TypeLeafKind: LF_STRING_ID (0x1605) +CHECK-NEXT: Id: 0x0 +CHECK-NEXT: StringData: d:\src\llvm\build\t.cpp +CHECK-NEXT: } +# Test that we contextually dump item ids and type ids from different databases. +CHECK-NEXT: UdtSourceLine (0x1001) { +CHECK-NEXT: TypeLeafKind: LF_UDT_SRC_LINE (0x1606) +CHECK-NEXT: UDT: B (0x1007) +CHECK-NEXT: SourceFile: d:\src\llvm\build\t.cpp (0x1000) +CHECK-NEXT: LineNumber: 3 +CHECK-NEXT: } +CHECK: FuncId (0x1002) { CHECK-NEXT: TypeLeafKind: LF_FUNC_ID (0x1601) CHECK-NEXT: ParentScope: 0x0 -CHECK-NEXT: FunctionType: int (B*) (0x100C) +CHECK-NEXT: FunctionType: int (B*) CHECK-NEXT: Name: g CHECK-NEXT: } -CHECK-NEXT: FuncId (0x100E) { +CHECK-NEXT: FuncId (0x1003) { CHECK-NEXT: TypeLeafKind: LF_FUNC_ID (0x1601) CHECK-NEXT: ParentScope: 0x0 -CHECK-NEXT: FunctionType: int (A*) (0x1003) +CHECK-NEXT: FunctionType: int (A*) CHECK-NEXT: Name: f CHECK-NEXT: } CHECK-NOT: FuncId +CHECK: ] Index: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp +++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp @@ -79,7 +79,8 @@ void printCOFFBaseReloc() override; void printCOFFDebugDirectory() override; void printCodeViewDebugInfo() override; - void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVTypes) override; + void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs, + llvm::codeview::TypeTableBuilder &CVTypes) override; void printStackMap() const override; private: void printSymbol(const SymbolRef &Sym); @@ -1064,7 +1065,8 @@ W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset); } -void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVTypes) { +void COFFDumper::mergeCodeViewTypes(TypeTableBuilder &CVIDs, + TypeTableBuilder &CVTypes) { for (const SectionRef &S : Obj->sections()) { StringRef SectionName; error(S.getName(SectionName)); @@ -1086,7 +1088,7 @@ error(object_error::parse_failed); } - if (auto EC = mergeTypeStreams(CVTypes, nullptr, Types)) { + if (auto EC = mergeTypeStreams(CVIDs, CVTypes, nullptr, Types)) { consumeError(std::move(EC)); return error(object_error::parse_failed); } @@ -1551,20 +1553,43 @@ } void llvm::dumpCodeViewMergedTypes(ScopedPrinter &Writer, + llvm::codeview::TypeTableBuilder &IDTable, llvm::codeview::TypeTableBuilder &CVTypes) { // Flatten it first, then run our dumper on it. - ListScope S(Writer, "MergedTypeStream"); - SmallString<0> Buf; + SmallString<0> TypeBuf; CVTypes.ForEachRecord([&](TypeIndex TI, ArrayRef Record) { - Buf.append(Record.begin(), Record.end()); + TypeBuf.append(Record.begin(), Record.end()); }); TypeDatabase TypeDB; - CVTypeDumper CVTD(TypeDB); - TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes); - if (auto EC = - CVTD.dump({Buf.str().bytes_begin(), Buf.str().bytes_end()}, TDV)) { - Writer.flush(); - error(llvm::errorToErrorCode(std::move(EC))); + { + ListScope S(Writer, "MergedTypeStream"); + CVTypeDumper CVTD(TypeDB); + TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes); + if (auto EC = CVTD.dump( + {TypeBuf.str().bytes_begin(), TypeBuf.str().bytes_end()}, TDV)) { + Writer.flush(); + error(llvm::errorToErrorCode(std::move(EC))); + } + } + + // Flatten the id stream and print it next. The ID stream refers to names from + // the type stream. + SmallString<0> IDBuf; + IDTable.ForEachRecord([&](TypeIndex TI, ArrayRef Record) { + IDBuf.append(Record.begin(), Record.end()); + }); + + { + ListScope S(Writer, "MergedIDStream"); + TypeDatabase IDDB; + CVTypeDumper CVTD(IDDB); + TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes); + TDV.setItemDB(IDDB); + if (auto EC = CVTD.dump( + {IDBuf.str().bytes_begin(), IDBuf.str().bytes_end()}, TDV)) { + Writer.flush(); + error(llvm::errorToErrorCode(std::move(EC))); + } } } Index: llvm/trunk/tools/llvm-readobj/ObjDumper.h =================================================================== --- llvm/trunk/tools/llvm-readobj/ObjDumper.h +++ llvm/trunk/tools/llvm-readobj/ObjDumper.h @@ -68,7 +68,8 @@ virtual void printCOFFBaseReloc() { } virtual void printCOFFDebugDirectory() { } virtual void printCodeViewDebugInfo() { } - virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVTypes) {} + virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs, + llvm::codeview::TypeTableBuilder &CVTypes) {} // Only implemented for MachO. virtual void printMachODataInCode() { } @@ -103,7 +104,8 @@ void dumpCOFFImportFile(const object::COFFImportFile *File); void dumpCodeViewMergedTypes(ScopedPrinter &Writer, - llvm::codeview::TypeTableBuilder &CVTypes); + llvm::codeview::TypeTableBuilder &IDTable, + llvm::codeview::TypeTableBuilder &TypeTable); } // namespace llvm Index: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp +++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp @@ -338,10 +338,12 @@ } namespace { struct ReadObjTypeTableBuilder { - ReadObjTypeTableBuilder() : Allocator(), Builder(Allocator) {} + ReadObjTypeTableBuilder() + : Allocator(), IDTable(Allocator), TypeTable(Allocator) {} llvm::BumpPtrAllocator Allocator; - llvm::codeview::TypeTableBuilder Builder; + llvm::codeview::TypeTableBuilder IDTable; + llvm::codeview::TypeTableBuilder TypeTable; }; } static ReadObjTypeTableBuilder CVTypes; @@ -446,7 +448,7 @@ if (opts::CodeView) Dumper->printCodeViewDebugInfo(); if (opts::CodeViewMergedTypes) - Dumper->mergeCodeViewTypes(CVTypes.Builder); + Dumper->mergeCodeViewTypes(CVTypes.IDTable, CVTypes.TypeTable); } if (Obj->isMachO()) { if (opts::MachODataInCode) @@ -551,7 +553,7 @@ if (opts::CodeViewMergedTypes) { ScopedPrinter W(outs()); - dumpCodeViewMergedTypes(W, CVTypes.Builder); + dumpCodeViewMergedTypes(W, CVTypes.IDTable, CVTypes.TypeTable); } return 0;