diff options
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 103 |
1 files changed, 80 insertions, 23 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index ff771fd00a3..29a935c9099 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2029,6 +2029,21 @@ void ASTReader::ResolveImportedPath(std::string &Filename, StringRef Prefix) { Filename.assign(Buffer.begin(), Buffer.end()); } +static bool isDiagnosedResult(ASTReader::ASTReadResult ARR, unsigned Caps) { + switch (ARR) { + case ASTReader::Failure: return true; + case ASTReader::Missing: return !(Caps & ASTReader::ARR_Missing); + case ASTReader::OutOfDate: return !(Caps & ASTReader::ARR_OutOfDate); + case ASTReader::VersionMismatch: return !(Caps & ASTReader::ARR_VersionMismatch); + case ASTReader::ConfigurationMismatch: + return !(Caps & ASTReader::ARR_ConfigurationMismatch); + case ASTReader::HadErrors: return true; + case ASTReader::Success: return false; + } + + llvm_unreachable("unknown ASTReadResult"); +} + ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, SmallVectorImpl<ImportedModule> &Loaded, @@ -2064,8 +2079,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, PP.getHeaderSearchInfo().getHeaderSearchOpts(); // All user input files reside at the index range [0, NumUserInputs), and - // system input files reside at [NumUserInputs, NumInputs). - if (!DisableValidation) { + // system input files reside at [NumUserInputs, NumInputs). For explicitly + // loaded module files, ignore missing inputs. + if (!DisableValidation && F.Kind != MK_ExplicitModule) { bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; // If we are reading a module, we will create a verification timestamp, @@ -2181,10 +2197,23 @@ ASTReader::ReadControlBlock(ModuleFile &F, ASTFileSignature StoredSignature = Record[Idx++]; auto ImportedFile = ReadPath(F, Record, Idx); + // If our client can't cope with us being out of date, we can't cope with + // our dependency being missing. + unsigned Capabilities = ClientLoadCapabilities; + if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) + Capabilities &= ~ARR_Missing; + // Load the AST file. - switch(ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, Loaded, - StoredSize, StoredModTime, StoredSignature, - ClientLoadCapabilities)) { + auto Result = ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, + Loaded, StoredSize, StoredModTime, + StoredSignature, Capabilities); + + // If we diagnosed a problem, produce a backtrace. + if (isDiagnosedResult(Result, Capabilities)) + Diag(diag::note_module_file_imported_by) + << F.FileName << !F.ModuleName.empty() << F.ModuleName; + + switch (Result) { case Failure: return Failure; // If we have to ignore the dependency, we'll have to ignore this too. case Missing: @@ -3152,11 +3181,18 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr; if (!ModMap) { assert(ImportedBy && "top-level import should be verified"); - if ((ClientLoadCapabilities & ARR_Missing) == 0) - Diag(diag::err_imported_module_not_found) << F.ModuleName << F.FileName - << ImportedBy->FileName - << F.ModuleMapPath; - return Missing; + if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) { + if (auto *ASTFE = M ? M->getASTFile() : nullptr) + // This module was defined by an imported (explicit) module. + Diag(diag::err_module_file_conflict) << F.ModuleName << F.FileName + << ASTFE->getName(); + else + // This module was built with a different module map. + Diag(diag::err_imported_module_not_found) + << F.ModuleName << F.FileName << ImportedBy->FileName + << F.ModuleMapPath; + } + return OutOfDate; } assert(M->Name == F.ModuleName && "found module with different name"); @@ -3557,6 +3593,20 @@ static bool startsWithASTFileMagic(BitstreamCursor &Stream) { Stream.Read(8) == 'H'; } +static unsigned moduleKindForDiagnostic(ModuleKind Kind) { + switch (Kind) { + case MK_PCH: + return 0; // PCH + case MK_ImplicitModule: + case MK_ExplicitModule: + return 1; // module + case MK_MainFile: + case MK_Preamble: + return 2; // main source file + } + llvm_unreachable("unknown module kind"); +} + ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, ModuleKind Type, @@ -3589,11 +3639,9 @@ ASTReader::ReadASTCore(StringRef FileName, return Missing; // Otherwise, return an error. - { - std::string Msg = "Unable to load module \"" + FileName.str() + "\": " - + ErrorStr; - Error(Msg); - } + Diag(diag::err_module_file_not_found) << moduleKindForDiagnostic(Type) + << FileName << ErrorStr.empty() + << ErrorStr; return Failure; case ModuleManager::OutOfDate: @@ -3603,11 +3651,9 @@ ASTReader::ReadASTCore(StringRef FileName, return OutOfDate; // Otherwise, return an error. - { - std::string Msg = "Unable to load module \"" + FileName.str() + "\": " - + ErrorStr; - Error(Msg); - } + Diag(diag::err_module_file_out_of_date) << moduleKindForDiagnostic(Type) + << FileName << ErrorStr.empty() + << ErrorStr; return Failure; } @@ -3628,7 +3674,8 @@ ASTReader::ReadASTCore(StringRef FileName, // Sniff for the signature. if (!startsWithASTFileMagic(Stream)) { - Diag(diag::err_not_a_pch_file) << FileName; + Diag(diag::err_module_file_invalid) << moduleKindForDiagnostic(Type) + << FileName; return Failure; } @@ -3661,6 +3708,18 @@ ASTReader::ReadASTCore(StringRef FileName, HaveReadControlBlock = true; switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) { case Success: + // Check that we didn't try to load a non-module AST file as a module. + // + // FIXME: Should we also perform the converse check? Loading a module as + // a PCH file sort of works, but it's a bit wonky. + if ((Type == MK_ImplicitModule || Type == MK_ExplicitModule) && + F.ModuleName.empty()) { + auto Result = (Type == MK_ImplicitModule) ? OutOfDate : Failure; + if (Result != OutOfDate || + (ClientLoadCapabilities & ARR_OutOfDate) == 0) + Diag(diag::err_module_file_not_module) << FileName; + return Result; + } break; case Failure: return Failure; @@ -3690,8 +3749,6 @@ ASTReader::ReadASTCore(StringRef FileName, break; } } - - return Success; } void ASTReader::InitializeContext() { |