Revert 106592 for now. It causes clang-selfhost build failure.
[oota-llvm.git] / lib / CompilerDriver / Action.cpp
index 816f793bc07dc5ae5d6ba40e156d85a3317d6fd0..5f30dce5855fd42293b3b58663bce7c249809865 100644 (file)
 #include "llvm/CompilerDriver/Action.h"
 #include "llvm/CompilerDriver/BuiltinOptions.h"
 
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SystemUtils.h"
 #include "llvm/System/Program.h"
+#include "llvm/System/TimeValue.h"
 
-#include <iostream>
 #include <stdexcept>
+#include <string>
 
 using namespace llvm;
 using namespace llvmc;
 
+namespace llvmc {
+
+extern int Main(int argc, char** argv);
+extern const char* ProgramName;
+
+}
+
 namespace {
-  int ExecuteProgram(const std::string& name,
-                     const StrVector& args) {
+
+  void PrintString (const std::string& str) {
+    errs() << str << ' ';
+  }
+
+  void PrintCommand (const std::string& Cmd, const StrVector& Args) {
+    errs() << Cmd << ' ';
+    std::for_each(Args.begin(), Args.end(), &PrintString);
+    errs() << '\n';
+  }
+
+  bool IsSegmentationFault (int returnCode) {
+#ifdef LLVM_ON_WIN32
+    return (returnCode >= 0xc0000000UL)
+#else
+    return (returnCode < 0);
+#endif
+  }
+
+  int ExecuteProgram (const std::string& name,
+                      const StrVector& args) {
     sys::Path prog = sys::Program::FindProgramByName(name);
 
-    if (prog.isEmpty())
-      throw std::runtime_error("Can't find program '" + name + "'");
+    if (prog.isEmpty()) {
+      prog = FindExecutable(name, ProgramName, (void *)(intptr_t)&Main);
+      if (prog.isEmpty())
+        throw std::runtime_error("Can't find program '" + name + "'");
+    }
     if (!prog.canExecute())
       throw std::runtime_error("Program '" + name + "' is not executable.");
 
@@ -54,22 +86,40 @@ namespace {
     argv.push_back(0);  // null terminate list.
 
     // Invoke the program.
-    return sys::Program::ExecuteAndWait(prog, &argv[0], 0, &redirects[0]);
-  }
+    int ret = sys::Program::ExecuteAndWait(prog, &argv[0], 0, &redirects[0]);
+
+    if (IsSegmentationFault(ret)) {
+      errs() << "Segmentation fault: ";
+      PrintCommand(name, args);
+    }
 
-  void print_string (const std::string& str) {
-    std::cerr << str << ' ';
+    return ret;
   }
 }
 
-int llvmc::Action::Execute() const {
-  if (DryRun || VerboseMode) {
-    std::cerr << Command_ << " ";
-    std::for_each(Args_.begin(), Args_.end(), print_string);
-    std::cerr << '\n';
+namespace llvmc {
+  void AppendToGlobalTimeLog (const std::string& cmd, double time);
+}
+
+int llvmc::Action::Execute () const {
+  if (DryRun || VerboseMode)
+    PrintCommand(Command_, Args_);
+
+  if (!DryRun) {
+    if (Time) {
+      sys::TimeValue now = sys::TimeValue::now();
+      int ret = ExecuteProgram(Command_, Args_);
+      sys::TimeValue now2 = sys::TimeValue::now();
+      now2 -= now;
+      double elapsed = now2.seconds()  + now2.microseconds()  / 1000000.0;
+      AppendToGlobalTimeLog(Command_, elapsed);
+
+      return ret;
+    }
+    else {
+      return ExecuteProgram(Command_, Args_);
+    }
   }
-  if (DryRun)
-    return 0;
-  else
-    return ExecuteProgram(Command_, Args_);
+
+  return 0;
 }