blob: 7d1a3d8fbc4eb43caac758fb757e8a6e4b0bca76 [file] [log] [blame]
Mikhail Glushenkov583cf312009-06-30 00:15:24 +00001//===--- Main.cpp - The LLVM Compiler Driver --------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open
6// Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// llvmc::Main function - driver entry point.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/CompilerDriver/BuiltinOptions.h"
15#include "llvm/CompilerDriver/CompilationGraph.h"
16#include "llvm/CompilerDriver/Error.h"
17#include "llvm/CompilerDriver/Plugin.h"
18
Bill Wendling9cdd4f52009-06-30 04:07:12 +000019#include "llvm/Support/raw_ostream.h"
Mikhail Glushenkov583cf312009-06-30 00:15:24 +000020#include "llvm/System/Path.h"
21
Mikhail Glushenkov583cf312009-06-30 00:15:24 +000022#include <stdexcept>
23#include <string>
24
25namespace cl = llvm::cl;
26namespace sys = llvm::sys;
27using namespace llvmc;
28
29namespace {
30
31 sys::Path getTempDir() {
32 sys::Path tempDir;
33
34 // GCC 4.5-style -save-temps handling.
35 if (SaveTemps == SaveTempsEnum::Unset) {
36 tempDir = sys::Path::GetTemporaryDirectory();
37 }
38 else if (SaveTemps == SaveTempsEnum::Obj && !OutputFilename.empty()) {
39 tempDir = OutputFilename;
Mikhail Glushenkoveebf60c2009-07-04 14:23:32 +000040 tempDir = tempDir.getDirname();
Mikhail Glushenkov583cf312009-06-30 00:15:24 +000041
42 if (!tempDir.exists()) {
43 std::string ErrMsg;
44 if (tempDir.createDirectoryOnDisk(true, &ErrMsg))
45 throw std::runtime_error(ErrMsg);
46 }
47 }
48 // else if (SaveTemps == Cwd) -> use current dir (leave tempDir empty)
49
50 return tempDir;
51 }
52
53 /// BuildTargets - A small wrapper for CompilationGraph::Build.
54 int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) {
55 int ret;
56 const sys::Path& tempDir = getTempDir();
57
58 try {
59 ret = graph.Build(tempDir, langMap);
60 }
61 catch(...) {
62 if (SaveTemps == SaveTempsEnum::Unset)
63 tempDir.eraseFromDisk(true);
64 throw;
65 }
66
67 if (SaveTemps == SaveTempsEnum::Unset)
68 tempDir.eraseFromDisk(true);
69 return ret;
70 }
71}
72
73namespace llvmc {
74
Mikhail Glushenkov875ace52009-06-30 00:16:00 +000075// Sometimes plugins want to condition on the value in argv[0].
76const char* ProgramName;
77
Mikhail Glushenkov583cf312009-06-30 00:15:24 +000078int Main(int argc, char** argv) {
79 try {
80 LanguageMap langMap;
81 CompilationGraph graph;
82
Mikhail Glushenkov875ace52009-06-30 00:16:00 +000083 ProgramName = argv[0];
84
Mikhail Glushenkov583cf312009-06-30 00:15:24 +000085 cl::ParseCommandLineOptions
86 (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
87
88 PluginLoader Plugins;
89 Plugins.PopulateLanguageMap(langMap);
90 Plugins.PopulateCompilationGraph(graph);
91
92 if (CheckGraph) {
93 int ret = graph.Check();
94 if (!ret)
Bill Wendling9cdd4f52009-06-30 04:07:12 +000095 llvm::errs() << "check-graph: no errors found.\n";
Mikhail Glushenkov583cf312009-06-30 00:15:24 +000096
97 return ret;
98 }
99
100 if (ViewGraph) {
101 graph.viewGraph();
102 if (!WriteGraph)
103 return 0;
104 }
105
106 if (WriteGraph) {
107 graph.writeGraph(OutputFilename.empty()
108 ? std::string("compilation-graph.dot")
109 : OutputFilename);
110 return 0;
111 }
112
113 if (InputFilenames.empty()) {
114 throw std::runtime_error("no input files");
115 }
116
117 return BuildTargets(graph, langMap);
118 }
119 catch(llvmc::error_code& ec) {
120 return ec.code();
121 }
122 catch(const std::exception& ex) {
Bill Wendling9cdd4f52009-06-30 04:07:12 +0000123 llvm::errs() << argv[0] << ": " << ex.what() << '\n';
Mikhail Glushenkov583cf312009-06-30 00:15:24 +0000124 }
125 catch(...) {
Bill Wendling9cdd4f52009-06-30 04:07:12 +0000126 llvm::errs() << argv[0] << ": unknown error!\n";
Mikhail Glushenkov583cf312009-06-30 00:15:24 +0000127 }
128 return 1;
129}
130
131} // end namespace llvmc