forked from OSchip/llvm-project
[Modules] Change result of reading AST block to llvm::Error instead
Reading the AST block can never fail with a recoverable error as modules cannot be removed during this phase. Change the return type of these functions to return an llvm::Error instead, ie. either success or failure. NFC other than the wording of some of the errors. Differential Revision: https://reviews.llvm.org/D108268
This commit is contained in:
parent
022538f276
commit
a4a5c00b53
|
@ -1320,18 +1320,18 @@ private:
|
|||
ASTReaderListener *Listener,
|
||||
bool ValidateDiagnosticOptions);
|
||||
|
||||
ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
|
||||
ASTReadResult ReadExtensionBlock(ModuleFile &F);
|
||||
llvm::Error ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
|
||||
llvm::Error ReadExtensionBlock(ModuleFile &F);
|
||||
void ReadModuleOffsetMap(ModuleFile &F) const;
|
||||
bool ParseLineTable(ModuleFile &F, const RecordData &Record);
|
||||
bool ReadSourceManagerBlock(ModuleFile &F);
|
||||
void ParseLineTable(ModuleFile &F, const RecordData &Record);
|
||||
llvm::Error ReadSourceManagerBlock(ModuleFile &F);
|
||||
llvm::BitstreamCursor &SLocCursorForID(int ID);
|
||||
SourceLocation getImportLocation(ModuleFile *F);
|
||||
ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
|
||||
const ModuleFile *ImportedBy,
|
||||
unsigned ClientLoadCapabilities);
|
||||
ASTReadResult ReadSubmoduleBlock(ModuleFile &F,
|
||||
unsigned ClientLoadCapabilities);
|
||||
llvm::Error ReadSubmoduleBlock(ModuleFile &F,
|
||||
unsigned ClientLoadCapabilities);
|
||||
static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
|
||||
ASTReaderListener &Listener,
|
||||
bool AllowCompatibleDifferences);
|
||||
|
@ -1904,8 +1904,9 @@ public:
|
|||
/// 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.
|
||||
static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID,
|
||||
uint64_t *StartOfBlockOffset = nullptr);
|
||||
static llvm::Error ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
|
||||
unsigned BlockID,
|
||||
uint64_t *StartOfBlockOffset = nullptr);
|
||||
|
||||
/// Finds all the visible declarations with a given name.
|
||||
/// The current implementation of this method just loads the entire
|
||||
|
|
|
@ -10,15 +10,13 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Basic/OpenMPKinds.h"
|
||||
#include "clang/Serialization/ASTRecordReader.h"
|
||||
#include "ASTCommon.h"
|
||||
#include "ASTReaderInternals.h"
|
||||
#include "clang/AST/AbstractTypeReader.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/ASTMutationListener.h"
|
||||
#include "clang/AST/ASTUnresolvedSet.h"
|
||||
#include "clang/AST/AbstractTypeReader.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclBase.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
|
@ -31,8 +29,8 @@
|
|||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/OpenMPClause.h"
|
||||
#include "clang/AST/ODRHash.h"
|
||||
#include "clang/AST/OpenMPClause.h"
|
||||
#include "clang/AST/RawCommentList.h"
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
#include "clang/AST/TemplateName.h"
|
||||
|
@ -42,6 +40,7 @@
|
|||
#include "clang/AST/UnresolvedSet.h"
|
||||
#include "clang/Basic/CommentOptions.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/DiagnosticError.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Basic/ExceptionSpecificationType.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
|
@ -51,6 +50,7 @@
|
|||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "clang/Basic/ObjCRuntime.h"
|
||||
#include "clang/Basic/OpenMPKinds.h"
|
||||
#include "clang/Basic/OperatorKinds.h"
|
||||
#include "clang/Basic/PragmaKinds.h"
|
||||
#include "clang/Basic/Sanitizers.h"
|
||||
|
@ -76,6 +76,7 @@
|
|||
#include "clang/Sema/Weak.h"
|
||||
#include "clang/Serialization/ASTBitCodes.h"
|
||||
#include "clang/Serialization/ASTDeserializationListener.h"
|
||||
#include "clang/Serialization/ASTRecordReader.h"
|
||||
#include "clang/Serialization/ContinuousRangeMap.h"
|
||||
#include "clang/Serialization/GlobalModuleIndex.h"
|
||||
#include "clang/Serialization/InMemoryModuleCache.h"
|
||||
|
@ -1263,7 +1264,29 @@ void ASTReader::Error(unsigned DiagID, StringRef Arg1, StringRef Arg2,
|
|||
}
|
||||
|
||||
void ASTReader::Error(llvm::Error &&Err) const {
|
||||
Error(toString(std::move(Err)));
|
||||
llvm::Error RemainingErr =
|
||||
handleErrors(std::move(Err), [this](const DiagnosticError &E) {
|
||||
auto Diag = E.getDiagnostic().second;
|
||||
|
||||
// Ideally we'd just emit it, but have to handle a possible in-flight
|
||||
// diagnostic. Note that the location is currently ignored as well.
|
||||
auto NumArgs = Diag.getStorage()->NumDiagArgs;
|
||||
assert(NumArgs <= 3 && "Can only have up to 3 arguments");
|
||||
StringRef Arg1, Arg2, Arg3;
|
||||
switch (NumArgs) {
|
||||
case 3:
|
||||
Arg3 = Diag.getStringArg(2);
|
||||
LLVM_FALLTHROUGH;
|
||||
case 2:
|
||||
Arg2 = Diag.getStringArg(1);
|
||||
LLVM_FALLTHROUGH;
|
||||
case 1:
|
||||
Arg1 = Diag.getStringArg(0);
|
||||
}
|
||||
Error(Diag.getDiagID(), Arg1, Arg2, Arg3);
|
||||
});
|
||||
if (RemainingErr)
|
||||
Error(toString(std::move(RemainingErr)));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1271,9 +1294,7 @@ void ASTReader::Error(llvm::Error &&Err) const {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Read the line table in the source manager block.
|
||||
/// \returns true if there was an error.
|
||||
bool ASTReader::ParseLineTable(ModuleFile &F,
|
||||
const RecordData &Record) {
|
||||
void ASTReader::ParseLineTable(ModuleFile &F, const RecordData &Record) {
|
||||
unsigned Idx = 0;
|
||||
LineTableInfo &LineTable = SourceMgr.getLineTable();
|
||||
|
||||
|
@ -1312,12 +1333,10 @@ bool ASTReader::ParseLineTable(ModuleFile &F,
|
|||
}
|
||||
LineTable.AddEntry(FileID::get(FID), Entries);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Read a source manager block
|
||||
bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
|
||||
llvm::Error ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
|
||||
using namespace SrcMgr;
|
||||
|
||||
BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor;
|
||||
|
@ -1329,36 +1348,29 @@ bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
|
|||
SLocEntryCursor = F.Stream;
|
||||
|
||||
// The stream itself is going to skip over the source manager block.
|
||||
if (llvm::Error Err = F.Stream.SkipBlock()) {
|
||||
Error(std::move(Err));
|
||||
return true;
|
||||
}
|
||||
if (llvm::Error Err = F.Stream.SkipBlock())
|
||||
return Err;
|
||||
|
||||
// Enter the source manager block.
|
||||
if (llvm::Error Err =
|
||||
SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) {
|
||||
Error(std::move(Err));
|
||||
return true;
|
||||
}
|
||||
if (llvm::Error Err = SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID))
|
||||
return Err;
|
||||
F.SourceManagerBlockStartOffset = SLocEntryCursor.GetCurrentBitNo();
|
||||
|
||||
RecordData Record;
|
||||
while (true) {
|
||||
Expected<llvm::BitstreamEntry> MaybeE =
|
||||
SLocEntryCursor.advanceSkippingSubblocks();
|
||||
if (!MaybeE) {
|
||||
Error(MaybeE.takeError());
|
||||
return true;
|
||||
}
|
||||
if (!MaybeE)
|
||||
return MaybeE.takeError();
|
||||
llvm::BitstreamEntry E = MaybeE.get();
|
||||
|
||||
switch (E.Kind) {
|
||||
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
|
||||
case llvm::BitstreamEntry::Error:
|
||||
Error("malformed block record in AST file");
|
||||
return true;
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"malformed block record in AST file");
|
||||
case llvm::BitstreamEntry::EndBlock:
|
||||
return false;
|
||||
return llvm::Error::success();
|
||||
case llvm::BitstreamEntry::Record:
|
||||
// The interesting case.
|
||||
break;
|
||||
|
@ -1369,10 +1381,8 @@ bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
|
|||
StringRef Blob;
|
||||
Expected<unsigned> MaybeRecord =
|
||||
SLocEntryCursor.readRecord(E.ID, Record, &Blob);
|
||||
if (!MaybeRecord) {
|
||||
Error(MaybeRecord.takeError());
|
||||
return true;
|
||||
}
|
||||
if (!MaybeRecord)
|
||||
return MaybeRecord.takeError();
|
||||
switch (MaybeRecord.get()) {
|
||||
default: // Default behavior: ignore.
|
||||
break;
|
||||
|
@ -1381,7 +1391,7 @@ bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
|
|||
case SM_SLOC_BUFFER_ENTRY:
|
||||
case SM_SLOC_EXPANSION_ENTRY:
|
||||
// Once we hit one of the source location entries, we're done.
|
||||
return false;
|
||||
return llvm::Error::success();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1632,13 +1642,11 @@ SourceLocation ASTReader::getImportLocation(ModuleFile *F) {
|
|||
/// 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,
|
||||
uint64_t *StartOfBlockOffset) {
|
||||
if (llvm::Error Err = Cursor.EnterSubBlock(BlockID)) {
|
||||
// FIXME this drops errors on the floor.
|
||||
consumeError(std::move(Err));
|
||||
return true;
|
||||
}
|
||||
llvm::Error ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor,
|
||||
unsigned BlockID,
|
||||
uint64_t *StartOfBlockOffset) {
|
||||
if (llvm::Error Err = Cursor.EnterSubBlock(BlockID))
|
||||
return Err;
|
||||
|
||||
if (StartOfBlockOffset)
|
||||
*StartOfBlockOffset = Cursor.GetCurrentBitNo();
|
||||
|
@ -1646,27 +1654,18 @@ bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID,
|
|||
while (true) {
|
||||
uint64_t Offset = Cursor.GetCurrentBitNo();
|
||||
Expected<unsigned> MaybeCode = Cursor.ReadCode();
|
||||
if (!MaybeCode) {
|
||||
// FIXME this drops errors on the floor.
|
||||
consumeError(MaybeCode.takeError());
|
||||
return true;
|
||||
}
|
||||
if (!MaybeCode)
|
||||
return MaybeCode.takeError();
|
||||
unsigned Code = MaybeCode.get();
|
||||
|
||||
// We expect all abbrevs to be at the start of the block.
|
||||
if (Code != llvm::bitc::DEFINE_ABBREV) {
|
||||
if (llvm::Error Err = Cursor.JumpToBit(Offset)) {
|
||||
// FIXME this drops errors on the floor.
|
||||
consumeError(std::move(Err));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (llvm::Error Err = Cursor.ReadAbbrevRecord()) {
|
||||
// FIXME this drops errors on the floor.
|
||||
consumeError(std::move(Err));
|
||||
return true;
|
||||
if (llvm::Error Err = Cursor.JumpToBit(Offset))
|
||||
return Err;
|
||||
return llvm::Error::success();
|
||||
}
|
||||
if (llvm::Error Err = Cursor.ReadAbbrevRecord())
|
||||
return Err;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2966,30 +2965,27 @@ ASTReader::ReadControlBlock(ModuleFile &F,
|
|||
}
|
||||
}
|
||||
|
||||
ASTReader::ASTReadResult
|
||||
ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
||||
llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
|
||||
unsigned ClientLoadCapabilities) {
|
||||
BitstreamCursor &Stream = F.Stream;
|
||||
|
||||
if (llvm::Error Err = Stream.EnterSubBlock(AST_BLOCK_ID)) {
|
||||
Error(std::move(Err));
|
||||
return Failure;
|
||||
}
|
||||
if (llvm::Error Err = Stream.EnterSubBlock(AST_BLOCK_ID))
|
||||
return Err;
|
||||
F.ASTBlockStartOffset = Stream.GetCurrentBitNo();
|
||||
|
||||
// Read all of the records and blocks for the AST file.
|
||||
RecordData Record;
|
||||
while (true) {
|
||||
Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
|
||||
if (!MaybeEntry) {
|
||||
Error(MaybeEntry.takeError());
|
||||
return Failure;
|
||||
}
|
||||
if (!MaybeEntry)
|
||||
return MaybeEntry.takeError();
|
||||
llvm::BitstreamEntry Entry = MaybeEntry.get();
|
||||
|
||||
switch (Entry.Kind) {
|
||||
case llvm::BitstreamEntry::Error:
|
||||
Error("error at end of module block in AST file");
|
||||
return Failure;
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"error at end of module block in AST file");
|
||||
case llvm::BitstreamEntry::EndBlock:
|
||||
// Outside of C++, we do not store a lookup map for the translation unit.
|
||||
// Instead, mark it as needing a lookup map to be built if this module
|
||||
|
@ -3002,7 +2998,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
DC->setMustBuildLookupTable();
|
||||
}
|
||||
|
||||
return Success;
|
||||
return llvm::Error::success();
|
||||
case llvm::BitstreamEntry::SubBlock:
|
||||
switch (Entry.ID) {
|
||||
case DECLTYPES_BLOCK_ID:
|
||||
|
@ -3011,15 +3007,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
// 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 (llvm::Error Err = Stream.SkipBlock()) {
|
||||
Error(std::move(Err));
|
||||
return Failure;
|
||||
}
|
||||
if (ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID,
|
||||
&F.DeclsBlockStartOffset)) {
|
||||
Error("malformed block record in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (llvm::Error Err = Stream.SkipBlock())
|
||||
return Err;
|
||||
if (llvm::Error Err = ReadBlockAbbrevs(
|
||||
F.DeclsCursor, DECLTYPES_BLOCK_ID, &F.DeclsBlockStartOffset))
|
||||
return Err;
|
||||
break;
|
||||
|
||||
case PREPROCESSOR_BLOCK_ID:
|
||||
|
@ -3027,14 +3019,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
if (!PP.getExternalSource())
|
||||
PP.setExternalSource(this);
|
||||
|
||||
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;
|
||||
}
|
||||
if (llvm::Error Err = Stream.SkipBlock())
|
||||
return Err;
|
||||
if (llvm::Error Err =
|
||||
ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID))
|
||||
return Err;
|
||||
F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();
|
||||
break;
|
||||
|
||||
|
@ -3042,14 +3031,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
F.PreprocessorDetailCursor = Stream;
|
||||
|
||||
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;
|
||||
return Err;
|
||||
}
|
||||
if (llvm::Error Err = ReadBlockAbbrevs(F.PreprocessorDetailCursor,
|
||||
PREPROCESSOR_DETAIL_BLOCK_ID))
|
||||
return Err;
|
||||
F.PreprocessorDetailStartOffset
|
||||
= F.PreprocessorDetailCursor.GetCurrentBitNo();
|
||||
|
||||
|
@ -3060,36 +3046,29 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case SOURCE_MANAGER_BLOCK_ID:
|
||||
if (ReadSourceManagerBlock(F))
|
||||
return Failure;
|
||||
if (llvm::Error Err = ReadSourceManagerBlock(F))
|
||||
return Err;
|
||||
break;
|
||||
|
||||
case SUBMODULE_BLOCK_ID:
|
||||
if (ASTReadResult Result =
|
||||
ReadSubmoduleBlock(F, ClientLoadCapabilities))
|
||||
return Result;
|
||||
if (llvm::Error Err = ReadSubmoduleBlock(F, ClientLoadCapabilities))
|
||||
return Err;
|
||||
break;
|
||||
|
||||
case COMMENTS_BLOCK_ID: {
|
||||
BitstreamCursor C = Stream;
|
||||
|
||||
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;
|
||||
}
|
||||
if (llvm::Error Err = Stream.SkipBlock())
|
||||
return Err;
|
||||
if (llvm::Error Err = ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID))
|
||||
return Err;
|
||||
CommentsCursors.push_back(std::make_pair(C, &F));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (llvm::Error Err = Stream.SkipBlock()) {
|
||||
Error(std::move(Err));
|
||||
return Failure;
|
||||
}
|
||||
if (llvm::Error Err = Stream.SkipBlock())
|
||||
return Err;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
|
@ -3104,10 +3083,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
StringRef Blob;
|
||||
Expected<unsigned> MaybeRecordType =
|
||||
Stream.readRecord(Entry.ID, Record, &Blob);
|
||||
if (!MaybeRecordType) {
|
||||
Error(MaybeRecordType.takeError());
|
||||
return Failure;
|
||||
}
|
||||
if (!MaybeRecordType)
|
||||
return MaybeRecordType.takeError();
|
||||
ASTRecordTypes RecordType = (ASTRecordTypes)MaybeRecordType.get();
|
||||
|
||||
// If we're not loading an AST context, we don't care about most records.
|
||||
|
@ -3138,10 +3115,10 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case TYPE_OFFSET: {
|
||||
if (F.LocalNumTypes != 0) {
|
||||
Error("duplicate TYPE_OFFSET record in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (F.LocalNumTypes != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"duplicate TYPE_OFFSET record in AST file");
|
||||
F.TypeOffsets = reinterpret_cast<const UnderalignedInt64 *>(Blob.data());
|
||||
F.LocalNumTypes = Record[0];
|
||||
unsigned LocalBaseTypeIndex = Record[1];
|
||||
|
@ -3162,10 +3139,10 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
}
|
||||
|
||||
case DECL_OFFSET: {
|
||||
if (F.LocalNumDecls != 0) {
|
||||
Error("duplicate DECL_OFFSET record in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (F.LocalNumDecls != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"duplicate DECL_OFFSET record in AST file");
|
||||
F.DeclOffsets = (const DeclOffset *)Blob.data();
|
||||
F.LocalNumDecls = Record[0];
|
||||
unsigned LocalBaseDeclID = Record[1];
|
||||
|
@ -3230,10 +3207,10 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case IDENTIFIER_OFFSET: {
|
||||
if (F.LocalNumIdentifiers != 0) {
|
||||
Error("duplicate IDENTIFIER_OFFSET record in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (F.LocalNumIdentifiers != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"duplicate IDENTIFIER_OFFSET record in AST file");
|
||||
F.IdentifierOffsets = (const uint32_t *)Blob.data();
|
||||
F.LocalNumIdentifiers = Record[0];
|
||||
unsigned LocalBaseIdentifierID = Record[1];
|
||||
|
@ -3284,10 +3261,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (SpecialTypes.size() != Record.size()) {
|
||||
Error("invalid special-types record");
|
||||
return Failure;
|
||||
}
|
||||
if (SpecialTypes.size() != Record.size())
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"invalid special-types record");
|
||||
|
||||
for (unsigned I = 0, N = Record.size(); I != N; ++I) {
|
||||
serialization::TypeID ID = getGlobalTypeID(F, Record[I]);
|
||||
|
@ -3316,10 +3292,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case WEAK_UNDECLARED_IDENTIFIERS:
|
||||
if (Record.size() % 4 != 0) {
|
||||
Error("invalid weak identifiers record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() % 4 != 0)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"invalid weak identifiers record");
|
||||
|
||||
// FIXME: Ignore weak undeclared identifiers from non-original PCH
|
||||
// files. This isn't the way to do it :)
|
||||
|
@ -3426,10 +3401,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
std::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
|
||||
SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,
|
||||
SLocSpaceSize);
|
||||
if (!F.SLocEntryBaseID) {
|
||||
Error("ran out of source locations");
|
||||
break;
|
||||
}
|
||||
if (!F.SLocEntryBaseID)
|
||||
return llvm::createStringError(std::errc::invalid_argument,
|
||||
"ran out of source locations");
|
||||
// Make our entry in the range map. BaseID is negative and growing, so
|
||||
// we invert it. Because we invert it, though, we need the other end of
|
||||
// the range.
|
||||
|
@ -3460,19 +3434,16 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case SOURCE_MANAGER_LINE_TABLE:
|
||||
if (ParseLineTable(F, Record)) {
|
||||
Error("malformed SOURCE_MANAGER_LINE_TABLE in AST file");
|
||||
return Failure;
|
||||
}
|
||||
ParseLineTable(F, Record);
|
||||
break;
|
||||
|
||||
case SOURCE_LOCATION_PRELOADS: {
|
||||
// Need to transform from the local view (1-based IDs) to the global view,
|
||||
// which is based off F.SLocEntryBaseID.
|
||||
if (!F.PreloadSLocEntries.empty()) {
|
||||
Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (!F.PreloadSLocEntries.empty())
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"Multiple SOURCE_LOCATION_PRELOADS records in AST file");
|
||||
|
||||
F.PreloadSLocEntries.swap(Record);
|
||||
break;
|
||||
|
@ -3484,10 +3455,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case VTABLE_USES:
|
||||
if (Record.size() % 3 != 0) {
|
||||
Error("Invalid VTABLE_USES record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() % 3 != 0)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"Invalid VTABLE_USES record");
|
||||
|
||||
// Later tables overwrite earlier ones.
|
||||
// FIXME: Modules will have some trouble with this. This is clearly not
|
||||
|
@ -3503,15 +3473,15 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case PENDING_IMPLICIT_INSTANTIATIONS:
|
||||
if (PendingInstantiations.size() % 2 != 0) {
|
||||
Error("Invalid existing PendingInstantiations");
|
||||
return Failure;
|
||||
}
|
||||
if (PendingInstantiations.size() % 2 != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"Invalid existing PendingInstantiations");
|
||||
|
||||
if (Record.size() % 2 != 0) {
|
||||
Error("Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() % 2 != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
|
||||
|
||||
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
|
||||
PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++]));
|
||||
|
@ -3521,10 +3491,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case SEMA_DECL_REFS:
|
||||
if (Record.size() != 3) {
|
||||
Error("Invalid SEMA_DECL_REFS block");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() != 3)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"Invalid SEMA_DECL_REFS block");
|
||||
for (unsigned I = 0, N = Record.size(); I != N; ++I)
|
||||
SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
|
||||
break;
|
||||
|
@ -3580,10 +3549,10 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
}
|
||||
|
||||
case DECL_UPDATE_OFFSETS:
|
||||
if (Record.size() % 2 != 0) {
|
||||
Error("invalid DECL_UPDATE_OFFSETS block in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() % 2 != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"invalid DECL_UPDATE_OFFSETS block in AST file");
|
||||
for (unsigned I = 0, N = Record.size(); I != N; I += 2) {
|
||||
GlobalDeclID ID = getGlobalDeclID(F, Record[I]);
|
||||
DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1]));
|
||||
|
@ -3597,10 +3566,10 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case OBJC_CATEGORIES_MAP:
|
||||
if (F.LocalNumObjCCategoriesInMap != 0) {
|
||||
Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (F.LocalNumObjCCategoriesInMap != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"duplicate OBJC_CATEGORIES_MAP record in AST file");
|
||||
|
||||
F.LocalNumObjCCategoriesInMap = Record[0];
|
||||
F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)Blob.data();
|
||||
|
@ -3665,15 +3634,13 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case UNDEFINED_BUT_USED:
|
||||
if (UndefinedButUsed.size() % 2 != 0) {
|
||||
Error("Invalid existing UndefinedButUsed");
|
||||
return Failure;
|
||||
}
|
||||
if (UndefinedButUsed.size() % 2 != 0)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"Invalid existing UndefinedButUsed");
|
||||
|
||||
if (Record.size() % 2 != 0) {
|
||||
Error("invalid undefined-but-used record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() % 2 != 0)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"invalid undefined-but-used record");
|
||||
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
|
||||
UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++]));
|
||||
UndefinedButUsed.push_back(
|
||||
|
@ -3712,10 +3679,10 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case MACRO_OFFSET: {
|
||||
if (F.LocalNumMacros != 0) {
|
||||
Error("duplicate MACRO_OFFSET record in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (F.LocalNumMacros != 0)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"duplicate MACRO_OFFSET record in AST file");
|
||||
F.MacroOffsets = (const uint32_t *)Blob.data();
|
||||
F.LocalNumMacros = Record[0];
|
||||
unsigned LocalBaseMacroID = Record[1];
|
||||
|
@ -3743,26 +3710,24 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case OPTIMIZE_PRAGMA_OPTIONS:
|
||||
if (Record.size() != 1) {
|
||||
Error("invalid pragma optimize record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() != 1)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"invalid pragma optimize record");
|
||||
OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]);
|
||||
break;
|
||||
|
||||
case MSSTRUCT_PRAGMA_OPTIONS:
|
||||
if (Record.size() != 1) {
|
||||
Error("invalid pragma ms_struct record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() != 1)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"invalid pragma ms_struct record");
|
||||
PragmaMSStructState = Record[0];
|
||||
break;
|
||||
|
||||
case POINTERS_TO_MEMBERS_PRAGMA_OPTIONS:
|
||||
if (Record.size() != 2) {
|
||||
Error("invalid pragma ms_struct record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() != 2)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"invalid pragma pointers to members record");
|
||||
PragmaMSPointersToMembersState = Record[0];
|
||||
PointersToMembersPragmaLocation = ReadSourceLocation(F, Record[1]);
|
||||
break;
|
||||
|
@ -3774,18 +3739,16 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH:
|
||||
if (Record.size() != 1) {
|
||||
Error("invalid cuda pragma options record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() != 1)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"invalid cuda pragma options record");
|
||||
ForceCUDAHostDeviceDepth = Record[0];
|
||||
break;
|
||||
|
||||
case ALIGN_PACK_PRAGMA_OPTIONS: {
|
||||
if (Record.size() < 3) {
|
||||
Error("invalid pragma pack record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() < 3)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"invalid pragma pack record");
|
||||
PragmaAlignPackCurrentValue = ReadAlignPackInfo(Record[0]);
|
||||
PragmaAlignPackCurrentLocation = ReadSourceLocation(F, Record[1]);
|
||||
unsigned NumStackEntries = Record[2];
|
||||
|
@ -3805,10 +3768,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
}
|
||||
|
||||
case FLOAT_CONTROL_PRAGMA_OPTIONS: {
|
||||
if (Record.size() < 3) {
|
||||
Error("invalid pragma pack record");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() < 3)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"invalid pragma float control record");
|
||||
FpPragmaCurrentValue = FPOptionsOverride::getFromOpaqueInt(Record[0]);
|
||||
FpPragmaCurrentLocation = ReadSourceLocation(F, Record[1]);
|
||||
unsigned NumStackEntries = Record[2];
|
||||
|
@ -4269,16 +4231,23 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
|
|||
return ReadResult;
|
||||
}
|
||||
|
||||
// Here comes stuff that we only do once the entire chain is loaded.
|
||||
// Here comes stuff that we only do once the entire chain is loaded. Do *not*
|
||||
// remove modules from this point. Various fields are updated during reading
|
||||
// the AST block and removing the modules would result in dangling pointers.
|
||||
// They are generally only incidentally dereferenced, ie. a binary search
|
||||
// runs over `GlobalSLocEntryMap`, which could cause an invalid module to
|
||||
// be dereferenced but it wouldn't actually be used.
|
||||
|
||||
// Load the AST blocks of all of the modules that we loaded. We can still
|
||||
// Load the AST blocks of all of the modules that we loaded. We can still
|
||||
// hit errors parsing the ASTs at this point.
|
||||
for (ImportedModule &M : Loaded) {
|
||||
ModuleFile &F = *M.Mod;
|
||||
|
||||
// Read the AST block.
|
||||
if (ReadASTBlock(F, ClientLoadCapabilities))
|
||||
if (llvm::Error Err = ReadASTBlock(F, ClientLoadCapabilities)) {
|
||||
Error(std::move(Err));
|
||||
return Failure;
|
||||
}
|
||||
|
||||
// The AST block should always have a definition for the main module.
|
||||
if (F.isModule() && !F.DidReadTopLevelSubmodule) {
|
||||
|
@ -4288,8 +4257,10 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
|
|||
|
||||
// Read the extension blocks.
|
||||
while (!SkipCursorToBlock(F.Stream, EXTENSION_BLOCK_ID)) {
|
||||
if (ReadExtensionBlock(F))
|
||||
if (llvm::Error Err = ReadExtensionBlock(F)) {
|
||||
Error(std::move(Err));
|
||||
return Failure;
|
||||
}
|
||||
}
|
||||
|
||||
// Once read, set the ModuleFile bit base offset and update the size in
|
||||
|
@ -4810,32 +4781,26 @@ static bool parseModuleFileExtensionMetadata(
|
|||
return false;
|
||||
}
|
||||
|
||||
ASTReader::ASTReadResult ASTReader::ReadExtensionBlock(ModuleFile &F) {
|
||||
llvm::Error ASTReader::ReadExtensionBlock(ModuleFile &F) {
|
||||
BitstreamCursor &Stream = F.Stream;
|
||||
|
||||
RecordData Record;
|
||||
while (true) {
|
||||
Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
|
||||
if (!MaybeEntry) {
|
||||
Error(MaybeEntry.takeError());
|
||||
return Failure;
|
||||
}
|
||||
if (!MaybeEntry)
|
||||
return MaybeEntry.takeError();
|
||||
llvm::BitstreamEntry Entry = MaybeEntry.get();
|
||||
|
||||
switch (Entry.Kind) {
|
||||
case llvm::BitstreamEntry::SubBlock:
|
||||
if (llvm::Error Err = Stream.SkipBlock()) {
|
||||
Error(std::move(Err));
|
||||
return Failure;
|
||||
}
|
||||
if (llvm::Error Err = Stream.SkipBlock())
|
||||
return Err;
|
||||
continue;
|
||||
|
||||
case llvm::BitstreamEntry::EndBlock:
|
||||
return Success;
|
||||
|
||||
return llvm::Error::success();
|
||||
case llvm::BitstreamEntry::Error:
|
||||
return HadErrors;
|
||||
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"malformed block record in AST file");
|
||||
case llvm::BitstreamEntry::Record:
|
||||
break;
|
||||
}
|
||||
|
@ -4844,17 +4809,15 @@ ASTReader::ASTReadResult ASTReader::ReadExtensionBlock(ModuleFile &F) {
|
|||
StringRef Blob;
|
||||
Expected<unsigned> MaybeRecCode =
|
||||
Stream.readRecord(Entry.ID, Record, &Blob);
|
||||
if (!MaybeRecCode) {
|
||||
Error(MaybeRecCode.takeError());
|
||||
return Failure;
|
||||
}
|
||||
if (!MaybeRecCode)
|
||||
return MaybeRecCode.takeError();
|
||||
switch (MaybeRecCode.get()) {
|
||||
case EXTENSION_METADATA: {
|
||||
ModuleFileExtensionMetadata Metadata;
|
||||
if (parseModuleFileExtensionMetadata(Record, Blob, Metadata)) {
|
||||
Error("malformed EXTENSION_METADATA in AST file");
|
||||
return Failure;
|
||||
}
|
||||
if (parseModuleFileExtensionMetadata(Record, Blob, Metadata))
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"malformed EXTENSION_METADATA in AST file");
|
||||
|
||||
// Find a module file extension with this block name.
|
||||
auto Known = ModuleFileExtensions.find(Metadata.BlockName);
|
||||
|
@ -4871,7 +4834,7 @@ ASTReader::ASTReadResult ASTReader::ReadExtensionBlock(ModuleFile &F) {
|
|||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
void ASTReader::InitializeContext() {
|
||||
|
@ -5451,13 +5414,11 @@ bool ASTReader::isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
|
|||
/*ValidateDiagnosticOptions=*/true);
|
||||
}
|
||||
|
||||
ASTReader::ASTReadResult
|
||||
ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
||||
llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
|
||||
unsigned ClientLoadCapabilities) {
|
||||
// Enter the submodule block.
|
||||
if (llvm::Error Err = F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {
|
||||
Error(std::move(Err));
|
||||
return Failure;
|
||||
}
|
||||
if (llvm::Error Err = F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID))
|
||||
return Err;
|
||||
|
||||
ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
|
||||
bool First = true;
|
||||
|
@ -5466,19 +5427,17 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
while (true) {
|
||||
Expected<llvm::BitstreamEntry> MaybeEntry =
|
||||
F.Stream.advanceSkippingSubblocks();
|
||||
if (!MaybeEntry) {
|
||||
Error(MaybeEntry.takeError());
|
||||
return Failure;
|
||||
}
|
||||
if (!MaybeEntry)
|
||||
return MaybeEntry.takeError();
|
||||
llvm::BitstreamEntry Entry = MaybeEntry.get();
|
||||
|
||||
switch (Entry.Kind) {
|
||||
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
|
||||
case llvm::BitstreamEntry::Error:
|
||||
Error("malformed block record in AST file");
|
||||
return Failure;
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"malformed block record in AST file");
|
||||
case llvm::BitstreamEntry::EndBlock:
|
||||
return Success;
|
||||
return llvm::Error::success();
|
||||
case llvm::BitstreamEntry::Record:
|
||||
// The interesting case.
|
||||
break;
|
||||
|
@ -5488,16 +5447,14 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
StringRef Blob;
|
||||
Record.clear();
|
||||
Expected<unsigned> MaybeKind = F.Stream.readRecord(Entry.ID, Record, &Blob);
|
||||
if (!MaybeKind) {
|
||||
Error(MaybeKind.takeError());
|
||||
return Failure;
|
||||
}
|
||||
if (!MaybeKind)
|
||||
return MaybeKind.takeError();
|
||||
unsigned Kind = MaybeKind.get();
|
||||
|
||||
if ((Kind == SUBMODULE_METADATA) != First) {
|
||||
Error("submodule metadata record should be at beginning of block");
|
||||
return Failure;
|
||||
}
|
||||
if ((Kind == SUBMODULE_METADATA) != First)
|
||||
return llvm::createStringError(
|
||||
std::errc::illegal_byte_sequence,
|
||||
"submodule metadata record should be at beginning of block");
|
||||
First = false;
|
||||
|
||||
// Submodule information is only valid if we have a current module.
|
||||
|
@ -5511,10 +5468,9 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
break;
|
||||
|
||||
case SUBMODULE_DEFINITION: {
|
||||
if (Record.size() < 12) {
|
||||
Error("malformed module definition");
|
||||
return Failure;
|
||||
}
|
||||
if (Record.size() < 12)
|
||||
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||
"malformed module definition");
|
||||
|
||||
StringRef Name = Blob;
|
||||
unsigned Idx = 0;
|
||||
|
@ -5546,10 +5502,9 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
|
||||
SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
|
||||
if (GlobalIndex >= SubmodulesLoaded.size() ||
|
||||
SubmodulesLoaded[GlobalIndex]) {
|
||||
Error("too many submodules");
|
||||
return Failure;
|
||||
}
|
||||
SubmodulesLoaded[GlobalIndex])
|
||||
return llvm::createStringError(std::errc::invalid_argument,
|
||||
"too many submodules");
|
||||
|
||||
if (!ParentModule) {
|
||||
if (const FileEntry *CurFile = CurrentModule->getASTFile()) {
|
||||
|
@ -5557,10 +5512,12 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||
if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation &
|
||||
DisableValidationForModuleKind::Module) &&
|
||||
CurFile != F.File) {
|
||||
Error(diag::err_module_file_conflict,
|
||||
CurrentModule->getTopLevelModuleName(), CurFile->getName(),
|
||||
F.File->getName());
|
||||
return Failure;
|
||||
auto ConflictError =
|
||||
PartialDiagnostic(diag::err_module_file_conflict,
|
||||
ContextObj->DiagAllocator)
|
||||
<< CurrentModule->getTopLevelModuleName() << CurFile->getName()
|
||||
<< F.File->getName();
|
||||
return DiagnosticError::create(CurrentImportLoc, ConflictError);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue