blob: 34e4038c139035c604ca409d5f0ff18547daa87b [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//
Misha Brukman3da94ae2005-04-22 00:00:37 +00003//
Reid Spencer5c56dc12004-08-13 20:22:43 +00004// The LLVM Compiler Infrastructure
5//
Misha Brukman3da94ae2005-04-22 00:00:37 +00006// This file was developed by Reid Spencer and is distributed under the
Reid Spencer5c56dc12004-08-13 20:22:43 +00007// University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukman3da94ae2005-04-22 00:00:37 +00008//
Reid Spencer5c56dc12004-08-13 20:22:43 +00009//===----------------------------------------------------------------------===//
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"
Reid Spencerbf437722004-08-15 08:19:46 +000016#include "ConfigLexer.h"
Reid Spencera01439a2004-08-24 13:55:17 +000017#include "llvm/Module.h"
Reid Spencer52c2dc12004-08-29 19:26:56 +000018#include "llvm/Bytecode/Reader.h"
Reid Spencer54fafe42004-09-14 01:58:45 +000019#include "llvm/Support/Timer.h"
Reid Spencer93426ba2004-08-29 20:02:28 +000020#include "llvm/System/Signals.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000021#include "llvm/ADT/SetVector.h"
22#include "llvm/ADT/StringExtras.h"
Brian Gaekefabf41f2004-12-20 04:02:01 +000023#include "llvm/Config/alloca.h"
Misha Brukmanbaec07c2005-04-20 04:51:29 +000024#include <iostream>
Reid Spencer5c56dc12004-08-13 20:22:43 +000025using namespace llvm;
26
27namespace {
Reid Spencer5c56dc12004-08-13 20:22:43 +000028
Reid Spenceraf77d742004-10-28 04:05:06 +000029void WriteAction(CompilerDriver::Action* action ) {
30 std::cerr << action->program.c_str();
Reid Spencerf6358c72004-12-19 18:00:56 +000031 std::vector<std::string>::const_iterator I = action->args.begin();
Reid Spenceraf77d742004-10-28 04:05:06 +000032 while (I != action->args.end()) {
Misha Brukman0b861482005-05-03 20:30:34 +000033 std::cerr << ' ' << *I;
Reid Spenceraf77d742004-10-28 04:05:06 +000034 ++I;
35 }
Misha Brukman0b861482005-05-03 20:30:34 +000036 std::cerr << '\n';
Reid Spenceraf77d742004-10-28 04:05:06 +000037}
38
39void DumpAction(CompilerDriver::Action* action) {
40 std::cerr << "command = " << action->program.c_str();
Reid Spencerf6358c72004-12-19 18:00:56 +000041 std::vector<std::string>::const_iterator I = action->args.begin();
Reid Spenceraf77d742004-10-28 04:05:06 +000042 while (I != action->args.end()) {
Misha Brukman0b861482005-05-03 20:30:34 +000043 std::cerr << ' ' << *I;
Reid Spenceraf77d742004-10-28 04:05:06 +000044 ++I;
45 }
Misha Brukman0b861482005-05-03 20:30:34 +000046 std::cerr << '\n';
47 std::cerr << "flags = " << action->flags << '\n';
Reid Spenceraf77d742004-10-28 04:05:06 +000048}
49
50void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
Misha Brukman3da94ae2005-04-22 00:00:37 +000051 std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
Reid Spenceraf77d742004-10-28 04:05:06 +000052 << ")\n";
53 std::cerr << "PreProcessor: ";
54 DumpAction(&cd->PreProcessor);
55 std::cerr << "Translator: ";
56 DumpAction(&cd->Translator);
57 std::cerr << "Optimizer: ";
58 DumpAction(&cd->Optimizer);
59 std::cerr << "Assembler: ";
60 DumpAction(&cd->Assembler);
61 std::cerr << "Linker: ";
62 DumpAction(&cd->Linker);
63}
64
65/// This specifies the passes to run for OPT_FAST_COMPILE (-O1)
66/// which should reduce the volume of code and make compilation
Misha Brukman3da94ae2005-04-22 00:00:37 +000067/// faster. This is also safe on any llvm module.
Reid Spenceraf77d742004-10-28 04:05:06 +000068static const char* DefaultFastCompileOptimizations[] = {
69 "-simplifycfg", "-mem2reg", "-instcombine"
70};
71
72class CompilerDriverImpl : public CompilerDriver {
73/// @name Constructors
74/// @{
75public:
76 CompilerDriverImpl(ConfigDataProvider& confDatProv )
77 : cdp(&confDatProv)
78 , finalPhase(LINKING)
Misha Brukman3da94ae2005-04-22 00:00:37 +000079 , optLevel(OPT_FAST_COMPILE)
Reid Spenceraf77d742004-10-28 04:05:06 +000080 , Flags(0)
81 , machine()
82 , LibraryPaths()
83 , TempDir()
84 , AdditionalArgs()
85 {
86 TempDir = sys::Path::GetTemporaryDirectory();
87 sys::RemoveDirectoryOnSignal(TempDir);
88 AdditionalArgs.reserve(NUM_PHASES);
89 StringVector emptyVec;
90 for (unsigned i = 0; i < NUM_PHASES; ++i)
91 AdditionalArgs.push_back(emptyVec);
92 }
93
94 virtual ~CompilerDriverImpl() {
95 cleanup();
96 cdp = 0;
97 LibraryPaths.clear();
98 IncludePaths.clear();
99 Defines.clear();
100 TempDir.clear();
101 AdditionalArgs.clear();
102 fOptions.clear();
103 MOptions.clear();
104 WOptions.clear();
105 }
106
107/// @}
108/// @name Methods
109/// @{
110public:
Misha Brukman0b861482005-05-03 20:30:34 +0000111 virtual void setFinalPhase(Phases phase) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000112 finalPhase = phase;
Reid Spenceraf77d742004-10-28 04:05:06 +0000113 }
114
Misha Brukman0b861482005-05-03 20:30:34 +0000115 virtual void setOptimization(OptimizationLevels level) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000116 optLevel = level;
Reid Spenceraf77d742004-10-28 04:05:06 +0000117 }
118
Misha Brukman0b861482005-05-03 20:30:34 +0000119 virtual void setDriverFlags(unsigned flags) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000120 Flags = flags & DRIVER_FLAGS_MASK;
Reid Spenceraf77d742004-10-28 04:05:06 +0000121 }
122
Misha Brukman0b861482005-05-03 20:30:34 +0000123 virtual void setOutputMachine(const std::string& machineName) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000124 machine = machineName;
125 }
126
127 virtual void setPhaseArgs(Phases phase, const StringVector& opts) {
128 assert(phase <= LINKING && phase >= PREPROCESSING);
129 AdditionalArgs[phase] = opts;
130 }
131
132 virtual void setIncludePaths(const StringVector& paths) {
133 StringVector::const_iterator I = paths.begin();
134 StringVector::const_iterator E = paths.end();
135 while (I != E) {
136 sys::Path tmp;
Reid Spencer07adb282004-11-05 22:15:36 +0000137 tmp.setDirectory(*I);
Reid Spenceraf77d742004-10-28 04:05:06 +0000138 IncludePaths.push_back(tmp);
Reid Spencer68fb37a2004-08-14 09:37:15 +0000139 ++I;
140 }
Reid Spencer68fb37a2004-08-14 09:37:15 +0000141 }
142
Reid Spenceraf77d742004-10-28 04:05:06 +0000143 virtual void setSymbolDefines(const StringVector& defs) {
144 Defines = defs;
145 }
146
147 virtual void setLibraryPaths(const StringVector& paths) {
148 StringVector::const_iterator I = paths.begin();
149 StringVector::const_iterator E = paths.end();
150 while (I != E) {
151 sys::Path tmp;
Reid Spencer07adb282004-11-05 22:15:36 +0000152 tmp.setDirectory(*I);
Reid Spenceraf77d742004-10-28 04:05:06 +0000153 LibraryPaths.push_back(tmp);
Reid Spencerbf437722004-08-15 08:19:46 +0000154 ++I;
155 }
Reid Spencerbf437722004-08-15 08:19:46 +0000156 }
157
Misha Brukman0b861482005-05-03 20:30:34 +0000158 virtual void addLibraryPath(const sys::Path& libPath) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000159 LibraryPaths.push_back(libPath);
Reid Spencer68fb37a2004-08-14 09:37:15 +0000160 }
Reid Spencer5c56dc12004-08-13 20:22:43 +0000161
Misha Brukman0b861482005-05-03 20:30:34 +0000162 virtual void addToolPath(const sys::Path& toolPath) {
Reid Spencer07adb282004-11-05 22:15:36 +0000163 ToolPaths.push_back(toolPath);
164 }
165
Reid Spenceraf77d742004-10-28 04:05:06 +0000166 virtual void setfPassThrough(const StringVector& fOpts) {
167 fOptions = fOpts;
168 }
Reid Spencer5c56dc12004-08-13 20:22:43 +0000169
Reid Spenceraf77d742004-10-28 04:05:06 +0000170 /// @brief Set the list of -M options to be passed through
171 virtual void setMPassThrough(const StringVector& MOpts) {
172 MOptions = MOpts;
173 }
Reid Spencerbae68252004-08-19 04:49:47 +0000174
Reid Spenceraf77d742004-10-28 04:05:06 +0000175 /// @brief Set the list of -W options to be passed through
176 virtual void setWPassThrough(const StringVector& WOpts) {
177 WOptions = WOpts;
178 }
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000179
Reid Spenceraf77d742004-10-28 04:05:06 +0000180/// @}
181/// @name Functions
182/// @{
183private:
184 bool isSet(DriverFlags flag) {
185 return 0 != ((flag & DRIVER_FLAGS_MASK) & Flags);
186 }
Reid Spencerbae68252004-08-19 04:49:47 +0000187
Reid Spenceraf77d742004-10-28 04:05:06 +0000188 void cleanup() {
189 if (!isSet(KEEP_TEMPS_FLAG)) {
Reid Spencerc7f08322005-07-07 18:21:42 +0000190 if (TempDir.isDirectory() && TempDir.canWrite())
Reid Spencer07adb282004-11-05 22:15:36 +0000191 TempDir.destroyDirectory(/*remove_contents=*/true);
Reid Spenceraf77d742004-10-28 04:05:06 +0000192 } else {
Reid Spencer12786d52004-12-13 08:53:36 +0000193 std::cout << "Temporary files are in " << TempDir << "\n";
Reid Spenceraf77d742004-10-28 04:05:06 +0000194 }
195 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000196
Misha Brukman3da94ae2005-04-22 00:00:37 +0000197 sys::Path MakeTempFile(const std::string& basename,
Misha Brukman0b861482005-05-03 20:30:34 +0000198 const std::string& suffix) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000199 sys::Path result(TempDir);
Reid Spencer07adb282004-11-05 22:15:36 +0000200 if (!result.appendFile(basename))
Reid Spenceraf77d742004-10-28 04:05:06 +0000201 throw basename + ": can't use this file name";
Reid Spencer07adb282004-11-05 22:15:36 +0000202 if (!result.appendSuffix(suffix))
Reid Spenceraf77d742004-10-28 04:05:06 +0000203 throw suffix + ": can't use this file suffix";
204 return result;
205 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000206
Misha Brukman3da94ae2005-04-22 00:00:37 +0000207 Action* GetAction(ConfigData* cd,
208 const sys::Path& input,
Reid Spenceraf77d742004-10-28 04:05:06 +0000209 const sys::Path& output,
210 Phases phase)
211 {
212 Action* pat = 0; ///< The pattern/template for the action
213 Action* action = new Action; ///< The actual action to execute
Reid Spencer52c2dc12004-08-29 19:26:56 +0000214
Reid Spenceraf77d742004-10-28 04:05:06 +0000215 // Get the action pattern
216 switch (phase) {
217 case PREPROCESSING: pat = &cd->PreProcessor; break;
218 case TRANSLATION: pat = &cd->Translator; break;
219 case OPTIMIZATION: pat = &cd->Optimizer; break;
220 case ASSEMBLY: pat = &cd->Assembler; break;
221 case LINKING: pat = &cd->Linker; break;
222 default:
223 assert(!"Invalid driver phase!");
224 break;
225 }
226 assert(pat != 0 && "Invalid command pattern");
Reid Spencer52c2dc12004-08-29 19:26:56 +0000227
Reid Spenceraf77d742004-10-28 04:05:06 +0000228 // Copy over some pattern things that don't need to change
229 action->program = pat->program;
230 action->flags = pat->flags;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000231
Reid Spenceraf77d742004-10-28 04:05:06 +0000232 // Do the substitutions from the pattern to the actual
233 StringVector::iterator PI = pat->args.begin();
234 StringVector::iterator PE = pat->args.end();
235 while (PI != PE) {
236 if ((*PI)[0] == '%' && PI->length() >2) {
237 bool found = true;
238 switch ((*PI)[1]) {
239 case 'a':
240 if (*PI == "%args%") {
241 if (AdditionalArgs.size() > unsigned(phase))
242 if (!AdditionalArgs[phase].empty()) {
243 // Get specific options for each kind of action type
244 StringVector& addargs = AdditionalArgs[phase];
245 // Add specific options for each kind of action type
Misha Brukman3da94ae2005-04-22 00:00:37 +0000246 action->args.insert(action->args.end(), addargs.begin(),
Reid Spenceraf77d742004-10-28 04:05:06 +0000247 addargs.end());
248 }
249 } else
250 found = false;
251 break;
Reid Spencercc97cfc2005-05-19 00:52:28 +0000252 case 'b':
253 if (*PI == "%bindir%") {
254 std::string tmp(*PI);
255 tmp.replace(0,8,LLVM_BINDIR);
256 action->args.push_back(tmp);
257 } else
258 found = false;
259 break;
Reid Spenceraf77d742004-10-28 04:05:06 +0000260 case 'd':
261 if (*PI == "%defs%") {
262 StringVector::iterator I = Defines.begin();
263 StringVector::iterator E = Defines.end();
264 while (I != E) {
265 action->args.push_back( std::string("-D") + *I);
266 ++I;
267 }
268 } else
269 found = false;
270 break;
271 case 'f':
272 if (*PI == "%fOpts%") {
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000273 if (!fOptions.empty())
Misha Brukman3da94ae2005-04-22 00:00:37 +0000274 action->args.insert(action->args.end(), fOptions.begin(),
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000275 fOptions.end());
Reid Spenceraf77d742004-10-28 04:05:06 +0000276 } else
277 found = false;
278 break;
279 case 'i':
280 if (*PI == "%in%") {
Reid Spencer1fce0912004-12-11 00:14:15 +0000281 action->args.push_back(input.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000282 } else if (*PI == "%incls%") {
283 PathVector::iterator I = IncludePaths.begin();
284 PathVector::iterator E = IncludePaths.end();
285 while (I != E) {
Reid Spencer1fce0912004-12-11 00:14:15 +0000286 action->args.push_back( std::string("-I") + I->toString() );
Reid Spenceraf77d742004-10-28 04:05:06 +0000287 ++I;
288 }
289 } else
290 found = false;
291 break;
292 case 'l':
Reid Spencercc97cfc2005-05-19 00:52:28 +0000293 if ((*PI)[1] == 'l') {
294 std::string tmp(*PI);
295 if (*PI == "%llvmgccdir%")
296 tmp.replace(0,12,LLVMGCCDIR);
297 else if (*PI == "%llvmgccarch%")
298 tmp.replace(0,13,LLVMGCCARCH);
299 else if (*PI == "%llvmgcc%")
300 tmp.replace(0,9,LLVMGCC);
301 else if (*PI == "%llvmgxx%")
302 tmp.replace(0,9,LLVMGXX);
303 else if (*PI == "%llvmcc1%")
304 tmp.replace(0,9,LLVMCC1);
305 else if (*PI == "%llvmcc1plus%")
306 tmp.replace(0,9,LLVMCC1);
307 else
308 found = false;
309 if (found)
310 action->args.push_back(tmp);
311 } else if (*PI == "%libs%") {
Reid Spenceraf77d742004-10-28 04:05:06 +0000312 PathVector::iterator I = LibraryPaths.begin();
313 PathVector::iterator E = LibraryPaths.end();
314 while (I != E) {
Reid Spencer1fce0912004-12-11 00:14:15 +0000315 action->args.push_back( std::string("-L") + I->toString() );
Reid Spenceraf77d742004-10-28 04:05:06 +0000316 ++I;
317 }
Reid Spencercc97cfc2005-05-19 00:52:28 +0000318 } else if (*PI == "%libdir%") {
319 std::string tmp(*PI);
320 tmp.replace(0,8,LLVM_LIBDIR);
321 action->args.push_back(tmp);
Reid Spenceraf77d742004-10-28 04:05:06 +0000322 } else
323 found = false;
324 break;
325 case 'o':
326 if (*PI == "%out%") {
Reid Spencer1fce0912004-12-11 00:14:15 +0000327 action->args.push_back(output.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000328 } else if (*PI == "%opt%") {
329 if (!isSet(EMIT_RAW_FLAG)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000330 if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
Reid Spenceraf77d742004-10-28 04:05:06 +0000331 !cd->opts[optLevel].empty())
Misha Brukman3da94ae2005-04-22 00:00:37 +0000332 action->args.insert(action->args.end(),
Reid Spenceraf77d742004-10-28 04:05:06 +0000333 cd->opts[optLevel].begin(),
334 cd->opts[optLevel].end());
335 else
Misha Brukman3da94ae2005-04-22 00:00:37 +0000336 throw std::string("Optimization options for level ") +
Reid Spenceraf77d742004-10-28 04:05:06 +0000337 utostr(unsigned(optLevel)) + " were not specified";
338 }
339 } else
340 found = false;
341 break;
342 case 's':
343 if (*PI == "%stats%") {
344 if (isSet(SHOW_STATS_FLAG))
345 action->args.push_back("-stats");
346 } else
347 found = false;
348 break;
349 case 't':
350 if (*PI == "%target%") {
351 action->args.push_back(std::string("-march=") + machine);
352 } else if (*PI == "%time%") {
353 if (isSet(TIME_PASSES_FLAG))
354 action->args.push_back("-time-passes");
355 } else
356 found = false;
357 break;
358 case 'v':
359 if (*PI == "%verbose%") {
360 if (isSet(VERBOSE_FLAG))
361 action->args.push_back("-v");
362 } else
363 found = false;
364 break;
365 case 'M':
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000366 if (*PI == "%Mopts%") {
367 if (!MOptions.empty())
Misha Brukman3da94ae2005-04-22 00:00:37 +0000368 action->args.insert(action->args.end(), MOptions.begin(),
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000369 MOptions.end());
Reid Spenceraf77d742004-10-28 04:05:06 +0000370 } else
371 found = false;
372 break;
373 case 'W':
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000374 if (*PI == "%Wopts%") {
375 for (StringVector::iterator I = WOptions.begin(),
376 E = WOptions.end(); I != E ; ++I ) {
Misha Brukman0b861482005-05-03 20:30:34 +0000377 action->args.push_back(std::string("-W") + *I);
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000378 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000379 } else
380 found = false;
381 break;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000382 default:
Reid Spenceraf77d742004-10-28 04:05:06 +0000383 found = false;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000384 break;
385 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000386 if (!found) {
387 // Did it even look like a substitution?
Misha Brukman3da94ae2005-04-22 00:00:37 +0000388 if (PI->length()>1 && (*PI)[0] == '%' &&
Reid Spenceraf77d742004-10-28 04:05:06 +0000389 (*PI)[PI->length()-1] == '%') {
390 throw std::string("Invalid substitution token: '") + *PI +
Reid Spencer1fce0912004-12-11 00:14:15 +0000391 "' for command '" + pat->program.toString() + "'";
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000392 } else if (!PI->empty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000393 // It's not a legal substitution, just pass it through
Reid Spencer52c2dc12004-08-29 19:26:56 +0000394 action->args.push_back(*PI);
395 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000396 }
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000397 } else if (!PI->empty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000398 // Its not a substitution, just put it in the action
399 action->args.push_back(*PI);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000400 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000401 PI++;
402 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000403
Reid Spenceraf77d742004-10-28 04:05:06 +0000404 // Finally, we're done
405 return action;
406 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000407
Reid Spenceraf77d742004-10-28 04:05:06 +0000408 bool DoAction(Action*action) {
409 assert(action != 0 && "Invalid Action!");
410 if (isSet(VERBOSE_FLAG))
411 WriteAction(action);
412 if (!isSet(DRY_RUN_FLAG)) {
413 sys::Path progpath = sys::Program::FindProgramByName(
Reid Spencer1fce0912004-12-11 00:14:15 +0000414 action->program.toString());
Reid Spencer07adb282004-11-05 22:15:36 +0000415 if (progpath.isEmpty())
Reid Spencer1fce0912004-12-11 00:14:15 +0000416 throw std::string("Can't find program '" +
417 action->program.toString()+"'");
Reid Spencerc7f08322005-07-07 18:21:42 +0000418 else if (progpath.canExecute())
Reid Spenceraf77d742004-10-28 04:05:06 +0000419 action->program = progpath;
420 else
Reid Spencer1fce0912004-12-11 00:14:15 +0000421 throw std::string("Program '"+action->program.toString()+
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000422 "' is not executable.");
Reid Spenceraf77d742004-10-28 04:05:06 +0000423
424 // Invoke the program
Misha Brukman3da94ae2005-04-22 00:00:37 +0000425 const char** Args = (const char**)
Reid Spencerc30088f2005-04-11 05:48:04 +0000426 alloca(sizeof(const char*)*(action->args.size()+2));
427 Args[0] = action->program.toString().c_str();
428 for (unsigned i = 1; i != action->args.size(); ++i)
Reid Spencerf6358c72004-12-19 18:00:56 +0000429 Args[i] = action->args[i].c_str();
Chris Lattner7456e3c2005-02-13 23:10:45 +0000430 Args[action->args.size()] = 0; // null terminate list.
Reid Spenceraf77d742004-10-28 04:05:06 +0000431 if (isSet(TIME_ACTIONS_FLAG)) {
Reid Spencer1fce0912004-12-11 00:14:15 +0000432 Timer timer(action->program.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000433 timer.startTimer();
Chris Lattner7456e3c2005-02-13 23:10:45 +0000434 int resultCode = sys::Program::ExecuteAndWait(action->program, Args);
Reid Spenceraf77d742004-10-28 04:05:06 +0000435 timer.stopTimer();
436 timer.print(timer,std::cerr);
437 return resultCode == 0;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000438 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000439 else
Chris Lattner7456e3c2005-02-13 23:10:45 +0000440 return 0 == sys::Program::ExecuteAndWait(action->program, Args);
Reid Spenceraf77d742004-10-28 04:05:06 +0000441 }
442 return true;
443 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000444
Reid Spenceraf77d742004-10-28 04:05:06 +0000445 /// This method tries various variants of a linkage item's file
446 /// name to see if it can find an appropriate file to link with
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000447 /// in the directories of the LibraryPaths.
Reid Spenceraf77d742004-10-28 04:05:06 +0000448 llvm::sys::Path GetPathForLinkageItem(const std::string& link_item,
Reid Spenceraf77d742004-10-28 04:05:06 +0000449 bool native = false) {
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000450 sys::Path fullpath;
451 fullpath.setFile(link_item);
Reid Spencerc7f08322005-07-07 18:21:42 +0000452 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000453 return fullpath;
Misha Brukman3da94ae2005-04-22 00:00:37 +0000454 for (PathVector::iterator PI = LibraryPaths.begin(),
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000455 PE = LibraryPaths.end(); PI != PE; ++PI) {
Reid Spencer1fce0912004-12-11 00:14:15 +0000456 fullpath.setDirectory(PI->toString());
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000457 fullpath.appendFile(link_item);
Reid Spencerc7f08322005-07-07 18:21:42 +0000458 if (fullpath.canRead())
Reid Spenceraf77d742004-10-28 04:05:06 +0000459 return fullpath;
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000460 if (native) {
461 fullpath.appendSuffix("a");
462 } else {
463 fullpath.appendSuffix("bc");
Reid Spencerc7f08322005-07-07 18:21:42 +0000464 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000465 return fullpath;
466 fullpath.elideSuffix();
467 fullpath.appendSuffix("o");
Reid Spencerc7f08322005-07-07 18:21:42 +0000468 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000469 return fullpath;
470 fullpath = *PI;
471 fullpath.appendFile(std::string("lib") + link_item);
472 fullpath.appendSuffix("a");
Reid Spencerc7f08322005-07-07 18:21:42 +0000473 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000474 return fullpath;
475 fullpath.elideSuffix();
476 fullpath.appendSuffix("so");
Reid Spencerc7f08322005-07-07 18:21:42 +0000477 if (fullpath.canRead())
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000478 return fullpath;
479 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000480 }
481
482 // Didn't find one.
483 fullpath.clear();
484 return fullpath;
485 }
486
487 /// This method processes a linkage item. The item could be a
488 /// Bytecode file needing translation to native code and that is
489 /// dependent on other bytecode libraries, or a native code
490 /// library that should just be linked into the program.
491 bool ProcessLinkageItem(const llvm::sys::Path& link_item,
492 SetVector<sys::Path>& set,
493 std::string& err) {
494 // First, see if the unadorned file name is not readable. If so,
495 // we must track down the file in the lib search path.
496 sys::Path fullpath;
Reid Spencerc7f08322005-07-07 18:21:42 +0000497 if (!link_item.canRead()) {
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000498 // look for the library using the -L arguments specified
Reid Spenceraf77d742004-10-28 04:05:06 +0000499 // on the command line.
Reid Spencer1fce0912004-12-11 00:14:15 +0000500 fullpath = GetPathForLinkageItem(link_item.toString());
Reid Spencer52c2dc12004-08-29 19:26:56 +0000501
Reid Spenceraf77d742004-10-28 04:05:06 +0000502 // If we didn't find the file in any of the library search paths
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000503 // we have to bail. No where else to look.
Reid Spencer07adb282004-11-05 22:15:36 +0000504 if (fullpath.isEmpty()) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000505 err =
Reid Spencer1fce0912004-12-11 00:14:15 +0000506 std::string("Can't find linkage item '") + link_item.toString() + "'";
Reid Spenceraf77d742004-10-28 04:05:06 +0000507 return false;
508 }
509 } else {
510 fullpath = link_item;
511 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000512
Reid Spenceraf77d742004-10-28 04:05:06 +0000513 // If we got here fullpath is the path to the file, and its readable.
514 set.insert(fullpath);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000515
Reid Spenceraf77d742004-10-28 04:05:06 +0000516 // If its an LLVM bytecode file ...
Reid Spencer07adb282004-11-05 22:15:36 +0000517 if (fullpath.isBytecodeFile()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000518 // Process the dependent libraries recursively
519 Module::LibraryListType modlibs;
Reid Spencer1fce0912004-12-11 00:14:15 +0000520 if (GetBytecodeDependentLibraries(fullpath.toString(),modlibs)) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000521 // Traverse the dependent libraries list
522 Module::lib_iterator LI = modlibs.begin();
523 Module::lib_iterator LE = modlibs.end();
524 while ( LI != LE ) {
525 if (!ProcessLinkageItem(sys::Path(*LI),set,err)) {
526 if (err.empty()) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000527 err = std::string("Library '") + *LI +
Reid Spenceraf77d742004-10-28 04:05:06 +0000528 "' is not valid for linking but is required by file '" +
Reid Spencer1fce0912004-12-11 00:14:15 +0000529 fullpath.toString() + "'";
Reid Spenceraf77d742004-10-28 04:05:06 +0000530 } else {
Reid Spencer1fce0912004-12-11 00:14:15 +0000531 err += " which is required by file '" + fullpath.toString() + "'";
Reid Spencer52c2dc12004-08-29 19:26:56 +0000532 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000533 return false;
534 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000535 ++LI;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000536 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000537 } else if (err.empty()) {
538 err = std::string(
Misha Brukman3da94ae2005-04-22 00:00:37 +0000539 "The dependent libraries could not be extracted from '") +
Reid Spencer1fce0912004-12-11 00:14:15 +0000540 fullpath.toString();
Reid Spenceraf77d742004-10-28 04:05:06 +0000541 return false;
542 }
543 }
544 return true;
545 }
546
547/// @}
548/// @name Methods
549/// @{
550public:
551 virtual int execute(const InputList& InpList, const sys::Path& Output ) {
552 try {
553 // Echo the configuration of options if we're running verbose
554 if (isSet(DEBUG_FLAG)) {
555 std::cerr << "Compiler Driver Options:\n";
556 std::cerr << "DryRun = " << isSet(DRY_RUN_FLAG) << "\n";
557 std::cerr << "Verbose = " << isSet(VERBOSE_FLAG) << " \n";
558 std::cerr << "TimeActions = " << isSet(TIME_ACTIONS_FLAG) << "\n";
559 std::cerr << "TimePasses = " << isSet(TIME_PASSES_FLAG) << "\n";
560 std::cerr << "ShowStats = " << isSet(SHOW_STATS_FLAG) << "\n";
561 std::cerr << "EmitRawCode = " << isSet(EMIT_RAW_FLAG) << "\n";
562 std::cerr << "EmitNativeCode = " << isSet(EMIT_NATIVE_FLAG) << "\n";
563 std::cerr << "KeepTemps = " << isSet(KEEP_TEMPS_FLAG) << "\n";
564 std::cerr << "OutputMachine = " << machine << "\n";
565 InputList::const_iterator I = InpList.begin();
566 while ( I != InpList.end() ) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000567 std::cerr << "Input: " << I->first << "(" << I->second
Reid Spenceraf77d742004-10-28 04:05:06 +0000568 << ")\n";
569 ++I;
570 }
Reid Spencer12786d52004-12-13 08:53:36 +0000571 std::cerr << "Output: " << Output << "\n";
Reid Spencer52c2dc12004-08-29 19:26:56 +0000572 }
573
Reid Spenceraf77d742004-10-28 04:05:06 +0000574 // If there's no input, we're done.
575 if (InpList.empty())
576 throw std::string("Nothing to compile.");
Reid Spencer52c2dc12004-08-29 19:26:56 +0000577
Reid Spenceraf77d742004-10-28 04:05:06 +0000578 // If they are asking for linking and didn't provide an output
579 // file then its an error (no way for us to "make up" a meaningful
580 // file name based on the various linker input files).
Reid Spencer07adb282004-11-05 22:15:36 +0000581 if (finalPhase == LINKING && Output.isEmpty())
Reid Spenceraf77d742004-10-28 04:05:06 +0000582 throw std::string(
583 "An output file name must be specified for linker output");
Reid Spencer52c2dc12004-08-29 19:26:56 +0000584
Reid Spenceraf77d742004-10-28 04:05:06 +0000585 // If they are not asking for linking, provided an output file and
586 // there is more than one input file, its an error
Reid Spencer07adb282004-11-05 22:15:36 +0000587 if (finalPhase != LINKING && !Output.isEmpty() && InpList.size() > 1)
Reid Spenceraf77d742004-10-28 04:05:06 +0000588 throw std::string("An output file name cannot be specified ") +
589 "with more than one input file name when not linking";
590
591 // This vector holds all the resulting actions of the following loop.
592 std::vector<Action*> actions;
593
594 /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
595 // for each input item
596 SetVector<sys::Path> LinkageItems;
Reid Spencerf6358c72004-12-19 18:00:56 +0000597 StringVector LibFiles;
Reid Spenceraf77d742004-10-28 04:05:06 +0000598 InputList::const_iterator I = InpList.begin();
Reid Spencer679a7232004-11-20 20:39:33 +0000599 for (InputList::const_iterator I = InpList.begin(), E = InpList.end();
600 I != E; ++I ) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000601 // Get the suffix of the file name
602 const std::string& ftype = I->second;
603
Misha Brukman3da94ae2005-04-22 00:00:37 +0000604 // If its a library, bytecode file, or object file, save
605 // it for linking below and short circuit the
Reid Spenceraf77d742004-10-28 04:05:06 +0000606 // pre-processing/translation/assembly phases
607 if (ftype.empty() || ftype == "o" || ftype == "bc" || ftype=="a") {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000608 // We shouldn't get any of these types of files unless we're
Reid Spenceraf77d742004-10-28 04:05:06 +0000609 // later going to link. Enforce this limit now.
610 if (finalPhase != LINKING) {
Reid Spencer52c2dc12004-08-29 19:26:56 +0000611 throw std::string(
Reid Spenceraf77d742004-10-28 04:05:06 +0000612 "Pre-compiled objects found but linking not requested");
613 }
614 if (ftype.empty())
Reid Spencer1fce0912004-12-11 00:14:15 +0000615 LibFiles.push_back(I->first.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000616 else
617 LinkageItems.insert(I->first);
Reid Spencer679a7232004-11-20 20:39:33 +0000618 continue; // short circuit remainder of loop
Reid Spenceraf77d742004-10-28 04:05:06 +0000619 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000620
Reid Spenceraf77d742004-10-28 04:05:06 +0000621 // At this point, we know its something we need to translate
622 // and/or optimize. See if we can get the configuration data
623 // for this kind of file.
624 ConfigData* cd = cdp->ProvideConfigData(I->second);
625 if (cd == 0)
Misha Brukman3da94ae2005-04-22 00:00:37 +0000626 throw std::string("Files of type '") + I->second +
627 "' are not recognized.";
Reid Spenceraf77d742004-10-28 04:05:06 +0000628 if (isSet(DEBUG_FLAG))
629 DumpConfigData(cd,I->second);
Reid Spencer54fafe42004-09-14 01:58:45 +0000630
Reid Spencer0b3c7d02004-11-23 23:45:49 +0000631 // Add the config data's library paths to the end of the list
632 for (StringVector::iterator LPI = cd->libpaths.begin(),
633 LPE = cd->libpaths.end(); LPI != LPE; ++LPI){
634 LibraryPaths.push_back(sys::Path(*LPI));
635 }
636
Reid Spenceraf77d742004-10-28 04:05:06 +0000637 // Initialize the input and output files
638 sys::Path InFile(I->first);
Reid Spencer07adb282004-11-05 22:15:36 +0000639 sys::Path OutFile(I->first.getBasename());
Reid Spencer52c2dc12004-08-29 19:26:56 +0000640
Reid Spenceraf77d742004-10-28 04:05:06 +0000641 // PRE-PROCESSING PHASE
642 Action& action = cd->PreProcessor;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000643
Reid Spenceraf77d742004-10-28 04:05:06 +0000644 // Get the preprocessing action, if needed, or error if appropriate
Reid Spencer07adb282004-11-05 22:15:36 +0000645 if (!action.program.isEmpty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000646 if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
647 if (finalPhase == PREPROCESSING) {
Reid Spencer679a7232004-11-20 20:39:33 +0000648 if (Output.isEmpty()) {
649 OutFile.appendSuffix("E");
650 actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
651 } else {
652 actions.push_back(GetAction(cd,InFile,Output,PREPROCESSING));
653 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000654 } else {
Reid Spencer07adb282004-11-05 22:15:36 +0000655 sys::Path TempFile(MakeTempFile(I->first.getBasename(),"E"));
Reid Spenceraf77d742004-10-28 04:05:06 +0000656 actions.push_back(GetAction(cd,InFile,TempFile,
657 PREPROCESSING));
658 InFile = TempFile;
659 }
660 }
661 } else if (finalPhase == PREPROCESSING) {
662 throw cd->langName + " does not support pre-processing";
663 } else if (action.isSet(REQUIRED_FLAG)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000664 throw std::string("Don't know how to pre-process ") +
Reid Spenceraf77d742004-10-28 04:05:06 +0000665 cd->langName + " files";
666 }
667
Misha Brukman3da94ae2005-04-22 00:00:37 +0000668 // Short-circuit remaining actions if all they want is
Reid Spenceraf77d742004-10-28 04:05:06 +0000669 // pre-processing
Reid Spencer679a7232004-11-20 20:39:33 +0000670 if (finalPhase == PREPROCESSING) { continue; };
Reid Spenceraf77d742004-10-28 04:05:06 +0000671
672 /// TRANSLATION PHASE
673 action = cd->Translator;
674
675 // Get the translation action, if needed, or error if appropriate
Reid Spencer07adb282004-11-05 22:15:36 +0000676 if (!action.program.isEmpty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000677 if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
678 if (finalPhase == TRANSLATION) {
Reid Spencer679a7232004-11-20 20:39:33 +0000679 if (Output.isEmpty()) {
680 OutFile.appendSuffix("o");
681 actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
682 } else {
683 actions.push_back(GetAction(cd,InFile,Output,TRANSLATION));
684 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000685 } else {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000686 sys::Path TempFile(MakeTempFile(I->first.getBasename(),"trans"));
Reid Spenceraf77d742004-10-28 04:05:06 +0000687 actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
688 InFile = TempFile;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000689 }
690
Reid Spenceraf77d742004-10-28 04:05:06 +0000691 // ll -> bc Helper
692 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
693 /// The output of the translator is an LLVM Assembly program
694 /// We need to translate it to bytecode
695 Action* action = new Action();
Reid Spencer07adb282004-11-05 22:15:36 +0000696 action->program.setFile("llvm-as");
Reid Spencer1fce0912004-12-11 00:14:15 +0000697 action->args.push_back(InFile.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000698 action->args.push_back("-o");
Reid Spencer07adb282004-11-05 22:15:36 +0000699 InFile.appendSuffix("bc");
Reid Spencer1fce0912004-12-11 00:14:15 +0000700 action->args.push_back(InFile.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000701 actions.push_back(action);
Reid Spencer52c2dc12004-08-29 19:26:56 +0000702 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000703 }
704 } else if (finalPhase == TRANSLATION) {
705 throw cd->langName + " does not support translation";
706 } else if (action.isSet(REQUIRED_FLAG)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000707 throw std::string("Don't know how to translate ") +
Reid Spenceraf77d742004-10-28 04:05:06 +0000708 cd->langName + " files";
709 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000710
Reid Spenceraf77d742004-10-28 04:05:06 +0000711 // Short-circuit remaining actions if all they want is translation
Reid Spencer679a7232004-11-20 20:39:33 +0000712 if (finalPhase == TRANSLATION) { continue; }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000713
Reid Spenceraf77d742004-10-28 04:05:06 +0000714 /// OPTIMIZATION PHASE
715 action = cd->Optimizer;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000716
Reid Spenceraf77d742004-10-28 04:05:06 +0000717 // Get the optimization action, if needed, or error if appropriate
718 if (!isSet(EMIT_RAW_FLAG)) {
Reid Spencer07adb282004-11-05 22:15:36 +0000719 if (!action.program.isEmpty()) {
Reid Spenceraf77d742004-10-28 04:05:06 +0000720 if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
721 if (finalPhase == OPTIMIZATION) {
Reid Spencer679a7232004-11-20 20:39:33 +0000722 if (Output.isEmpty()) {
723 OutFile.appendSuffix("o");
724 actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
725 } else {
726 actions.push_back(GetAction(cd,InFile,Output,OPTIMIZATION));
727 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000728 } else {
Reid Spencer07adb282004-11-05 22:15:36 +0000729 sys::Path TempFile(MakeTempFile(I->first.getBasename(),"opt"));
Reid Spenceraf77d742004-10-28 04:05:06 +0000730 actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION));
731 InFile = TempFile;
732 }
733 // ll -> bc Helper
734 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
735 /// The output of the optimizer is an LLVM Assembly program
736 /// We need to translate it to bytecode with llvm-as
Reid Spencer52c2dc12004-08-29 19:26:56 +0000737 Action* action = new Action();
Reid Spencer07adb282004-11-05 22:15:36 +0000738 action->program.setFile("llvm-as");
Reid Spencer1fce0912004-12-11 00:14:15 +0000739 action->args.push_back(InFile.toString());
Reid Spencer52c2dc12004-08-29 19:26:56 +0000740 action->args.push_back("-f");
741 action->args.push_back("-o");
Reid Spencer07adb282004-11-05 22:15:36 +0000742 InFile.appendSuffix("bc");
Reid Spencer1fce0912004-12-11 00:14:15 +0000743 action->args.push_back(InFile.toString());
Reid Spencer52c2dc12004-08-29 19:26:56 +0000744 actions.push_back(action);
745 }
746 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000747 } else if (finalPhase == OPTIMIZATION) {
748 throw cd->langName + " does not support optimization";
749 } else if (action.isSet(REQUIRED_FLAG)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000750 throw std::string("Don't know how to optimize ") +
Reid Spenceraf77d742004-10-28 04:05:06 +0000751 cd->langName + " files";
Reid Spencer52c2dc12004-08-29 19:26:56 +0000752 }
Reid Spencer52c2dc12004-08-29 19:26:56 +0000753 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000754
755 // Short-circuit remaining actions if all they want is optimization
Reid Spencer679a7232004-11-20 20:39:33 +0000756 if (finalPhase == OPTIMIZATION) { continue; }
Reid Spenceraf77d742004-10-28 04:05:06 +0000757
758 /// ASSEMBLY PHASE
759 action = cd->Assembler;
760
761 if (finalPhase == ASSEMBLY) {
Reid Spencer679a7232004-11-20 20:39:33 +0000762
763 // Build either a native compilation action or a disassembly action
764 Action* action = new Action();
Reid Spenceraf77d742004-10-28 04:05:06 +0000765 if (isSet(EMIT_NATIVE_FLAG)) {
766 // Use llc to get the native assembly file
Reid Spencer07adb282004-11-05 22:15:36 +0000767 action->program.setFile("llc");
Reid Spencer1fce0912004-12-11 00:14:15 +0000768 action->args.push_back(InFile.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000769 action->args.push_back("-f");
770 action->args.push_back("-o");
Reid Spencer679a7232004-11-20 20:39:33 +0000771 if (Output.isEmpty()) {
772 OutFile.appendSuffix("o");
Reid Spencer1fce0912004-12-11 00:14:15 +0000773 action->args.push_back(OutFile.toString());
Reid Spencer679a7232004-11-20 20:39:33 +0000774 } else {
Reid Spencer1fce0912004-12-11 00:14:15 +0000775 action->args.push_back(Output.toString());
Reid Spencer679a7232004-11-20 20:39:33 +0000776 }
777 actions.push_back(action);
Reid Spenceraf77d742004-10-28 04:05:06 +0000778 } else {
779 // Just convert back to llvm assembly with llvm-dis
Reid Spencer07adb282004-11-05 22:15:36 +0000780 action->program.setFile("llvm-dis");
Reid Spencer1fce0912004-12-11 00:14:15 +0000781 action->args.push_back(InFile.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000782 action->args.push_back("-f");
783 action->args.push_back("-o");
Reid Spencer679a7232004-11-20 20:39:33 +0000784 if (Output.isEmpty()) {
785 OutFile.appendSuffix("ll");
Reid Spencer1fce0912004-12-11 00:14:15 +0000786 action->args.push_back(OutFile.toString());
Reid Spencer679a7232004-11-20 20:39:33 +0000787 } else {
Reid Spencer1fce0912004-12-11 00:14:15 +0000788 action->args.push_back(Output.toString());
Reid Spencer679a7232004-11-20 20:39:33 +0000789 }
Reid Spenceraf77d742004-10-28 04:05:06 +0000790 }
791
Reid Spencer679a7232004-11-20 20:39:33 +0000792 // Put the action on the list
793 actions.push_back(action);
794
Misha Brukman3da94ae2005-04-22 00:00:37 +0000795 // Short circuit the rest of the loop, we don't want to link
Reid Spenceraf77d742004-10-28 04:05:06 +0000796 continue;
797 }
798
799 // Register the result of the actions as a link candidate
800 LinkageItems.insert(InFile);
801
Reid Spenceraf77d742004-10-28 04:05:06 +0000802 } // end while loop over each input file
803
804 /// RUN THE COMPILATION ACTIONS
805 std::vector<Action*>::iterator AI = actions.begin();
806 std::vector<Action*>::iterator AE = actions.end();
807 while (AI != AE) {
808 if (!DoAction(*AI))
809 throw std::string("Action failed");
810 AI++;
Reid Spencer52c2dc12004-08-29 19:26:56 +0000811 }
812
Reid Spenceraf77d742004-10-28 04:05:06 +0000813 /// LINKING PHASE
814 if (finalPhase == LINKING) {
Reid Spencer52c2dc12004-08-29 19:26:56 +0000815
Reid Spenceraf77d742004-10-28 04:05:06 +0000816 // Insert the platform-specific system libraries to the path list
Reid Spencer11db4b82004-12-13 03:01:26 +0000817 std::vector<sys::Path> SysLibs;
818 sys::Path::GetSystemLibraryPaths(SysLibs);
819 LibraryPaths.insert(LibraryPaths.end(), SysLibs.begin(), SysLibs.end());
Reid Spenceraf77d742004-10-28 04:05:06 +0000820
821 // Set up the linking action with llvm-ld
822 Action* link = new Action();
Reid Spencer07adb282004-11-05 22:15:36 +0000823 link->program.setFile("llvm-ld");
Reid Spenceraf77d742004-10-28 04:05:06 +0000824
825 // Add in the optimization level requested
826 switch (optLevel) {
827 case OPT_FAST_COMPILE:
828 link->args.push_back("-O1");
829 break;
830 case OPT_SIMPLE:
831 link->args.push_back("-O2");
832 break;
833 case OPT_AGGRESSIVE:
834 link->args.push_back("-O3");
835 break;
836 case OPT_LINK_TIME:
837 link->args.push_back("-O4");
838 break;
839 case OPT_AGGRESSIVE_LINK_TIME:
840 link->args.push_back("-O5");
841 break;
842 case OPT_NONE:
843 break;
844 }
845
846 // Add in all the linkage items we generated. This includes the
847 // output from the translation/optimization phases as well as any
848 // -l arguments specified.
Misha Brukman3da94ae2005-04-22 00:00:37 +0000849 for (PathVector::const_iterator I=LinkageItems.begin(),
Reid Spenceraf77d742004-10-28 04:05:06 +0000850 E=LinkageItems.end(); I != E; ++I )
Reid Spencer1fce0912004-12-11 00:14:15 +0000851 link->args.push_back(I->toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000852
853 // Add in all the libraries we found.
Reid Spencerf6358c72004-12-19 18:00:56 +0000854 for (StringVector::const_iterator I=LibFiles.begin(),
Reid Spenceraf77d742004-10-28 04:05:06 +0000855 E=LibFiles.end(); I != E; ++I )
856 link->args.push_back(std::string("-l")+*I);
857
858 // Add in all the library paths to the command line
859 for (PathVector::const_iterator I=LibraryPaths.begin(),
860 E=LibraryPaths.end(); I != E; ++I)
Reid Spencer1fce0912004-12-11 00:14:15 +0000861 link->args.push_back( std::string("-L") + I->toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000862
863 // Add in the additional linker arguments requested
864 for (StringVector::const_iterator I=AdditionalArgs[LINKING].begin(),
865 E=AdditionalArgs[LINKING].end(); I != E; ++I)
866 link->args.push_back( *I );
867
868 // Add in other optional flags
869 if (isSet(EMIT_NATIVE_FLAG))
870 link->args.push_back("-native");
871 if (isSet(VERBOSE_FLAG))
872 link->args.push_back("-v");
873 if (isSet(TIME_PASSES_FLAG))
874 link->args.push_back("-time-passes");
875 if (isSet(SHOW_STATS_FLAG))
876 link->args.push_back("-stats");
877 if (isSet(STRIP_OUTPUT_FLAG))
878 link->args.push_back("-s");
879 if (isSet(DEBUG_FLAG)) {
880 link->args.push_back("-debug");
881 link->args.push_back("-debug-pass=Details");
882 }
883
884 // Add in mandatory flags
885 link->args.push_back("-o");
Reid Spencer1fce0912004-12-11 00:14:15 +0000886 link->args.push_back(Output.toString());
Reid Spenceraf77d742004-10-28 04:05:06 +0000887
888 // Execute the link
889 if (!DoAction(link))
890 throw std::string("Action failed");
891 }
892 } catch (std::string& msg) {
893 cleanup();
894 throw;
895 } catch (...) {
896 cleanup();
897 throw std::string("Unspecified error");
898 }
899 cleanup();
900 return 0;
901 }
902
903/// @}
904/// @name Data
905/// @{
906private:
907 ConfigDataProvider* cdp; ///< Where we get configuration data from
908 Phases finalPhase; ///< The final phase of compilation
909 OptimizationLevels optLevel; ///< The optimization level to apply
910 unsigned Flags; ///< The driver flags
911 std::string machine; ///< Target machine name
912 PathVector LibraryPaths; ///< -L options
913 PathVector IncludePaths; ///< -I options
Reid Spencer07adb282004-11-05 22:15:36 +0000914 PathVector ToolPaths; ///< -B options
Reid Spenceraf77d742004-10-28 04:05:06 +0000915 StringVector Defines; ///< -D options
916 sys::Path TempDir; ///< Name of the temporary directory.
917 StringTable AdditionalArgs; ///< The -Txyz options
918 StringVector fOptions; ///< -f options
919 StringVector MOptions; ///< -M options
920 StringVector WOptions; ///< -W options
921
922/// @}
923};
Reid Spencer5c56dc12004-08-13 20:22:43 +0000924}
925
926CompilerDriver::~CompilerDriver() {
Reid Spencer52c2dc12004-08-29 19:26:56 +0000927}
928
Reid Spencercc97cfc2005-05-19 00:52:28 +0000929CompilerDriver::ConfigDataProvider::~ConfigDataProvider() {}
930
Reid Spencer52c2dc12004-08-29 19:26:56 +0000931CompilerDriver*
932CompilerDriver::Get(ConfigDataProvider& CDP) {
933 return new CompilerDriverImpl(CDP);
Reid Spencerbae68252004-08-19 04:49:47 +0000934}
935
936CompilerDriver::ConfigData::ConfigData()
937 : langName()
938 , PreProcessor()
939 , Translator()
940 , Optimizer()
941 , Assembler()
942 , Linker()
943{
944 StringVector emptyVec;
945 for (unsigned i = 0; i < NUM_PHASES; ++i)
946 opts.push_back(emptyVec);
Reid Spencer5c56dc12004-08-13 20:22:43 +0000947}