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