Fix header commentary.
[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   const char OutputSuffix[] = ".o";
33
34 }
35
36
37 CompilerDriver::CompilerDriver(ConfigDataProvider& confDatProv )
38   : cdp(&confDatProv)
39   , finalPhase(LINKING)
40   , optLevel(OPT_FAST_COMPILE) 
41   , isDryRun(false)
42   , isVerbose(false)
43   , isDebug(false)
44   , timeActions(false)
45   , emitRawCode(false)
46   , emitNativeCode(false)
47   , machine()
48   , libPaths()
49 {
50   // FIXME: These libraries are platform specific
51   libPaths.push_back("/lib");
52   libPaths.push_back("/usr/lib");
53 }
54
55 CompilerDriver::~CompilerDriver() {
56   cdp = 0;
57   libPaths.clear();
58 }
59
60 void CompilerDriver::error( const std::string& errmsg ) {
61   std::cerr << "Error: " << errmsg << ".\n";
62   exit(1);
63 }
64
65 CompilerDriver::Action* CompilerDriver::GetAction(ConfigData* cd, 
66                           const std::string& input, 
67                           const std::string& output,
68                           Phases phase)
69 {
70   Action* pat = 0;
71   switch (phase) {
72     case PREPROCESSING: pat = &cd->PreProcessor; break;
73     case TRANSLATION:   pat = &cd->Translator; break;
74     case OPTIMIZATION:  pat = &cd->Optimizer; break;
75     case ASSEMBLY:      pat = &cd->Assembler; break;
76     case LINKING:       pat = &cd->Linker; break;
77     default:
78       assert(!"Invalid driver phase!");
79       break;
80   }
81   assert(pat != 0 && "Invalid command pattern");
82   Action* a = new Action(*pat);
83   a->args[pat->inputAt] = input;
84   a->args[pat->outputAt] = output;
85   return a;
86 }
87
88 void CompilerDriver::WriteAction(Action* a) {
89   std::cerr << a->program;
90   std::vector<std::string>::iterator I = a->args.begin();
91   while (I != a->args.end()) {
92     std::cerr << " " + *I;
93     ++I;
94   }
95   std::cerr << "\n";
96 }
97
98 void CompilerDriver::DoAction(Action*a)
99 {
100   if (isVerbose)
101     WriteAction(a);
102   if (!isDryRun) {
103     std::cerr << "execve(\"" << a->program << "\",[\n";
104     std::vector<std::string>::iterator I = a->args.begin();
105     while (I != a->args.end()) {
106       std::cerr << "  \"" << *I << "\",\n";
107       ++I;
108     }
109     std::cerr << "],ENV);\n";
110   }
111 }
112
113 int CompilerDriver::execute(const InputList& InpList, 
114                             const std::string& Output ) {
115   // Echo the configuration of options if we're running verbose
116   if (isDebug)
117   {
118     std::cerr << "Compiler Driver Options:\n";
119     std::cerr << "DryRun = " << isDryRun << "\n";
120     std::cerr << "Verbose = " << isVerbose << " \n";
121     std::cerr << "TimeActions = " << timeActions << "\n";
122     std::cerr << "EmitRawCode = " << emitRawCode << "\n";
123     std::cerr << "OutputMachine = " << machine << "\n";
124     std::cerr << "EmitNativeCode = " << emitNativeCode << "\n";
125     InputList::const_iterator I = InpList.begin();
126     while ( I != InpList.end() ) {
127       std::cerr << "Input: " << I->first << "(" << I->second << ")\n";
128       ++I;
129     }
130     std::cerr << "Output: " << Output << "\n";
131   }
132
133   // If there's no input, we're done.
134   if (InpList.empty())
135     error("Nothing to compile.");
136
137   // If they are asking for linking and didn't provide an output
138   // file then its an error (no way for us to "make up" a meaningful
139   // file name based on the various linker input files).
140   if (finalPhase == LINKING && Output.empty())
141     error("An output file name must be specified for linker output");
142
143   std::vector<Action*> actions;
144
145   /// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
146   // for each input item
147   std::vector<std::string> LinkageItems;
148   InputList::const_iterator I = InpList.begin();
149   while ( I != InpList.end() ) {
150     // Get the suffix of the file name
151     std::string suffix = GetSuffix(I->first);
152
153     // If its a library, bytecode file, or object file, save 
154     // it for linking below and short circuit the 
155     // pre-processing/translation/assembly phases
156     if (I->second.empty() || suffix == "o" || suffix == "bc") {
157       // We shouldn't get any of these types of files unless we're 
158       // later going to link. Enforce this limit now.
159       if (finalPhase != LINKING) {
160         error("Pre-compiled objects found but linking not requested");
161       }
162       LinkageItems.push_back(I->first);
163       continue; // short circuit remainder of loop
164     }
165
166     // At this point, we know its something we need to translate
167     // and/or optimize. See if we can get the configuration data
168     // for this kind of file.
169     ConfigData* cd = cdp->ProvideConfigData(I->second);
170     if (cd == 0)
171       error(std::string("Files of type '") + I->second + 
172             "' are not recognized." ); 
173
174     // We have valid configuration data, now figure out where the output
175     // of compilation should end up.
176     std::string OutFile;
177     if (finalPhase != LINKING) {
178       if (InpList.size() == 1 && !Output.empty()) 
179         OutFile = Output;
180       else
181         OutFile = RemoveSuffix(I->first) + OutputSuffix;
182     } else {
183       OutFile = Output;
184     }
185
186     /// PRE-PROCESSING PHASE
187     if (finalPhase == PREPROCESSING) {
188       if (cd->PreProcessor.program.empty())
189         error(cd->langName + " does not support pre-processing");
190       else
191         actions.push_back(GetAction(cd,I->first,OutFile,PREPROCESSING));
192     } else if (cd->PreprocessorNeeded && !cd->TranslatorPreprocesses) {
193       if (!cd->PreProcessor.program.empty()) {
194         actions.push_back(GetAction(cd,I->first,OutFile,PREPROCESSING));
195       }
196     }
197
198     // Short-circuit remaining actions if all they want is pre-processing
199     if (finalPhase == PREPROCESSING) { ++I; continue; };
200
201     /// TRANSLATION PHASE
202     actions.push_back(GetAction(cd,I->first,OutFile,TRANSLATION));
203     // Short-circuit remaining actions if all they want is translation
204     if (finalPhase == TRANSLATION) { ++I; continue; }
205
206     /// OPTIMIZATION PHASE
207     actions.push_back(GetAction(cd,I->first,OutFile,OPTIMIZATION));
208     // Short-circuit remaining actions if all they want is optimization
209     if (finalPhase == OPTIMIZATION) { ++I; continue; }
210
211     ++I;
212   }
213
214   /// LINKING PHASE
215
216   /// RUN THE ACTIONS
217   std::vector<Action*>::iterator aIter = actions.begin();
218   while (aIter != actions.end()) {
219     DoAction(*aIter);
220     aIter++;
221   }
222
223   return 0;
224 }
225
226 // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab