* Add `deplibs' keyword for specifying a list of dependent libraries
[oota-llvm.git] / tools / llvmc / CompilerDriver.cpp
1 //===- CompilerDriver.cpp - The LLVM Compiler Driver ------------*- C++ -*-===//
2 //
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 //
11 // This file implements the bulk of the LLVM Compiler Driver (llvmc).
12 //
13 //===------------------------------------------------------------------------===
14
15 #include "CompilerDriver.h"
16 #include "ConfigLexer.h"
17 #include "llvm/Module.h"
18 #include "llvm/Bytecode/Reader.h"
19 #include "llvm/Support/Timer.h"
20 #include "llvm/System/Signals.h"
21 #include "llvm/ADT/SetVector.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include <iostream>
24
25 using namespace llvm;
26
27 namespace {
28
29   void WriteAction(CompilerDriver::Action* action ) {
30     std::cerr << action->program.c_str();
31     std::vector<std::string>::iterator I = action->args.begin();
32     while (I != action->args.end()) {
33       std::cerr << " " + *I;
34       ++I;
35     }
36     std::cerr << "\n";
37   }
38
39   void DumpAction(CompilerDriver::Action* action) {
40     std::cerr << "command = " << action->program.c_str();
41     std::vector<std::string>::iterator I = action->args.begin();
42     while (I != action->args.end()) {
43       std::cerr << " " + *I;
44       ++I;
45     }
46     std::cerr << "\n";
47     std::cerr << "flags = " << action->flags << "\n";
48   }
49
50   void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
51     std::cerr << "Configuration Data For '" << cd->langName << "' (" << type 
52       << ")\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
67   /// faster. This is also safe on any llvm module. 
68   static const char* DefaultFastCompileOptimizations[] = {
69     "-simplifycfg", "-mem2reg", "-instcombine"
70   };
71
72   class CompilerDriverImpl : public CompilerDriver {
73     /// @name Constructors
74     /// @{
75     public:
76       CompilerDriverImpl(ConfigDataProvider& confDatProv )
77         : cdp(&confDatProv)
78         , finalPhase(LINKING)
79         , optLevel(OPT_FAST_COMPILE) 
80         , 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         AdditionalArgs.clear();
99       }
100
101     /// @}
102     /// @name Methods
103     /// @{
104     public:
105       virtual void setFinalPhase( Phases phase ) { 
106         finalPhase = phase; 
107       }
108
109       virtual void setOptimization( OptimizationLevels level ) { 
110         optLevel = level; 
111       }
112
113       virtual void setDriverFlags( unsigned flags ) {
114         Flags = flags & DRIVER_FLAGS_MASK; 
115       }
116
117       virtual void setOutputMachine( const std::string& machineName ) {
118         machine = machineName;
119       }
120
121       virtual void setPhaseArgs(Phases phase, const StringVector& opts) {
122         assert(phase <= LINKING && phase >= PREPROCESSING);
123         AdditionalArgs[phase] = opts;
124       }
125
126       virtual void setIncludePaths(const StringVector& paths) {
127         StringVector::const_iterator I = paths.begin();
128         StringVector::const_iterator E = paths.end();
129         while (I != E) {
130           sys::Path tmp;
131           tmp.set_directory(*I);
132           IncludePaths.push_back(tmp);
133           ++I;
134         }
135       }
136
137       virtual void setSymbolDefines(const StringVector& defs) {
138         Defines = defs;
139       }
140
141       virtual void setLibraryPaths(const StringVector& paths) {
142         StringVector::const_iterator I = paths.begin();
143         StringVector::const_iterator E = paths.end();
144         while (I != E) {
145           sys::Path tmp;
146           tmp.set_directory(*I);
147           LibraryPaths.push_back(tmp);
148           ++I;
149         }
150       }
151
152       virtual void addLibraryPath( const sys::Path& libPath ) {
153         LibraryPaths.push_back(libPath);
154       }
155
156       virtual void setfPassThrough(const StringVector& fOpts) {
157         fOptions = fOpts;
158       }
159
160       /// @brief Set the list of -M options to be passed through
161       virtual void setMPassThrough(const StringVector& MOpts) {
162         MOptions = MOpts;
163       }
164
165       /// @brief Set the list of -W options to be passed through
166       virtual void setWPassThrough(const StringVector& WOpts) {
167         WOptions = WOpts;
168       }
169     /// @}
170     /// @name Functions
171     /// @{
172     private:
173       bool isSet(DriverFlags flag) {
174         return 0 != ((flag & DRIVER_FLAGS_MASK) & Flags);
175       }
176
177       void cleanup() {
178         if (!isSet(KEEP_TEMPS_FLAG)) {
179           if (TempDir.is_directory() && TempDir.writable())
180             TempDir.destroy_directory(/*remove_contents=*/true);
181         } else {
182           std::cout << "Temporary files are in " << TempDir.get() << "\n";
183         }
184       }
185
186       sys::Path MakeTempFile(const std::string& basename, const std::string& suffix ) {
187         sys::Path result(TempDir);
188         if (!result.append_file(basename))
189           throw basename + ": can't use this file name";
190         if (!result.append_suffix(suffix))
191           throw suffix + ": can't use this file suffix";
192         return result;
193       }
194
195       Action* GetAction(ConfigData* cd, 
196                         const sys::Path& input, 
197                         const sys::Path& output,
198                         Phases phase)
199       {
200         Action* pat = 0; ///< The pattern/template for the action
201         Action* action = new Action; ///< The actual action to execute
202
203         // Get the action pattern
204         switch (phase) {
205           case PREPROCESSING: pat = &cd->PreProcessor; break;
206           case TRANSLATION:   pat = &cd->Translator; break;
207           case OPTIMIZATION:  pat = &cd->Optimizer; break;
208           case ASSEMBLY:      pat = &cd->Assembler; break;
209           case LINKING:       pat = &cd->Linker; break;
210           default:
211             assert(!"Invalid driver phase!");
212             break;
213         }
214         assert(pat != 0 && "Invalid command pattern");
215
216         // Copy over some pattern things that don't need to change
217         action->program = pat->program;
218         action->flags = pat->flags;
219
220         // Do the substitutions from the pattern to the actual
221         StringVector::iterator PI = pat->args.begin();
222         StringVector::iterator PE = pat->args.end();
223         while (PI != PE) {
224           if ((*PI)[0] == '%' && PI->length() >2) {
225             bool found = true;
226             switch ((*PI)[1]) {
227               case 'a':
228                 if (*PI == "%args%") {
229                   if (AdditionalArgs.size() > unsigned(phase))
230                     if (!AdditionalArgs[phase].empty()) {
231                       // Get specific options for each kind of action type
232                       StringVector& addargs = AdditionalArgs[phase];
233                       // Add specific options for each kind of action type
234                       action->args.insert(action->args.end(), addargs.begin(), addargs.end());
235                     }
236                 } else
237                   found = false;
238                 break;
239               case 'd':
240                 if (*PI == "%defs%") {
241                   StringVector::iterator I = Defines.begin();
242                   StringVector::iterator E = Defines.end();
243                   while (I != E) {
244                     action->args.push_back( std::string("-D") + *I);
245                     ++I;
246                   }
247                 } else
248                   found = false;
249                 break;
250               case 'f':
251                 if (*PI == "%force%") {
252                   if (isSet(FORCE_FLAG))
253                     action->args.push_back("-f");
254                 } else if (*PI == "%fOpts%") {
255                     action->args.insert(action->args.end(), fOptions.begin(), 
256                                         fOptions.end());
257                 } else
258                   found = false;
259                 break;
260               case 'i':
261                 if (*PI == "%in%") {
262                   action->args.push_back(input.get());
263                 } else if (*PI == "%incls%") {
264                   PathVector::iterator I = IncludePaths.begin();
265                   PathVector::iterator E = IncludePaths.end();
266                   while (I != E) {
267                     action->args.push_back( std::string("-I") + I->get() );
268                     ++I;
269                   }
270                 } else
271                   found = false;
272                 break;
273               case 'l':
274                 if (*PI == "%libs%") {
275                   PathVector::iterator I = LibraryPaths.begin();
276                   PathVector::iterator E = LibraryPaths.end();
277                   while (I != E) {
278                     action->args.push_back( std::string("-L") + I->get() );
279                     ++I;
280                   }
281                 } else
282                   found = false;
283                 break;
284               case 'o':
285                 if (*PI == "%out%") {
286                   action->args.push_back(output.get());
287                 } else if (*PI == "%opt%") {
288                   if (!isSet(EMIT_RAW_FLAG)) {
289                     if (cd->opts.size() > static_cast<unsigned>(optLevel) && 
290                         !cd->opts[optLevel].empty())
291                       action->args.insert(action->args.end(), cd->opts[optLevel].begin(),
292                           cd->opts[optLevel].end());
293                     else
294                       throw std::string("Optimization options for level ") + 
295                             utostr(unsigned(optLevel)) + " were not specified";
296                   }
297                 } else
298                   found = false;
299                 break;
300               case 's':
301                 if (*PI == "%stats%") {
302                   if (isSet(SHOW_STATS_FLAG))
303                     action->args.push_back("-stats");
304                 } else
305                   found = false;
306                 break;
307               case 't':
308                 if (*PI == "%target%") {
309                   action->args.push_back(std::string("-march=") + machine);
310                 } else if (*PI == "%time%") {
311                   if (isSet(TIME_PASSES_FLAG))
312                     action->args.push_back("-time-passes");
313                 } else
314                   found = false;
315                 break;
316               case 'v':
317                 if (*PI == "%verbose%") {
318                   if (isSet(VERBOSE_FLAG))
319                     action->args.push_back("-v");
320                 } else
321                   found  = false;
322                 break;
323               case 'M':
324                 if (*PI == "%Mopts") {
325                   action->args.insert(action->args.end(), MOptions.begin(), 
326                                       MOptions.end());
327                 } else
328                   found = false;
329                 break;
330               case 'W':
331                 if (*PI == "%Wopts") {
332                   action->args.insert(action->args.end(), WOptions.begin(), 
333                                       WOptions.end());
334                 } else
335                   found = false;
336                 break;
337               default:
338                 found = false;
339                 break;
340             }
341             if (!found) {
342               // Did it even look like a substitution?
343               if (PI->length()>1 && (*PI)[0] == '%' && 
344                   (*PI)[PI->length()-1] == '%') {
345                 throw std::string("Invalid substitution token: '") + *PI +
346                       "' for command '" + pat->program.get() + "'";
347               } else {
348                 // It's not a legal substitution, just pass it through
349                 action->args.push_back(*PI);
350               }
351             }
352           } else {
353             // Its not a substitution, just put it in the action
354             action->args.push_back(*PI);
355           }
356           PI++;
357         }
358
359         // Finally, we're done
360         return action;
361       }
362
363       bool DoAction(Action*action) {
364         assert(action != 0 && "Invalid Action!");
365         if (isSet(VERBOSE_FLAG))
366           WriteAction(action);
367         if (!isSet(DRY_RUN_FLAG)) {
368           action->program = sys::Program::FindProgramByName(action->program.get());
369           if (action->program.is_empty())
370             throw std::string("Can't find program '") + action->program.get() + "'";
371
372           // Invoke the program
373           if (isSet(TIME_ACTIONS_FLAG)) {
374             Timer timer(action->program.get());
375             timer.startTimer();
376             int resultCode = sys::Program::ExecuteAndWait(action->program,action->args);
377             timer.stopTimer();
378             timer.print(timer,std::cerr);
379             return resultCode == 0;
380           }
381           else
382             return 0 == sys::Program::ExecuteAndWait(action->program, action->args);
383         }
384         return true;
385       }
386
387       /// This method tries various variants of a linkage item's file
388       /// name to see if it can find an appropriate file to link with
389       /// in the directory specified.
390       llvm::sys::Path GetPathForLinkageItem(const std::string& link_item,
391                                             const sys::Path& dir,
392                                             bool native = false) {
393         sys::Path fullpath(dir);
394         fullpath.append_file(link_item);
395         if (native) {
396           fullpath.append_suffix("a");
397         } else {
398           fullpath.append_suffix("bc");
399           if (fullpath.readable()) 
400             return fullpath;
401           fullpath.elide_suffix();
402           fullpath.append_suffix("o");
403           if (fullpath.readable()) 
404             return fullpath;
405           fullpath = dir;
406           fullpath.append_file(std::string("lib") + link_item);
407           fullpath.append_suffix("a");
408           if (fullpath.readable())
409             return fullpath;
410           fullpath.elide_suffix();
411           fullpath.append_suffix("so");
412           if (fullpath.readable())
413             return fullpath;
414         }
415
416         // Didn't find one.
417         fullpath.clear();
418         return fullpath;
419       }
420
421       /// This method processes a linkage item. The item could be a
422       /// Bytecode file needing translation to native code and that is
423       /// dependent on other bytecode libraries, or a native code
424       /// library that should just be linked into the program.
425       bool ProcessLinkageItem(const llvm::sys::Path& link_item,
426                               SetVector<sys::Path>& set,
427                               std::string& err) {
428         // First, see if the unadorned file name is not readable. If so,
429         // we must track down the file in the lib search path.
430         sys::Path fullpath;
431         if (!link_item.readable()) {
432           // First, look for the library using the -L arguments specified
433           // on the command line.
434           PathVector::iterator PI = LibraryPaths.begin();
435           PathVector::iterator PE = LibraryPaths.end();
436           while (PI != PE && fullpath.is_empty()) {
437             fullpath = GetPathForLinkageItem(link_item.get(),*PI);
438             ++PI;
439           }
440
441           // If we didn't find the file in any of the library search paths
442           // so we have to bail. No where else to look.
443           if (fullpath.is_empty()) {
444             err = std::string("Can't find linkage item '") + link_item.get() + "'";
445             return false;
446           }
447         } else {
448           fullpath = link_item;
449         }
450
451         // If we got here fullpath is the path to the file, and its readable.
452         set.insert(fullpath);
453
454         // If its an LLVM bytecode file ...
455         if (fullpath.is_bytecode_file()) {
456           // Process the dependent libraries recursively
457           Module::LibraryListType modlibs;
458           if (GetBytecodeDependentLibraries(fullpath.get(),modlibs)) {
459             // Traverse the dependent libraries list
460             Module::lib_iterator LI = modlibs.begin();
461             Module::lib_iterator LE = modlibs.end();
462             while ( LI != LE ) {
463               if (!ProcessLinkageItem(sys::Path(*LI),set,err)) {
464                 if (err.empty()) {
465                   err = std::string("Library '") + *LI + 
466                         "' is not valid for linking but is required by file '" +
467                         fullpath.get() + "'";
468                 } else {
469                   err += " which is required by file '" + fullpath.get() + "'";
470                 }
471                 return false;
472               }
473               ++LI;
474             }
475           } else if (err.empty()) {
476             err = std::string("The dependent libraries could not be extracted from '")
477                               + fullpath.get();
478             return false;
479           }
480         }
481         return true;
482       }
483
484     /// @}
485     /// @name Methods
486     /// @{
487     public:
488       virtual int execute(const InputList& InpList, const sys::Path& Output ) {
489         try {
490           // Echo the configuration of options if we're running verbose
491           if (isSet(DEBUG_FLAG)) {
492             std::cerr << "Compiler Driver Options:\n";
493             std::cerr << "DryRun = " << isSet(DRY_RUN_FLAG) << "\n";
494             std::cerr << "Verbose = " << isSet(VERBOSE_FLAG) << " \n";
495             std::cerr << "TimeActions = " << isSet(TIME_ACTIONS_FLAG) << "\n";
496             std::cerr << "TimePasses = " << isSet(TIME_PASSES_FLAG) << "\n";
497             std::cerr << "ShowStats = " << isSet(SHOW_STATS_FLAG) << "\n";
498             std::cerr << "EmitRawCode = " << isSet(EMIT_RAW_FLAG) << "\n";
499             std::cerr << "EmitNativeCode = " << isSet(EMIT_NATIVE_FLAG) << "\n";
500             std::cerr << "ForceOutput = " << isSet(FORCE_FLAG) << "\n";
501             std::cerr << "KeepTemps = " << isSet(KEEP_TEMPS_FLAG) << "\n";
502             std::cerr << "OutputMachine = " << machine << "\n";
503             InputList::const_iterator I = InpList.begin();
504             while ( I != InpList.end() ) {
505               std::cerr << "Input: " << I->first.get() << "(" << I->second << ")\n";
506               ++I;
507             }
508             std::cerr << "Output: " << Output.get() << "\n";
509           }
510
511           // If there's no input, we're done.
512           if (InpList.empty())
513             throw std::string("Nothing to compile.");
514
515           // If they are asking for linking and didn't provide an output
516           // file then its an error (no way for us to "make up" a meaningful
517           // file name based on the various linker input files).
518           if (finalPhase == LINKING && Output.is_empty())
519             throw std::string(
520               "An output file name must be specified for linker output");
521
522           // If they are not asking for linking, provided an output file and
523           // there is more than one input file, its an error
524           if (finalPhase != LINKING && !Output.is_empty() && 
525               InpList.size() > 1) 
526             throw std::string("An output file name cannot be specified ") +
527               "with more than one input file name when not linking";
528
529           // This vector holds all the resulting actions of the following loop.
530           std::vector<Action*> actions;
531
532           /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
533           // for each input item
534           SetVector<sys::Path> LinkageItems;
535           std::vector<std::string> LibFiles;
536           sys::Path OutFile(Output);
537           InputList::const_iterator I = InpList.begin();
538           while ( I != InpList.end() ) {
539             // Get the suffix of the file name
540             const std::string& ftype = I->second;
541
542             // If its a library, bytecode file, or object file, save 
543             // it for linking below and short circuit the 
544             // pre-processing/translation/assembly phases
545             if (ftype.empty() ||  ftype == "o" || ftype == "bc" || ftype=="a") {
546               // We shouldn't get any of these types of files unless we're 
547               // later going to link. Enforce this limit now.
548               if (finalPhase != LINKING) {
549                 throw std::string(
550                   "Pre-compiled objects found but linking not requested");
551               }
552               if (ftype.empty())
553                 LibFiles.push_back(I->first.get());
554               else
555                 LinkageItems.insert(I->first);
556               ++I; continue; // short circuit remainder of loop
557             }
558
559             // At this point, we know its something we need to translate
560             // and/or optimize. See if we can get the configuration data
561             // for this kind of file.
562             ConfigData* cd = cdp->ProvideConfigData(I->second);
563             if (cd == 0)
564               throw std::string("Files of type '") + I->second + 
565                     "' are not recognized."; 
566             if (isSet(DEBUG_FLAG))
567               DumpConfigData(cd,I->second);
568
569             // Initialize the input file
570             sys::Path InFile(I->first);
571
572             // PRE-PROCESSING PHASE
573             Action& action = cd->PreProcessor;
574
575             // Get the preprocessing action, if needed, or error if appropriate
576             if (!action.program.is_empty()) {
577               if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
578                 if (finalPhase == PREPROCESSING) {
579                   if (OutFile.is_empty()) {
580                     OutFile = I->first;
581                     OutFile.append_suffix("E");
582                   }
583                   actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
584                 } else {
585                   sys::Path TempFile(MakeTempFile(I->first.get(),"E"));
586                   actions.push_back(GetAction(cd,InFile,TempFile,PREPROCESSING));
587                   InFile = TempFile;
588                 }
589               }
590             } else if (finalPhase == PREPROCESSING) {
591               throw cd->langName + " does not support pre-processing";
592             } else if (action.isSet(REQUIRED_FLAG)) {
593               throw std::string("Don't know how to pre-process ") + 
594                     cd->langName + " files";
595             }
596
597             // Short-circuit remaining actions if all they want is pre-processing
598             if (finalPhase == PREPROCESSING) { ++I; continue; };
599
600             /// TRANSLATION PHASE
601             action = cd->Translator;
602
603             // Get the translation action, if needed, or error if appropriate
604             if (!action.program.is_empty()) {
605               if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
606                 if (finalPhase == TRANSLATION) {
607                   if (OutFile.is_empty()) {
608                     OutFile = I->first;
609                     OutFile.append_suffix("o");
610                   }
611                   actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
612                 } else {
613                   sys::Path TempFile(MakeTempFile(I->first.get(),"trans")); 
614                   actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
615                   InFile = TempFile;
616                 }
617
618                 // ll -> bc Helper
619                 if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
620                   /// The output of the translator is an LLVM Assembly program
621                   /// We need to translate it to bytecode
622                   Action* action = new Action();
623                   action->program.set_file("llvm-as");
624                   action->args.push_back(InFile.get());
625                   action->args.push_back("-o");
626                   InFile.append_suffix("bc");
627                   action->args.push_back(InFile.get());
628                   actions.push_back(action);
629                 }
630               }
631             } else if (finalPhase == TRANSLATION) {
632               throw cd->langName + " does not support translation";
633             } else if (action.isSet(REQUIRED_FLAG)) {
634               throw std::string("Don't know how to translate ") + 
635                     cd->langName + " files";
636             }
637
638             // Short-circuit remaining actions if all they want is translation
639             if (finalPhase == TRANSLATION) { ++I; continue; }
640
641             /// OPTIMIZATION PHASE
642             action = cd->Optimizer;
643
644             // Get the optimization action, if needed, or error if appropriate
645             if (!isSet(EMIT_RAW_FLAG)) {
646               if (!action.program.is_empty()) {
647                 if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
648                   if (finalPhase == OPTIMIZATION) {
649                     if (OutFile.is_empty()) {
650                       OutFile = I->first;
651                       OutFile.append_suffix("o");
652                     }
653                     actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
654                   } else {
655                     sys::Path TempFile(MakeTempFile(I->first.get(),"opt"));
656                     actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION));
657                     InFile = TempFile;
658                   }
659                   // ll -> bc Helper
660                   if (action.isSet(OUTPUT_IS_ASM_FLAG)) {
661                     /// The output of the optimizer is an LLVM Assembly program
662                     /// We need to translate it to bytecode with llvm-as
663                     Action* action = new Action();
664                     action->program.set_file("llvm-as");
665                     action->args.push_back(InFile.get());
666                     action->args.push_back("-f");
667                     action->args.push_back("-o");
668                     InFile.append_suffix("bc");
669                     action->args.push_back(InFile.get());
670                     actions.push_back(action);
671                   }
672                 }
673               } else if (finalPhase == OPTIMIZATION) {
674                 throw cd->langName + " does not support optimization";
675               } else if (action.isSet(REQUIRED_FLAG)) {
676                 throw std::string("Don't know how to optimize ") + 
677                     cd->langName + " files";
678               }
679             }
680
681             // Short-circuit remaining actions if all they want is optimization
682             if (finalPhase == OPTIMIZATION) { ++I; continue; }
683
684             /// ASSEMBLY PHASE
685             action = cd->Assembler;
686
687             if (finalPhase == ASSEMBLY) {
688               if (isSet(EMIT_NATIVE_FLAG)) {
689                 // Use llc to get the native assembly file
690                 Action* action = new Action();
691                 action->program.set_file("llc");
692                 action->args.push_back(InFile.get());
693                 action->args.push_back("-f");
694                 action->args.push_back("-o");
695                 if (OutFile.is_empty()) {
696                   OutFile = I->first;
697                   OutFile.append_suffix("s");
698                 }
699                 action->args.push_back(OutFile.get());
700               } else {
701                 // Just convert back to llvm assembly with llvm-dis
702                 Action* action = new Action();
703                 action->program.set_file("llvm-dis");
704                 action->args.push_back(InFile.get());
705                 action->args.push_back("-f");
706                 action->args.push_back("-o");
707                 action->args.push_back(OutFile.get());
708                 actions.push_back(action);
709               }
710
711               // Short circuit the rest of the loop, we don't want to link 
712               ++I; 
713               continue;
714             }
715
716             // Register the result of the actions as a link candidate
717             LinkageItems.insert(InFile);
718
719             // Go to next file to be processed
720             ++I;
721           } // end while loop over each input file
722
723           /// RUN THE COMPILATION ACTIONS
724           std::vector<Action*>::iterator AI = actions.begin();
725           std::vector<Action*>::iterator AE = actions.end();
726           while (AI != AE) {
727             if (!DoAction(*AI))
728               throw std::string("Action failed");
729             AI++;
730           }
731
732           /// LINKING PHASE
733           if (finalPhase == LINKING) {
734             // Insert the platform-specific system libraries to the path list
735             LibraryPaths.push_back(sys::Path::GetSystemLibraryPath1());
736             LibraryPaths.push_back(sys::Path::GetSystemLibraryPath2());
737
738             // We're emitting native code so let's build an gccld Action
739             Action* link = new Action();
740             link->program.set_file("llvm-ld");
741
742             // Add in the optimization level requested
743             switch (optLevel) {
744               case OPT_FAST_COMPILE:
745                 link->args.push_back("-O1");
746                 break;
747               case OPT_SIMPLE:
748                 link->args.push_back("-O2");
749                 break;
750               case OPT_AGGRESSIVE:
751                 link->args.push_back("-O3");
752                 break;
753               case OPT_LINK_TIME:
754                 link->args.push_back("-O4");
755                 break;
756               case OPT_AGGRESSIVE_LINK_TIME:
757                 link->args.push_back("-O5");
758                 break;
759               case OPT_NONE:
760                 break;
761             }
762
763             // Add in all the linkage items we generated. This includes the
764             // output from the translation/optimization phases as well as any
765             // -l arguments specified.
766             for (PathVector::const_iterator I=LinkageItems.begin(), 
767                  E=LinkageItems.end(); I != E; ++I )
768               link->args.push_back(I->get());
769
770             // Add in all the libraries we found.
771             for (std::vector<std::string>::const_iterator I=LibFiles.begin(),
772                  E=LibFiles.end(); I != E; ++I )
773               link->args.push_back(std::string("-l")+*I);
774
775             // Add in all the library paths to the command line
776             for (PathVector::const_iterator I=LibraryPaths.begin(),
777                  E=LibraryPaths.end(); I != E; ++I)
778               link->args.push_back( std::string("-L") + I->get());
779
780             // Add in other optional flags
781             if (isSet(EMIT_NATIVE_FLAG))
782               link->args.push_back("-native");
783             if (isSet(VERBOSE_FLAG))
784               link->args.push_back("-v");
785             if (isSet(TIME_PASSES_FLAG))
786               link->args.push_back("-time-passes");
787             if (isSet(SHOW_STATS_FLAG))
788               link->args.push_back("-stats");
789             if (isSet(STRIP_OUTPUT_FLAG))
790               link->args.push_back("-s");
791             if (isSet(DEBUG_FLAG)) {
792               link->args.push_back("-debug");
793               link->args.push_back("-debug-pass=Details");
794             }
795
796             // Add in mandatory flags
797             link->args.push_back("-o");
798             link->args.push_back(OutFile.get());
799
800             // Execute the link
801             if (!DoAction(link))
802                 throw std::string("Action failed");
803           }
804         } catch (std::string& msg) {
805           cleanup();
806           throw;
807         } catch (...) {
808           cleanup();
809           throw std::string("Unspecified error");
810         }
811         cleanup();
812         return 0;
813       }
814
815     /// @}
816     /// @name Data
817     /// @{
818     private:
819       ConfigDataProvider* cdp;      ///< Where we get configuration data from
820       Phases finalPhase;            ///< The final phase of compilation
821       OptimizationLevels optLevel;  ///< The optimization level to apply
822       unsigned Flags;               ///< The driver flags
823       std::string machine;          ///< Target machine name
824       PathVector LibraryPaths;      ///< -L options
825       PathVector IncludePaths;      ///< -I options
826       StringVector Defines;         ///< -D options
827       sys::Path TempDir;            ///< Name of the temporary directory.
828       StringTable AdditionalArgs;   ///< The -Txyz options
829       StringVector fOptions;        ///< -f options
830       StringVector MOptions;        ///< -M options
831       StringVector WOptions;        ///< -W options
832
833     /// @}
834   };
835 }
836
837 CompilerDriver::~CompilerDriver() {
838 }
839
840 CompilerDriver*
841 CompilerDriver::Get(ConfigDataProvider& CDP) {
842   return new CompilerDriverImpl(CDP);
843 }
844
845 CompilerDriver::ConfigData::ConfigData()
846   : langName()
847   , PreProcessor()
848   , Translator()
849   , Optimizer()
850   , Assembler()
851   , Linker()
852 {
853   StringVector emptyVec;
854   for (unsigned i = 0; i < NUM_PHASES; ++i)
855     opts.push_back(emptyVec);
856 }
857
858 // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab