From e735e2deb9e57d9b62c1258ee236ccfeba8e84b2 Mon Sep 17 00:00:00 2001
From: "Jonathan D. Turner" <jonathan.d.turner@gmail.com>
Date: Fri, 5 Aug 2011 22:17:03 +0000
Subject: [PATCH] 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
---
 include/clang/Frontend/PreprocessorOptions.h |  1 +
 lib/Frontend/CompilerInvocation.cpp          | 10 ++++++++
 lib/Frontend/FrontendAction.cpp              | 27 +++++++++++++++++++-
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h
index f461e9ea076..040b8451998 100644
--- a/include/clang/Frontend/PreprocessorOptions.h
+++ b/include/clang/Frontend/PreprocessorOptions.h
@@ -41,6 +41,7 @@ class PreprocessorOptions {
 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 b2bd759dc28..88c972c8281 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -775,6 +775,10 @@ static void PreprocessorOptsToArgs(const PreprocessorOptions &Opts,
     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 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
     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 89d95fc97d8..0753686a347 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 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                 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 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
       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();
-- 
GitLab