Index: lld/COFF/PDB.cpp =================================================================== --- lld/COFF/PDB.cpp +++ lld/COFF/PDB.cpp @@ -96,8 +96,8 @@ msf::StreamReader Reader(Stream); if (auto EC = Reader.readArray(Types, Reader.getLength())) fatal(EC, "Reader::readArray failed"); - if (!codeview::mergeTypeStreams(Builder, Types)) - fatal("codeview::mergeTypeStreams failed"); + if (auto EC = codeview::mergeTypeStreams(Builder, Types)) + fatal(EC, "codeview::mergeTypeStreams failed"); } // Construct section contents. Index: llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -18,7 +18,7 @@ namespace codeview { /// Merges one type stream into another. Returns true on success. -bool mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types); +Error mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types); } // end namespace codeview } // end namespace llvm Index: llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -55,9 +55,7 @@ class TypeStreamMerger : public TypeVisitorCallbacks { public: TypeStreamMerger(TypeTableBuilder &DestStream) - : DestStream(DestStream), FieldListBuilder(DestStream) { - assert(!hadError()); - } + : DestStream(DestStream), FieldListBuilder(DestStream) {} /// TypeVisitorCallbacks overrides. #define TYPE_RECORD(EnumName, EnumVal, Name) \ @@ -74,12 +72,14 @@ Error visitTypeEnd(CVType &Record) override; Error visitMemberEnd(CVMemberRecord &Record) override; - bool mergeStream(const CVTypeArray &Types); + Error mergeStream(const CVTypeArray &Types); private: template Error visitKnownRecordImpl(RecordType &Record) { - FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap); + if (!Record.remapTypeIndices(IndexMap)) + LastError = + llvm::make_error(cv_error_code::corrupt_record); IndexMap.push_back(DestStream.writeKnownType(Record)); return Error::success(); } @@ -94,14 +94,14 @@ template Error visitKnownMemberRecordImpl(RecordType &Record) { - FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap); + if (!Record.remapTypeIndices(IndexMap)) + LastError = + llvm::make_error(cv_error_code::corrupt_record); FieldListBuilder.writeMemberType(Record); return Error::success(); } - bool hadError() { return FoundBadTypeIndex; } - - bool FoundBadTypeIndex = false; + Optional LastError; BumpPtrAllocator Allocator; @@ -163,7 +163,7 @@ return llvm::make_error(cv_error_code::corrupt_record); } -bool TypeStreamMerger::mergeStream(const CVTypeArray &Types) { +Error TypeStreamMerger::mergeStream(const CVTypeArray &Types) { assert(IndexMap.empty()); TypeVisitorCallbackPipeline Pipeline; @@ -173,15 +173,19 @@ CVTypeVisitor Visitor(Pipeline); - if (auto EC = Visitor.visitTypeStream(Types)) { - consumeError(std::move(EC)); - return false; - } + if (auto EC = Visitor.visitTypeStream(Types)) + return EC; IndexMap.clear(); - return !hadError(); + + if (LastError.hasValue()) { + Error E = std::move(*LastError); + LastError.reset(); + return E; + } + return Error::success(); } -bool llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestStream, - const CVTypeArray &Types) { +Error llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestStream, + const CVTypeArray &Types) { return TypeStreamMerger(DestStream).mergeStream(Types); }