summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSerializationKinds.td2
-rw-r--r--clang/lib/Serialization/ASTReader.cpp23
-rw-r--r--clang/test/PCH/modified-module-dependency.m20
-rw-r--r--clang/test/PCH/modified-module-dependency.module.map4
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 *
+}
OpenPOWER on IntegriCloud