[cfe-commits] r66783 - in /cfe/trunk: include/clang/Driver/Action.h include/clang/Driver/Driver.h lib/Driver/Driver.cpp

Daniel Dunbar daniel at zuster.org
Thu Mar 12 00:58:46 PDT 2009


Author: ddunbar
Date: Thu Mar 12 02:58:46 2009
New Revision: 66783

URL: http://llvm.org/viewvc/llvm-project?rev=66783&view=rev
Log:
Driver: Start sketching construction of abstract built actions.

Added:
    cfe/trunk/include/clang/Driver/Action.h
Modified:
    cfe/trunk/include/clang/Driver/Driver.h
    cfe/trunk/lib/Driver/Driver.cpp

Added: cfe/trunk/include/clang/Driver/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Action.h?rev=66783&view=auto

==============================================================================
--- cfe/trunk/include/clang/Driver/Action.h (added)
+++ cfe/trunk/include/clang/Driver/Action.h Thu Mar 12 02:58:46 2009
@@ -0,0 +1,28 @@
+//===--- Action.h - Abstract compilation steps ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_ACTION_H_
+#define CLANG_DRIVER_ACTION_H_
+
+namespace clang {
+namespace driver {
+
+/// Action - Represent an abstract compilation step to perform. 
+///
+/// An action represents an edge in the compilation graph; typically
+/// it is a job to transform an input using some tool.
+class Action {
+public:
+  
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif

Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=66783&r1=66782&r2=66783&view=diff

==============================================================================
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Thu Mar 12 02:58:46 2009
@@ -14,8 +14,14 @@
 #include <set>
 #include <string>
 
+namespace llvm {
+  template<typename T, unsigned N> class SmallVector;
+  class raw_ostream;
+}
+
 namespace clang {
 namespace driver {
+  class Action;
   class ArgList;
   class Compilation;
   class HostInfo;
@@ -80,19 +86,39 @@
          const char *_DefaultHostTriple);
   ~Driver();
 
-  
   const OptTable &getOpts() const { return *Opts; }
 
   /// BuildCompilation - Construct a compilation object for a command
   /// line argument vector.
   Compilation *BuildCompilation(int argc, const char **argv);
 
-  /// PrintOptions - Print the given list of arguments.
-  void PrintOptions(const ArgList *Args);
+  /// PrintOptions - Print the list of arguments.
+  void PrintOptions(const ArgList &Args);
+
+  /// PrintActions - Print the list of actions.
+  void PrintActions(const llvm::SmallVector<Action*, 2> &Actions);
 
   /// GetHostInfo - Construct a new host info object for the given
   /// host triple.
   static HostInfo *GetHostInfo(const char *HostTriple);
+
+  /// BuildUniversalActions - Construct the list of actions to perform
+  /// for the given arguments, which may require a universal build.
+  ///
+  /// \param Args - The input arguments.
+  /// \param Actions - The list to store the resulting actions onto.
+  void BuildUniversalActions(const ArgList &Args, 
+                             llvm::SmallVector<Action*, 2> &Actions);
+
+  /// BuildActions - Construct the list of actions to perform for the
+  /// given arguments, which are only done for a single architecture.
+  ///
+  /// \param Args - The input arguments.
+  /// \param Actions - The list to store the resulting actions onto.
+  void BuildActions(const ArgList &Args, 
+                    llvm::SmallVector<Action*, 2> &Actions);
+
+  llvm::raw_ostream &Diag(const char *Message) const;
 };
 
 } // end namespace driver

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=66783&r1=66782&r2=66783&view=diff

==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Thu Mar 12 02:58:46 2009
@@ -9,14 +9,17 @@
 
 #include "clang/Driver/Driver.h"
 
+#include "clang/Driver/Action.h"
 #include "clang/Driver/Arg.h"
 #include "clang/Driver/ArgList.h"
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/HostInfo.h"
 #include "clang/Driver/Option.h"
 #include "clang/Driver/Options.h"
+#include "clang/Driver/Types.h"
 
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
 using namespace clang::driver;
 
 Driver::Driver(const char *_Name, const char *_Dir,
@@ -41,8 +44,14 @@
   while (Index < End) {
     unsigned Prev = Index;
     Arg *A = getOpts().ParseOneArg(*Args, Index, End);
-    if (A)
+    if (A) {
+      if (A->getOption().isUnsupported()) {
+        Diag("unsupported option: ") << A->getOption().getName() << "\n";
+        continue;
+      }
+
       Args->append(A);
+    }
 
     assert(Index > Prev && "Parser failed to consume argument.");
   }
@@ -53,7 +62,7 @@
 Compilation *Driver::BuildCompilation(int argc, const char **argv) {
   // FIXME: This stuff needs to go into the Compilation, not the
   // driver.
-  bool CCCPrintOptions = false, CCCPrintPhases = false;
+  bool CCCPrintOptions = false, CCCPrintActions = false;
 
   const char **Start = argv + 1, **End = argv + argc;
   const char *HostTriple = DefaultHostTriple.c_str();
@@ -70,7 +79,7 @@
     if (!strcmp(Opt, "print-options")) {
       CCCPrintOptions = true;
     } else if (!strcmp(Opt, "print-phases")) {
-      CCCPrintPhases = true;
+      CCCPrintActions = true;
     } else if (!strcmp(Opt, "cxx")) {
       CCCIsCXX = true;
     } else if (!strcmp(Opt, "echo")) {
@@ -115,18 +124,32 @@
 
   // FIXME: This behavior shouldn't be here.
   if (CCCPrintOptions) {
-    PrintOptions(Args);
+    PrintOptions(*Args);
     exit(0);
   }
-  
+
+  // Construct the list of abstract actions to perform for this
+  // compilation.
+  llvm::SmallVector<Action*, 2> Actions;
+  if (Host->useDriverDriver())
+    BuildUniversalActions(*Args, Actions);
+  else
+    BuildActions(*Args, Actions);
+
+  // FIXME: This behavior shouldn't be here.
+  if (CCCPrintActions) {
+    PrintActions(Actions);
+    exit(0);
+  }
+    
   assert(0 && "FIXME: Implement");
 
   return new Compilation();
 }
 
-void Driver::PrintOptions(const ArgList *Args) {
+void Driver::PrintOptions(const ArgList &Args) {
   unsigned i = 0;
-  for (ArgList::const_iterator it = Args->begin(), ie = Args->end(); 
+  for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); 
        it != ie; ++it, ++i) {
     Arg *A = *it;
     llvm::errs() << "Option " << i << " - "
@@ -135,12 +158,112 @@
     for (unsigned j = 0; j < A->getNumValues(); ++j) {
       if (j)
         llvm::errs() << ", ";
-      llvm::errs() << '"' << A->getValue(*Args, j) << '"';
+      llvm::errs() << '"' << A->getValue(Args, j) << '"';
     }
     llvm::errs() << "}\n";
   }
 }
 
+void Driver::PrintActions(const llvm::SmallVector<Action*, 2> &Actions) {
+  llvm::errs() << "FIXME: Print actions.";
+}
+
+void Driver::BuildUniversalActions(const ArgList &Args, 
+                                   llvm::SmallVector<Action*, 2> &Actions) {
+  // FIXME: Implement
+  BuildActions(Args, Actions);
+}
+
+void Driver::BuildActions(const ArgList &Args, 
+                          llvm::SmallVector<Action*, 2> &Actions) {
+  types::ID InputType = types::TY_INVALID;
+  Arg *InputTypeArg = 0;
+  
+  llvm::SmallVector<std::pair<types::ID, const Arg*>, 16> Inputs;
+  for (ArgList::const_iterator it = Args.begin(), ie = Args.end(); 
+       it != ie; ++it) {
+    Arg *A = *it;
+
+    if (isa<InputOption>(A->getOption())) {
+      const char *Value = A->getValue(Args);
+      types::ID Ty = types::TY_INVALID;
+
+      // Infer the input type if necessary.
+      if (!InputType) {
+        // stdin must be handled specially.
+        if (memcmp(Value, "-", 2) == 0) {
+          // If running with -E, treat as a C input (this changes the
+          // builtin macros, for example). This may be overridden by
+          // -ObjC below.
+          //
+          // Otherwise emit an error but still use a valid type to
+          // avoid spurious errors (e.g., no inputs).
+          if (!Args.hasArg(options::OPT_E))
+            Diag("-E or -x required when input is from standard input");
+          Ty = types::TY_C;
+        } else {
+          // Otherwise lookup by extension, and fallback to ObjectType
+          // if not found.
+          if (const char *Ext = strrchr(Value, '.'))
+            Ty = types::lookupTypeForExtension(Ext + 1);
+          if (Ty == types::TY_INVALID)
+            Ty = types::TY_Object;
+        }
+
+        // -ObjC and -ObjC++ override the default language, but only
+        // -for "source files". We just treat everything that isn't a
+        // -linker input as a source file.
+        // 
+        // FIXME: Clean this up if we move the phase sequence into the
+        // type.
+        if (Ty != types::TY_Object) {
+          if (Args.hasArg(options::OPT_ObjC))
+            Ty = types::TY_ObjC;
+          else if (Args.hasArg(options::OPT_ObjCXX))
+            Ty = types::TY_ObjCXX;
+        }
+      } else {
+        assert(InputTypeArg && "InputType set w/o InputTypeArg");
+        InputTypeArg->claim();
+        Ty = InputType;
+      }
+
+      // Check that the file exists. It isn't clear this is worth
+      // doing, since the tool presumably does this anyway, and this
+      // just adds an extra stat to the equation, but this is gcc
+      // compatible.
+      if (memcmp(Value, "-", 2) != 0 && !llvm::sys::Path(Value).exists())
+        Diag("no such file or directory: ") << A->getValue(Args) << "\n";
+      else
+        Inputs.push_back(std::make_pair(Ty, A));
+
+    } else if (A->getOption().isLinkerInput()) {
+      // Just treat as object type, we could make a special type for
+      // this if necessary.
+      Inputs.push_back(std::make_pair(types::TY_Object, A));
+
+    } else if (A->getOption().getId() == options::OPT_x) {
+      InputTypeArg = A;      
+      InputType = types::lookupTypeForTypeSpecifier(A->getValue(Args));
+
+      // Follow gcc behavior and treat as linker input for invalid -x
+      // options. Its not clear why we shouldn't just revert to
+      // unknown; but this isn't very important, we might as well be
+      // bug comatible.
+      if (!InputType) {
+        Diag("language not recognized: ") << A->getValue(Args) << "\n";
+        InputType = types::TY_Object;
+      }
+    }
+  }
+
+  for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
+    llvm::errs() << "input " << i << ": " 
+                 << Inputs[i].second->getValue(Args) << "\n";
+  }
+  exit(0);
+}
+
 HostInfo *Driver::GetHostInfo(const char *Triple) {
   // Dice into arch, platform, and OS. This matches 
   //  arch,platform,os = '(.*?)-(.*?)-(.*?)'
@@ -163,3 +286,8 @@
     
   return new UnknownHostInfo(Arch.c_str(), Platform.c_str(), OS.c_str());
 }
+
+// FIXME: Migrate to a normal diagnostics client.
+llvm::raw_ostream &Driver::Diag(const char *Message) const {
+  return (llvm::errs() << Message);
+}





More information about the cfe-commits mailing list