diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h index f461e9ea076f0f1e08e9b9dbb6e19be4297109fc..040b8451998714598883efd0c11073e4e6b33c31 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 b2bd759dc283d67fc2550fbbbb336b9509607297..88c972c82818a91ce862886db7a8d528a14ec96e 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 89d95fc97d8125139d1d0903992649425e8194a5..0753686a3476ced51d90aa0e3b13d04184088d5f 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();