Re-add the autoconf rule for the docs/doxygen.cfg file.
[oota-llvm.git] / lib / CompilerDriver / Main.cpp
index 7d1a3d8fbc4eb43caac758fb757e8a6e4b0bca76..7120027f7ce0e84668115eda8862835cdf2ed0d0 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CompilerDriver/AutoGenerated.h"
 #include "llvm/CompilerDriver/BuiltinOptions.h"
 #include "llvm/CompilerDriver/CompilationGraph.h"
 #include "llvm/CompilerDriver/Error.h"
-#include "llvm/CompilerDriver/Plugin.h"
 
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
 
-#include <stdexcept>
+#include <sstream>
 #include <string>
 
 namespace cl = llvm::cl;
@@ -28,104 +29,118 @@ using namespace llvmc;
 
 namespace {
 
-  sys::Path getTempDir() {
-    sys::Path tempDir;
+  std::stringstream* GlobalTimeLog;
 
+  /// GetTempDir - Get the temporary directory location. Returns non-zero value
+  /// on error.
+  int GetTempDir(sys::Path& tempDir) {
+    // The --temp-dir option.
+    if (!TempDirname.empty()) {
+      tempDir = TempDirname;
+    }
     // GCC 4.5-style -save-temps handling.
-    if (SaveTemps == SaveTempsEnum::Unset) {
+    else if (SaveTemps == SaveTempsEnum::Unset) {
       tempDir = sys::Path::GetTemporaryDirectory();
+      return 0;
     }
     else if (SaveTemps == SaveTempsEnum::Obj && !OutputFilename.empty()) {
-      tempDir = OutputFilename;
-      tempDir = tempDir.getDirname();
+      tempDir = sys::path::parent_path(OutputFilename);
+    }
+    else {
+      // SaveTemps == Cwd --> use current dir (leave tempDir empty).
+      return 0;
+    }
 
-      if (!tempDir.exists()) {
-        std::string ErrMsg;
-        if (tempDir.createDirectoryOnDisk(true, &ErrMsg))
-          throw std::runtime_error(ErrMsg);
+    bool Exists;
+    if (llvm::sys::fs::exists(tempDir.str(), Exists) || !Exists) {
+      std::string ErrMsg;
+      if (tempDir.createDirectoryOnDisk(true, &ErrMsg)) {
+        PrintError(ErrMsg);
+        return 1;
       }
     }
-    // else if (SaveTemps == Cwd) -> use current dir (leave tempDir empty)
 
-    return tempDir;
+    return 0;
   }
 
-  /// BuildTargets - A small wrapper for CompilationGraph::Build.
+  /// BuildTargets - A small wrapper for CompilationGraph::Build. Returns
+  /// non-zero value in case of error.
   int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) {
     int ret;
-    const sys::Path& tempDir = getTempDir();
+    sys::Path tempDir;
+    bool toDelete = (SaveTemps == SaveTempsEnum::Unset);
 
-    try {
-      ret = graph.Build(tempDir, langMap);
-    }
-    catch(...) {
-      if (SaveTemps == SaveTempsEnum::Unset)
-        tempDir.eraseFromDisk(true);
-      throw;
-    }
+    if (int ret = GetTempDir(tempDir))
+      return ret;
 
-    if (SaveTemps == SaveTempsEnum::Unset)
+    ret = graph.Build(tempDir, langMap);
+
+    if (toDelete)
       tempDir.eraseFromDisk(true);
+
     return ret;
   }
 }
 
 namespace llvmc {
 
-// Sometimes plugins want to condition on the value in argv[0].
+// Used to implement -time option. External linkage is intentional.
+void AppendToGlobalTimeLog(const std::string& cmd, double time) {
+  *GlobalTimeLog << "# " << cmd << ' ' << time << '\n';
+}
+
+// Sometimes user code wants to access the argv[0] value.
 const char* ProgramName;
 
 int Main(int argc, char** argv) {
-  try {
-    LanguageMap langMap;
-    CompilationGraph graph;
-
-    ProgramName = argv[0];
+  int ret = 0;
+  LanguageMap langMap;
+  CompilationGraph graph;
 
-    cl::ParseCommandLineOptions
-      (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
+  ProgramName = argv[0];
 
-    PluginLoader Plugins;
-    Plugins.PopulateLanguageMap(langMap);
-    Plugins.PopulateCompilationGraph(graph);
+  cl::ParseCommandLineOptions
+    (argc, argv,
+     /* Overview = */ "LLVM Compiler Driver (Work In Progress)",
+     /* ReadResponseFiles = */ false);
 
-    if (CheckGraph) {
-      int ret = graph.Check();
-      if (!ret)
-        llvm::errs() << "check-graph: no errors found.\n";
+  if (int ret = autogenerated::RunInitialization(langMap, graph))
+    return ret;
 
-      return ret;
-    }
+  if (CheckGraph) {
+    ret = graph.Check();
+    if (!ret)
+      llvm::errs() << "check-graph: no errors found.\n";
 
-    if (ViewGraph) {
-      graph.viewGraph();
-      if (!WriteGraph)
-        return 0;
-    }
+    return ret;
+  }
 
-    if (WriteGraph) {
-      graph.writeGraph(OutputFilename.empty()
-                       ? std::string("compilation-graph.dot")
-                       : OutputFilename);
+  if (ViewGraph) {
+    graph.viewGraph();
+    if (!WriteGraph)
       return 0;
-    }
-
-    if (InputFilenames.empty()) {
-      throw std::runtime_error("no input files");
-    }
-
-    return BuildTargets(graph, langMap);
   }
-  catch(llvmc::error_code& ec) {
-    return ec.code();
+
+  if (WriteGraph) {
+    const std::string& Out = (OutputFilename.empty()
+                              ? std::string("compilation-graph.dot")
+                              : OutputFilename);
+    return graph.writeGraph(Out);
   }
-  catch(const std::exception& ex) {
-    llvm::errs() << argv[0] << ": " << ex.what() << '\n';
+
+  if (Time) {
+    GlobalTimeLog = new std::stringstream;
+    GlobalTimeLog->precision(2);
   }
-  catch(...) {
-    llvm::errs() << argv[0] << ": unknown error!\n";
+
+  ret = BuildTargets(graph, langMap);
+
+  if (Time) {
+    llvm::errs() << GlobalTimeLog->str();
+    delete GlobalTimeLog;
   }
-  return 1;
+
+  return ret;
 }
 
 } // end namespace llvmc