<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Nov 14, 2012, at 9:42 PM, Nick Lewycky <<a href="mailto:nlewycky@google.com">nlewycky@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-family:arial,helvetica,sans-serif;font-size:10pt">Please consider this for the clang 3.2 branch. It's a recent regression that will affect people trying to use clang as a drop-in replacement for gcc (myself, and I imagine the freebsd folks and clang/Debian project).<br></div></blockquote><div><br></div>Approved.</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>- Doug</div><div><br><blockquote type="cite"><div style="font-family:arial,helvetica,sans-serif;font-size:10pt"><div class="gmail_quote">On 14 November 2012 21:36, Nick Lewycky <span dir="ltr"><<a href="mailto:nicholas@mxc.ca" target="_blank">nicholas@mxc.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Author: nicholas<br>
Date: Wed Nov 14 23:36:36 2012<br>
New Revision: 168024<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=168024&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=168024&view=rev</a><br>
Log:<br>
Revert r167567, restoring the ability of clang to run gcc in cases where it<br>
can't handle the input file type. This resulted in PR14338.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Driver/Driver.h<br>
    cfe/trunk/include/clang/Driver/Types.h<br>
    cfe/trunk/lib/Driver/Driver.cpp<br>
    cfe/trunk/lib/Driver/ToolChains.cpp<br>
    cfe/trunk/lib/Driver/Tools.cpp<br>
    cfe/trunk/lib/Driver/Tools.h<br>
    cfe/trunk/lib/Driver/Types.cpp<br>
    cfe/trunk/lib/Driver/WindowsToolChain.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Driver/Driver.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=168024&r1=168023&r2=168024&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=168024&r1=168023&r2=168024&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Driver/Driver.h (original)<br>
+++ cfe/trunk/include/clang/Driver/Driver.h Wed Nov 14 23:36:36 2012<br>
@@ -363,6 +363,11 @@<br>
   /// GCC goes to extra lengths here to be a bit more robust.<br>
   std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const;<br>
<br>
+  /// ShouldUseClangCompilar - Should the clang compiler be used to<br>
+  /// handle this action.<br>
+  bool ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,<br>
+                              const llvm::Triple &ArchName) const;<br>
+<br>
   bool IsUsingLTO(const ArgList &Args) const;<br>
<br>
 private:<br>
<br>
Modified: cfe/trunk/include/clang/Driver/Types.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Types.h?rev=168024&r1=168023&r2=168024&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Types.h?rev=168024&r1=168023&r2=168024&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Driver/Types.h (original)<br>
+++ cfe/trunk/include/clang/Driver/Types.h Wed Nov 14 23:36:36 2012<br>
@@ -56,6 +56,9 @@<br>
   /// types).<br>
   bool canLipoType(ID Id);<br>
<br>
+  /// isAcceptedByClang - Can clang handle this input type.<br>
+  bool isAcceptedByClang(ID Id);<br>
+<br>
   /// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).<br>
   bool isCXX(ID Id);<br>
<br>
<br>
Modified: cfe/trunk/lib/Driver/Driver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=168024&r1=168023&r2=168024&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=168024&r1=168023&r2=168024&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Driver/Driver.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Driver.cpp Wed Nov 14 23:36:36 2012<br>
@@ -1731,6 +1731,22 @@<br>
   return *TC;<br>
 }<br>
<br>
+bool Driver::ShouldUseClangCompiler(const Compilation &C, const JobAction &JA,<br>
+                                    const llvm::Triple &Triple) const {<br>
+  // Check if user requested no clang, or clang doesn't understand this type (we<br>
+  // only handle single inputs for now).<br>
+  if (JA.size() != 1 ||<br>
+      !types::isAcceptedByClang((*JA.begin())->getType()))<br>
+    return false;<br>
+<br>
+  // Otherwise make sure this is an action clang understands.<br>
+  if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&<br>
+      !isa<CompileJobAction>(JA))<br>
+    return false;<br>
+<br>
+  return true;<br>
+}<br>
+<br>
 /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the<br>
 /// grouped values as integers. Numbers which are not provided are set to 0.<br>
 ///<br>
<br>
Modified: cfe/trunk/lib/Driver/ToolChains.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=168024&r1=168023&r2=168024&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=168024&r1=168023&r2=168024&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)<br>
+++ cfe/trunk/lib/Driver/ToolChains.cpp Wed Nov 14 23:36:36 2012<br>
@@ -177,6 +177,12 @@<br>
 Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,<br>
                          const ActionList &Inputs) const {<br>
   Action::ActionClass Key = JA.getKind();<br>
+<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) {<br>
+    // FIXME: This seems like a hacky way to choose clang frontend.<br>
+    Key = Action::AnalyzeJobClass;<br>
+  }<br>
+<br>
   bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,<br>
                                              options::OPT_no_integrated_as,<br>
                                              IsIntegratedAssemblerDefault());<br>
@@ -188,11 +194,13 @@<br>
     case Action::BindArchClass:<br>
       llvm_unreachable("Invalid tool kind.");<br>
     case Action::PreprocessJobClass:<br>
+      T = new tools::darwin::Preprocess(*this); break;<br>
     case Action::AnalyzeJobClass:<br>
     case Action::MigrateJobClass:<br>
+      T = new tools::Clang(*this); break;<br>
     case Action::PrecompileJobClass:<br>
     case Action::CompileJobClass:<br>
-      T = new tools::Clang(*this); break;<br>
+      T = new tools::darwin::Compile(*this); break;<br>
     case Action::AssembleJobClass: {<br>
       if (UseIntegratedAs)<br>
         T = new tools::ClangAs(*this);<br>
@@ -1326,7 +1334,11 @@<br>
 Tool &Generic_GCC::SelectTool(const Compilation &C,<br>
                               const JobAction &JA,<br>
                               const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
<br>
   Tool *&T = Tools[Key];<br>
   if (!T) {<br>
@@ -1335,11 +1347,14 @@<br>
     case Action::BindArchClass:<br>
       llvm_unreachable("Invalid tool kind.");<br>
     case Action::PreprocessJobClass:<br>
+      T = new tools::gcc::Preprocess(*this); break;<br>
     case Action::PrecompileJobClass:<br>
+      T = new tools::gcc::Precompile(*this); break;<br>
     case Action::AnalyzeJobClass:<br>
     case Action::MigrateJobClass:<br>
-    case Action::CompileJobClass:<br>
       T = new tools::Clang(*this); break;<br>
+    case Action::CompileJobClass:<br>
+      T = new tools::gcc::Compile(*this); break;<br>
     case Action::AssembleJobClass:<br>
       T = new tools::gcc::Assemble(*this); break;<br>
     case Action::LinkJobClass:<br>
@@ -1389,18 +1404,27 @@<br>
 Tool &Hexagon_TC::SelectTool(const Compilation &C,<br>
                              const JobAction &JA,<br>
                              const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  //   if (JA.getKind () == Action::CompileJobClass)<br>
+  //     Key = JA.getKind ();<br>
+  //     else<br>
+<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
+  //   if ((JA.getKind () == Action::CompileJobClass)<br>
+  //     && (JA.getType () != types::TY_LTO_BC)) {<br>
+  //     Key = JA.getKind ();<br>
+  //   }<br>
+<br>
   Tool *&T = Tools[Key];<br>
   if (!T) {<br>
     switch (Key) {<br>
     case Action::InputClass:<br>
     case Action::BindArchClass:<br>
       assert(0 && "Invalid tool kind.");<br>
-    case Action::PreprocessJobClass:<br>
-    case Action::PrecompileJobClass:<br>
     case Action::AnalyzeJobClass:<br>
-    case Action::MigrateJobClass:<br>
-    case Action::CompileJobClass:<br>
       T = new tools::Clang(*this); break;<br>
     case Action::AssembleJobClass:<br>
       T = new tools::hexagon::Assemble(*this); break;<br>
@@ -1484,7 +1508,12 @@<br>
<br>
 Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA,<br>
                           const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
+<br>
   bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,<br>
                                              options::OPT_no_integrated_as,<br>
                                              IsIntegratedAssemblerDefault());<br>
@@ -1519,7 +1548,12 @@<br>
<br>
 Tool &Bitrig::SelectTool(const Compilation &C, const JobAction &JA,<br>
                          const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
+<br>
   bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,<br>
                                              options::OPT_no_integrated_as,<br>
                                              IsIntegratedAssemblerDefault());<br>
@@ -1606,7 +1640,12 @@<br>
<br>
 Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA,<br>
                           const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
+<br>
   bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,<br>
                                              options::OPT_no_integrated_as,<br>
                                              IsIntegratedAssemblerDefault());<br>
@@ -1650,7 +1689,12 @@<br>
<br>
 Tool &NetBSD::SelectTool(const Compilation &C, const JobAction &JA,<br>
                          const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
+<br>
   bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,<br>
                                              options::OPT_no_integrated_as,<br>
                                              IsIntegratedAssemblerDefault());<br>
@@ -1685,7 +1729,11 @@<br>
<br>
 Tool &Minix::SelectTool(const Compilation &C, const JobAction &JA,<br>
                         const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
<br>
   Tool *&T = Tools[Key];<br>
   if (!T) {<br>
@@ -1722,7 +1770,11 @@<br>
<br>
 Tool &AuroraUX::SelectTool(const Compilation &C, const JobAction &JA,<br>
                            const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
<br>
   Tool *&T = Tools[Key];<br>
   if (!T) {<br>
@@ -1755,7 +1807,11 @@<br>
<br>
 Tool &Solaris::SelectTool(const Compilation &C, const JobAction &JA,<br>
                            const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
<br>
   Tool *&T = Tools[Key];<br>
   if (!T) {<br>
@@ -2128,7 +2184,12 @@<br>
<br>
 Tool &Linux::SelectTool(const Compilation &C, const JobAction &JA,<br>
                         const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
+<br>
   bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,<br>
                                              options::OPT_no_integrated_as,<br>
                                              IsIntegratedAssemblerDefault());<br>
@@ -2346,7 +2407,11 @@<br>
<br>
 Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA,<br>
                             const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
<br>
   Tool *&T = Tools[Key];<br>
   if (!T) {<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=168024&r1=168023&r2=168024&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=168024&r1=168023&r2=168024&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tools.cpp Wed Nov 14 23:36:36 2012<br>
@@ -257,7 +257,7 @@<br>
                A->getOption().matches(options::OPT_MM)) {<br>
       DepFile = "-";<br>
     } else {<br>
-      DepFile = getDependencyFileName(Args, Inputs);<br>
+      DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);<br>
       C.addFailureResultFile(DepFile);<br>
     }<br>
     CmdArgs.push_back("-dependency-file");<br>
@@ -1713,10 +1713,10 @@<br>
   // Set the main file name, so that debug info works even with<br>
   // -save-temps.<br>
   CmdArgs.push_back("-main-file-name");<br>
-  CmdArgs.push_back(getBaseInputName(Args, Inputs));<br>
+  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));<br>
<br>
   // Some flags which affect the language (via preprocessor<br>
-  // defines).<br>
+  // defines). See darwin::CC1::AddCPPArgs.<br>
   if (Args.hasArg(options::OPT_static))<br>
     CmdArgs.push_back("-static-define");<br>
<br>
@@ -3636,14 +3636,38 @@<br>
     .Default(llvm::Triple::UnknownArch);<br>
 }<br>
<br>
-const char *Clang::getBaseInputName(const ArgList &Args,<br>
-                                    const InputInfoList &Inputs) {<br>
+const char *darwin::CC1::getCC1Name(types::ID Type) const {<br>
+  switch (Type) {<br>
+  default:<br>
+    llvm_unreachable("Unexpected type for Darwin CC1 tool.");<br>
+  case types::TY_Asm:<br>
+  case types::TY_C: case types::TY_CHeader:<br>
+  case types::TY_PP_C: case types::TY_PP_CHeader:<br>
+    return "cc1";<br>
+  case types::TY_ObjC: case types::TY_ObjCHeader:<br>
+  case types::TY_PP_ObjC: case types::TY_PP_ObjC_Alias:<br>
+  case types::TY_PP_ObjCHeader:<br>
+    return "cc1obj";<br>
+  case types::TY_CXX: case types::TY_CXXHeader:<br>
+  case types::TY_PP_CXX: case types::TY_PP_CXXHeader:<br>
+    return "cc1plus";<br>
+  case types::TY_ObjCXX: case types::TY_ObjCXXHeader:<br>
+  case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXX_Alias:<br>
+  case types::TY_PP_ObjCXXHeader:<br>
+    return "cc1objplus";<br>
+  }<br>
+}<br>
+<br>
+void darwin::CC1::anchor() {}<br>
+<br>
+const char *darwin::CC1::getBaseInputName(const ArgList &Args,<br>
+                                          const InputInfoList &Inputs) {<br>
   return Args.MakeArgString(<br>
     llvm::sys::path::filename(Inputs[0].getBaseInput()));<br>
 }<br>
<br>
-const char *Clang::getBaseInputStem(const ArgList &Args,<br>
-                                    const InputInfoList &Inputs) {<br>
+const char *darwin::CC1::getBaseInputStem(const ArgList &Args,<br>
+                                          const InputInfoList &Inputs) {<br>
   const char *Str = getBaseInputName(Args, Inputs);<br>
<br>
   if (const char *End = strrchr(Str, '.'))<br>
@@ -3652,8 +3676,9 @@<br>
   return Str;<br>
 }<br>
<br>
-const char *Clang::getDependencyFileName(const ArgList &Args,<br>
-                                         const InputInfoList &Inputs) {<br>
+const char *<br>
+darwin::CC1::getDependencyFileName(const ArgList &Args,<br>
+                                   const InputInfoList &Inputs) {<br>
   // FIXME: Think about this more.<br>
   std::string Res;<br>
<br>
@@ -3661,11 +3686,588 @@<br>
     std::string Str(OutputOpt->getValue());<br>
     Res = Str.substr(0, Str.rfind('.'));<br>
   } else {<br>
-    Res = getBaseInputStem(Args, Inputs);<br>
+    Res = darwin::CC1::getBaseInputStem(Args, Inputs);<br>
   }<br>
   return Args.MakeArgString(Res + ".d");<br>
 }<br>
<br>
+void darwin::CC1::RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const {<br>
+  for (ArgStringList::iterator it = CmdArgs.begin(), ie = CmdArgs.end();<br>
+       it != ie;) {<br>
+<br>
+    StringRef Option = *it;<br>
+    bool RemoveOption = false;<br>
+<br>
+    // Erase both -fmodule-cache-path and its argument.<br>
+    if (Option.equals("-fmodule-cache-path") && it+2 != ie) {<br>
+      it = CmdArgs.erase(it, it+2);<br>
+      ie = CmdArgs.end();<br>
+      continue;<br>
+    }<br>
+<br>
+    // Remove unsupported -f options.<br>
+    if (Option.startswith("-f")) {<br>
+      // Remove -f/-fno- to reduce the number of cases.<br>
+      if (Option.startswith("-fno-"))<br>
+        Option = Option.substr(5);<br>
+      else<br>
+        Option = Option.substr(2);<br>
+      RemoveOption = llvm::StringSwitch<bool>(Option)<br>
+        .Case("altivec", true)<br>
+        .Case("modules", true)<br>
+        .Case("diagnostics-show-note-include-stack", true)<br>
+        .Default(false);<br>
+    }<br>
+<br>
+    // Handle machine specific options.<br>
+    if (Option.startswith("-m")) {<br>
+      RemoveOption = llvm::StringSwitch<bool>(Option)<br>
+        .Case("-mthumb", true)<br>
+        .Case("-mno-thumb", true)<br>
+        .Case("-mno-fused-madd", true)<br>
+        .Case("-mlong-branch", true)<br>
+        .Case("-mlongcall", true)<br>
+        .Case("-mcpu=G4", true)<br>
+        .Case("-mcpu=G5", true)<br>
+        .Default(false);<br>
+    }<br>
+<br>
+    // Handle warning options.<br>
+    if (Option.startswith("-W")) {<br>
+      // Remove -W/-Wno- to reduce the number of cases.<br>
+      if (Option.startswith("-Wno-"))<br>
+        Option = Option.substr(5);<br>
+      else<br>
+        Option = Option.substr(2);<br>
+<br>
+      RemoveOption = llvm::StringSwitch<bool>(Option)<br>
+        .Case("address-of-temporary", true)<br>
+        .Case("ambiguous-member-template", true)<br>
+        .Case("analyzer-incompatible-plugin", true)<br>
+        .Case("array-bounds", true)<br>
+        .Case("array-bounds-pointer-arithmetic", true)<br>
+        .Case("bind-to-temporary-copy", true)<br>
+        .Case("bitwise-op-parentheses", true)<br>
+        .Case("bool-conversions", true)<br>
+        .Case("builtin-macro-redefined", true)<br>
+        .Case("c++-hex-floats", true)<br>
+        .Case("c++0x-compat", true)<br>
+        .Case("c++0x-extensions", true)<br>
+        .Case("c++0x-narrowing", true)<br>
+        .Case("c++11-compat", true)<br>
+        .Case("c++11-extensions", true)<br>
+        .Case("c++11-narrowing", true)<br>
+        .Case("conditional-uninitialized", true)<br>
+        .Case("constant-conversion", true)<br>
+        .Case("conversion-null", true)<br>
+        .Case("CFString-literal", true)<br>
+        .Case("constant-logical-operand", true)<br>
+        .Case("custom-atomic-properties", true)<br>
+        .Case("default-arg-special-member", true)<br>
+        .Case("delegating-ctor-cycles", true)<br>
+        .Case("delete-non-virtual-dtor", true)<br>
+        .Case("deprecated-implementations", true)<br>
+        .Case("deprecated-writable-strings", true)<br>
+        .Case("distributed-object-modifiers", true)<br>
+        .Case("duplicate-method-arg", true)<br>
+        .Case("dynamic-class-memaccess", true)<br>
+        .Case("enum-compare", true)<br>
+        .Case("enum-conversion", true)<br>
+        .Case("exit-time-destructors", true)<br>
+        .Case("gnu", true)<br>
+        .Case("gnu-designator", true)<br>
+        .Case("header-hygiene", true)<br>
+        .Case("idiomatic-parentheses", true)<br>
+        .Case("ignored-qualifiers", true)<br>
+        .Case("implicit-atomic-properties", true)<br>
+        .Case("incompatible-pointer-types", true)<br>
+        .Case("incomplete-implementation", true)<br>
+        .Case("int-conversion", true)<br>
+        .Case("initializer-overrides", true)<br>
+        .Case("invalid-noreturn", true)<br>
+        .Case("invalid-token-paste", true)<br>
+        .Case("language-extension-token", true)<br>
+        .Case("literal-conversion", true)<br>
+        .Case("literal-range", true)<br>
+        .Case("local-type-template-args", true)<br>
+        .Case("logical-op-parentheses", true)<br>
+        .Case("method-signatures", true)<br>
+        .Case("microsoft", true)<br>
+        .Case("mismatched-tags", true)<br>
+        .Case("missing-method-return-type", true)<br>
+        .Case("non-pod-varargs", true)<br>
+        .Case("nonfragile-abi2", true)<br>
+        .Case("null-arithmetic", true)<br>
+        .Case("null-dereference", true)<br>
+        .Case("out-of-line-declaration", true)<br>
+        .Case("overriding-method-mismatch", true)<br>
+        .Case("readonly-setter-attrs", true)<br>
+        .Case("return-stack-address", true)<br>
+        .Case("self-assign", true)<br>
+        .Case("semicolon-before-method-body", true)<br>
+        .Case("sentinel", true)<br>
+        .Case("shift-overflow", true)<br>
+        .Case("shift-sign-overflow", true)<br>
+        .Case("sign-conversion", true)<br>
+        .Case("sizeof-array-argument", true)<br>
+        .Case("sizeof-pointer-memaccess", true)<br>
+        .Case("string-compare", true)<br>
+        .Case("super-class-method-mismatch", true)<br>
+        .Case("tautological-compare", true)<br>
+        .Case("typedef-redefinition", true)<br>
+        .Case("typename-missing", true)<br>
+        .Case("undefined-reinterpret-cast", true)<br>
+        .Case("unknown-warning-option", true)<br>
+        .Case("unnamed-type-template-args", true)<br>
+        .Case("unneeded-internal-declaration", true)<br>
+        .Case("unneeded-member-function", true)<br>
+        .Case("unused-comparison", true)<br>
+        .Case("unused-exception-parameter", true)<br>
+        .Case("unused-member-function", true)<br>
+        .Case("unused-result", true)<br>
+        .Case("vector-conversions", true)<br>
+        .Case("vla", true)<br>
+        .Case("used-but-marked-unused", true)<br>
+        .Case("weak-vtables", true)<br>
+        .Default(false);<br>
+    } // if (Option.startswith("-W"))<br>
+    if (RemoveOption) {<br>
+      it = CmdArgs.erase(it);<br>
+      ie = CmdArgs.end();<br>
+    } else {<br>
+      ++it;<br>
+    }<br>
+  }<br>
+}<br>
+<br>
+void darwin::CC1::AddCC1Args(const ArgList &Args,<br>
+                             ArgStringList &CmdArgs) const {<br>
+  const Driver &D = getToolChain().getDriver();<br>
+<br>
+  CheckCodeGenerationOptions(D, Args);<br>
+<br>
+  // Derived from cc1 spec.<br>
+  if ((!Args.hasArg(options::OPT_mkernel) ||<br>
+       (getDarwinToolChain().isTargetIPhoneOS() &&<br>
+        !getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) &&<br>
+      !Args.hasArg(options::OPT_static) &&<br>
+      !Args.hasArg(options::OPT_mdynamic_no_pic))<br>
+    CmdArgs.push_back("-fPIC");<br>
+<br>
+  if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||<br>
+      getToolChain().getTriple().getArch() == llvm::Triple::thumb) {<br>
+    if (!Args.hasArg(options::OPT_fbuiltin_strcat))<br>
+      CmdArgs.push_back("-fno-builtin-strcat");<br>
+    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))<br>
+      CmdArgs.push_back("-fno-builtin-strcpy");<br>
+  }<br>
+<br>
+  if (Args.hasArg(options::OPT_g_Flag) &&<br>
+      !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))<br>
+    CmdArgs.push_back("-feliminate-unused-debug-symbols");<br>
+}<br>
+<br>
+void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,<br>
+                                    const InputInfoList &Inputs,<br>
+                                    const ArgStringList &OutputArgs) const {<br>
+  const Driver &D = getToolChain().getDriver();<br>
+<br>
+  // Derived from cc1_options spec.<br>
+  if (Args.hasArg(options::OPT_fast) ||<br>
+      Args.hasArg(options::OPT_fastf) ||<br>
+      Args.hasArg(options::OPT_fastcp))<br>
+    CmdArgs.push_back("-O3");<br>
+<br>
+  if (Arg *A = Args.getLastArg(options::OPT_pg))<br>
+    if (Args.hasArg(options::OPT_fomit_frame_pointer))<br>
+      D.Diag(diag::err_drv_argument_not_allowed_with)<br>
+        << A->getAsString(Args) << "-fomit-frame-pointer";<br>
+<br>
+  AddCC1Args(Args, CmdArgs);<br>
+<br>
+  if (!Args.hasArg(options::OPT_Q))<br>
+    CmdArgs.push_back("-quiet");<br>
+<br>
+  CmdArgs.push_back("-dumpbase");<br>
+  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_a_Group);<br>
+<br>
+  // FIXME: The goal is to use the user provided -o if that is our<br>
+  // final output, otherwise to drive from the original input<br>
+  // name. Find a clean way to go about this.<br>
+  if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&<br>
+      Args.hasArg(options::OPT_o)) {<br>
+    Arg *OutputOpt = Args.getLastArg(options::OPT_o);<br>
+    CmdArgs.push_back("-auxbase-strip");<br>
+    CmdArgs.push_back(OutputOpt->getValue());<br>
+  } else {<br>
+    CmdArgs.push_back("-auxbase");<br>
+    CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));<br>
+  }<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_g_Group);<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_O);<br>
+  // FIXME: -Wall is getting some special treatment. Investigate.<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_w);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,<br>
+                  options::OPT_trigraphs);<br>
+  if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {<br>
+    // Honor -std-default.<br>
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,<br>
+                              "-std=", /*Joined=*/true);<br>
+  }<br>
+<br>
+  if (Args.hasArg(options::OPT_v))<br>
+    CmdArgs.push_back("-version");<br>
+  if (Args.hasArg(options::OPT_pg) &&<br>
+      getToolChain().SupportsProfiling())<br>
+    CmdArgs.push_back("-p");<br>
+  Args.AddLastArg(CmdArgs, options::OPT_p);<br>
+<br>
+  // The driver treats -fsyntax-only specially.<br>
+  if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||<br>
+      getToolChain().getTriple().getArch() == llvm::Triple::thumb) {<br>
+    // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are<br>
+    // used to inhibit the default -fno-builtin-str{cat,cpy}.<br>
+    //<br>
+    // FIXME: Should we grow a better way to deal with "removing" args?<br>
+    for (arg_iterator it = Args.filtered_begin(options::OPT_f_Group,<br>
+                                               options::OPT_fsyntax_only),<br>
+           ie = Args.filtered_end(); it != ie; ++it) {<br>
+      if (!(*it)->getOption().matches(options::OPT_fbuiltin_strcat) &&<br>
+          !(*it)->getOption().matches(options::OPT_fbuiltin_strcpy)) {<br>
+        (*it)->claim();<br>
+        (*it)->render(Args, CmdArgs);<br>
+      }<br>
+    }<br>
+  } else<br>
+    Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);<br>
+<br>
+  // Claim Clang only -f options, they aren't worth warning about.<br>
+  Args.ClaimAllArgs(options::OPT_f_clang_Group);<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_undef);<br>
+  if (Args.hasArg(options::OPT_Qn))<br>
+    CmdArgs.push_back("-fno-ident");<br>
+<br>
+  // FIXME: This isn't correct.<br>
+  //Args.AddLastArg(CmdArgs, options::OPT__help)<br>
+  //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)<br>
+<br>
+  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());<br>
+<br>
+  // FIXME: Still don't get what is happening here. Investigate.<br>
+  Args.AddAllArgs(CmdArgs, options::OPT__param);<br>
+<br>
+  if (Args.hasArg(options::OPT_fmudflap) ||<br>
+      Args.hasArg(options::OPT_fmudflapth)) {<br>
+    CmdArgs.push_back("-fno-builtin");<br>
+    CmdArgs.push_back("-fno-merge-constants");<br>
+  }<br>
+<br>
+  if (Args.hasArg(options::OPT_coverage)) {<br>
+    CmdArgs.push_back("-fprofile-arcs");<br>
+    CmdArgs.push_back("-ftest-coverage");<br>
+  }<br>
+<br>
+  if (types::isCXX(Inputs[0].getType()))<br>
+    CmdArgs.push_back("-D__private_extern__=extern");<br>
+}<br>
+<br>
+void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,<br>
+                                    const InputInfoList &Inputs,<br>
+                                    const ArgStringList &OutputArgs) const {<br>
+  // Derived from cpp_options<br>
+  AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);<br>
+<br>
+  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());<br>
+<br>
+  AddCC1Args(Args, CmdArgs);<br>
+<br>
+  // NOTE: The code below has some commonality with cpp_options, but<br>
+  // in classic gcc style ends up sending things in different<br>
+  // orders. This may be a good merge candidate once we drop pedantic<br>
+  // compatibility.<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,<br>
+                  options::OPT_trigraphs);<br>
+  if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {<br>
+    // Honor -std-default.<br>
+    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,<br>
+                              "-std=", /*Joined=*/true);<br>
+  }<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_w);<br>
+<br>
+  // The driver treats -fsyntax-only specially.<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);<br>
+<br>
+  // Claim Clang only -f options, they aren't worth warning about.<br>
+  Args.ClaimAllArgs(options::OPT_f_clang_Group);<br>
+<br>
+  if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&<br>
+      !Args.hasArg(options::OPT_fno_working_directory))<br>
+    CmdArgs.push_back("-fworking-directory");<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_O);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_undef);<br>
+  if (Args.hasArg(options::OPT_save_temps))<br>
+    CmdArgs.push_back("-fpch-preprocess");<br>
+}<br>
+<br>
+void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,<br>
+                                          ArgStringList &CmdArgs,<br>
+                                          const InputInfoList &Inputs) const {<br>
+  const Driver &D = getToolChain().getDriver();<br>
+<br>
+  CheckPreprocessingOptions(D, Args);<br>
+<br>
+  // Derived from cpp_unique_options.<br>
+  // -{C,CC} only with -E is checked in CheckPreprocessingOptions().<br>
+  Args.AddLastArg(CmdArgs, options::OPT_C);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_CC);<br>
+  if (!Args.hasArg(options::OPT_Q))<br>
+    CmdArgs.push_back("-quiet");<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_nostdincxx);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_v);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_P);<br>
+<br>
+  // FIXME: Handle %I properly.<br>
+  if (getToolChain().getArch() == llvm::Triple::x86_64) {<br>
+    CmdArgs.push_back("-imultilib");<br>
+    CmdArgs.push_back("x86_64");<br>
+  }<br>
+<br>
+  if (Args.hasArg(options::OPT_MD)) {<br>
+    CmdArgs.push_back("-MD");<br>
+    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));<br>
+  }<br>
+<br>
+  if (Args.hasArg(options::OPT_MMD)) {<br>
+    CmdArgs.push_back("-MMD");<br>
+    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));<br>
+  }<br>
+<br>
+  Args.AddLastArg(CmdArgs, options::OPT_M);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_MM);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_MF);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_MG);<br>
+  Args.AddLastArg(CmdArgs, options::OPT_MP);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_MQ);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_MT);<br>
+  if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&<br>
+      (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {<br>
+    if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {<br>
+      CmdArgs.push_back("-MQ");<br>
+      CmdArgs.push_back(OutputOpt->getValue());<br>
+    }<br>
+  }<br>
+<br>
+  Args.AddLastArg(CmdArgs, options::OPT_remap);<br>
+  if (Args.hasArg(options::OPT_g3))<br>
+    CmdArgs.push_back("-dD");<br>
+  Args.AddLastArg(CmdArgs, options::OPT_H);<br>
+<br>
+  AddCPPArgs(Args, CmdArgs);<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_i_Group);<br>
+<br>
+  for (InputInfoList::const_iterator<br>
+         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {<br>
+    const InputInfo &II = *it;<br>
+<br>
+    CmdArgs.push_back(II.getFilename());<br>
+  }<br>
+<br>
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,<br>
+                       options::OPT_Xpreprocessor);<br>
+<br>
+  if (Args.hasArg(options::OPT_fmudflap)) {<br>
+    CmdArgs.push_back("-D_MUDFLAP");<br>
+    CmdArgs.push_back("-include");<br>
+    CmdArgs.push_back("mf-runtime.h");<br>
+  }<br>
+<br>
+  if (Args.hasArg(options::OPT_fmudflapth)) {<br>
+    CmdArgs.push_back("-D_MUDFLAP");<br>
+    CmdArgs.push_back("-D_MUDFLAPTH");<br>
+    CmdArgs.push_back("-include");<br>
+    CmdArgs.push_back("mf-runtime.h");<br>
+  }<br>
+}<br>
+<br>
+void darwin::CC1::AddCPPArgs(const ArgList &Args,<br>
+                             ArgStringList &CmdArgs) const {<br>
+  // Derived from cpp spec.<br>
+<br>
+  if (Args.hasArg(options::OPT_static)) {<br>
+    // The gcc spec is broken here, it refers to dynamic but<br>
+    // that has been translated. Start by being bug compatible.<br>
+<br>
+    // if (!Args.hasArg(arglist.parser.dynamicOption))<br>
+    CmdArgs.push_back("-D__STATIC__");<br>
+  } else<br>
+    CmdArgs.push_back("-D__DYNAMIC__");<br>
+<br>
+  if (Args.hasArg(options::OPT_pthread))<br>
+    CmdArgs.push_back("-D_REENTRANT");<br>
+}<br>
+<br>
+void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,<br>
+                                      const InputInfo &Output,<br>
+                                      const InputInfoList &Inputs,<br>
+                                      const ArgList &Args,<br>
+                                      const char *LinkingOutput) const {<br>
+  ArgStringList CmdArgs;<br>
+<br>
+  assert(Inputs.size() == 1 && "Unexpected number of inputs!");<br>
+<br>
+  CmdArgs.push_back("-E");<br>
+<br>
+  if (Args.hasArg(options::OPT_traditional) ||<br>
+      Args.hasArg(options::OPT_traditional_cpp))<br>
+    CmdArgs.push_back("-traditional-cpp");<br>
+<br>
+  ArgStringList OutputArgs;<br>
+  assert(Output.isFilename() && "Unexpected CC1 output.");<br>
+  OutputArgs.push_back("-o");<br>
+  OutputArgs.push_back(Output.getFilename());<br>
+<br>
+  if (Args.hasArg(options::OPT_E) || getToolChain().getDriver().CCCIsCPP) {<br>
+    AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);<br>
+  } else {<br>
+    AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());<br>
+    CmdArgs.append(OutputArgs.begin(), OutputArgs.end());<br>
+  }<br>
+<br>
+  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);<br>
+<br>
+  RemoveCC1UnsupportedArgs(CmdArgs);<br>
+<br>
+  const char *CC1Name = getCC1Name(Inputs[0].getType());<br>
+  const char *Exec =<br>
+    Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));<br>
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));<br>
+}<br>
+<br>
+void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,<br>
+                                   const InputInfo &Output,<br>
+                                   const InputInfoList &Inputs,<br>
+                                   const ArgList &Args,<br>
+                                   const char *LinkingOutput) const {<br>
+  const Driver &D = getToolChain().getDriver();<br>
+  ArgStringList CmdArgs;<br>
+<br>
+  assert(Inputs.size() == 1 && "Unexpected number of inputs!");<br>
+<br>
+  // Silence warning about unused --serialize-diagnostics<br>
+  Args.ClaimAllArgs(options::OPT__serialize_diags);<br>
+<br>
+  types::ID InputType = Inputs[0].getType();<br>
+  if (const Arg *A = Args.getLastArg(options::OPT_traditional))<br>
+    D.Diag(diag::err_drv_argument_only_allowed_with)<br>
+      << A->getAsString(Args) << "-E";<br>
+<br>
+  if (JA.getType() == types::TY_LLVM_IR ||<br>
+      JA.getType() == types::TY_LTO_IR)<br>
+    CmdArgs.push_back("-emit-llvm");<br>
+  else if (JA.getType() == types::TY_LLVM_BC ||<br>
+           JA.getType() == types::TY_LTO_BC)<br>
+    CmdArgs.push_back("-emit-llvm-bc");<br>
+  else if (Output.getType() == types::TY_AST)<br>
+    D.Diag(diag::err_drv_no_ast_support)<br>
+      << getToolChain().getTripleString();<br>
+  else if (JA.getType() != types::TY_PP_Asm &&<br>
+           JA.getType() != types::TY_PCH)<br>
+    D.Diag(diag::err_drv_invalid_gcc_output_type)<br>
+      << getTypeName(JA.getType());<br>
+<br>
+  ArgStringList OutputArgs;<br>
+  if (Output.getType() != types::TY_PCH) {<br>
+    OutputArgs.push_back("-o");<br>
+    if (Output.isNothing())<br>
+      OutputArgs.push_back("/dev/null");<br>
+    else<br>
+      OutputArgs.push_back(Output.getFilename());<br>
+  }<br>
+<br>
+  // There is no need for this level of compatibility, but it makes<br>
+  // diffing easier.<br>
+  bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||<br>
+                          Args.hasArg(options::OPT_S));<br>
+<br>
+  if (types::getPreprocessedType(InputType) != types::TY_INVALID) {<br>
+    AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);<br>
+    if (OutputArgsEarly) {<br>
+      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);<br>
+    } else {<br>
+      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());<br>
+      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());<br>
+    }<br>
+  } else {<br>
+    CmdArgs.push_back("-fpreprocessed");<br>
+<br>
+    for (InputInfoList::const_iterator<br>
+           it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {<br>
+      const InputInfo &II = *it;<br>
+<br>
+      // Reject AST inputs.<br>
+      if (II.getType() == types::TY_AST) {<br>
+        D.Diag(diag::err_drv_no_ast_support)<br>
+          << getToolChain().getTripleString();<br>
+        return;<br>
+      }<br>
+<br>
+      CmdArgs.push_back(II.getFilename());<br>
+    }<br>
+<br>
+    if (OutputArgsEarly) {<br>
+      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);<br>
+    } else {<br>
+      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());<br>
+      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());<br>
+    }<br>
+  }<br>
+<br>
+  if (Output.getType() == types::TY_PCH) {<br>
+    assert(Output.isFilename() && "Invalid PCH output.");<br>
+<br>
+    CmdArgs.push_back("-o");<br>
+    // NOTE: gcc uses a temp .s file for this, but there doesn't seem<br>
+    // to be a good reason.<br>
+    const char *TmpPath = C.getArgs().MakeArgString(<br>
+      D.GetTemporaryPath("cc", "s"));<br>
+    C.addTempFile(TmpPath);<br>
+    CmdArgs.push_back(TmpPath);<br>
+<br>
+    // If we're emitting a pch file with the last 4 characters of ".pth"<br>
+    // and falling back to llvm-gcc we want to use ".gch" instead.<br>
+    std::string OutputFile(Output.getFilename());<br>
+    size_t loc = OutputFile.rfind(".pth");<br>
+    if (loc != std::string::npos)<br>
+      OutputFile.replace(loc, 4, ".gch");<br>
+    const char *Tmp = C.getArgs().MakeArgString("--output-pch="+OutputFile);<br>
+    CmdArgs.push_back(Tmp);<br>
+  }<br>
+<br>
+  RemoveCC1UnsupportedArgs(CmdArgs);<br>
+<br>
+  const char *CC1Name = getCC1Name(Inputs[0].getType());<br>
+  const char *Exec =<br>
+    Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));<br>
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));<br>
+}<br>
+<br>
 void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,<br>
                                     const InputInfo &Output,<br>
                                     const InputInfoList &Inputs,<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.h?rev=168024&r1=168023&r2=168024&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.h?rev=168024&r1=168023&r2=168024&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Driver/Tools.h (original)<br>
+++ cfe/trunk/lib/Driver/Tools.h Wed Nov 14 23:36:36 2012<br>
@@ -31,13 +31,6 @@<br>
<br>
   /// \brief Clang compiler tool.<br>
   class LLVM_LIBRARY_VISIBILITY Clang : public Tool {<br>
-    static const char *getBaseInputName(const ArgList &Args,<br>
-                                        const InputInfoList &Inputs);<br>
-    static const char *getBaseInputStem(const ArgList &Args,<br>
-                                        const InputInfoList &Inputs);<br>
-    static const char *getDependencyFileName(const ArgList &Args,<br>
-                                             const InputInfoList &Inputs);<br>
-<br>
     void AddPreprocessingOptions(Compilation &C,<br>
                                  const Driver &D,<br>
                                  const ArgList &Args,<br>
@@ -225,6 +218,63 @@<br>
                const ToolChain &TC) : Tool(Name, ShortName, TC) {}<br>
   };<br>
<br>
+  class LLVM_LIBRARY_VISIBILITY CC1 : public DarwinTool  {<br>
+    virtual void anchor();<br>
+  public:<br>
+    static const char *getBaseInputName(const ArgList &Args,<br>
+                                 const InputInfoList &Input);<br>
+    static const char *getBaseInputStem(const ArgList &Args,<br>
+                                 const InputInfoList &Input);<br>
+    static const char *getDependencyFileName(const ArgList &Args,<br>
+                                             const InputInfoList &Inputs);<br>
+<br>
+  protected:<br>
+    const char *getCC1Name(types::ID Type) const;<br>
+<br>
+    void AddCC1Args(const ArgList &Args, ArgStringList &CmdArgs) const;<br>
+    void RemoveCC1UnsupportedArgs(ArgStringList &CmdArgs) const;<br>
+    void AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,<br>
+                           const InputInfoList &Inputs,<br>
+                           const ArgStringList &OutputArgs) const;<br>
+    void AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,<br>
+                           const InputInfoList &Inputs,<br>
+                           const ArgStringList &OutputArgs) const;<br>
+    void AddCPPUniqueOptionsArgs(const ArgList &Args,<br>
+                                 ArgStringList &CmdArgs,<br>
+                                 const InputInfoList &Inputs) const;<br>
+    void AddCPPArgs(const ArgList &Args, ArgStringList &CmdArgs) const;<br>
+<br>
+  public:<br>
+    CC1(const char *Name, const char *ShortName,<br>
+        const ToolChain &TC) : DarwinTool(Name, ShortName, TC) {}<br>
+<br>
+    virtual bool hasGoodDiagnostics() const { return true; }<br>
+    virtual bool hasIntegratedCPP() const { return true; }<br>
+  };<br>
+<br>
+  class LLVM_LIBRARY_VISIBILITY Preprocess : public CC1  {<br>
+  public:<br>
+    Preprocess(const ToolChain &TC) : CC1("darwin::Preprocess",<br>
+                                          "gcc preprocessor", TC) {}<br>
+<br>
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,<br>
+                              const InputInfo &Output,<br>
+                              const InputInfoList &Inputs,<br>
+                              const ArgList &TCArgs,<br>
+                              const char *LinkingOutput) const;<br>
+  };<br>
+<br>
+  class LLVM_LIBRARY_VISIBILITY Compile : public CC1  {<br>
+  public:<br>
+    Compile(const ToolChain &TC) : CC1("darwin::Compile", "gcc frontend", TC) {}<br>
+<br>
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,<br>
+                              const InputInfo &Output,<br>
+                              const InputInfoList &Inputs,<br>
+                              const ArgList &TCArgs,<br>
+                              const char *LinkingOutput) const;<br>
+  };<br>
+<br>
   class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool  {<br>
   public:<br>
     Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble",<br>
<br>
Modified: cfe/trunk/lib/Driver/Types.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Types.cpp?rev=168024&r1=168023&r2=168024&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Types.cpp?rev=168024&r1=168023&r2=168024&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Driver/Types.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Types.cpp Wed Nov 14 23:36:36 2012<br>
@@ -71,6 +71,29 @@<br>
           Id == TY_LTO_BC);<br>
 }<br>
<br>
+bool types::isAcceptedByClang(ID Id) {<br>
+  switch (Id) {<br>
+  default:<br>
+    return false;<br>
+<br>
+  case TY_Asm:<br>
+  case TY_C: case TY_PP_C:<br>
+  case TY_CL:<br>
+  case TY_CUDA:<br>
+  case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:<br>
+  case TY_CXX: case TY_PP_CXX:<br>
+  case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:<br>
+  case TY_CHeader: case TY_PP_CHeader:<br>
+  case TY_CLHeader:<br>
+  case TY_ObjCHeader: case TY_PP_ObjCHeader:<br>
+  case TY_CXXHeader: case TY_PP_CXXHeader:<br>
+  case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:<br>
+  case TY_AST:<br>
+  case TY_LLVM_IR: case TY_LLVM_BC:<br>
+    return true;<br>
+  }<br>
+}<br>
+<br>
 bool types::isObjC(ID Id) {<br>
   switch (Id) {<br>
   default:<br>
<br>
Modified: cfe/trunk/lib/Driver/WindowsToolChain.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/WindowsToolChain.cpp?rev=168024&r1=168023&r2=168024&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/WindowsToolChain.cpp?rev=168024&r1=168023&r2=168024&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Driver/WindowsToolChain.cpp (original)<br>
+++ cfe/trunk/lib/Driver/WindowsToolChain.cpp Wed Nov 14 23:36:36 2012<br>
@@ -37,7 +37,12 @@<br>
<br>
 Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA,<br>
                           const ActionList &Inputs) const {<br>
-  Action::ActionClass Key = JA.getKind();<br>
+  Action::ActionClass Key;<br>
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))<br>
+    Key = Action::AnalyzeJobClass;<br>
+  else<br>
+    Key = JA.getKind();<br>
+<br>
   bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,<br>
                                              options::OPT_no_integrated_as,<br>
                                              IsIntegratedAssemblerDefault());<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>
</blockquote></div><br></body></html>