[clang] [Reland] [APINotes] Refactor APINotesReader to propagate llvm::Error (PR #184212)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 2 11:51:24 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Maria Fernanda GuimarĂ£es (mafeguimaraes)
<details>
<summary>Changes</summary>
Reland of #<!-- -->183812 with the explicit `std::move` restored to fix buildbot failures on older compilers.
---
Patch is 54.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/184212.diff
3 Files Affected:
- (modified) clang/include/clang/APINotes/APINotesReader.h (+4-3)
- (modified) clang/lib/APINotes/APINotesManager.cpp (+11-4)
- (modified) clang/lib/APINotes/APINotesReader.cpp (+431-404)
``````````diff
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..f00c7ac1d9d9b 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.takeEr...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/184212
More information about the cfe-commits
mailing list