diff options
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSerializationKinds.td | 2 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 23 | ||||
| -rw-r--r-- | clang/test/PCH/modified-module-dependency.m | 20 | ||||
| -rw-r--r-- | clang/test/PCH/modified-module-dependency.module.map | 4 |
4 files changed, 45 insertions, 4 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td index 81509cc1882..fe1de9db6f7 100644 --- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -22,6 +22,8 @@ def err_fe_pch_file_modified : Error< DefaultFatal; def err_fe_pch_file_overridden : Error< "file '%0' from the precompiled header has been overridden">; +def note_pch_required_by : Note<"'%0' required by '%1'">; +def note_pch_rebuild_required : Note<"please rebuild precompiled header '%0'">; def note_module_cache_path : Note< "after modifying system headers, please delete the module cache at '%0'">; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 26281cc747c..76f62f5e71a 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1729,11 +1729,26 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { #endif )) { if (Complain) { - Error(diag::err_fe_pch_file_modified, Filename, F.FileName); - if (Context.getLangOpts().Modules && !Diags.isDiagnosticInFlight()) { - Diag(diag::note_module_cache_path) - << PP.getHeaderSearchInfo().getModuleCachePath(); + // Build a list of the PCH imports that got us here (in reverse). + SmallVector<ModuleFile *, 4> ImportStack(1, &F); + while (ImportStack.back()->ImportedBy.size() > 0) + ImportStack.push_back(ImportStack.back()->ImportedBy[0]); + + // The top-level PCH is stale. + StringRef TopLevelPCHName(ImportStack.back()->FileName); + Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName); + + // Print the import stack. + if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) { + Diag(diag::note_pch_required_by) + << Filename << ImportStack[0]->FileName; + for (unsigned I = 1; I < ImportStack.size(); ++I) + Diag(diag::note_pch_required_by) + << ImportStack[I-1]->FileName << ImportStack[I]->FileName; } + + if (!Diags.isDiagnosticInFlight()) + Diag(diag::note_pch_rebuild_required) << TopLevelPCHName; } IsOutOfDate = true; diff --git a/clang/test/PCH/modified-module-dependency.m b/clang/test/PCH/modified-module-dependency.m new file mode 100644 index 00000000000..656fa345655 --- /dev/null +++ b/clang/test/PCH/modified-module-dependency.m @@ -0,0 +1,20 @@ +// RUN: rm -rf %t-dir +// RUN: mkdir -p %t-dir +// RUN: echo '@import test;' > %t-dir/prefix.h +// RUN: echo 'void foo(void);' > %t-dir/test.h +// RUN: cp %S/modified-module-dependency.module.map %t-dir/module.map + +// Precompile prefix.pch. +// RUN: %clang_cc1 -x objective-c -I %t-dir -fmodules -fmodules-cache-path=%t-dir/cache -emit-pch %t-dir/prefix.h -o %t-dir/prefix.pch + +// Modify the dependency. +// RUN: echo ' ' >> %t-dir/test.h + +// Run and check the diagnostics. +// RUN: not %clang_cc1 -x objective-c -include-pch %t-dir/prefix.pch -fmodules -fmodules-cache-path=%t-dir/cache -fsyntax-only %s 2> %t-dir/log +// RUN: FileCheck %s < %t-dir/log + +// CHECK: file '{{.*}}/test.h' has been modified since the precompiled header '{{.*}}prefix.pch' was built +// CHECK: '{{.*}}/test.h' required by '{{.*}}/test.pcm' +// CHECK: '{{.*}}/test.pcm' required by '{{.*}}/prefix.pch' +// CHECK: please rebuild precompiled header '{{.*}}/prefix.pch' diff --git a/clang/test/PCH/modified-module-dependency.module.map b/clang/test/PCH/modified-module-dependency.module.map new file mode 100644 index 00000000000..b4706778f89 --- /dev/null +++ b/clang/test/PCH/modified-module-dependency.module.map @@ -0,0 +1,4 @@ +module test { + header "test.h" + export * +} |

