]> granicus.if.org Git - clang/commitdiff
Driver: Execute jobs; no pipe support yet.
authorDaniel Dunbar <daniel@zuster.org>
Wed, 18 Mar 2009 22:44:24 +0000 (22:44 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 18 Mar 2009 22:44:24 +0000 (22:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67250 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticDriverKinds.def
include/clang/Basic/DiagnosticDriverKinds.td
include/clang/Driver/Compilation.h
lib/Driver/Compilation.cpp

index 9a5567fd91b8ffc7373226bfefcafdbe4c506998..778fdf3186d7b8cbf71a9c2b79d401d7f4af9682 100644 (file)
@@ -34,6 +34,8 @@ DIAG(err_drv_unable_to_make_temp, ERROR,
      "unable to make temporary file: %0")
 DIAG(err_drv_unable_to_remove_file, ERROR,
      "unable to remove file: %0")
+DIAG(err_drv_command_failure, ERROR,
+     "unable to execute command: %0")
 
 DIAG(warn_drv_input_file_unused, WARNING,
      "%0: '%1' input file unused when '%2' is present")
index 1bd3047f5ad042d7f601509057ede1b0b7eedaed..1422cfaac96b23fbd625b1384661de3a211350bf 100644 (file)
@@ -27,6 +27,8 @@ def err_drv_unable_to_make_temp : Error<
   "unable to make temporary file: %0">;
 def err_drv_unable_to_remove_file : Error<
   "unable to remove file: %0">;
+def err_drv_command_failure : Error<
+  "unable to execute command: %0">;
 
 def warn_drv_input_file_unused : Warning<
   "%0: '%1' input file unused when '%2' is present">;
index ec47d030e717a427618faa1ae3a7fdce25dba3fd..eaa57914b822fbb136f7c53fdc6d53ea74a65794 100644 (file)
@@ -105,8 +105,14 @@ private:
   /// OS - The stream to print on.
   /// J - The job to print.
   /// Terminator - A string to print at the end of the line.
-  void PrintJob(llvm::raw_ostream &OS, const Job *J, 
-                const char *Terminator) const;
+  /// Quote - Should separate arguments be quoted.
+  void PrintJob(llvm::raw_ostream &OS, const Job &J, 
+                const char *Terminator, bool Quote) const;
+
+  /// ExecuteJob - Execute a single job.
+  ///
+  /// \return The accumulated result code of the job.
+  int ExecuteJob(const Job &J) const;
 };
 
 } // end namespace driver
index 0bd573856ea1a0ca53da75b7daf61987993cb743..5234165ab5bb6d3c6864f7b525fcc3d9a7a6533c 100644 (file)
@@ -16,6 +16,7 @@
 #include "clang/Driver/ToolChain.h"
 
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Program.h"
 #include <sys/stat.h>
 #include <errno.h>
 using namespace clang::driver;
@@ -54,23 +55,27 @@ const ArgList &Compilation::getArgsForToolChain(const ToolChain *TC) {
   return *Entry;
 }
 
-void Compilation::PrintJob(llvm::raw_ostream &OS, const Job *J, 
-                           const char *Terminator) const {
-  if (const Command *C = dyn_cast<Command>(J)) {
+void Compilation::PrintJob(llvm::raw_ostream &OS, const Job &J, 
+                           const char *Terminator, bool Quote) const {
+  if (const Command *C = dyn_cast<Command>(&J)) {
     OS << " \"" << C->getExecutable() << '"';
     for (ArgStringList::const_iterator it = C->getArguments().begin(),
-           ie = C->getArguments().end(); it != ie; ++it)
-      OS << " \"" << *it << '"';
+           ie = C->getArguments().end(); it != ie; ++it) {
+      if (Quote)
+        OS << " \"" << *it << '"';
+      else
+        OS << ' ' << *it;
+    }
     OS << Terminator;
-  } else if (const PipedJob *PJ = dyn_cast<PipedJob>(J)) {
+  } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
     for (PipedJob::const_iterator 
            it = PJ->begin(), ie = PJ->end(); it != ie; ++it)
-      PrintJob(OS, *it, (it + 1 != PJ->end()) ? " |\n" : "\n");
+      PrintJob(OS, **it, (it + 1 != PJ->end()) ? " |\n" : "\n", Quote);
   } else {
-    const JobList *Jobs = cast<JobList>(J);
+    const JobList *Jobs = cast<JobList>(&J);
     for (JobList::const_iterator 
            it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
-      PrintJob(OS, *it, Terminator);
+      PrintJob(OS, **it, Terminator, Quote);
   }
 }
 
@@ -90,7 +95,8 @@ bool Compilation::CleanupFileList(const ArgStringList &Files,
 
       // FIXME: Grumble, P.exists() is broken. PR3837.
       struct stat buf;
-      if (::stat(P.c_str(), &buf) || errno != ENOENT) {
+      if (::stat(P.c_str(), &buf) == 0 
+          || errno != ENOENT) {
         if (IssueErrors)
           getDriver().Diag(clang::diag::err_drv_unable_to_remove_file)
             << Error;
@@ -102,16 +108,52 @@ bool Compilation::CleanupFileList(const ArgStringList &Files,
   return Success;
 }
 
+int Compilation::ExecuteJob(const Job &J) const {
+  if (const Command *C = dyn_cast<Command>(&J)) {
+    llvm::sys::Path Prog(C->getExecutable());
+    const char **Argv = new const char*[C->getArguments().size() + 2];
+    Argv[0] = C->getExecutable();
+    std::copy(C->getArguments().begin(), C->getArguments().end(), Argv+1);
+    Argv[C->getArguments().size() + 1] = 0;
+
+    if (getDriver().CCCEcho || getArgs().hasArg(options::OPT_v))
+      PrintJob(llvm::errs(), J, "\n", false);
+    
+    std::string Error;
+    int Res = 
+      llvm::sys::Program::ExecuteAndWait(Prog, Argv,
+                                         /*env*/0, /*redirects*/0,
+                                         /*secondsToWait*/0, /*memoryLimit*/0,
+                                         &Error);
+    if (!Error.empty()) {
+      assert(Res && "Error string set with 0 result code!");
+      getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
+    }
+    
+    delete[] Argv;
+    return Res;
+  } else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
+    (void) PJ;
+    getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe";
+    return 1;
+  } else {
+    const JobList *Jobs = cast<JobList>(&J);
+    for (JobList::const_iterator 
+           it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
+      if (int Res = ExecuteJob(**it))
+        return Res;
+    return 0;
+  }
+}
+
 int Compilation::Execute() const {
   // Just print if -### was present.
   if (getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
-    PrintJob(llvm::errs(), &Jobs, "\n");
+    PrintJob(llvm::errs(), Jobs, "\n", true);
     return 0;
   }
 
-  // FIXME: Execute.
-
-  int Res = 0;
+  int Res = ExecuteJob(Jobs);
   
   // Remove temp files.
   CleanupFileList(TempFiles);