Missing )
[oota-llvm.git] / lib / CompilerDriver / Main.cpp
1 //===--- 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
19 #include "llvm/Support/raw_ostream.h"
20 #include "llvm/System/Path.h"
21
22 #include <stdexcept>
23 #include <string>
24
25 namespace cl = llvm::cl;
26 namespace sys = llvm::sys;
27 using namespace llvmc;
28
29 namespace {
30
31   sys::Path getTempDir() {
32     sys::Path tempDir;
33
34     if (! TempDirname.empty()) {
35       tempDir = TempDirname;
36       if (!tempDir.exists()) {
37         std::string ErrMsg;
38         if (tempDir.createDirectoryOnDisk(true, &ErrMsg))
39           throw std::runtime_error(ErrMsg);
40       }
41     }
42
43     // GCC 4.5-style -save-temps handling.
44     if (SaveTemps == SaveTempsEnum::Unset) {
45       tempDir = sys::Path::GetTemporaryDirectory();
46     }
47     else if (SaveTemps == SaveTempsEnum::Obj && !OutputFilename.empty()) {
48       tempDir = OutputFilename;
49       tempDir = tempDir.getDirname();
50
51       if (!tempDir.exists()) {
52         std::string ErrMsg;
53         if (tempDir.createDirectoryOnDisk(true, &ErrMsg))
54           throw std::runtime_error(ErrMsg);
55       }
56     }
57     // else if (SaveTemps == Cwd) -> use current dir (leave tempDir empty)
58
59     return tempDir;
60   }
61
62   /// BuildTargets - A small wrapper for CompilationGraph::Build.
63   int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) {
64     int ret;
65     const sys::Path& tempDir = getTempDir();
66
67     try {
68       ret = graph.Build(tempDir, langMap);
69     }
70     catch(...) {
71       if (SaveTemps == SaveTempsEnum::Unset)
72         tempDir.eraseFromDisk(true);
73       throw;
74     }
75
76     if (SaveTemps == SaveTempsEnum::Unset)
77       tempDir.eraseFromDisk(true);
78     return ret;
79   }
80 }
81
82 namespace llvmc {
83
84 // Sometimes plugins want to condition on the value in argv[0].
85 const char* ProgramName;
86
87 int Main(int argc, char** argv) {
88   try {
89     LanguageMap langMap;
90     CompilationGraph graph;
91
92     ProgramName = argv[0];
93
94     cl::ParseCommandLineOptions
95       (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
96
97     PluginLoader Plugins;
98     Plugins.PopulateLanguageMap(langMap);
99     Plugins.PopulateCompilationGraph(graph);
100
101     if (CheckGraph) {
102       int ret = graph.Check();
103       if (!ret)
104         llvm::errs() << "check-graph: no errors found.\n";
105
106       return ret;
107     }
108
109     if (ViewGraph) {
110       graph.viewGraph();
111       if (!WriteGraph)
112         return 0;
113     }
114
115     if (WriteGraph) {
116       graph.writeGraph(OutputFilename.empty()
117                        ? std::string("compilation-graph.dot")
118                        : OutputFilename);
119       return 0;
120     }
121
122     if (InputFilenames.empty()) {
123       throw std::runtime_error("no input files");
124     }
125
126     return BuildTargets(graph, langMap);
127   }
128   catch(llvmc::error_code& ec) {
129     return ec.code();
130   }
131   catch(const std::exception& ex) {
132     llvm::errs() << argv[0] << ": " << ex.what() << '\n';
133   }
134   catch(...) {
135     llvm::errs() << argv[0] << ": unknown error!\n";
136   }
137   return 1;
138 }
139
140 } // end namespace llvmc