Give better diagnostics when -fmodule-file= finds a bad file: if the file is

found indirectly, explain how we got there, and distinguish between 'file not
found' and 'file found but invalid'.

llvm-svn: 230839
This commit is contained in:
Richard Smith 2015-02-28 03:09:52 +00:00
parent 9ef0d1c145
commit 37bd29a5e6
3 changed files with 33 additions and 6 deletions

View File

@ -197,7 +197,11 @@ def err_conflicting_module_names : Error<
def err_conflicting_module_files : Error< def err_conflicting_module_files : Error<
"module '%0' is defined in both '%1' and '%2'">; "module '%0' is defined in both '%1' and '%2'">;
def err_module_file_not_found : Error< def err_module_file_not_found : Error<
"file '%0' is not a precompiled module file">, DefaultFatal; "module file '%0' not found">, DefaultFatal;
def err_module_file_invalid : Error<
"file '%0' is not a valid precompiled module file">, DefaultFatal;
def note_module_file_imported_by : Note<
"imported by %select{|module '%2' in }1'%0'">;
def err_module_file_not_module : Error< def err_module_file_not_module : Error<
"AST file '%0' was not built as a module">, DefaultFatal; "AST file '%0' was not built as a module">, DefaultFatal;

View File

@ -1279,6 +1279,7 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
struct ReadModuleNames : ASTReaderListener { struct ReadModuleNames : ASTReaderListener {
CompilerInstance &CI; CompilerInstance &CI;
std::vector<StringRef> ModuleFileStack; std::vector<StringRef> ModuleFileStack;
std::vector<StringRef> ModuleNameStack;
bool Failed; bool Failed;
bool TopFileIsModule; bool TopFileIsModule;
@ -1295,20 +1296,29 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
} }
ModuleFileStack.push_back(FileName); ModuleFileStack.push_back(FileName);
ModuleNameStack.push_back(StringRef());
if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(), if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
*this)) { *this)) {
CI.getDiagnostics().Report(SourceLocation(), CI.getDiagnostics().Report(
diag::err_module_file_not_found) SourceLocation(), CI.getFileManager().getBufferForFile(FileName)
? diag::err_module_file_invalid
: diag::err_module_file_not_found)
<< FileName; << FileName;
// FIXME: Produce a note stack explaining how we got here. for (int I = ModuleFileStack.size() - 2; I >= 0; --I)
CI.getDiagnostics().Report(SourceLocation(),
diag::note_module_file_imported_by)
<< ModuleFileStack[I]
<< !ModuleNameStack[I].empty() << ModuleNameStack[I];
Failed = true; Failed = true;
} }
ModuleNameStack.pop_back();
ModuleFileStack.pop_back(); ModuleFileStack.pop_back();
} }
void ReadModuleName(StringRef ModuleName) override { void ReadModuleName(StringRef ModuleName) override {
if (ModuleFileStack.size() == 1) if (ModuleFileStack.size() == 1)
TopFileIsModule = true; TopFileIsModule = true;
ModuleNameStack.back() = ModuleName;
auto &ModuleFile = CI.ModuleFileOverrides[ModuleName]; auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
if (!ModuleFile.empty() && if (!ModuleFile.empty() &&

View File

@ -148,11 +148,24 @@
// RUN: -fmodule-file=%t/not.pcm \ // RUN: -fmodule-file=%t/not.pcm \
// RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-BAD-FILE %s // RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-BAD-FILE %s
// //
// CHECK-BAD-FILE: fatal error: file '{{.*}}not.pcm' is not a valid precompiled module file
// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \ // RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
// RUN: -fmodule-file=%t/nonexistent.pcm \ // RUN: -fmodule-file=%t/nonexistent.pcm \
// RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-BAD-FILE %s // RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-NO-FILE %s
// //
// CHECK-BAD-FILE: fatal error: file '{{.*}}t.pcm' is not a precompiled module file // CHECK-NO-FILE: fatal error: module file '{{.*}}nonexistent.pcm' not found
// RUN: mv %t/a.pcm %t/a-tmp.pcm
// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
// RUN: -I%S/Inputs/explicit-build \
// RUN: -fmodule-file=%t/c.pcm \
// RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-NO-FILE-INDIRECT %s
// RUN: mv %t/a-tmp.pcm %t/a.pcm
//
// CHECK-NO-FILE-INDIRECT: error: module file '{{.*}}a.pcm' not found
// CHECK-NO-FILE-INDIRECT-NEXT: note: imported by module 'b' in '{{.*}}b.pcm'
// CHECK-NO-FILE-INDIRECT-NEXT: note: imported by module 'c' in '{{.*}}c.pcm'
// ------------------------------- // -------------------------------
// Check that we don't get upset if B's timestamp is newer than C's. // Check that we don't get upset if B's timestamp is newer than C's.