assert(Offset != 0);
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Offset);
+ if (llvm::Error Err = Cursor.JumpToBit(Offset)) {
+ Error(std::move(Err));
+ return true;
+ }
RecordData Record;
StringRef Blob;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record, &Blob);
+ Expected<unsigned> MaybeCode = Cursor.ReadCode();
+ if (!MaybeCode) {
+ Error(MaybeCode.takeError());
+ return true;
+ }
+ unsigned Code = MaybeCode.get();
+
+ Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record, &Blob);
+ if (!MaybeRecCode) {
+ Error(MaybeRecCode.takeError());
+ return true;
+ }
+ unsigned RecCode = MaybeRecCode.get();
if (RecCode != DECL_CONTEXT_LEXICAL) {
Error("Expected lexical block");
return true;
assert(Offset != 0);
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Offset);
+ if (llvm::Error Err = Cursor.JumpToBit(Offset)) {
+ Error(std::move(Err));
+ return true;
+ }
RecordData Record;
StringRef Blob;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record, &Blob);
+ Expected<unsigned> MaybeCode = Cursor.ReadCode();
+ if (!MaybeCode) {
+ Error(MaybeCode.takeError());
+ return true;
+ }
+ unsigned Code = MaybeCode.get();
+
+ Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record, &Blob);
+ if (!MaybeRecCode) {
+ Error(MaybeRecCode.takeError());
+ return true;
+ }
+ unsigned RecCode = MaybeRecCode.get();
if (RecCode != DECL_CONTEXT_VISIBLE) {
Error("Expected visible lookup table block");
return true;
Diag(DiagID) << Arg1 << Arg2;
}
+void ASTReader::Error(llvm::Error &&Err) const {
+ Error(toString(std::move(Err)));
+}
+
//===----------------------------------------------------------------------===//
// Source Manager Deserialization
//===----------------------------------------------------------------------===//
SLocEntryCursor = F.Stream;
// The stream itself is going to skip over the source manager block.
- if (F.Stream.SkipBlock()) {
- Error("malformed block record in AST file");
+ if (llvm::Error Err = F.Stream.SkipBlock()) {
+ Error(std::move(Err));
return true;
}
// Enter the source manager block.
- if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
- Error("malformed source manager block record in AST file");
+ if (llvm::Error Err =
+ SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
+ Error(std::move(Err));
return true;
}
RecordData Record;
while (true) {
- llvm::BitstreamEntry E = SLocEntryCursor.advanceSkippingSubblocks();
+ Expected<llvm::BitstreamEntry> MaybeE =
+ SLocEntryCursor.advanceSkippingSubblocks();
+ if (!MaybeE) {
+ Error(MaybeE.takeError());
+ return true;
+ }
+ llvm::BitstreamEntry E = MaybeE.get();
switch (E.Kind) {
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
// Read a record.
Record.clear();
StringRef Blob;
- switch (SLocEntryCursor.readRecord(E.ID, Record, &Blob)) {
+ Expected<unsigned> MaybeRecord =
+ SLocEntryCursor.readRecord(E.ID, Record, &Blob);
+ if (!MaybeRecord) {
+ Error(MaybeRecord.takeError());
+ return true;
+ }
+ switch (MaybeRecord.get()) {
default: // Default behavior: ignore.
break;
StringRef Name) -> std::unique_ptr<llvm::MemoryBuffer> {
RecordData Record;
StringRef Blob;
- unsigned Code = SLocEntryCursor.ReadCode();
- unsigned RecCode = SLocEntryCursor.readRecord(Code, Record, &Blob);
+ Expected<unsigned> MaybeCode = SLocEntryCursor.ReadCode();
+ if (!MaybeCode) {
+ Error(MaybeCode.takeError());
+ return nullptr;
+ }
+ unsigned Code = MaybeCode.get();
+
+ Expected<unsigned> MaybeRecCode =
+ SLocEntryCursor.readRecord(Code, Record, &Blob);
+ if (!MaybeRecCode) {
+ Error(MaybeRecCode.takeError());
+ return nullptr;
+ }
+ unsigned RecCode = MaybeRecCode.get();
if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
if (!llvm::zlib::isAvailable()) {
};
ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second;
- F->SLocEntryCursor.JumpToBit(F->SLocEntryOffsets[ID - F->SLocEntryBaseID]);
+ if (llvm::Error Err = F->SLocEntryCursor.JumpToBit(
+ F->SLocEntryOffsets[ID - F->SLocEntryBaseID])) {
+ Error(std::move(Err));
+ return true;
+ }
+
BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor;
unsigned BaseOffset = F->SLocEntryBaseOffset;
++NumSLocEntriesRead;
- llvm::BitstreamEntry Entry = SLocEntryCursor.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = SLocEntryCursor.advance();
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return true;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
+
if (Entry.Kind != llvm::BitstreamEntry::Record) {
Error("incorrectly-formatted source location entry in AST file");
return true;
RecordData Record;
StringRef Blob;
- switch (SLocEntryCursor.readRecord(Entry.ID, Record, &Blob)) {
+ Expected<unsigned> MaybeSLOC =
+ SLocEntryCursor.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeSLOC) {
+ Error(MaybeSLOC.takeError());
+ return true;
+ }
+ switch (MaybeSLOC.get()) {
default:
Error("incorrectly-formatted source location entry in AST file");
return true;
return F->ImportedBy[0]->FirstLoc;
}
-/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
-/// specified cursor. Read the abbreviations that are at the top of the block
-/// and then leave the cursor pointing into the block.
+/// Enter a subblock of the specified BlockID with the specified cursor. Read
+/// the abbreviations that are at the top of the block and then leave the cursor
+/// pointing into the block.
bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) {
- if (Cursor.EnterSubBlock(BlockID))
+ if (llvm::Error Err = Cursor.EnterSubBlock(BlockID)) {
+ // FIXME this drops errors on the floor.
+ consumeError(std::move(Err));
return true;
+ }
while (true) {
uint64_t Offset = Cursor.GetCurrentBitNo();
- unsigned Code = Cursor.ReadCode();
+ Expected<unsigned> MaybeCode = Cursor.ReadCode();
+ if (!MaybeCode) {
+ // FIXME this drops errors on the floor.
+ consumeError(MaybeCode.takeError());
+ return true;
+ }
+ unsigned Code = MaybeCode.get();
// We expect all abbrevs to be at the start of the block.
if (Code != llvm::bitc::DEFINE_ABBREV) {
- Cursor.JumpToBit(Offset);
+ if (llvm::Error Err = Cursor.JumpToBit(Offset)) {
+ // FIXME this drops errors on the floor.
+ consumeError(std::move(Err));
+ return true;
+ }
return false;
}
- Cursor.ReadAbbrevRecord();
+ if (llvm::Error Err = Cursor.ReadAbbrevRecord()) {
+ // FIXME this drops errors on the floor.
+ consumeError(std::move(Err));
+ return true;
+ }
}
}
// after reading this macro.
SavedStreamPosition SavedPosition(Stream);
- Stream.JumpToBit(Offset);
+ if (llvm::Error Err = Stream.JumpToBit(Offset)) {
+ // FIXME this drops errors on the floor.
+ consumeError(std::move(Err));
+ return nullptr;
+ }
RecordData Record;
SmallVector<IdentifierInfo*, 16> MacroParams;
MacroInfo *Macro = nullptr;
// pop it (removing all the abbreviations from the cursor) since we want to
// be able to reseek within the block and read entries.
unsigned Flags = BitstreamCursor::AF_DontPopBlockAtEnd;
- llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(Flags);
+ Expected<llvm::BitstreamEntry> MaybeEntry =
+ Stream.advanceSkippingSubblocks(Flags);
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return Macro;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
// Read a record.
Record.clear();
- PreprocessorRecordTypes RecType =
- (PreprocessorRecordTypes)Stream.readRecord(Entry.ID, Record);
+ PreprocessorRecordTypes RecType;
+ if (Expected<unsigned> MaybeRecType = Stream.readRecord(Entry.ID, Record))
+ RecType = (PreprocessorRecordTypes)MaybeRecType.get();
+ else {
+ Error(MaybeRecType.takeError());
+ return Macro;
+ }
switch (RecType) {
case PP_MODULE_MACRO:
case PP_MACRO_DIRECTIVE_HISTORY:
continue;
BitstreamCursor Cursor = MacroCursor;
- Cursor.JumpToBit(I.MacroStartOffset);
+ if (llvm::Error Err = Cursor.JumpToBit(I.MacroStartOffset)) {
+ Error(std::move(Err));
+ return;
+ }
RecordData Record;
while (true) {
- llvm::BitstreamEntry E = Cursor.advanceSkippingSubblocks();
+ Expected<llvm::BitstreamEntry> MaybeE = Cursor.advanceSkippingSubblocks();
+ if (!MaybeE) {
+ Error(MaybeE.takeError());
+ return;
+ }
+ llvm::BitstreamEntry E = MaybeE.get();
switch (E.Kind) {
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
case llvm::BitstreamEntry::EndBlock:
goto NextCursor;
- case llvm::BitstreamEntry::Record:
+ case llvm::BitstreamEntry::Record: {
Record.clear();
- switch (Cursor.readRecord(E.ID, Record)) {
+ Expected<unsigned> MaybeRecord = Cursor.readRecord(E.ID, Record);
+ if (!MaybeRecord) {
+ Error(MaybeRecord.takeError());
+ return;
+ }
+ switch (MaybeRecord.get()) {
default: // Default behavior: ignore.
break;
}
break;
}
+ }
}
NextCursor: ;
}
BitstreamCursor &Cursor = M.MacroCursor;
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(PMInfo.MacroDirectivesOffset);
+ if (llvm::Error Err = Cursor.JumpToBit(PMInfo.MacroDirectivesOffset)) {
+ Error(std::move(Err));
+ return;
+ }
struct ModuleMacroRecord {
SubmoduleID SubModID;
// macro histroy.
RecordData Record;
while (true) {
- llvm::BitstreamEntry Entry =
+ Expected<llvm::BitstreamEntry> MaybeEntry =
Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
+
if (Entry.Kind != llvm::BitstreamEntry::Record) {
Error("malformed block record in AST file");
return;
}
Record.clear();
- switch ((PreprocessorRecordTypes)Cursor.readRecord(Entry.ID, Record)) {
+ Expected<unsigned> MaybePP = Cursor.readRecord(Entry.ID, Record);
+ if (!MaybePP) {
+ Error(MaybePP.takeError());
+ return;
+ }
+ switch ((PreprocessorRecordTypes)MaybePP.get()) {
case PP_MACRO_DIRECTIVE_HISTORY:
break;
// Go find this input file.
BitstreamCursor &Cursor = F.InputFilesCursor;
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
+ if (llvm::Error Err = Cursor.JumpToBit(F.InputFileOffsets[ID - 1])) {
+ // FIXME this drops errors on the floor.
+ consumeError(std::move(Err));
+ }
- unsigned Code = Cursor.ReadCode();
+ Expected<unsigned> MaybeCode = Cursor.ReadCode();
+ if (!MaybeCode) {
+ // FIXME this drops errors on the floor.
+ consumeError(MaybeCode.takeError());
+ }
+ unsigned Code = MaybeCode.get();
RecordData Record;
StringRef Blob;
- unsigned Result = Cursor.readRecord(Code, Record, &Blob);
- assert(static_cast<InputFileRecordTypes>(Result) == INPUT_FILE &&
- "invalid record type for input file");
- (void)Result;
+ if (Expected<unsigned> Maybe = Cursor.readRecord(Code, Record, &Blob))
+ assert(static_cast<InputFileRecordTypes>(Maybe.get()) == INPUT_FILE &&
+ "invalid record type for input file");
+ else {
+ // FIXME this drops errors on the floor.
+ consumeError(Maybe.takeError());
+ }
assert(Record[0] == ID && "Bogus stored ID or offset");
InputFileInfo R;
// Go find this input file.
BitstreamCursor &Cursor = F.InputFilesCursor;
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
+ if (llvm::Error Err = Cursor.JumpToBit(F.InputFileOffsets[ID - 1])) {
+ // FIXME this drops errors on the floor.
+ consumeError(std::move(Err));
+ }
InputFileInfo FI = readInputFileInfo(F, ID);
off_t StoredSize = FI.StoredSize;
BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
std::string &SuggestedPredefines) {
- if (Stream.EnterSubBlock(OPTIONS_BLOCK_ID))
+ if (llvm::Error Err = Stream.EnterSubBlock(OPTIONS_BLOCK_ID)) {
+ // FIXME this drops errors on the floor.
+ consumeError(std::move(Err));
return Failure;
+ }
// Read all of the records in the options block.
RecordData Record;
ASTReadResult Result = Success;
while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
+ if (!MaybeEntry) {
+ // FIXME this drops errors on the floor.
+ consumeError(MaybeEntry.takeError());
+ return Failure;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
// Read and process a record.
Record.clear();
- switch ((OptionsRecordTypes)Stream.readRecord(Entry.ID, Record)) {
+ Expected<unsigned> MaybeRecordType = Stream.readRecord(Entry.ID, Record);
+ if (!MaybeRecordType) {
+ // FIXME this drops errors on the floor.
+ consumeError(MaybeRecordType.takeError());
+ return Failure;
+ }
+ switch ((OptionsRecordTypes)MaybeRecordType.get()) {
case LANGUAGE_OPTIONS: {
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
if (ParseLanguageOptions(Record, Complain, Listener,
BitstreamCursor &Stream = F.Stream;
ASTReadResult Result = Success;
- if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
- Error("malformed block record in AST file");
+ if (llvm::Error Err = Stream.EnterSubBlock(CONTROL_BLOCK_ID)) {
+ Error(std::move(Err));
return Failure;
}
unsigned NumUserInputs = 0;
StringRef BaseDirectoryAsWritten;
while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return Failure;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
switch (Entry.ID) {
case INPUT_FILES_BLOCK_ID:
F.InputFilesCursor = Stream;
- if (Stream.SkipBlock() || // Skip with the main cursor
- // Read the abbreviations
- ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) {
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
+ return Failure;
+ }
+ if (ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) {
Error("malformed block record in AST file");
return Failure;
}
// middle of a block.
if (Result != Success)
return Result;
- } else if (Stream.SkipBlock()) {
- Error("malformed block record in AST file");
+ } else if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
return Failure;
}
continue;
default:
- if (Stream.SkipBlock()) {
- Error("malformed block record in AST file");
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
return Failure;
}
continue;
// Read and process a record.
Record.clear();
StringRef Blob;
- switch ((ControlRecordTypes)Stream.readRecord(Entry.ID, Record, &Blob)) {
+ Expected<unsigned> MaybeRecordType =
+ Stream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeRecordType) {
+ Error(MaybeRecordType.takeError());
+ return Failure;
+ }
+ switch ((ControlRecordTypes)MaybeRecordType.get()) {
case METADATA: {
if (Record[0] != VERSION_MAJOR && !DisableValidation) {
if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
BitstreamCursor &Stream = F.Stream;
- if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
- Error("malformed block record in AST file");
+ if (llvm::Error Err = Stream.EnterSubBlock(AST_BLOCK_ID)) {
+ Error(std::move(Err));
return Failure;
}
// Read all of the records and blocks for the AST file.
RecordData Record;
while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return Failure;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
// cursor to it, enter the block and read the abbrevs in that block.
// With the main cursor, we just skip over it.
F.DeclsCursor = Stream;
- if (Stream.SkipBlock() || // Skip with the main cursor.
- // Read the abbrevs.
- ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
+ return Failure;
+ }
+ if (ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
Error("malformed block record in AST file");
return Failure;
}
if (!PP.getExternalSource())
PP.setExternalSource(this);
- if (Stream.SkipBlock() ||
- ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
+ return Failure;
+ }
+ if (ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
Error("malformed block record in AST file");
return Failure;
}
case PREPROCESSOR_DETAIL_BLOCK_ID:
F.PreprocessorDetailCursor = Stream;
- if (Stream.SkipBlock() ||
- ReadBlockAbbrevs(F.PreprocessorDetailCursor,
+
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
+ return Failure;
+ }
+ if (ReadBlockAbbrevs(F.PreprocessorDetailCursor,
PREPROCESSOR_DETAIL_BLOCK_ID)) {
- Error("malformed preprocessor detail record in AST file");
- return Failure;
- }
+ Error("malformed preprocessor detail record in AST file");
+ return Failure;
+ }
F.PreprocessorDetailStartOffset
= F.PreprocessorDetailCursor.GetCurrentBitNo();
case COMMENTS_BLOCK_ID: {
BitstreamCursor C = Stream;
- if (Stream.SkipBlock() ||
- ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {
+
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
+ return Failure;
+ }
+ if (ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {
Error("malformed comments block in AST file");
return Failure;
}
}
default:
- if (Stream.SkipBlock()) {
- Error("malformed block record in AST file");
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
return Failure;
}
break;
// Read and process a record.
Record.clear();
StringRef Blob;
- auto RecordType =
- (ASTRecordTypes)Stream.readRecord(Entry.ID, Record, &Blob);
+ Expected<unsigned> MaybeRecordType =
+ Stream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeRecordType) {
+ Error(MaybeRecordType.takeError());
+ return Failure;
+ }
+ ASTRecordTypes RecordType = (ASTRecordTypes)MaybeRecordType.get();
// If we're not loading an AST context, we don't care about most records.
if (!ContextObj) {
TriedLoadingGlobalIndex = true;
StringRef ModuleCachePath
= getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
- std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode> Result
- = GlobalModuleIndex::readIndex(ModuleCachePath);
- if (!Result.first)
+ std::pair<GlobalModuleIndex *, llvm::Error> Result =
+ GlobalModuleIndex::readIndex(ModuleCachePath);
+ if (llvm::Error Err = std::move(Result.second)) {
+ assert(!Result.first);
+ consumeError(std::move(Err)); // FIXME this drops errors on the floor.
return true;
+ }
GlobalIndex.reset(Result.first);
ModuleMgr.setGlobalIndex(GlobalIndex.get());
/// true on failure.
static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) {
while (true) {
- llvm::BitstreamEntry Entry = Cursor.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = Cursor.advance();
+ if (!MaybeEntry) {
+ // FIXME this drops errors on the floor.
+ consumeError(MaybeEntry.takeError());
+ return true;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
+
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
case llvm::BitstreamEntry::EndBlock:
case llvm::BitstreamEntry::Record:
// Ignore top-level records.
- Cursor.skipRecord(Entry.ID);
- break;
+ if (Expected<unsigned> Skipped = Cursor.skipRecord(Entry.ID))
+ break;
+ else {
+ // FIXME this drops errors on the floor.
+ consumeError(Skipped.takeError());
+ return true;
+ }
case llvm::BitstreamEntry::SubBlock:
if (Entry.ID == BlockID) {
- if (Cursor.EnterSubBlock(BlockID))
+ if (llvm::Error Err = Cursor.EnterSubBlock(BlockID)) {
+ // FIXME this drops the error on the floor.
+ consumeError(std::move(Err));
return true;
+ }
// Found it!
return false;
}
- if (Cursor.SkipBlock())
+ if (llvm::Error Err = Cursor.SkipBlock()) {
+ // FIXME this drops the error on the floor.
+ consumeError(std::move(Err));
return true;
+ }
}
}
}
static ASTFileSignature readASTFileSignature(StringRef PCH);
-/// Whether \p Stream starts with the AST/PCH file magic number 'CPCH'.
-static bool startsWithASTFileMagic(BitstreamCursor &Stream) {
- return Stream.canSkipToPos(4) &&
- Stream.Read(8) == 'C' &&
- Stream.Read(8) == 'P' &&
- Stream.Read(8) == 'C' &&
- Stream.Read(8) == 'H';
+/// Whether \p Stream doesn't start with the AST/PCH file magic number 'CPCH'.
+static llvm::Error doesntStartWithASTFileMagic(BitstreamCursor &Stream) {
+ // FIXME checking magic headers is done in other places such as
+ // SerializedDiagnosticReader and GlobalModuleIndex, but error handling isn't
+ // always done the same. Unify it all with a helper.
+ if (!Stream.canSkipToPos(4))
+ return llvm::createStringError(std::errc::illegal_byte_sequence,
+ "file too small to contain AST file magic");
+ for (unsigned C : {'C', 'P', 'C', 'H'})
+ if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = Stream.Read(8)) {
+ if (Res.get() != C)
+ return llvm::createStringError(
+ std::errc::illegal_byte_sequence,
+ "file doesn't start with AST file magic");
+ } else
+ return Res.takeError();
+ return llvm::Error::success();
}
static unsigned moduleKindForDiagnostic(ModuleKind Kind) {
F.SizeInBits = F.Buffer->getBufferSize() * 8;
// Sniff for the signature.
- if (!startsWithASTFileMagic(Stream)) {
- Diag(diag::err_module_file_invalid) << moduleKindForDiagnostic(Type)
- << FileName;
+ if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) {
+ Diag(diag::err_module_file_invalid)
+ << moduleKindForDiagnostic(Type) << FileName << std::move(Err);
return Failure;
}
// This is used for compatibility with older PCH formats.
bool HaveReadControlBlock = false;
while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return Failure;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
return Failure;
default:
- if (Stream.SkipBlock()) {
- Error("malformed block record in AST file");
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
return Failure;
}
break;
BitstreamCursor Stream(StreamData);
// Sniff for the signature.
- if (!startsWithASTFileMagic(Stream))
+ if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) {
+ // FIXME this drops the error on the floor.
+ consumeError(std::move(Err));
return Failure;
+ }
// Scan for the UNHASHED_CONTROL_BLOCK_ID block.
if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
RecordData Record;
ASTReadResult Result = Success;
while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
+ if (!MaybeEntry) {
+ // FIXME this drops the error on the floor.
+ consumeError(MaybeEntry.takeError());
+ return Failure;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
// Read and process a record.
Record.clear();
- switch (
- (UnhashedControlBlockRecordTypes)Stream.readRecord(Entry.ID, Record)) {
+ Expected<unsigned> MaybeRecordType = Stream.readRecord(Entry.ID, Record);
+ if (!MaybeRecordType) {
+ // FIXME this drops the error.
+ return Failure;
+ }
+ switch ((UnhashedControlBlockRecordTypes)MaybeRecordType.get()) {
case SIGNATURE:
if (F)
std::copy(Record.begin(), Record.end(), F->Signature.data());
RecordData Record;
while (true) {
- llvm::BitstreamEntry Entry = Stream.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return Failure;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
+
switch (Entry.Kind) {
case llvm::BitstreamEntry::SubBlock:
- if (Stream.SkipBlock())
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ Error(std::move(Err));
return Failure;
-
+ }
continue;
case llvm::BitstreamEntry::EndBlock:
Record.clear();
StringRef Blob;
- unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
- switch (RecCode) {
+ Expected<unsigned> MaybeRecCode =
+ Stream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeRecCode) {
+ Error(MaybeRecCode.takeError());
+ return Failure;
+ }
+ switch (MaybeRecCode.get()) {
case EXTENSION_METADATA: {
ModuleFileExtensionMetadata Metadata;
if (parseModuleFileExtensionMetadata(Record, Blob, Metadata))
/// else returns 0.
static ASTFileSignature readASTFileSignature(StringRef PCH) {
BitstreamCursor Stream(PCH);
- if (!startsWithASTFileMagic(Stream))
+ if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) {
+ // FIXME this drops the error on the floor.
+ consumeError(std::move(Err));
return ASTFileSignature();
+ }
// Scan for the UNHASHED_CONTROL_BLOCK_ID block.
if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
// Scan for SIGNATURE inside the diagnostic options block.
ASTReader::RecordData Record;
while (true) {
- llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+ Expected<llvm::BitstreamEntry> MaybeEntry =
+ Stream.advanceSkippingSubblocks();
+ if (!MaybeEntry) {
+ // FIXME this drops the error on the floor.
+ consumeError(MaybeEntry.takeError());
+ return ASTFileSignature();
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
+
if (Entry.Kind != llvm::BitstreamEntry::Record)
return ASTFileSignature();
Record.clear();
StringRef Blob;
- if (SIGNATURE == Stream.readRecord(Entry.ID, Record, &Blob))
+ Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeRecord) {
+ // FIXME this drops the error on the floor.
+ consumeError(MaybeRecord.takeError());
+ return ASTFileSignature();
+ }
+ if (SIGNATURE == MaybeRecord.get())
return {{{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
(uint32_t)Record[3], (uint32_t)Record[4]}}};
}
BitstreamCursor Stream(PCHContainerRdr.ExtractPCH(**Buffer));
// Sniff for the signature.
- if (!startsWithASTFileMagic(Stream)) {
- Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName;
+ if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) {
+ Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName << std::move(Err);
return std::string();
}
// Scan for ORIGINAL_FILE inside the control block.
RecordData Record;
while (true) {
- llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+ Expected<llvm::BitstreamEntry> MaybeEntry =
+ Stream.advanceSkippingSubblocks();
+ if (!MaybeEntry) {
+ // FIXME this drops errors on the floor.
+ consumeError(MaybeEntry.takeError());
+ return std::string();
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
+
if (Entry.Kind == llvm::BitstreamEntry::EndBlock)
return std::string();
Record.clear();
StringRef Blob;
- if (Stream.readRecord(Entry.ID, Record, &Blob) == ORIGINAL_FILE)
+ Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeRecord) {
+ // FIXME this drops the errors on the floor.
+ consumeError(MaybeRecord.takeError());
+ return std::string();
+ }
+ if (ORIGINAL_FILE == MaybeRecord.get())
return Blob.str();
}
}
BitstreamCursor Stream(Bytes);
// Sniff for the signature.
- if (!startsWithASTFileMagic(Stream))
+ if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) {
+ consumeError(std::move(Err)); // FIXME this drops errors on the floor.
return true;
+ }
// Scan for the CONTROL_BLOCK_ID block.
if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID))
std::string ModuleDir;
bool DoneWithControlBlock = false;
while (!DoneWithControlBlock) {
- llvm::BitstreamEntry Entry = Stream.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
+ if (!MaybeEntry) {
+ // FIXME this drops the error on the floor.
+ consumeError(MaybeEntry.takeError());
+ return true;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::SubBlock: {
case INPUT_FILES_BLOCK_ID:
InputFilesCursor = Stream;
- if (Stream.SkipBlock() ||
- (NeedsInputFiles &&
- ReadBlockAbbrevs(InputFilesCursor, INPUT_FILES_BLOCK_ID)))
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ // FIXME this drops the error on the floor.
+ consumeError(std::move(Err));
+ return true;
+ }
+ if (NeedsInputFiles &&
+ ReadBlockAbbrevs(InputFilesCursor, INPUT_FILES_BLOCK_ID))
return true;
break;
default:
- if (Stream.SkipBlock())
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ // FIXME this drops the error on the floor.
+ consumeError(std::move(Err));
return true;
+ }
break;
}
Record.clear();
StringRef Blob;
- unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
- switch ((ControlRecordTypes)RecCode) {
+ Expected<unsigned> MaybeRecCode =
+ Stream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeRecCode) {
+ // FIXME this drops the error.
+ return Failure;
+ }
+ switch ((ControlRecordTypes)MaybeRecCode.get()) {
case METADATA:
if (Record[0] != VERSION_MAJOR)
return true;
BitstreamCursor &Cursor = InputFilesCursor;
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(InputFileOffs[I]);
+ if (llvm::Error Err = Cursor.JumpToBit(InputFileOffs[I])) {
+ // FIXME this drops errors on the floor.
+ consumeError(std::move(Err));
+ }
+
+ Expected<unsigned> MaybeCode = Cursor.ReadCode();
+ if (!MaybeCode) {
+ // FIXME this drops errors on the floor.
+ consumeError(MaybeCode.takeError());
+ }
+ unsigned Code = MaybeCode.get();
- unsigned Code = Cursor.ReadCode();
RecordData Record;
StringRef Blob;
bool shouldContinue = false;
- switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {
+ Expected<unsigned> MaybeRecordType =
+ Cursor.readRecord(Code, Record, &Blob);
+ if (!MaybeRecordType) {
+ // FIXME this drops errors on the floor.
+ consumeError(MaybeRecordType.takeError());
+ }
+ switch ((InputFileRecordTypes)MaybeRecordType.get()) {
case INPUT_FILE:
bool Overridden = static_cast<bool>(Record[3]);
std::string Filename = Blob;
while (!SkipCursorToBlock(Stream, EXTENSION_BLOCK_ID)) {
bool DoneWithExtensionBlock = false;
while (!DoneWithExtensionBlock) {
- llvm::BitstreamEntry Entry = Stream.advance();
-
- switch (Entry.Kind) {
- case llvm::BitstreamEntry::SubBlock:
- if (Stream.SkipBlock())
- return true;
-
- continue;
+ Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
+ if (!MaybeEntry) {
+ // FIXME this drops the error.
+ return true;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
+
+ switch (Entry.Kind) {
+ case llvm::BitstreamEntry::SubBlock:
+ if (llvm::Error Err = Stream.SkipBlock()) {
+ // FIXME this drops the error on the floor.
+ consumeError(std::move(Err));
+ return true;
+ }
+ continue;
- case llvm::BitstreamEntry::EndBlock:
- DoneWithExtensionBlock = true;
- continue;
+ case llvm::BitstreamEntry::EndBlock:
+ DoneWithExtensionBlock = true;
+ continue;
- case llvm::BitstreamEntry::Error:
- return true;
+ case llvm::BitstreamEntry::Error:
+ return true;
- case llvm::BitstreamEntry::Record:
- break;
- }
+ case llvm::BitstreamEntry::Record:
+ break;
+ }
Record.clear();
StringRef Blob;
- unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
- switch (RecCode) {
+ Expected<unsigned> MaybeRecCode =
+ Stream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeRecCode) {
+ // FIXME this drops the error.
+ return true;
+ }
+ switch (MaybeRecCode.get()) {
case EXTENSION_METADATA: {
ModuleFileExtensionMetadata Metadata;
if (parseModuleFileExtensionMetadata(Record, Blob, Metadata))
ASTReader::ASTReadResult
ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
// Enter the submodule block.
- if (F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {
- Error("malformed submodule block record in AST file");
+ if (llvm::Error Err = F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {
+ Error(std::move(Err));
return Failure;
}
Module *CurrentModule = nullptr;
RecordData Record;
while (true) {
- llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
+ Expected<llvm::BitstreamEntry> MaybeEntry =
+ F.Stream.advanceSkippingSubblocks();
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return Failure;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
// Read a record.
StringRef Blob;
Record.clear();
- auto Kind = F.Stream.readRecord(Entry.ID, Record, &Blob);
+ Expected<unsigned> MaybeKind = F.Stream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeKind) {
+ Error(MaybeKind.takeError());
+ return Failure;
+ }
+ unsigned Kind = MaybeKind.get();
if ((Kind == SUBMODULE_METADATA) != First) {
Error("submodule metadata record should be at beginning of block");
}
SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);
- M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset);
+ if (llvm::Error Err =
+ M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset)) {
+ Error(std::move(Err));
+ return nullptr;
+ }
+
+ Expected<llvm::BitstreamEntry> MaybeEntry =
+ M.PreprocessorDetailCursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return nullptr;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
- llvm::BitstreamEntry Entry =
- M.PreprocessorDetailCursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
if (Entry.Kind != llvm::BitstreamEntry::Record)
return nullptr;
PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
StringRef Blob;
RecordData Record;
- PreprocessorDetailRecordTypes RecType =
- (PreprocessorDetailRecordTypes)M.PreprocessorDetailCursor.readRecord(
- Entry.ID, Record, &Blob);
- switch (RecType) {
+ Expected<unsigned> MaybeRecType =
+ M.PreprocessorDetailCursor.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeRecType) {
+ Error(MaybeRecType.takeError());
+ return nullptr;
+ }
+ switch ((PreprocessorDetailRecordTypes)MaybeRecType.get()) {
case PPD_MACRO_EXPANSION: {
bool isBuiltin = Record[0];
IdentifierInfo *Name = nullptr;
Deserializing AType(this);
unsigned Idx = 0;
- DeclsCursor.JumpToBit(Loc.Offset);
+ if (llvm::Error Err = DeclsCursor.JumpToBit(Loc.Offset)) {
+ Error(std::move(Err));
+ return QualType();
+ }
RecordData Record;
- unsigned Code = DeclsCursor.ReadCode();
- switch ((TypeCode)DeclsCursor.readRecord(Code, Record)) {
+ Expected<unsigned> MaybeCode = DeclsCursor.ReadCode();
+ if (!MaybeCode) {
+ Error(MaybeCode.takeError());
+ return QualType();
+ }
+ unsigned Code = MaybeCode.get();
+
+ Expected<unsigned> MaybeTypeCode = DeclsCursor.readRecord(Code, Record);
+ if (!MaybeTypeCode) {
+ Error(MaybeTypeCode.takeError());
+ return QualType();
+ }
+ switch ((TypeCode)MaybeTypeCode.get()) {
case TYPE_EXT_QUAL: {
if (Record.size() != 2) {
Error("Incorrect encoding of extended qualifier type");
RecordLocation Loc = getLocalBitOffset(Offset);
BitstreamCursor &Cursor = Loc.F->DeclsCursor;
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Loc.Offset);
+ if (llvm::Error Err = Cursor.JumpToBit(Loc.Offset)) {
+ Error(std::move(Err));
+ return nullptr;
+ }
ReadingKindTracker ReadingKind(Read_Decl, *this);
RecordData Record;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record);
- if (RecCode != DECL_CXX_CTOR_INITIALIZERS) {
+ Expected<unsigned> MaybeCode = Cursor.ReadCode();
+ if (!MaybeCode) {
+ Error(MaybeCode.takeError());
+ return nullptr;
+ }
+ unsigned Code = MaybeCode.get();
+
+ Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record);
+ if (!MaybeRecCode) {
+ Error(MaybeRecCode.takeError());
+ return nullptr;
+ }
+ if (MaybeRecCode.get() != DECL_CXX_CTOR_INITIALIZERS) {
Error("malformed AST file: missing C++ ctor initializers");
return nullptr;
}
RecordLocation Loc = getLocalBitOffset(Offset);
BitstreamCursor &Cursor = Loc.F->DeclsCursor;
SavedStreamPosition SavedPosition(Cursor);
- Cursor.JumpToBit(Loc.Offset);
+ if (llvm::Error Err = Cursor.JumpToBit(Loc.Offset)) {
+ Error(std::move(Err));
+ return nullptr;
+ }
ReadingKindTracker ReadingKind(Read_Decl, *this);
RecordData Record;
- unsigned Code = Cursor.ReadCode();
- unsigned RecCode = Cursor.readRecord(Code, Record);
+
+ Expected<unsigned> MaybeCode = Cursor.ReadCode();
+ if (!MaybeCode) {
+ Error(MaybeCode.takeError());
+ return nullptr;
+ }
+ unsigned Code = MaybeCode.get();
+
+ Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record);
+ if (!MaybeRecCode) {
+ Error(MaybeCode.takeError());
+ return nullptr;
+ }
+ unsigned RecCode = MaybeRecCode.get();
+
if (RecCode != DECL_CXX_BASE_SPECIFIERS) {
Error("malformed AST file: missing C++ base specifiers");
return nullptr;
// Offset here is a global offset across the entire chain.
RecordLocation Loc = getLocalBitOffset(Offset);
- Loc.F->DeclsCursor.JumpToBit(Loc.Offset);
+ if (llvm::Error Err = Loc.F->DeclsCursor.JumpToBit(Loc.Offset)) {
+ Error(std::move(Err));
+ return nullptr;
+ }
assert(NumCurrentElementsDeserializing == 0 &&
"should not be called while already deserializing");
Deserializing D(this);
RecordData Record;
while (true) {
- llvm::BitstreamEntry Entry =
- Cursor.advanceSkippingSubblocks(BitstreamCursor::AF_DontPopBlockAtEnd);
+ Expected<llvm::BitstreamEntry> MaybeEntry =
+ Cursor.advanceSkippingSubblocks(
+ BitstreamCursor::AF_DontPopBlockAtEnd);
+ if (!MaybeEntry) {
+ Error(MaybeEntry.takeError());
+ return;
+ }
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
switch (Entry.Kind) {
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
// Read a record.
Record.clear();
- switch ((CommentRecordTypes)Cursor.readRecord(Entry.ID, Record)) {
+ Expected<unsigned> MaybeComment = Cursor.readRecord(Entry.ID, Record);
+ if (!MaybeComment) {
+ Error(MaybeComment.takeError());
+ return;
+ }
+ switch ((CommentRecordTypes)MaybeComment.get()) {
case COMMENTS_RAW_COMMENT: {
unsigned Idx = 0;
SourceRange SR = ReadSourceRange(F, Record, Idx);
return SemaObj ? SemaObj->IdResolver : DummyIdResolver;
}
-unsigned ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor,
- unsigned AbbrevID) {
+Expected<unsigned> ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor,
+ unsigned AbbrevID) {
Idx = 0;
Record.clear();
return Cursor.readRecord(AbbrevID, Record);
llvm::BitstreamCursor Cursor)
: Buffer(std::move(Buffer)), IdentifierIndex(), NumIdentifierLookups(),
NumIdentifierLookupHits() {
+ auto Fail = [&Buffer](llvm::Error &&Err) {
+ report_fatal_error("Module index '" + Buffer->getBufferIdentifier() +
+ "' failed: " + toString(std::move(Err)));
+ };
+
llvm::TimeTraceScope TimeScope("Module LoadIndex", StringRef(""));
// Read the global index.
bool InGlobalIndexBlock = false;
bool Done = false;
while (!Done) {
- llvm::BitstreamEntry Entry = Cursor.advance();
+ llvm::BitstreamEntry Entry;
+ if (Expected<llvm::BitstreamEntry> Res = Cursor.advance())
+ Entry = Res.get();
+ else
+ Fail(Res.takeError());
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
case llvm::BitstreamEntry::SubBlock:
if (!InGlobalIndexBlock && Entry.ID == GLOBAL_INDEX_BLOCK_ID) {
- if (Cursor.EnterSubBlock(GLOBAL_INDEX_BLOCK_ID))
- return;
-
+ if (llvm::Error Err = Cursor.EnterSubBlock(GLOBAL_INDEX_BLOCK_ID))
+ Fail(std::move(Err));
InGlobalIndexBlock = true;
- } else if (Cursor.SkipBlock()) {
- return;
- }
+ } else if (llvm::Error Err = Cursor.SkipBlock())
+ Fail(std::move(Err));
continue;
}
SmallVector<uint64_t, 64> Record;
StringRef Blob;
- switch ((IndexRecordTypes)Cursor.readRecord(Entry.ID, Record, &Blob)) {
+ Expected<unsigned> MaybeIndexRecord =
+ Cursor.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeIndexRecord)
+ Fail(MaybeIndexRecord.takeError());
+ IndexRecordTypes IndexRecord =
+ static_cast<IndexRecordTypes>(MaybeIndexRecord.get());
+ switch (IndexRecord) {
case INDEX_METADATA:
// Make sure that the version matches.
if (Record.size() < 1 || Record[0] != CurrentVersion)
delete static_cast<IdentifierIndexTable *>(IdentifierIndex);
}
-std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode>
+std::pair<GlobalModuleIndex *, llvm::Error>
GlobalModuleIndex::readIndex(StringRef Path) {
// Load the index file, if it's there.
llvm::SmallString<128> IndexPath;
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferOrErr =
llvm::MemoryBuffer::getFile(IndexPath.c_str());
if (!BufferOrErr)
- return std::make_pair(nullptr, EC_NotFound);
+ return std::make_pair(nullptr,
+ llvm::errorCodeToError(BufferOrErr.getError()));
std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(BufferOrErr.get());
/// The main bitstream cursor for the main block.
llvm::BitstreamCursor Cursor(*Buffer);
// Sniff for the signature.
- if (Cursor.Read(8) != 'B' ||
- Cursor.Read(8) != 'C' ||
- Cursor.Read(8) != 'G' ||
- Cursor.Read(8) != 'I') {
- return std::make_pair(nullptr, EC_IOError);
+ for (unsigned char C : {'B', 'C', 'G', 'I'}) {
+ if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = Cursor.Read(8)) {
+ if (Res.get() != C)
+ return std::make_pair(
+ nullptr, llvm::createStringError(std::errc::illegal_byte_sequence,
+ "expected signature BCGI"));
+ } else
+ return std::make_pair(nullptr, Res.takeError());
}
return std::make_pair(new GlobalModuleIndex(std::move(Buffer), Cursor),
- EC_None);
+ llvm::Error::success());
}
void
: FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr) {}
/// Load the contents of the given module file into the builder.
- ///
- /// \returns true if an error occurred, false otherwise.
- bool loadModuleFile(const FileEntry *File);
+ llvm::Error loadModuleFile(const FileEntry *File);
/// Write the index to the given bitstream.
/// \returns true if an error occurred, false otherwise.
};
}
-bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
+llvm::Error GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
// Open the module file.
auto Buffer = FileMgr.getBufferForFile(File, /*isVolatile=*/true);
- if (!Buffer) {
- return true;
- }
+ if (!Buffer)
+ return llvm::createStringError(Buffer.getError(),
+ "failed getting buffer for module file");
// Initialize the input stream
llvm::BitstreamCursor InStream(PCHContainerRdr.ExtractPCH(**Buffer));
// Sniff for the signature.
- if (InStream.Read(8) != 'C' ||
- InStream.Read(8) != 'P' ||
- InStream.Read(8) != 'C' ||
- InStream.Read(8) != 'H') {
- return true;
- }
+ for (unsigned char C : {'C', 'P', 'C', 'H'})
+ if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = InStream.Read(8)) {
+ if (Res.get() != C)
+ return llvm::createStringError(std::errc::illegal_byte_sequence,
+ "expected signature CPCH");
+ } else
+ return Res.takeError();
// Record this module file and assign it a unique ID (if it doesn't have
// one already).
enum { Other, ControlBlock, ASTBlock, DiagnosticOptionsBlock } State = Other;
bool Done = false;
while (!Done) {
- llvm::BitstreamEntry Entry = InStream.advance();
+ Expected<llvm::BitstreamEntry> MaybeEntry = InStream.advance();
+ if (!MaybeEntry)
+ return MaybeEntry.takeError();
+ llvm::BitstreamEntry Entry = MaybeEntry.get();
+
switch (Entry.Kind) {
case llvm::BitstreamEntry::Error:
Done = true;
case llvm::BitstreamEntry::Record:
// In the 'other' state, just skip the record. We don't care.
if (State == Other) {
- InStream.skipRecord(Entry.ID);
- continue;
+ if (llvm::Expected<unsigned> Skipped = InStream.skipRecord(Entry.ID))
+ continue;
+ else
+ return Skipped.takeError();
}
// Handle potentially-interesting records below.
case llvm::BitstreamEntry::SubBlock:
if (Entry.ID == CONTROL_BLOCK_ID) {
- if (InStream.EnterSubBlock(CONTROL_BLOCK_ID))
- return true;
+ if (llvm::Error Err = InStream.EnterSubBlock(CONTROL_BLOCK_ID))
+ return Err;
// Found the control block.
State = ControlBlock;
}
if (Entry.ID == AST_BLOCK_ID) {
- if (InStream.EnterSubBlock(AST_BLOCK_ID))
- return true;
+ if (llvm::Error Err = InStream.EnterSubBlock(AST_BLOCK_ID))
+ return Err;
// Found the AST block.
State = ASTBlock;
}
if (Entry.ID == UNHASHED_CONTROL_BLOCK_ID) {
- if (InStream.EnterSubBlock(UNHASHED_CONTROL_BLOCK_ID))
- return true;
+ if (llvm::Error Err = InStream.EnterSubBlock(UNHASHED_CONTROL_BLOCK_ID))
+ return Err;
// Found the Diagnostic Options block.
State = DiagnosticOptionsBlock;
continue;
}
- if (InStream.SkipBlock())
- return true;
+ if (llvm::Error Err = InStream.SkipBlock())
+ return Err;
continue;
// Read the given record.
SmallVector<uint64_t, 64> Record;
StringRef Blob;
- unsigned Code = InStream.readRecord(Entry.ID, Record, &Blob);
+ Expected<unsigned> MaybeCode = InStream.readRecord(Entry.ID, Record, &Blob);
+ if (!MaybeCode)
+ return MaybeCode.takeError();
+ unsigned Code = MaybeCode.get();
// Handle module dependencies.
if (State == ControlBlock && Code == IMPORTS) {
/*cacheFailure=*/false);
if (!DependsOnFile)
- return true;
+ return llvm::createStringError(std::errc::bad_file_descriptor,
+ "imported file \"%s\" not found",
+ ImportedFile.c_str());
// Save the information in ImportedModuleFileInfo so we can verify after
// loading all pcms.
// We don't care about this record.
}
- return false;
+ return llvm::Error::success();
}
namespace {
return false;
}
-GlobalModuleIndex::ErrorCode
+llvm::Error
GlobalModuleIndex::writeIndex(FileManager &FileMgr,
const PCHContainerReader &PCHContainerRdr,
StringRef Path) {
llvm::LockFileManager Locked(IndexPath);
switch (Locked) {
case llvm::LockFileManager::LFS_Error:
- return EC_IOError;
+ return llvm::createStringError(std::errc::io_error, "LFS error");
case llvm::LockFileManager::LFS_Owned:
// We're responsible for building the index ourselves. Do so below.
case llvm::LockFileManager::LFS_Shared:
// Someone else is responsible for building the index. We don't care
// when they finish, so we're done.
- return EC_Building;
+ return llvm::createStringError(std::errc::device_or_resource_busy,
+ "someone else is building the index");
}
// The module index builder.
// in the process of rebuilding a module. They'll rebuild the index
// at the end of that translation unit, so we don't have to.
if (llvm::sys::path::extension(D->path()) == ".pcm.lock")
- return EC_Building;
+ return llvm::createStringError(std::errc::device_or_resource_busy,
+ "someone else is building the index");
continue;
}
continue;
// Load this module file.
- if (Builder.loadModuleFile(ModuleFile))
- return EC_IOError;
+ if (llvm::Error Err = Builder.loadModuleFile(ModuleFile))
+ return Err;
}
// The output buffer, into which the global index will be written.
{
llvm::BitstreamWriter OutputStream(OutputBuffer);
if (Builder.writeIndex(OutputStream))
- return EC_IOError;
+ return llvm::createStringError(std::errc::io_error,
+ "failed writing index");
}
// Write the global index file to a temporary file.
int TmpFD;
if (llvm::sys::fs::createUniqueFile(IndexPath + "-%%%%%%%%", TmpFD,
IndexTmpPath))
- return EC_IOError;
+ return llvm::createStringError(std::errc::io_error,
+ "failed creating unique file");
// Open the temporary global index file for output.
llvm::raw_fd_ostream Out(TmpFD, true);
if (Out.has_error())
- return EC_IOError;
+ return llvm::createStringError(Out.error(), "failed outputting to stream");
// Write the index.
Out.write(OutputBuffer.data(), OutputBuffer.size());
Out.close();
if (Out.has_error())
- return EC_IOError;
+ return llvm::createStringError(Out.error(), "failed writing to stream");
// Remove the old index file. It isn't relevant any more.
llvm::sys::fs::remove(IndexPath);
// Rename the newly-written index file to the proper name.
- if (llvm::sys::fs::rename(IndexTmpPath, IndexPath)) {
- // Rename failed; just remove the
+ if (std::error_code Err = llvm::sys::fs::rename(IndexTmpPath, IndexPath)) {
+ // Remove the file on failure, don't check whether removal succeeded.
llvm::sys::fs::remove(IndexTmpPath);
- return EC_IOError;
+ return llvm::createStringError(Err, "failed renaming file \"%s\" to \"%s\"",
+ IndexTmpPath.c_str(), IndexPath.c_str());
}
- // We're done.
- return EC_None;
+ return llvm::Error::success();
}
namespace {