Index: lld/trunk/COFF/PDB.cpp =================================================================== --- lld/trunk/COFF/PDB.cpp +++ lld/trunk/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 Err = codeview::mergeTypeStreams(Builder, Types)) + fatal(Err, "codeview::mergeTypeStreams failed"); } // Construct section contents. 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 @@ -13,12 +13,13 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/Support/Error.h" namespace llvm { 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/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ llvm/trunk/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,15 @@ 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 = joinErrors( + std::move(*LastError), + llvm::make_error(cv_error_code::corrupt_record)); IndexMap.push_back(DestStream.writeKnownType(Record)); return Error::success(); } @@ -94,14 +95,15 @@ template Error visitKnownMemberRecordImpl(RecordType &Record) { - FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap); + if (!Record.remapTypeIndices(IndexMap)) + LastError = joinErrors( + std::move(*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,9 +165,10 @@ 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; + LastError = Error::success(); TypeDeserializer Deserializer; Pipeline.addCallbackToPipeline(Deserializer); @@ -173,15 +176,16 @@ 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(); + + Error Ret = std::move(*LastError); + LastError.reset(); + return Ret; } -bool llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestStream, - const CVTypeArray &Types) { +Error llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestStream, + const CVTypeArray &Types) { return TypeStreamMerger(DestStream).mergeStream(Types); }