blob: ff63b2100ede5aae661d3ff04585a11a09a3f152 [file] [log] [blame]
Reid Spencera3f18552004-08-13 20:25:54 +00001//===- CompilerDriver.cpp - The LLVM Compiler Driver ------------*- C++ -*-===//
Reid Spencer5c56dc12004-08-13 20:22:43 +00002//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file was developed by Reid Spencer and is distributed under the
7// University of Illinois Open Source License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10//
Reid Spencera3f18552004-08-13 20:25:54 +000011// This file implements the bulk of the LLVM Compiler Driver (llvmc).
Reid Spencer5c56dc12004-08-13 20:22:43 +000012//
13//===------------------------------------------------------------------------===
14
15#include "CompilerDriver.h"
16#include <iostream>
17
18using namespace llvm;
19
20namespace {
21 inline std::string RemoveSuffix(const std::string& fullName) {
22 size_t dotpos = fullName.rfind('.',fullName.size());
23 if ( dotpos == std::string::npos ) return fullName;
24 return fullName.substr(0, dotpos);
25 }
26
27 inline std::string GetSuffix(const std::string& fullName) {
28 size_t dotpos = fullName.rfind('.',fullName.size());
29 if ( dotpos = std::string::npos ) return "";
30 return fullName.substr(dotpos+1);
31 }
Reid Spencer68fb37a2004-08-14 09:37:15 +000032
Reid Spencer5c56dc12004-08-13 20:22:43 +000033 const char OutputSuffix[] = ".o";
34
Reid Spencer68fb37a2004-08-14 09:37:15 +000035 void WriteAction(CompilerDriver::Action* a) {
36 std::cerr << a->program;
37 std::vector<std::string>::iterator I = a->args.begin();
38 while (I != a->args.end()) {
39 std::cerr << " " + *I;
40 ++I;
41 }
42 std::cerr << "\n";
43 }
44
45 void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
46 std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
47 << ")\n";
48 std::cerr << "translator.preprocesses=" << cd->TranslatorPreprocesses
49 << "\n";
50 std::cerr << "translator.groks_dash_O=" << cd->TranslatorGroksDashO << "\n";
51 std::cerr << "translator.optimizes=" << cd->TranslatorOptimizes << "\n";
52 std::cerr << "preprocessor.needed=" << cd->PreprocessorNeeded << "\n";
53 std::cerr << "PreProcessor: ";
54 WriteAction(&cd->PreProcessor);
55 std::cerr << "Translator: ";
56 WriteAction(&cd->Translator);
57 std::cerr << "Optimizer: ";
58 WriteAction(&cd->Optimizer);
59 std::cerr << "Assembler: ";
60 WriteAction(&cd->Assembler);
61 std::cerr << "Linker: ";
62 WriteAction(&cd->Linker);
63 }
Reid Spencer5c56dc12004-08-13 20:22:43 +000064}
65
66
67CompilerDriver::CompilerDriver(ConfigDataProvider& confDatProv )
68 : cdp(&confDatProv)
69 , finalPhase(LINKING)
70 , optLevel(OPT_FAST_COMPILE)
71 , isDryRun(false)
72 , isVerbose(false)
73 , isDebug(false)
74 , timeActions(false)
75 , emitRawCode(false)
76 , emitNativeCode(false)
77 , machine()
78 , libPaths()
79{
80 // FIXME: These libraries are platform specific
81 libPaths.push_back("/lib");
82 libPaths.push_back("/usr/lib");
83}
84
85CompilerDriver::~CompilerDriver() {
86 cdp = 0;
87 libPaths.clear();
88}
89
90void CompilerDriver::error( const std::string& errmsg ) {
91 std::cerr << "Error: " << errmsg << ".\n";
92 exit(1);
93}
94
95CompilerDriver::Action* CompilerDriver::GetAction(ConfigData* cd,
96 const std::string& input,
97 const std::string& output,
98 Phases phase)
99{
100 Action* pat = 0;
101 switch (phase) {
102 case PREPROCESSING: pat = &cd->PreProcessor; break;
103 case TRANSLATION: pat = &cd->Translator; break;
104 case OPTIMIZATION: pat = &cd->Optimizer; break;
105 case ASSEMBLY: pat = &cd->Assembler; break;
106 case LINKING: pat = &cd->Linker; break;
107 default:
108 assert(!"Invalid driver phase!");
109 break;
110 }
111 assert(pat != 0 && "Invalid command pattern");
112 Action* a = new Action(*pat);
Reid Spencer68fb37a2004-08-14 09:37:15 +0000113 if (pat->inputAt < a->args.size())
114 a->args[pat->inputAt] = input;
115 if (pat->outputAt < a->args.size())
116 a->args[pat->outputAt] = output;
Reid Spencer5c56dc12004-08-13 20:22:43 +0000117 return a;
118}
119
Reid Spencer5c56dc12004-08-13 20:22:43 +0000120void CompilerDriver::DoAction(Action*a)
121{
122 if (isVerbose)
123 WriteAction(a);
124 if (!isDryRun) {
125 std::cerr << "execve(\"" << a->program << "\",[\n";
126 std::vector<std::string>::iterator I = a->args.begin();
127 while (I != a->args.end()) {
128 std::cerr << " \"" << *I << "\",\n";
129 ++I;
130 }
131 std::cerr << "],ENV);\n";
132 }
133}
134
135int CompilerDriver::execute(const InputList& InpList,
136 const std::string& Output ) {
137 // Echo the configuration of options if we're running verbose
138 if (isDebug)
139 {
140 std::cerr << "Compiler Driver Options:\n";
141 std::cerr << "DryRun = " << isDryRun << "\n";
142 std::cerr << "Verbose = " << isVerbose << " \n";
143 std::cerr << "TimeActions = " << timeActions << "\n";
144 std::cerr << "EmitRawCode = " << emitRawCode << "\n";
145 std::cerr << "OutputMachine = " << machine << "\n";
146 std::cerr << "EmitNativeCode = " << emitNativeCode << "\n";
147 InputList::const_iterator I = InpList.begin();
148 while ( I != InpList.end() ) {
149 std::cerr << "Input: " << I->first << "(" << I->second << ")\n";
150 ++I;
151 }
152 std::cerr << "Output: " << Output << "\n";
153 }
154
155 // If there's no input, we're done.
156 if (InpList.empty())
157 error("Nothing to compile.");
158
159 // If they are asking for linking and didn't provide an output
160 // file then its an error (no way for us to "make up" a meaningful
161 // file name based on the various linker input files).
162 if (finalPhase == LINKING && Output.empty())
163 error("An output file name must be specified for linker output");
164
165 std::vector<Action*> actions;
166
167 /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
168 // for each input item
169 std::vector<std::string> LinkageItems;
170 InputList::const_iterator I = InpList.begin();
171 while ( I != InpList.end() ) {
172 // Get the suffix of the file name
173 std::string suffix = GetSuffix(I->first);
174
175 // If its a library, bytecode file, or object file, save
176 // it for linking below and short circuit the
177 // pre-processing/translation/assembly phases
178 if (I->second.empty() || suffix == "o" || suffix == "bc") {
179 // We shouldn't get any of these types of files unless we're
180 // later going to link. Enforce this limit now.
181 if (finalPhase != LINKING) {
182 error("Pre-compiled objects found but linking not requested");
183 }
184 LinkageItems.push_back(I->first);
185 continue; // short circuit remainder of loop
186 }
187
188 // At this point, we know its something we need to translate
189 // and/or optimize. See if we can get the configuration data
190 // for this kind of file.
191 ConfigData* cd = cdp->ProvideConfigData(I->second);
192 if (cd == 0)
193 error(std::string("Files of type '") + I->second +
194 "' are not recognized." );
Reid Spencer68fb37a2004-08-14 09:37:15 +0000195 if (isDebug)
196 DumpConfigData(cd,I->second);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000197
198 // We have valid configuration data, now figure out where the output
199 // of compilation should end up.
200 std::string OutFile;
201 if (finalPhase != LINKING) {
202 if (InpList.size() == 1 && !Output.empty())
203 OutFile = Output;
204 else
205 OutFile = RemoveSuffix(I->first) + OutputSuffix;
206 } else {
207 OutFile = Output;
208 }
209
210 /// PRE-PROCESSING PHASE
211 if (finalPhase == PREPROCESSING) {
212 if (cd->PreProcessor.program.empty())
213 error(cd->langName + " does not support pre-processing");
214 else
215 actions.push_back(GetAction(cd,I->first,OutFile,PREPROCESSING));
216 } else if (cd->PreprocessorNeeded && !cd->TranslatorPreprocesses) {
217 if (!cd->PreProcessor.program.empty()) {
218 actions.push_back(GetAction(cd,I->first,OutFile,PREPROCESSING));
219 }
220 }
221
222 // Short-circuit remaining actions if all they want is pre-processing
223 if (finalPhase == PREPROCESSING) { ++I; continue; };
224
225 /// TRANSLATION PHASE
226 actions.push_back(GetAction(cd,I->first,OutFile,TRANSLATION));
227 // Short-circuit remaining actions if all they want is translation
228 if (finalPhase == TRANSLATION) { ++I; continue; }
229
230 /// OPTIMIZATION PHASE
231 actions.push_back(GetAction(cd,I->first,OutFile,OPTIMIZATION));
232 // Short-circuit remaining actions if all they want is optimization
233 if (finalPhase == OPTIMIZATION) { ++I; continue; }
234
235 ++I;
236 }
237
238 /// LINKING PHASE
239
240 /// RUN THE ACTIONS
241 std::vector<Action*>::iterator aIter = actions.begin();
242 while (aIter != actions.end()) {
243 DoAction(*aIter);
244 aIter++;
245 }
246
247 return 0;
248}
249
250// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab