Wire up -import-module to run ReadAST for each module loaded.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136987 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h
index f461e9e..040b845 100644
--- a/include/clang/Frontend/PreprocessorOptions.h
+++ b/include/clang/Frontend/PreprocessorOptions.h
@@ -41,6 +41,7 @@
 public:
   std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
   std::vector<std::string> Includes;
+  std::vector<std::string> Modules;
   std::vector<std::string> MacroIncludes;
 
   unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index b2bd759..88c972c 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -775,6 +775,10 @@
     Res.push_back("-include");
     Res.push_back(Opts.Includes[i]);
   }
+  for (unsigned i = 0, e = Opts.Modules.size(); i != e; ++i) {
+    Res.push_back("-import_module");
+    Res.push_back(Opts.Modules[i]);
+  }
   for (unsigned i = 0, e = Opts.MacroIncludes.size(); i != e; ++i) {
     Res.push_back("-imacros");
     Res.push_back(Opts.MacroIncludes[i]);
@@ -1807,6 +1811,12 @@
     Opts.ChainedIncludes.push_back(A->getValue(Args));
   }
 
+  for (arg_iterator it = Args.filtered_begin(OPT_import_module),
+      ie = Args.filtered_end(); it != ie; ++it) {
+    const Arg *A = *it;
+    Opts.Modules.push_back(A->getValue(Args));
+  }
+
   // Include 'altivec.h' if -faltivec option present
   if (Args.hasArg(OPT_faltivec))
     Opts.Includes.push_back("altivec.h");
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 89d95fc..0753686 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -20,6 +20,7 @@
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Parse/ParseAST.h"
 #include "clang/Serialization/ASTDeserializationListener.h"
+#include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ChainedIncludesSource.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Timer.h"
@@ -239,6 +240,30 @@
                                 DeserialListener);
       if (!CI.getASTContext().getExternalSource())
         goto failure;
+    } else if (!CI.getPreprocessorOpts().Modules.empty()) {
+      // Use PCH.
+      assert(hasPCHSupport() && "This action does not have PCH support!");
+      ASTDeserializationListener *DeserialListener =
+          Consumer->GetASTDeserializationListener();
+      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls)
+        DeserialListener = new DeserializedDeclsDumper(DeserialListener);
+      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty())
+        DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(),
+                         CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
+                                                        DeserialListener);
+
+      CI.createPCHExternalASTSource(CI.getPreprocessorOpts().Modules[0],
+                                    true, true, DeserialListener);
+
+      for (unsigned I = 1, E = CI.getPreprocessorOpts().Modules.size(); I != E;
+          ++I) {
+
+        ASTReader *ModMgr = CI.getModuleManager();
+        ModMgr->ReadAST(CI.getPreprocessorOpts().Modules[I],
+            serialization::MK_Module);
+      }
+      if (!CI.getASTContext().getExternalSource())
+        goto failure;
     }
 
     CI.setASTConsumer(Consumer.take());
@@ -246,7 +271,7 @@
       goto failure;
   }
 
-  // Initialize builtin info as long as we aren't using an external AST
+  // Initialize built-in info as long as we aren't using an external AST
   // source.
   if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
     Preprocessor &PP = CI.getPreprocessor();