https://github.com/mafeguimaraes updated https://github.com/llvm/llvm-project/pull/183812
From f3feb320c274bf2823b6804d97bd3cc478c774fe Mon Sep 17 00:00:00 2001 From: mafeguimaraes <[email protected]> Date: Fri, 27 Feb 2026 16:10:44 -0300 Subject: [PATCH] [APINotes] Refactor APINotesReader to propagate llvm::Error instead of dropping it --- clang/include/clang/APINotes/APINotesReader.h | 7 +- clang/lib/APINotes/APINotesManager.cpp | 15 +- clang/lib/APINotes/APINotesReader.cpp | 836 +++++++++--------- 3 files changed, 447 insertions(+), 411 deletions(-) diff --git a/clang/include/clang/APINotes/APINotesReader.h b/clang/include/clang/APINotes/APINotesReader.h index baf6334064024..7151c7fc90fd8 100644 --- a/clang/include/clang/APINotes/APINotesReader.h +++ b/clang/include/clang/APINotes/APINotesReader.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_APINOTES_READER_H #include "clang/APINotes/Types.h" +#include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/VersionTuple.h" #include <memory> @@ -30,14 +31,14 @@ class APINotesReader { std::unique_ptr<Implementation> Implementation; APINotesReader(llvm::MemoryBuffer *InputBuffer, - llvm::VersionTuple SwiftVersion, bool &Failed); + llvm::VersionTuple SwiftVersion, llvm::Error &Err); public: /// Create a new API notes reader from the given member buffer, which /// contains the contents of a binary API notes file. /// - /// \returns the new API notes reader, or null if an error occurred. - static std::unique_ptr<APINotesReader> + /// \returns the new API notes reader, or an error if one occurred. + static llvm::Expected<std::unique_ptr<APINotesReader>> Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer, llvm::VersionTuple SwiftVersion); diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index 60868ab104c46..acb84c3949cb1 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -98,8 +98,11 @@ APINotesManager::loadAPINotes(FileEntryRef APINotesFile) { // Load the binary form we just compiled. auto Reader = APINotesReader::Create(std::move(CompiledBuffer), SwiftVersion); - assert(Reader && "Could not load the API notes we just generated?"); - return Reader; + if (!Reader) { + llvm::consumeError(Reader.takeError()); + return nullptr; + } + return std::move(Reader.get()); } std::unique_ptr<APINotesReader> @@ -118,9 +121,13 @@ APINotesManager::loadAPINotes(StringRef Buffer) { CompiledBuffer = llvm::MemoryBuffer::getMemBufferCopy( StringRef(APINotesBuffer.data(), APINotesBuffer.size())); + auto Reader = APINotesReader::Create(std::move(CompiledBuffer), SwiftVersion); - assert(Reader && "Could not load the API notes we just generated?"); - return Reader; + if (!Reader) { + llvm::consumeError(Reader.takeError()); + return nullptr; + } + return std::move(Reader.get()); } bool APINotesManager::loadAPINotes(const DirectoryEntry *HeaderDir, diff --git a/clang/lib/APINotes/APINotesReader.cpp b/clang/lib/APINotes/APINotesReader.cpp index 7f9bb5f12cda7..d01d70f0736b9 100644 --- a/clang/lib/APINotes/APINotesReader.cpp +++ b/clang/lib/APINotes/APINotesReader.cpp @@ -782,32 +782,32 @@ class APINotesReader::Implementation { /// optional if the string is unknown. std::optional<SelectorID> getSelector(ObjCSelectorRef Selector); - bool readControlBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readIdentifierBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readContextBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readObjCPropertyBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readObjCMethodBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readCXXMethodBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readFieldBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readObjCSelectorBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readGlobalVariableBlock(llvm::BitstreamCursor &Cursor, + llvm::Error readControlBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor, + llvm::Error readIdentifierBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readContextBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readEnumConstantBlock(llvm::BitstreamCursor &Cursor, + llvm::Error readObjCPropertyBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readObjCMethodBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readCXXMethodBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readFieldBlock(llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readTagBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); - bool readTypedefBlock(llvm::BitstreamCursor &Cursor, - llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readObjCSelectorBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readGlobalVariableBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readGlobalFunctionBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readEnumConstantBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readTagBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); + llvm::Error readTypedefBlock(llvm::BitstreamCursor &Cursor, + llvm::SmallVectorImpl<uint64_t> &Scratch); }; std::optional<IdentifierID> @@ -848,37 +848,36 @@ APINotesReader::Implementation::getSelector(ObjCSelectorRef Selector) { return *Known; } -bool APINotesReader::Implementation::readControlBlock( +llvm::Error APINotesReader::Implementation::readControlBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(CONTROL_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter control block"); bool SawMetadata = false; llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown metadata sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -888,9 +887,7 @@ bool APINotesReader::Implementation::readControlBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); @@ -898,10 +895,12 @@ bool APINotesReader::Implementation::readControlBlock( case control_block::METADATA: // Already saw metadata. if (SawMetadata) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple metadata records found"); if (Scratch[0] != VERSION_MAJOR || Scratch[1] != VERSION_MINOR) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Version mismatch in API Notes"); SawMetadata = true; break; @@ -924,46 +923,47 @@ bool APINotesReader::Implementation::readControlBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return !SawMetadata; + if (!SawMetadata) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing metadata record"); + + return llvm::Error::success(); } -bool APINotesReader::Implementation::readIdentifierBlock( +llvm::Error APINotesReader::Implementation::readIdentifierBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(IDENTIFIER_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter identifier block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -973,16 +973,15 @@ bool APINotesReader::Implementation::readIdentifierBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case identifier_block::IDENTIFIER_DATA: { // Already saw identifier table. if (IdentifierTable) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple identifier records found"); uint32_t tableOffset; identifier_block::IdentifierDataLayout::readRecord(Scratch, tableOffset); @@ -1000,46 +999,43 @@ bool APINotesReader::Implementation::readIdentifierBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readContextBlock( +llvm::Error APINotesReader::Implementation::readContextBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(OBJC_CONTEXT_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter Objective-C context block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1049,16 +1045,15 @@ bool APINotesReader::Implementation::readContextBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case context_block::CONTEXT_ID_DATA: { // Already saw Objective-C / C++ context ID table. if (ContextIDTable) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple context ID records found"); uint32_t tableOffset; context_block::ContextIDLayout::readRecord(Scratch, tableOffset); @@ -1072,7 +1067,8 @@ bool APINotesReader::Implementation::readContextBlock( case context_block::CONTEXT_INFO_DATA: { // Already saw Objective-C / C++ context info table. if (ContextInfoTable) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple context info records found"); uint32_t tableOffset; context_block::ContextInfoLayout::readRecord(Scratch, tableOffset); @@ -1090,46 +1086,44 @@ bool APINotesReader::Implementation::readContextBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readObjCPropertyBlock( +llvm::Error APINotesReader::Implementation::readObjCPropertyBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(OBJC_PROPERTY_BLOCK_ID)) - return true; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Failed to enter Objective-C property block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1139,16 +1133,16 @@ bool APINotesReader::Implementation::readObjCPropertyBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case objc_property_block::OBJC_PROPERTY_DATA: { // Already saw Objective-C property table. if (ObjCPropertyTable) - return true; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Multiple Objective-C property records found"); uint32_t tableOffset; objc_property_block::ObjCPropertyDataLayout::readRecord(Scratch, @@ -1167,45 +1161,42 @@ bool APINotesReader::Implementation::readObjCPropertyBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readObjCMethodBlock( +llvm::Error APINotesReader::Implementation::readObjCMethodBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(OBJC_METHOD_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter Objective-C method block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1215,16 +1206,16 @@ bool APINotesReader::Implementation::readObjCMethodBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case objc_method_block::OBJC_METHOD_DATA: { // Already saw Objective-C method table. if (ObjCMethodTable) - return true; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Multiple Objective-C method records found"); uint32_t tableOffset; objc_method_block::ObjCMethodDataLayout::readRecord(Scratch, tableOffset); @@ -1242,45 +1233,42 @@ bool APINotesReader::Implementation::readObjCMethodBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readCXXMethodBlock( +llvm::Error APINotesReader::Implementation::readCXXMethodBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(CXX_METHOD_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter C++ method block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1290,16 +1278,15 @@ bool APINotesReader::Implementation::readCXXMethodBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case cxx_method_block::CXX_METHOD_DATA: { // Already saw C++ method table. if (CXXMethodTable) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple C++ method records found"); uint32_t tableOffset; cxx_method_block::CXXMethodDataLayout::readRecord(Scratch, tableOffset); @@ -1317,45 +1304,42 @@ bool APINotesReader::Implementation::readCXXMethodBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readFieldBlock( +llvm::Error APINotesReader::Implementation::readFieldBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(FIELD_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter field block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1365,16 +1349,15 @@ bool APINotesReader::Implementation::readFieldBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case field_block::FIELD_DATA: { // Already saw field table. if (FieldTable) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple field records found"); uint32_t tableOffset; field_block::FieldDataLayout::readRecord(Scratch, tableOffset); @@ -1392,45 +1375,43 @@ bool APINotesReader::Implementation::readFieldBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readObjCSelectorBlock( +llvm::Error APINotesReader::Implementation::readObjCSelectorBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID)) - return true; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Failed to enter Objective-C selector block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1440,16 +1421,16 @@ bool APINotesReader::Implementation::readObjCSelectorBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case objc_selector_block::OBJC_SELECTOR_DATA: { // Already saw Objective-C selector table. if (ObjCSelectorTable) - return true; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Multiple Objective-C selector records found"); uint32_t tableOffset; objc_selector_block::ObjCSelectorDataLayout::readRecord(Scratch, @@ -1468,45 +1449,42 @@ bool APINotesReader::Implementation::readObjCSelectorBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readGlobalVariableBlock( +llvm::Error APINotesReader::Implementation::readGlobalVariableBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(GLOBAL_VARIABLE_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter global variable block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1516,16 +1494,16 @@ bool APINotesReader::Implementation::readGlobalVariableBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case global_variable_block::GLOBAL_VARIABLE_DATA: { // Already saw global variable table. if (GlobalVariableTable) - return true; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Multiple global variable records found"); uint32_t tableOffset; global_variable_block::GlobalVariableDataLayout::readRecord(Scratch, @@ -1544,45 +1522,43 @@ bool APINotesReader::Implementation::readGlobalVariableBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + ; + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readGlobalFunctionBlock( +llvm::Error APINotesReader::Implementation::readGlobalFunctionBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(GLOBAL_FUNCTION_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter global function block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1592,16 +1568,16 @@ bool APINotesReader::Implementation::readGlobalFunctionBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case global_function_block::GLOBAL_FUNCTION_DATA: { // Already saw global function table. if (GlobalFunctionTable) - return true; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Multiple global function records found"); uint32_t tableOffset; global_function_block::GlobalFunctionDataLayout::readRecord(Scratch, @@ -1620,45 +1596,42 @@ bool APINotesReader::Implementation::readGlobalFunctionBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readEnumConstantBlock( +llvm::Error APINotesReader::Implementation::readEnumConstantBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(ENUM_CONSTANT_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter enum constant block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1668,16 +1641,15 @@ bool APINotesReader::Implementation::readEnumConstantBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case enum_constant_block::ENUM_CONSTANT_DATA: { // Already saw enumerator table. if (EnumConstantTable) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple enum constant records found"); uint32_t tableOffset; enum_constant_block::EnumConstantDataLayout::readRecord(Scratch, @@ -1696,45 +1668,42 @@ bool APINotesReader::Implementation::readEnumConstantBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readTagBlock( +llvm::Error APINotesReader::Implementation::readTagBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(TAG_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter tag block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1744,16 +1713,15 @@ bool APINotesReader::Implementation::readTagBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case tag_block::TAG_DATA: { // Already saw tag table. if (TagTable) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple tag records found"); uint32_t tableOffset; tag_block::TagDataLayout::readRecord(Scratch, tableOffset); @@ -1771,45 +1739,42 @@ bool APINotesReader::Implementation::readTagBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } -bool APINotesReader::Implementation::readTypedefBlock( +llvm::Error APINotesReader::Implementation::readTypedefBlock( llvm::BitstreamCursor &Cursor, llvm::SmallVectorImpl<uint64_t> &Scratch) { if (Cursor.EnterSubBlock(TYPEDEF_BLOCK_ID)) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to enter typedef block"); llvm::Expected<llvm::BitstreamEntry> MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + llvm::BitstreamEntry Next = MaybeNext.get(); while (Next.Kind != llvm::BitstreamEntry::EndBlock) { if (Next.Kind == llvm::BitstreamEntry::Error) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Malformed bitstream entry"); if (Next.Kind == llvm::BitstreamEntry::SubBlock) { // Unknown sub-block, possibly for use by a future version of the // API notes format. if (Cursor.SkipBlock()) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip sub-block"); MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); continue; } @@ -1819,16 +1784,15 @@ bool APINotesReader::Implementation::readTypedefBlock( llvm::Expected<unsigned> MaybeKind = Cursor.readRecord(Next.ID, Scratch, &BlobData); if (!MaybeKind) { - // FIXME this drops the error on the floor. - consumeError(MaybeKind.takeError()); - return false; + return MaybeKind.takeError(); } unsigned Kind = MaybeKind.get(); switch (Kind) { case typedef_block::TYPEDEF_DATA: { // Already saw typedef table. if (TypedefTable) - return true; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple typedef records found"); uint32_t tableOffset; typedef_block::TypedefDataLayout::readRecord(Scratch, tableOffset); @@ -1846,21 +1810,19 @@ bool APINotesReader::Implementation::readTypedefBlock( } MaybeNext = Cursor.advance(); - if (!MaybeNext) { - // FIXME this drops the error on the floor. - consumeError(MaybeNext.takeError()); - return false; - } + if (!MaybeNext) + return MaybeNext.takeError(); + Next = MaybeNext.get(); } - return false; + return llvm::Error::success(); } APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer, - llvm::VersionTuple SwiftVersion, bool &Failed) + llvm::VersionTuple SwiftVersion, + llvm::Error &Err) : Implementation(new class Implementation) { - Failed = false; // Initialize the input buffer. Implementation->InputBuffer = InputBuffer; @@ -1870,19 +1832,20 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer, // Validate signature. for (auto byte : API_NOTES_SIGNATURE) { if (Cursor.AtEndOfStream()) { - Failed = true; + Err = llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Unexpected end of stream while reading signature"); return; } - if (llvm::Expected<llvm::SimpleBitstreamCursor::word_t> maybeRead = - Cursor.Read(8)) { - if (maybeRead.get() != byte) { - Failed = true; - return; - } - } else { - // FIXME this drops the error on the floor. - consumeError(maybeRead.takeError()); - Failed = true; + llvm::Expected<llvm::SimpleBitstreamCursor::word_t> maybeRead = + Cursor.Read(8); + if (!maybeRead) { + Err = maybeRead.takeError(); + return; + } + if (maybeRead.get() != byte) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Invalid signature in API notes file"); return; } } @@ -1893,9 +1856,7 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer, while (!Cursor.AtEndOfStream()) { llvm::Expected<llvm::BitstreamEntry> MaybeTopLevelEntry = Cursor.advance(); if (!MaybeTopLevelEntry) { - // FIXME this drops the error on the floor. - consumeError(MaybeTopLevelEntry.takeError()); - Failed = true; + Err = MaybeTopLevelEntry.takeError(); return; } llvm::BitstreamEntry TopLevelEntry = MaybeTopLevelEntry.get(); @@ -1906,115 +1867,179 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer, switch (TopLevelEntry.ID) { case llvm::bitc::BLOCKINFO_BLOCK_ID: if (!Cursor.ReadBlockInfoBlock()) { - Failed = true; - break; + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to read block info"); + return; } break; case CONTROL_BLOCK_ID: // Only allow a single control block. - if (HasValidControlBlock || - Implementation->readControlBlock(Cursor, Scratch)) { - Failed = true; + if (HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Multiple control blocks found"); + return; + } + if (llvm::Error BlockErr = + Implementation->readControlBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } - HasValidControlBlock = true; break; case IDENTIFIER_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readIdentifierBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readIdentifierBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case OBJC_CONTEXT_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readContextBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readContextBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } - break; case OBJC_PROPERTY_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readObjCPropertyBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readObjCPropertyBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case OBJC_METHOD_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readObjCMethodBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readObjCMethodBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case CXX_METHOD_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readCXXMethodBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readCXXMethodBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case FIELD_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readFieldBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readFieldBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case OBJC_SELECTOR_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readObjCSelectorBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readObjCSelectorBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case GLOBAL_VARIABLE_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readGlobalVariableBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readGlobalVariableBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case GLOBAL_FUNCTION_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readGlobalFunctionBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readGlobalFunctionBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case ENUM_CONSTANT_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readEnumConstantBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readEnumConstantBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case TAG_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readTagBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readTagBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; case TYPEDEF_BLOCK_ID: - if (!HasValidControlBlock || - Implementation->readTypedefBlock(Cursor, Scratch)) { - Failed = true; + if (!HasValidControlBlock) { + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Missing control block"); + return; + } + if (llvm::Error BlockErr = + Implementation->readTypedefBlock(Cursor, Scratch)) { + Err = std::move(BlockErr); return; } break; @@ -2023,7 +2048,8 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer, // Unknown top-level block, possibly for use by a future version of the // module format. if (Cursor.SkipBlock()) { - Failed = true; + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to skip unknown top-level block"); return; } break; @@ -2031,23 +2057,25 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *InputBuffer, } if (!Cursor.AtEndOfStream()) { - Failed = true; + Err = llvm::createStringError(llvm::inconvertibleErrorCode(), + "Bitstream has unread data after all blocks"); return; } } APINotesReader::~APINotesReader() { delete Implementation->InputBuffer; } -std::unique_ptr<APINotesReader> +llvm::Expected<std::unique_ptr<APINotesReader>> APINotesReader::Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer, llvm::VersionTuple SwiftVersion) { - bool Failed = false; + llvm::Error Err = llvm::Error::success(); std::unique_ptr<APINotesReader> Reader( - new APINotesReader(InputBuffer.release(), SwiftVersion, Failed)); - if (Failed) - return nullptr; + new APINotesReader(InputBuffer.release(), SwiftVersion, Err)); + + if (Err) + return std::move(Err); - return Reader; + return std::move(Reader); } template <typename T> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
