Preliminary PCH support in the driver

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69410 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 5afcefe..67e92c2 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -45,7 +45,7 @@
     Host(0),
     CCCIsCXX(false), CCCEcho(false), CCCPrintBindings(false),
     CCCGenericGCCName("gcc"), CCCUseClang(true), CCCUseClangCXX(false), 
-    CCCUseClangCPP(true),
+    CCCUseClangCPP(true), CCCUsePCH(false),
     SuppressMissingInputWarning(false)
 {
   // Only use clang on i386 and x86_64 by default.
@@ -142,6 +142,10 @@
 
     } else if (!strcmp(Opt, "clang-cxx")) {
       CCCUseClangCXX = true;
+    } else if (!strcmp(Opt, "pch-is-pch")) {
+      CCCUsePCH = true;
+    } else if (!strcmp(Opt, "pch-is-pth")) {
+      CCCUsePCH = false;
     } else if (!strcmp(Opt, "no-clang")) {
       CCCUseClang = false;
     } else if (!strcmp(Opt, "no-clang-cpp")) {
@@ -287,6 +291,10 @@
     OptionHelp.push_back(std::make_pair("-ccc-clang-archs",
                                         "Comma separate list of architectures "
                                         "to use the clang compiler for"));
+    OptionHelp.push_back(std::make_pair("-ccc-pch-is-pch",
+                                     "Use lazy PCH for precompiled headers"));
+    OptionHelp.push_back(std::make_pair("-ccc-pch-is-pth",
+                         "Use pretokenized headers for precompiled headers"));
 
     OptionHelp.push_back(std::make_pair("\nDEBUG/DEVELOPMENT OPTIONS:",""));
     OptionHelp.push_back(std::make_pair("-ccc-host-triple",
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index ad83fe7..8256142 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -31,7 +31,8 @@
 using namespace clang::driver;
 using namespace clang::driver::tools;
 
-void Clang::AddPreprocessingOptions(const ArgList &Args,
+void Clang::AddPreprocessingOptions(const Driver &D, 
+                                    const ArgList &Args,
                                     ArgStringList &CmdArgs,
                                     const InputInfo &Output,
                                     const InputInfoList &Inputs) const {
@@ -94,10 +95,11 @@
 
   // FIXME: Use iterator.
 
-  // Add -i* options, and automatically translate to -include-pth for
-  // transparent PCH support. It's wonky, but we include looking for
-  // .gch so we can support seamless replacement into a build system
-  // already set up to be generating .gch files.
+  // Add -i* options, and automatically translate to
+  // -include-pch/-include-pth for transparent PCH support. It's
+  // wonky, but we include looking for .gch so we can support seamless
+  // replacement into a build system already set up to be generating
+  // .gch files.
   for (ArgList::const_iterator
          it = Args.begin(), ie = Args.end(); it != ie; ++it) {
     const Arg *A = *it;
@@ -106,20 +108,40 @@
 
     if (A->getOption().matches(options::OPT_include)) {
       bool FoundPTH = false;
+      bool FoundPCH = false;
       llvm::sys::Path P(A->getValue(Args));
-      P.appendSuffix("pth");
-      if (P.exists()) {
-        FoundPTH = true;
-      } else {
-        P.eraseSuffix();
-        P.appendSuffix("gch");
+      if (D.CCCUsePCH) {
+        P.appendSuffix("pch");
         if (P.exists())
-          FoundPTH = true;
+          FoundPCH = true;
+        else 
+          P.eraseSuffix();
       }
 
-      if (FoundPTH) {
+      if (!FoundPCH) {
+        P.appendSuffix("pth");
+        if (P.exists()) 
+          FoundPTH = true;
+        else
+          P.eraseSuffix();
+      } 
+      
+      if (!FoundPCH && !FoundPTH) {
+        P.appendSuffix("gch");
+        if (P.exists()) {
+          FoundPCH = D.CCCUsePCH;
+          FoundPTH = !D.CCCUsePCH;
+        }
+        else 
+          P.eraseSuffix();
+      }
+
+      if (FoundPCH || FoundPTH) {
         A->claim();
-        CmdArgs.push_back("-include-pth");
+        if (FoundPCH)
+          CmdArgs.push_back("-include-pch");
+        else
+          CmdArgs.push_back("-include-pth");
         CmdArgs.push_back(Args.MakeArgString(P.c_str()));
         continue;
       }
@@ -168,7 +190,10 @@
     else
       CmdArgs.push_back("-E");
   } else if (isa<PrecompileJobAction>(JA)) {
-    CmdArgs.push_back("-emit-pth");
+    if (D.CCCUsePCH)
+      CmdArgs.push_back("-emit-pch");
+    else
+      CmdArgs.push_back("-emit-pth");
   } else {
     assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
 
@@ -380,7 +405,7 @@
   // FIXME: Support -fpreprocessed
   types::ID InputType = Inputs[0].getType();
   if (types::getPreprocessedType(InputType) != types::TY_INVALID)
-    AddPreprocessingOptions(Args, CmdArgs, Output, Inputs);
+    AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs);
 
   // Manually translate -O to -O1 and -O4 to -O3; let clang reject
   // others.
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index 7be2706..8b66495 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -18,6 +18,8 @@
 
 namespace clang {
 namespace driver {
+  class Driver;
+
 namespace toolchains {
   class Darwin_X86;
 }
@@ -25,7 +27,8 @@
 namespace tools {
 
   class VISIBILITY_HIDDEN Clang : public Tool {
-    void AddPreprocessingOptions(const ArgList &Args,
+    void AddPreprocessingOptions(const Driver &D,
+                                 const ArgList &Args,
                                  ArgStringList &CmdArgs,
                                  const InputInfo &Output,
                                  const InputInfoList &Inputs) const;