//
//===----------------------------------------------------------------------===//
+#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;
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.
else if (SaveTemps == SaveTempsEnum::Unset) {
tempDir = sys::Path::GetTemporaryDirectory();
- return tempDir;
+ 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 tempDir;
+ return 0;
}
- if (!tempDir.exists()) {
+ bool Exists;
+ if (llvm::sys::fs::exists(tempDir.str(), Exists) || !Exists) {
std::string ErrMsg;
- if (tempDir.createDirectoryOnDisk(true, &ErrMsg))
- throw std::runtime_error(ErrMsg);
+ if (tempDir.createDirectoryOnDisk(true, &ErrMsg)) {
+ PrintError(ErrMsg);
+ return 1;
+ }
}
- 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 (toDelete)
- tempDir.eraseFromDisk(true);
- throw;
- }
+ if (int ret = GetTempDir(tempDir))
+ return ret;
+
+ 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;
+ int ret = 0;
+ LanguageMap langMap;
+ CompilationGraph graph;
- ProgramName = argv[0];
+ ProgramName = argv[0];
- cl::ParseCommandLineOptions
- (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
+ cl::ParseCommandLineOptions
+ (argc, argv,
+ /* Overview = */ "LLVM Compiler Driver (Work In Progress)",
+ /* ReadResponseFiles = */ false);
- PluginLoader Plugins;
- Plugins.PopulateLanguageMap(langMap);
- Plugins.PopulateCompilationGraph(graph);
+ if (int ret = autogenerated::RunInitialization(langMap, graph))
+ return ret;
- if (CheckGraph) {
- int ret = graph.Check();
- if (!ret)
- llvm::errs() << "check-graph: no errors found.\n";
+ if (CheckGraph) {
+ ret = graph.Check();
+ if (!ret)
+ llvm::errs() << "check-graph: no errors found.\n";
- return ret;
- }
-
- 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