Index: lld/COFF/PDB.cpp =================================================================== --- lld/COFF/PDB.cpp +++ lld/COFF/PDB.cpp @@ -83,33 +83,22 @@ } static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, - codeview::TypeTableBuilder &TypeTable, - std::vector &Data) { + codeview::TypeTableBuilder &TypeTable) { // 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()); + // FIXME: Hash types. + TpiBuilder.addTypeRecord(Rec, None); }); - - 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) { + codeview::TypeTableBuilder &TypeTable, + codeview::TypeTableBuilder &IDTable) { // Visit all .debug$T sections to add them to Builder. - codeview::TypeTableBuilder IDTable(BAlloc); - codeview::TypeTableBuilder TypeTable(BAlloc); for (ObjectFile *File : Symtab->ObjectFiles) { ArrayRef Data = getDebugSection(File, ".debug$T"); if (Data.empty()) @@ -132,10 +121,10 @@ } // Construct TPI stream contents. - addTypeInfo(Builder.getTpiBuilder(), TypeTable, TpiData); + addTypeInfo(Builder.getTpiBuilder(), TypeTable); // Construct IPI stream contents. - addTypeInfo(Builder.getIpiBuilder(), IDTable, IpiData); + addTypeInfo(Builder.getIpiBuilder(), IDTable); } static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) { @@ -213,9 +202,9 @@ auto &DbiBuilder = Builder.getDbiBuilder(); DbiBuilder.setVersionHeader(pdb::PdbDbiV110); - std::vector TpiData; - std::vector IpiData; - mergeDebugT(Symtab, Builder, TpiData, IpiData); + codeview::TypeTableBuilder TypeTable(BAlloc); + codeview::TypeTableBuilder IDTable(BAlloc); + mergeDebugT(Symtab, Builder, TypeTable, IDTable); // Add Section Contributions. std::vector Contribs = Index: llvm/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h =================================================================== --- llvm/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h +++ llvm/include/llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h @@ -53,7 +53,7 @@ TpiStreamBuilder &operator=(const TpiStreamBuilder &) = delete; void setVersionHeader(PdbRaw_TpiVer Version); - void addTypeRecord(const codeview::CVType &Record); + void addTypeRecord(ArrayRef Type, Optional Hash); Error finalizeMsfLayout(); @@ -68,9 +68,11 @@ msf::MSFBuilder &Msf; BumpPtrAllocator &Allocator; + size_t TypeRecordBytes = 0; + Optional VerHeader; - std::vector TypeRecords; - BinaryItemStream TypeRecordStream; + std::vector> TypeRecords; + std::vector TypeHashes; uint32_t HashStreamIndex = kInvalidStreamIndex; std::unique_ptr HashValueStream; Index: llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp =================================================================== --- llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp +++ llvm/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp @@ -34,8 +34,7 @@ using namespace llvm::support; TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf, uint32_t StreamIdx) - : Msf(Msf), Allocator(Msf.getAllocator()), - TypeRecordStream(llvm::support::little), Header(nullptr), Idx(StreamIdx) { + : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) { } TpiStreamBuilder::~TpiStreamBuilder() = default; @@ -44,9 +43,12 @@ VerHeader = Version; } -void TpiStreamBuilder::addTypeRecord(const codeview::CVType &Record) { +void TpiStreamBuilder::addTypeRecord(ArrayRef Record, + Optional Hash) { + TypeRecordBytes += Record.size(); TypeRecords.push_back(Record); - TypeRecordStream.setItems(TypeRecords); + if (Hash) + TypeHashes.push_back(*Hash); } Error TpiStreamBuilder::finalize() { @@ -62,7 +64,7 @@ H->HeaderSize = sizeof(TpiStreamHeader); H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex; H->TypeIndexEnd = H->TypeIndexBegin + Count; - H->TypeRecordBytes = TypeRecordStream.getLength(); + H->TypeRecordBytes = TypeRecordBytes; H->HashStreamIndex = HashStreamIndex; H->HashAuxStreamIndex = kInvalidStreamIndex; @@ -84,13 +86,13 @@ } uint32_t TpiStreamBuilder::calculateSerializedLength() { - return sizeof(TpiStreamHeader) + TypeRecordStream.getLength(); + return sizeof(TpiStreamHeader) + TypeRecordBytes; } uint32_t TpiStreamBuilder::calculateHashBufferSize() const { - if (TypeRecords.empty() || !TypeRecords[0].Hash.hasValue()) - return 0; - return TypeRecords.size() * sizeof(ulittle32_t); + assert(TypeHashes.size() == TypeHashes.size() && + "either all or no type records should have hashes"); + return TypeHashes.size() * sizeof(ulittle32_t); } Error TpiStreamBuilder::finalizeMsfLayout() { @@ -107,10 +109,10 @@ if (!ExpectedIndex) return ExpectedIndex.takeError(); HashStreamIndex = *ExpectedIndex; - ulittle32_t *H = Allocator.Allocate(TypeRecords.size()); - MutableArrayRef HashBuffer(H, TypeRecords.size()); - for (uint32_t I = 0; I < TypeRecords.size(); ++I) { - HashBuffer[I] = *TypeRecords[I].Hash % MinTpiHashBuckets; + ulittle32_t *H = Allocator.Allocate(TypeHashes.size()); + MutableArrayRef HashBuffer(H, TypeHashes.size()); + for (uint32_t I = 0; I < TypeHashes.size(); ++I) { + HashBuffer[I] = TypeHashes[I] % MinTpiHashBuckets; } ArrayRef Bytes(reinterpret_cast(HashBuffer.data()), HashBufferSize); @@ -131,9 +133,9 @@ if (auto EC = Writer.writeObject(*Header)) return EC; - auto RecordArray = VarStreamArray(TypeRecordStream); - if (auto EC = Writer.writeArray(RecordArray)) - return EC; + for (auto Rec : TypeRecords) + if (auto EC = Writer.writeBytes(Rec)) + return EC; if (HashStreamIndex != kInvalidStreamIndex) { auto HVS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer, Index: llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp =================================================================== --- llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -436,13 +436,13 @@ const auto &Tpi = YamlObj.TpiStream.getValueOr(DefaultTpiStream); TpiBuilder.setVersionHeader(Tpi.Version); for (const auto &R : Tpi.Records) - TpiBuilder.addTypeRecord(R.Record); + TpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash); const auto &Ipi = YamlObj.IpiStream.getValueOr(DefaultTpiStream); auto &IpiBuilder = Builder.getIpiBuilder(); IpiBuilder.setVersionHeader(Ipi.Version); for (const auto &R : Ipi.Records) - IpiBuilder.addTypeRecord(R.Record); + TpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash); ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile)); }