blob: 3a2917032ec2708ec1717a78e9a4cb04f3a4e0e9 [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
19#include "llvm/System/Path.h"
20
21#include <iostream>
22#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;
40
41 if (!tempDir.exists()) {
42 std::string ErrMsg;
43 if (tempDir.createDirectoryOnDisk(true, &ErrMsg))
44 throw std::runtime_error(ErrMsg);
45 }
46 }
47 // else if (SaveTemps == Cwd) -> use current dir (leave tempDir empty)
48
49 return tempDir;
50 }
51
52 /// BuildTargets - A small wrapper for CompilationGraph::Build.
53 int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) {
54 int ret;
55 const sys::Path& tempDir = getTempDir();
56
57 try {
58 ret = graph.Build(tempDir, langMap);
59 }
60 catch(...) {
61 if (SaveTemps == SaveTempsEnum::Unset)
62 tempDir.eraseFromDisk(true);
63 throw;
64 }
65
66 if (SaveTemps == SaveTempsEnum::Unset)
67 tempDir.eraseFromDisk(true);
68 return ret;
69 }
70}
71
72namespace llvmc {
73
Mikhail Glushenkov875ace52009-06-30 00:16:00 +000074// Sometimes plugins want to condition on the value in argv[0].
75const char* ProgramName;
76
Mikhail Glushenkov583cf312009-06-30 00:15:24 +000077int Main(int argc, char** argv) {
78 try {
79 LanguageMap langMap;
80 CompilationGraph graph;
81
Mikhail Glushenkov875ace52009-06-30 00:16:00 +000082 ProgramName = argv[0];
83
Mikhail Glushenkov583cf312009-06-30 00:15:24 +000084 cl::ParseCommandLineOptions
85 (argc, argv, "LLVM Compiler Driver (Work In Progress)", true);
86
87 PluginLoader Plugins;
88 Plugins.PopulateLanguageMap(langMap);
89 Plugins.PopulateCompilationGraph(graph);
90
91 if (CheckGraph) {
92 int ret = graph.Check();
93 if (!ret)
94 std::cerr << "check-graph: no errors found.\n";
95
96 return ret;
97 }
98
99 if (ViewGraph) {
100 graph.viewGraph();
101 if (!WriteGraph)
102 return 0;
103 }
104
105 if (WriteGraph) {
106 graph.writeGraph(OutputFilename.empty()
107 ? std::string("compilation-graph.dot")
108 : OutputFilename);
109 return 0;
110 }
111
112 if (InputFilenames.empty()) {
113 throw std::runtime_error("no input files");
114 }
115
116 return BuildTargets(graph, langMap);
117 }
118 catch(llvmc::error_code& ec) {
119 return ec.code();
120 }
121 catch(const std::exception& ex) {
122 std::cerr << argv[0] << ": " << ex.what() << '\n';
123 }
124 catch(...) {
125 std::cerr << argv[0] << ": unknown error!\n";
126 }
127 return 1;
128}
129
130} // end namespace llvmc