ff63b2100ede5aae661d3ff04585a11a09a3f152
[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 <iostream>
17
18 using namespace llvm;
19
20 namespace {
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   }
32
33   const char OutputSuffix[] = ".o";
34
35   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   }
64 }
65
66
67 CompilerDriver::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
85 CompilerDriver::~CompilerDriver() {
86   cdp = 0;
87   libPaths.clear();
88 }
89
90 void CompilerDriver::error( const std::string& errmsg ) {
91   std::cerr << "Error: " << errmsg << ".\n";
92   exit(1);
93 }
94
95 CompilerDriver::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);
113   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;
117   return a;
118 }
119
120 void 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
135 int 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." ); 
195     if (isDebug)
196       DumpConfigData(cd,I->second);
197
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