]> granicus.if.org Git - clang/commitdiff
Driver: Add majority of driver-driver implementation.
authorDaniel Dunbar <daniel@zuster.org>
Thu, 12 Mar 2009 18:40:18 +0000 (18:40 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 12 Mar 2009 18:40:18 +0000 (18:40 +0000)
 - Compare to driverdriver.c if bored; not completely fair since the
   driver gets a bit more code in other places to handle binding archs
   (for Xarch) but not completely unfair either.

Fear not, extra Action classes will have a happy home for their
vtables soon.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66817 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticDriverKinds.def
include/clang/Basic/DiagnosticDriverKinds.td
include/clang/Driver/Action.h
lib/Driver/Action.cpp [new file with mode: 0644]
lib/Driver/Driver.cpp

index 9cdc6e387b428b128f0346c5d5d8ff802f8d0f63..47332b6d197575c6c0da4a05d4a929666414c1f5 100644 (file)
@@ -20,3 +20,7 @@ DIAG(err_drv_unknown_stdin_type, ERROR,
      "-E or -x required when input is from standard input")
 DIAG(err_drv_unknown_language, ERROR,
      "language not recognized: '%0'")
+DIAG(err_drv_invalid_opt_with_multiple_archs, ERROR,
+     "option '%0' cannot be used with multiple -arch options")
+DIAG(err_drv_invalid_output_with_multiple_archs, ERROR,
+     "cannot use '%0' output with multiple -arch options")
index 6301b6fb32ff9979b95d905ff380df951212d2e1..29eb259001ab597bd948e7fe375d80f018c0d9a0 100644 (file)
@@ -14,5 +14,9 @@ def err_drv_unsupported_opt : Error<"unsupported option '%0'">
 def err_drv_unknown_stdin_type : Error<
     "-E or -x required when input is from standard input">
 def err_drv_unknown_language : Error<"language not recognized: '%0'">
+def err_drv_invalid_opt_with_multiple_archs : Error<
+     "option '%0' cannot be used with multiple -arch options">
+def err_drv_invalid_output_with_multiple_archs : Error<
+     "cannot use '%0' output with multiple -arch options">
 
 }
index 12ded40de9b6c413a3b745a08fa6fd18d33fd3c1..1eb754be1683d66d96ae22d1cdbbd36bd5b4b365 100644 (file)
 #ifndef CLANG_DRIVER_ACTION_H_
 #define CLANG_DRIVER_ACTION_H_
 
+#include "llvm/ADT/SmallVector.h"
+
+#include "clang/Driver/Types.h"
+#include "clang/Driver/Util.h"
+
 namespace clang {
 namespace driver {
 
@@ -17,9 +22,49 @@ namespace driver {
 ///
 /// An action represents an edge in the compilation graph; typically
 /// it is a job to transform an input using some tool.
+///
+/// The current driver is hard wired to expect actions which produce a
+/// single primary output, at least in terms of controlling the
+/// compilation. Actions can produce auxiliary files, but can only
+/// produce a single output to feed into subsequent actions.
 class Action {
+  /// The output type of this action.
+  types::ID Type;
+  
+  ActionList Inputs;
+
+protected:
+  Action(const ActionList &_Inputs, types::ID _Type) : Type(_Type),
+                                                       Inputs(_Inputs) {}  
 public:
+  virtual ~Action();
   
+  types::ID getType() { return Type; }
+};
+
+class InputAction : public Action {
+};
+
+class BindArchAction : public Action {
+  const char *ArchName;
+
+public:
+  BindArchAction(Action *Input, const char *_ArchName) 
+    : Action(ActionList(&Input, &Input + 1), Input->getType()),
+      ArchName(_ArchName) {
+  }
+};
+
+class JobAction : public Action {
+protected:
+  JobAction(ActionList &Inputs, types::ID Type) 
+    : Action(Inputs, Type) {}
+};
+
+class LipoJobAction : public JobAction {
+public:
+  LipoJobAction(ActionList &Inputs, types::ID Type) 
+    : JobAction(Inputs, Type) {}
 };
 
 } // end namespace driver
diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp
new file mode 100644 (file)
index 0000000..d9bfce1
--- /dev/null
@@ -0,0 +1,15 @@
+//===--- Action.cpp - Abstract compilation steps ------------------------*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Action.h"
+
+#include <cassert>
+using namespace clang::driver;
+
+Action::~Action() {}
index 2b763c6ae57274b2bc602f648cfff1733b6fae17..4ceeb77c1555a7c4b59549d1855c1af1cfe70df6 100644 (file)
@@ -19,6 +19,7 @@
 #include "clang/Driver/Options.h"
 #include "clang/Driver/Types.h"
 
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/System/Path.h"
 using namespace clang::driver;
@@ -171,8 +172,73 @@ void Driver::PrintActions(const ActionList &Actions) const {
 }
 
 void Driver::BuildUniversalActions(ArgList &Args, ActionList &Actions) {
-  // FIXME: Implement
-  BuildActions(Args, Actions);
+  llvm::StringMap<Arg *> Archs;
+  for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); 
+       it != ie; ++it) {
+    Arg *A = *it;
+
+    if (A->getOption().getId() == options::OPT_arch) {
+      // FIXME: We need to handle canonicalization of the specified
+      // arch?
+
+      Archs[A->getValue(Args)] = A;
+    }
+  }
+
+  // When there is no explicit arch for this platform, get one from
+  // the host so that -Xarch_ is handled correctly.
+  if (!Archs.size()) {
+    const char *Arch = Host->getArchName().c_str();
+    Archs[Arch] = Args.MakeSeparateArg(getOpts().getOption(options::OPT_arch),
+                                       Arch);
+  }
+
+  // FIXME: We killed off some others but these aren't yet detected in
+  // a functional manner. If we added information to jobs about which
+  // "auxiliary" files they wrote then we could detect the conflict
+  // these cause downstream.
+  if (Archs.size() > 1) {
+    // No recovery needed, the point of this is just to prevent
+    // overwriting the same files.
+    if (const Arg *A = Args.getLastArg(options::OPT_M_Group))
+      Diag(clang::diag::err_drv_invalid_opt_with_multiple_archs) 
+        << A->getOption().getName();
+    if (const Arg *A = Args.getLastArg(options::OPT_save_temps))
+      Diag(clang::diag::err_drv_invalid_opt_with_multiple_archs) 
+        << A->getOption().getName();
+  }
+
+  ActionList SingleActions;
+  BuildActions(Args, SingleActions);
+
+  // Add in arch binding and lipo (if necessary) for every top level
+  // action.
+  for (unsigned i = 0, e = SingleActions.size(); i != e; ++i) {
+    Action *Act = SingleActions[i];
+
+    // Make sure we can lipo this kind of output. If not (and it is an
+    // actual output) then we disallow, since we can't create an
+    // output file with the right name without overwriting it. We
+    // could remove this oddity by just changing the output names to
+    // include the arch, which would also fix
+    // -save-temps. Compatibility wins for now.
+
+    if (Archs.size() > 1 && types::canLipoType(Act->getType()))
+      Diag(clang::diag::err_drv_invalid_output_with_multiple_archs)
+        << types::getTypeName(Act->getType());
+
+    ActionList Inputs;
+    for (llvm::StringMap<Arg*>::iterator it = Archs.begin(), ie = Archs.end();
+         it != ie; ++it)
+      Inputs.push_back(new BindArchAction(Act, it->second->getValue(Args)));
+
+    // Lipo if necessary, We do it this way because we need to set the
+    // arch flag so that -Xarch_ gets overwritten.
+    if (Inputs.size() == 1 || Act->getType() == types::TY_Nothing)
+      Actions.append(Inputs.begin(), Inputs.end());
+    else
+      Actions.push_back(new LipoJobAction(Inputs, Act->getType()));
+  }
 }
 
 void Driver::BuildActions(ArgList &Args, ActionList &Actions) {