Driver: Add an explicit argument translation phase to the driver itself. We are going to need this to handle things like -Xassembler, -Xpreprocessor, and -Xlinker which we might have to introspect.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105842 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 63f1dee..4657302 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -240,10 +240,8 @@
 
 //
 
-DerivedArgList::DerivedArgList(InputArgList &_BaseArgs, bool OnlyProxy)
+DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs)
   : BaseArgs(_BaseArgs) {
-  if (OnlyProxy)
-    getArgs() = _BaseArgs.getArgs();
 }
 
 DerivedArgList::~DerivedArgList() {
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 227f79a..282e9fe 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -22,20 +22,22 @@
 #include <errno.h>
 using namespace clang::driver;
 
-Compilation::Compilation(const Driver &D,
-                         const ToolChain &_DefaultToolChain,
-                         InputArgList *_Args)
-  : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) {
+Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
+                         InputArgList *_Args, DerivedArgList *_TranslatedArgs)
+  : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
+    TranslatedArgs(_TranslatedArgs) {
 }
 
 Compilation::~Compilation() {
+  delete TranslatedArgs;
   delete Args;
 
   // Free any derived arg lists.
   for (llvm::DenseMap<std::pair<const ToolChain*, const char*>,
                       DerivedArgList*>::iterator it = TCArgs.begin(),
          ie = TCArgs.end(); it != ie; ++it)
-    delete it->second;
+    if (it->second != TranslatedArgs)
+      delete it->second;
 
   // Free the actions, if built.
   for (ActionList::iterator it = Actions.begin(), ie = Actions.end();
@@ -49,8 +51,11 @@
     TC = &DefaultToolChain;
 
   DerivedArgList *&Entry = TCArgs[std::make_pair(TC, BoundArch)];
-  if (!Entry)
-    Entry = TC->TranslateArgs(*Args, BoundArch);
+  if (!Entry) {
+    Entry = TC->TranslateArgs(*TranslatedArgs, BoundArch);
+    if (!Entry)
+      Entry = TranslatedArgs;
+  }
 
   return *Entry;
 }
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 7b45070..4663fb9 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -110,6 +110,16 @@
   return Args;
 }
 
+DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
+  DerivedArgList *DAL = new DerivedArgList(Args);
+
+  for (ArgList::const_iterator it = Args.begin(),
+         ie = Args.end(); it != ie; ++it)
+    DAL->append(*it);
+
+  return DAL;
+}
+
 Compilation *Driver::BuildCompilation(int argc, const char **argv) {
   llvm::PrettyStackTraceString CrashInfo("Compilation construction");
 
@@ -179,8 +189,12 @@
 
   Host = GetHostInfo(HostTriple);
 
+  // Perform the default argument translations.
+  DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args);
+
   // The compilation takes ownership of Args.
-  Compilation *C = new Compilation(*this, *Host->CreateToolChain(*Args), Args);
+  Compilation *C = new Compilation(*this, *Host->CreateToolChain(*Args), Args,
+                                   TranslatedArgs);
 
   // FIXME: This behavior shouldn't be here.
   if (CCCPrintOptions) {
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 92c7d79..ba329e3 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -388,9 +388,9 @@
   }
 }
 
-DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
+DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
                                       const char *BoundArch) const {
-  DerivedArgList *DAL = new DerivedArgList(Args, false);
+  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
   const OptTable &Opts = getDriver().getOpts();
 
   // FIXME: We really want to get out of the tool chain level argument
@@ -478,7 +478,8 @@
   }
   setTarget(iPhoneVersion, Major, Minor, Micro);
 
-  for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
+  for (ArgList::const_iterator it = Args.begin(),
+         ie = Args.end(); it != ie; ++it) {
     Arg *A = *it;
 
     if (A->getOption().matches(options::OPT_Xarch__)) {
@@ -764,12 +765,6 @@
   return 0;
 }
 
-DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args,
-                                           const char *BoundArch) const {
-  return new DerivedArgList(Args, true);
-}
-
-
 /// TCEToolChain - A tool chain using the llvm bitcode tools to perform
 /// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
 /// Currently does not support anything else but compilation.
@@ -824,11 +819,6 @@
   return *T;
 }
 
-DerivedArgList *TCEToolChain::TranslateArgs(InputArgList &Args,
-                                            const char *BoundArch) const {
-  return new DerivedArgList(Args, true);
-}
-
 /// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
 
 OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index ad975bf..f561016 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -33,9 +33,6 @@
   Generic_GCC(const HostInfo &Host, const llvm::Triple& Triple);
   ~Generic_GCC();
 
-  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
-                                        const char *BoundArch) const;
-
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
 
   virtual bool IsUnwindTablesDefault() const;
@@ -147,7 +144,7 @@
   /// @name ToolChain Implementation
   /// {
 
-  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
+  virtual DerivedArgList *TranslateArgs(const DerivedArgList &Args,
                                         const char *BoundArch) const;
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
@@ -290,8 +287,6 @@
   TCEToolChain(const HostInfo &Host, const llvm::Triple& Triple);
   ~TCEToolChain();
 
-  virtual DerivedArgList *TranslateArgs(InputArgList &Args,
-                                        const char *BoundArch) const;
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
   bool IsMathErrnoDefault() const;
   bool IsUnwindTablesDefault() const;