[PCH/modules] Require the preprocessing record option to match the used PCH, if modules are enabled.

The preprocessing record becomes important when modules are enabled, since it is used to calculate the
module cache hash.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180635 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 7137404..1b45b10 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -58,6 +58,10 @@
     "%select{command line contains|precompiled header was built with}0 "
     "'-undef' but %select{precompiled header was not built with it|"
     "it is not present on the command line}0">;
+def err_pch_pp_detailed_record : Error<
+    "%select{command line contains|precompiled header was built with}0 "
+    "'-detailed-preprocessing-record' but %select{precompiled header was not "
+    "built with it|it is not present on the command line}0">;
 
 def err_not_a_pch_file : Error<
     "'%0' does not appear to be a precompiled header file">, DefaultFatal;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 20d0404..9406c74 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -257,7 +257,8 @@
                                      const PreprocessorOptions &ExistingPPOpts,
                                      DiagnosticsEngine *Diags,
                                      FileManager &FileMgr,
-                                     std::string &SuggestedPredefines) {
+                                     std::string &SuggestedPredefines,
+                                     const LangOptions &LangOpts) {
   // Check macro definitions.
   MacroDefinitionsMap ASTFileMacros;
   collectMacroDefinitions(PPOpts, ASTFileMacros);
@@ -323,6 +324,15 @@
     return true;
   }
 
+  // Detailed record is important since it is used for the module cache hash.
+  if (LangOpts.Modules &&
+      PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord) {
+    if (Diags) {
+      Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord;
+    }
+    return true;
+  }
+
   // Compute the #include and #include_macros lines we need.
   for (unsigned I = 0, N = ExistingPPOpts.Includes.size(); I != N; ++I) {
     StringRef File = ExistingPPOpts.Includes[I];
@@ -363,7 +373,8 @@
   return checkPreprocessorOptions(PPOpts, ExistingPPOpts,
                                   Complain? &Reader.Diags : 0,
                                   PP.getFileManager(),
-                                  SuggestedPredefines);
+                                  SuggestedPredefines,
+                                  PP.getLangOpts());
 }
 
 void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
@@ -3427,7 +3438,7 @@
                                          bool Complain,
                                          std::string &SuggestedPredefines) {
       return checkPreprocessorOptions(ExistingPPOpts, PPOpts, 0, FileMgr,
-                                      SuggestedPredefines);
+                                      SuggestedPredefines, ExistingLangOpts);
     }
   };
 }
@@ -4004,6 +4015,7 @@
   }
 
   PPOpts.UsePredefines = Record[Idx++];
+  PPOpts.DetailedRecord = Record[Idx++];
   PPOpts.ImplicitPCHInclude = ReadString(Record, Idx);
   PPOpts.ImplicitPTHInclude = ReadString(Record, Idx);
   PPOpts.ObjCXXARCStandardLibrary =
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index ba53bda..9d9d619 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1170,6 +1170,8 @@
     AddString(PPOpts.MacroIncludes[I], Record);
 
   Record.push_back(PPOpts.UsePredefines);
+  // Detailed record is important since it is used for the module cache hash.
+  Record.push_back(PPOpts.DetailedRecord);
   AddString(PPOpts.ImplicitPCHInclude, Record);
   AddString(PPOpts.ImplicitPTHInclude, Record);
   Record.push_back(static_cast<unsigned>(PPOpts.ObjCXXARCStandardLibrary));
diff --git a/test/Index/targeted-annotation.c b/test/Index/targeted-annotation.c
index cfa1046..022a139 100644
--- a/test/Index/targeted-annotation.c
+++ b/test/Index/targeted-annotation.c
@@ -82,10 +82,10 @@
 // TOP: Identifier: "TARGETED_TOP_H" [2:9 - 2:23] preprocessing directive=
 // TOP: Punctuation: "#" [3:1 - 3:2] preprocessing directive=
 // TOP: Identifier: "define" [3:2 - 3:8] preprocessing directive=
-// TOP: Identifier: "TARGETED_TOP_H" [3:9 - 3:23] preprocessing directive=
-// TOP: Punctuation: "#" [5:1 - 5:2] preprocessing directive=
-// TOP: Identifier: "include" [5:2 - 5:9] preprocessing directive=
-// TOP: Literal: ""targeted-nested1.h"" [5:10 - 5:30] preprocessing directive=
+// TOP: Identifier: "TARGETED_TOP_H" [3:9 - 3:23] macro definition=TARGETED_TOP_H
+// TOP: Punctuation: "#" [5:1 - 5:2] inclusion directive=targeted-nested1.h
+// TOP: Identifier: "include" [5:2 - 5:9] inclusion directive=targeted-nested1.h
+// TOP: Literal: ""targeted-nested1.h"" [5:10 - 5:30] inclusion directive=targeted-nested1.h
 // TOP: Keyword: "enum" [7:1 - 7:5] EnumDecl=:7:1 (Definition)
 // TOP: Punctuation: "{" [7:6 - 7:7] EnumDecl=:7:1 (Definition)
 // TOP: Identifier: "VALUE" [8:3 - 8:8] EnumConstantDecl=VALUE:8:3 (Definition)
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 9b083e4..3f39a78 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -3508,6 +3508,7 @@
                                   unsaved_files,
                                   num_unsaved_files,
                                   CXTranslationUnit_Incomplete |
+                                  CXTranslationUnit_DetailedPreprocessingRecord|
                                     CXTranslationUnit_ForSerialization);
   if (!TU) {
     fprintf(stderr, "Unable to load translation unit!\n");