]> granicus.if.org Git - clang/commitdiff
Driver: Handle magic -ccc- options.
authorDaniel Dunbar <daniel@zuster.org>
Tue, 10 Mar 2009 20:52:46 +0000 (20:52 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 10 Mar 2009 20:52:46 +0000 (20:52 +0000)
 - Follows ccc currently, but this functionality should eventually be
   outside the Driver lib.

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

include/clang/Driver/Driver.h
lib/Driver/Driver.cpp
tools/ccc/ccclib/Driver.py
tools/driver/driver.cpp

index dc30367c8b3ded5395cf3cf094bd099b8e19a3eb..61ec5498d695fb32eb995c00ba22fc2a1a9c46e7 100644 (file)
 #ifndef CLANG_DRIVER_DRIVER_H_
 #define CLANG_DRIVER_DRIVER_H_
 
+#include <list>
+#include <set>
+#include <string>
+
 namespace clang {
 namespace driver {
   class ArgList;
   class Compilation;
+  class HostInfo;
   class OptTable;
 
 /// Driver - Encapsulate logic for constructing compilation processes
@@ -25,15 +30,61 @@ class Driver {
   /// ArgList.
   ArgList *ParseArgStrings(const char **ArgBegin, const char **ArgEnd);
 
+  // FIXME: Privatize once interface is stable.
+public:
+  /// The name the driver was invoked as.
+  std::string Name;
+  
+  /// The path the driver executable was in, as invoked from the
+  /// command line.
+  std::string Dir;
+
+  /// Host information for the platform the driver is running as. This
+  /// will generally be the actual host platform, but not always.
+  HostInfo *Host;
+
+  /// Information about the host which can be overriden by the user.
+  std::string HostBits, HostMachine, HostSystem, HostRelease;
+
+  /// Whether the driver should follow g++ like behavior.
+  bool CCCIsCXX : 1;
+  
+  /// Echo commands while executing (in -v style).
+  bool CCCEcho : 1;
+
+  /// Don't use clang for any tasks.
+  bool CCCNoClang : 1;
+
+  /// Don't use clang for handling C++ and Objective-C++ inputs.
+  bool CCCNoClangCXX : 1;
+
+  /// Don't use clang as a preprocessor (clang's preprocessor will
+  /// still be used where an integrated CPP would).
+  bool CCCNoClangCPP : 1;
+
+  /// Only use clang for the given architectures. Only used when
+  /// non-empty.
+  std::set<std::string> CCCClangArchs;
+
+  /// Certain options suppress the 'no input files' warning.
+  bool SuppressMissingInputWarning : 1;
+  
+  std::list<std::string> TempFiles;
+  std::list<std::string> ResultFiles;
+
 public:
-  Driver();
+  Driver(const char *_Name, const char *_Dir);
   ~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);
 };
 
 } // end namespace driver
index 5750154a09b79b539424c94714401977c0d3ebf3..6b1d44e5e75592e166ba14b40e06c583fedce312 100644 (file)
 #include "llvm/Support/raw_ostream.h"
 using namespace clang::driver;
 
-Driver::Driver() : Opts(new OptTable()) {
+Driver::Driver(const char *_Name, const char *_Dir) 
+  : Opts(new OptTable()),
+    Name(_Name), Dir(_Dir), Host(0),
+    CCCIsCXX(false), CCCEcho(false), 
+    CCCNoClang(false), CCCNoClangCXX(false), CCCNoClangCPP(false)
+{
   
 }
 
@@ -43,11 +48,88 @@ ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) {
 }
 
 Compilation *Driver::BuildCompilation(int argc, const char **argv) {
-  ArgList *Args = ParseArgStrings(argv + 1, argv + argc);
+  // FIXME: This stuff needs to go into the Compilation, not the
+  // driver.
+  bool CCCPrintOptions = false, CCCPrintPhases = false;
 
-  // Hard coded to print-options behavior.
+  const char **Start = argv + 1, **End = argv + argc;
+
+  // Read -ccc args. 
+  //
+  // FIXME: We need to figure out where this behavior should
+  // live. Most of it should be outside in the client; the parts that
+  // aren't should have proper options, either by introducing new ones
+  // or by overloading gcc ones like -V or -b.
+  for (; Start != End && memcmp(*Start, "-ccc-", 5) == 0; ++Start) {
+    const char *Opt = *Start + 5;
+    
+    if (!strcmp(Opt, "print-options")) {
+      CCCPrintOptions = true;
+    } else if (!strcmp(Opt, "print-phases")) {
+      CCCPrintPhases = true;
+    } else if (!strcmp(Opt, "cxx")) {
+      CCCIsCXX = true;
+    } else if (!strcmp(Opt, "echo")) {
+      CCCEcho = true;
+      
+    } else if (!strcmp(Opt, "no-clang")) {
+      CCCNoClang = true;
+    } else if (!strcmp(Opt, "no-clang-cxx")) {
+      CCCNoClangCXX = true;
+    } else if (!strcmp(Opt, "no-clang-cpp")) {
+      CCCNoClangCPP = true;
+    } else if (!strcmp(Opt, "clang-archs")) {
+      assert(Start+1 < End && "FIXME: -ccc- argument handling.");
+      const char *Cur = *++Start;
+    
+      for (;;) {
+        const char *Next = strchr(Cur, ',');
+
+        if (Next) {
+          CCCClangArchs.insert(std::string(Cur, Next));
+          Cur = Next + 1;
+        } else {
+          CCCClangArchs.insert(std::string(Cur));
+          break;
+        }
+      }
+
+    } else if (!strcmp(Opt, "host-bits")) {
+      assert(Start+1 < End && "FIXME: -ccc- argument handling.");
+      HostBits = *++Start;
+    } else if (!strcmp(Opt, "host-machine")) {
+      assert(Start+1 < End && "FIXME: -ccc- argument handling.");
+      HostMachine = *++Start;
+    } else if (!strcmp(Opt, "host-release")) {
+      assert(Start+1 < End && "FIXME: -ccc- argument handling.");
+      HostRelease = *++Start;
+    } else if (!strcmp(Opt, "host-system")) {
+      assert(Start+1 < End && "FIXME: -ccc- argument handling.");
+      HostSystem = *++Start;
+
+    } else {
+      // FIXME: Error handling.
+      llvm::errs() << "invalid option: " << *Start << "\n";
+      exit(1);
+    }
+  }
+  
+  ArgList *Args = ParseArgStrings(Start, End);
+
+  // FIXME: This behavior shouldn't be here.
+  if (CCCPrintOptions) {
+    PrintOptions(Args);
+    exit(0);
+  }
+
+  assert(0 && "FIXME: Implement");
+
+  return new Compilation();
+}
+
+void Driver::PrintOptions(const ArgList *Args) {
   unsigned i = 0;
-  for (ArgList::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 << " - "
@@ -60,6 +142,4 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
     }
     llvm::errs() << "}\n";
   }
-
-  return new Compilation();
 }
index e6aba65fc766ac49c42c56a8b5a40ae8dc927bae..eee3ad3819486d7dcb3c886f4330ecf6e644050c 100644 (file)
@@ -30,7 +30,6 @@ class Driver(object):
         self.cccHostSystem = self.cccHostRelease = None
         self.cccCXX = False
         self.cccEcho = False
-        self.cccFallback = False
         self.cccNoClang = self.cccNoClangCXX = self.cccNoClangPreprocessor = False
         self.cccClangArchs = None
 
@@ -139,8 +138,6 @@ class Driver(object):
                 self.cccCXX = True
             elif opt == 'echo':
                 self.cccEcho = True
-            elif opt == 'fallback':
-                self.cccFallback = True
 
             elif opt == 'no-clang':
                 self.cccNoClang = True
index 31990a8f2aa3dc48ddf3533cf2fa28e87368cce3..ad6c807327214c4105963bd32c4f1084c759bc45 100644 (file)
 #include "clang/Driver/Options.h"
 
 #include "llvm/ADT/OwningPtr.h"
+#include "llvm/System/Path.h"
 #include "llvm/System/Signals.h"
 using namespace clang::driver;
 
 int main(int argc, const char **argv) {
   llvm::sys::PrintStackTraceOnErrorSignal();
 
-  llvm::OwningPtr<Driver> TheDriver(new Driver());
+  // FIXME: We should use GetMainExecutable here, probably, but we may
+  // want to handle symbolic links slightly differently. The problem
+  // is that the path derived from this will influence search paths.
+  llvm::sys::Path Path(argv[0]);
+
+  llvm::OwningPtr<Driver> TheDriver(new Driver(Path.getBasename().c_str(),
+                                               Path.getDirname().c_str()));
 
   llvm::OwningPtr<Compilation> C(TheDriver->BuildCompilation(argc, argv));