blob: f1d3e58bad9c927334436837a6a6b4f8a86f3e9b [file] [log] [blame]
Reid Spencere37345e2004-08-13 20:25:54 +00001//===- CompilerDriver.cpp - The LLVM Compiler Driver ------------*- C++ -*-===//
Reid Spencercf7c2fe2004-08-13 20:22:43 +00002//
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//
Reid Spencere37345e2004-08-13 20:25:54 +000011// This file implements the bulk of the LLVM Compiler Driver (llvmc).
Reid Spencercf7c2fe2004-08-13 20:22:43 +000012//
13//===------------------------------------------------------------------------===
14
15#include "CompilerDriver.h"
16#include <iostream>
17
18using namespace llvm;
19
20namespace {
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
37CompilerDriver::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
55CompilerDriver::~CompilerDriver() {
56 cdp = 0;
57 libPaths.clear();
58}
59
60void CompilerDriver::error( const std::string& errmsg ) {
61 std::cerr << "Error: " << errmsg << ".\n";
62 exit(1);
63}
64
65CompilerDriver::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
88void 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
98void 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
113int 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