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<
"module '%0' is defined in both '%1' and '%2'">;
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<
"AST file '%0' was not built as a module">, DefaultFatal;

View File

@ -1279,6 +1279,7 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
struct ReadModuleNames : ASTReaderListener {
CompilerInstance &CI;
std::vector<StringRef> ModuleFileStack;
std::vector<StringRef> ModuleNameStack;
bool Failed;
bool TopFileIsModule;
@ -1295,20 +1296,29 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
}
ModuleFileStack.push_back(FileName);
ModuleNameStack.push_back(StringRef());
if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
*this)) {
CI.getDiagnostics().Report(SourceLocation(),
diag::err_module_file_not_found)
CI.getDiagnostics().Report(
SourceLocation(), CI.getFileManager().getBufferForFile(FileName)
? diag::err_module_file_invalid
: diag::err_module_file_not_found)
<< 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;
}
ModuleNameStack.pop_back();
ModuleFileStack.pop_back();
}
void ReadModuleName(StringRef ModuleName) override {
if (ModuleFileStack.size() == 1)
TopFileIsModule = true;
ModuleNameStack.back() = ModuleName;
auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
if (!ModuleFile.empty() &&

View File

@ -148,11 +148,24 @@
// RUN: -fmodule-file=%t/not.pcm \
// 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: -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.