#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include <iostream>
+#include "llvm/Config/alloca.h"
using namespace llvm;
void WriteAction(CompilerDriver::Action* action ) {
std::cerr << action->program.c_str();
- std::vector<std::string>::iterator I = action->args.begin();
+ std::vector<std::string>::const_iterator I = action->args.begin();
while (I != action->args.end()) {
- std::cerr << " " + *I;
+ std::cerr << " " << *I;
++I;
}
std::cerr << "\n";
void DumpAction(CompilerDriver::Action* action) {
std::cerr << "command = " << action->program.c_str();
- std::vector<std::string>::iterator I = action->args.begin();
+ std::vector<std::string>::const_iterator I = action->args.begin();
while (I != action->args.end()) {
- std::cerr << " " + *I;
+ std::cerr << " " << *I;
++I;
}
std::cerr << "\n";
virtual void setWPassThrough(const StringVector& WOpts) {
WOptions = WOpts;
}
+
/// @}
/// @name Functions
/// @{
if (TempDir.isDirectory() && TempDir.writable())
TempDir.destroyDirectory(/*remove_contents=*/true);
} else {
- std::cout << "Temporary files are in " << TempDir.get() << "\n";
+ std::cout << "Temporary files are in " << TempDir << "\n";
}
}
break;
case 'f':
if (*PI == "%fOpts%") {
- action->args.insert(action->args.end(), fOptions.begin(),
- fOptions.end());
+ if (!fOptions.empty())
+ action->args.insert(action->args.end(), fOptions.begin(),
+ fOptions.end());
} else
found = false;
break;
case 'i':
if (*PI == "%in%") {
- action->args.push_back(input.get());
+ action->args.push_back(input.toString());
} else if (*PI == "%incls%") {
PathVector::iterator I = IncludePaths.begin();
PathVector::iterator E = IncludePaths.end();
while (I != E) {
- action->args.push_back( std::string("-I") + I->get() );
+ action->args.push_back( std::string("-I") + I->toString() );
++I;
}
} else
PathVector::iterator I = LibraryPaths.begin();
PathVector::iterator E = LibraryPaths.end();
while (I != E) {
- action->args.push_back( std::string("-L") + I->get() );
+ action->args.push_back( std::string("-L") + I->toString() );
++I;
}
} else
break;
case 'o':
if (*PI == "%out%") {
- action->args.push_back(output.get());
+ action->args.push_back(output.toString());
} else if (*PI == "%opt%") {
if (!isSet(EMIT_RAW_FLAG)) {
if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
found = false;
break;
case 'M':
- if (*PI == "%Mopts") {
- action->args.insert(action->args.end(), MOptions.begin(),
- MOptions.end());
+ if (*PI == "%Mopts%") {
+ if (!MOptions.empty())
+ action->args.insert(action->args.end(), MOptions.begin(),
+ MOptions.end());
} else
found = false;
break;
case 'W':
- if (*PI == "%Wopts") {
- action->args.insert(action->args.end(), WOptions.begin(),
- WOptions.end());
+ if (*PI == "%Wopts%") {
+ for (StringVector::iterator I = WOptions.begin(),
+ E = WOptions.end(); I != E ; ++I ) {
+ action->args.push_back( std::string("-W") + *I );
+ }
} else
found = false;
break;
if (PI->length()>1 && (*PI)[0] == '%' &&
(*PI)[PI->length()-1] == '%') {
throw std::string("Invalid substitution token: '") + *PI +
- "' for command '" + pat->program.get() + "'";
- } else {
+ "' for command '" + pat->program.toString() + "'";
+ } else if (!PI->empty()) {
// It's not a legal substitution, just pass it through
action->args.push_back(*PI);
}
}
- } else {
+ } else if (!PI->empty()) {
// Its not a substitution, just put it in the action
action->args.push_back(*PI);
}
WriteAction(action);
if (!isSet(DRY_RUN_FLAG)) {
sys::Path progpath = sys::Program::FindProgramByName(
- action->program.get());
+ action->program.toString());
if (progpath.isEmpty())
- throw std::string("Can't find program '"+progpath.get()+"'");
+ throw std::string("Can't find program '" +
+ action->program.toString()+"'");
else if (progpath.executable())
action->program = progpath;
else
- throw std::string("Program '"+progpath.get()+"' is not executable.");
+ throw std::string("Program '"+action->program.toString()+
+ "' is not executable.");
// Invoke the program
+ const char** Args = (const char**)
+ alloca(sizeof(const char*)*(action->args.size()+2));
+ Args[0] = action->program.toString().c_str();
+ for (unsigned i = 1; i != action->args.size(); ++i)
+ Args[i] = action->args[i].c_str();
+ Args[action->args.size()] = 0; // null terminate list.
if (isSet(TIME_ACTIONS_FLAG)) {
- Timer timer(action->program.get());
+ Timer timer(action->program.toString());
timer.startTimer();
- int resultCode =
- sys::Program::ExecuteAndWait(action->program,action->args);
+ int resultCode = sys::Program::ExecuteAndWait(action->program, Args);
timer.stopTimer();
timer.print(timer,std::cerr);
return resultCode == 0;
}
else
- return 0 ==
- sys::Program::ExecuteAndWait(action->program, action->args);
+ return 0 == sys::Program::ExecuteAndWait(action->program, Args);
}
return true;
}
/// This method tries various variants of a linkage item's file
/// name to see if it can find an appropriate file to link with
- /// in the directory specified.
+ /// in the directories of the LibraryPaths.
llvm::sys::Path GetPathForLinkageItem(const std::string& link_item,
- const sys::Path& dir,
bool native = false) {
- sys::Path fullpath(dir);
- fullpath.appendFile(link_item);
- if (native) {
- fullpath.appendSuffix("a");
- } else {
- fullpath.appendSuffix("bc");
- if (fullpath.readable())
- return fullpath;
- fullpath.elideSuffix();
- fullpath.appendSuffix("o");
- if (fullpath.readable())
- return fullpath;
- fullpath = dir;
- fullpath.appendFile(std::string("lib") + link_item);
- fullpath.appendSuffix("a");
- if (fullpath.readable())
- return fullpath;
- fullpath.elideSuffix();
- fullpath.appendSuffix("so");
+ sys::Path fullpath;
+ fullpath.setFile(link_item);
+ if (fullpath.readable())
+ return fullpath;
+ for (PathVector::iterator PI = LibraryPaths.begin(),
+ PE = LibraryPaths.end(); PI != PE; ++PI) {
+ fullpath.setDirectory(PI->toString());
+ fullpath.appendFile(link_item);
if (fullpath.readable())
return fullpath;
+ if (native) {
+ fullpath.appendSuffix("a");
+ } else {
+ fullpath.appendSuffix("bc");
+ if (fullpath.readable())
+ return fullpath;
+ fullpath.elideSuffix();
+ fullpath.appendSuffix("o");
+ if (fullpath.readable())
+ return fullpath;
+ fullpath = *PI;
+ fullpath.appendFile(std::string("lib") + link_item);
+ fullpath.appendSuffix("a");
+ if (fullpath.readable())
+ return fullpath;
+ fullpath.elideSuffix();
+ fullpath.appendSuffix("so");
+ if (fullpath.readable())
+ return fullpath;
+ }
}
// Didn't find one.
// we must track down the file in the lib search path.
sys::Path fullpath;
if (!link_item.readable()) {
- // First, look for the library using the -L arguments specified
+ // look for the library using the -L arguments specified
// on the command line.
- PathVector::iterator PI = LibraryPaths.begin();
- PathVector::iterator PE = LibraryPaths.end();
- while (PI != PE && fullpath.isEmpty()) {
- fullpath = GetPathForLinkageItem(link_item.get(),*PI);
- ++PI;
- }
+ fullpath = GetPathForLinkageItem(link_item.toString());
// If we didn't find the file in any of the library search paths
- // so we have to bail. No where else to look.
+ // we have to bail. No where else to look.
if (fullpath.isEmpty()) {
err =
- std::string("Can't find linkage item '") + link_item.get() + "'";
+ std::string("Can't find linkage item '") + link_item.toString() + "'";
return false;
}
} else {
if (fullpath.isBytecodeFile()) {
// Process the dependent libraries recursively
Module::LibraryListType modlibs;
- if (GetBytecodeDependentLibraries(fullpath.get(),modlibs)) {
+ if (GetBytecodeDependentLibraries(fullpath.toString(),modlibs)) {
// Traverse the dependent libraries list
Module::lib_iterator LI = modlibs.begin();
Module::lib_iterator LE = modlibs.end();
if (err.empty()) {
err = std::string("Library '") + *LI +
"' is not valid for linking but is required by file '" +
- fullpath.get() + "'";
+ fullpath.toString() + "'";
} else {
- err += " which is required by file '" + fullpath.get() + "'";
+ err += " which is required by file '" + fullpath.toString() + "'";
}
return false;
}
} else if (err.empty()) {
err = std::string(
"The dependent libraries could not be extracted from '") +
- fullpath.get();
+ fullpath.toString();
return false;
}
}
std::cerr << "OutputMachine = " << machine << "\n";
InputList::const_iterator I = InpList.begin();
while ( I != InpList.end() ) {
- std::cerr << "Input: " << I->first.get() << "(" << I->second
+ std::cerr << "Input: " << I->first << "(" << I->second
<< ")\n";
++I;
}
- std::cerr << "Output: " << Output.get() << "\n";
+ std::cerr << "Output: " << Output << "\n";
}
// If there's no input, we're done.
/// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
// for each input item
SetVector<sys::Path> LinkageItems;
- std::vector<std::string> LibFiles;
+ StringVector LibFiles;
InputList::const_iterator I = InpList.begin();
- while ( I != InpList.end() ) {
+ for (InputList::const_iterator I = InpList.begin(), E = InpList.end();
+ I != E; ++I ) {
// Get the suffix of the file name
const std::string& ftype = I->second;
"Pre-compiled objects found but linking not requested");
}
if (ftype.empty())
- LibFiles.push_back(I->first.get());
+ LibFiles.push_back(I->first.toString());
else
LinkageItems.insert(I->first);
- ++I; continue; // short circuit remainder of loop
+ continue; // short circuit remainder of loop
}
// At this point, we know its something we need to translate
if (isSet(DEBUG_FLAG))
DumpConfigData(cd,I->second);
+ // Add the config data's library paths to the end of the list
+ for (StringVector::iterator LPI = cd->libpaths.begin(),
+ LPE = cd->libpaths.end(); LPI != LPE; ++LPI){
+ LibraryPaths.push_back(sys::Path(*LPI));
+ }
+
// Initialize the input and output files
sys::Path InFile(I->first);
sys::Path OutFile(I->first.getBasename());
if (!action.program.isEmpty()) {
if (action.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
if (finalPhase == PREPROCESSING) {
- OutFile.appendSuffix("E");
- actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("E");
+ actions.push_back(GetAction(cd,InFile,OutFile,PREPROCESSING));
+ } else {
+ actions.push_back(GetAction(cd,InFile,Output,PREPROCESSING));
+ }
} else {
sys::Path TempFile(MakeTempFile(I->first.getBasename(),"E"));
actions.push_back(GetAction(cd,InFile,TempFile,
// Short-circuit remaining actions if all they want is
// pre-processing
- if (finalPhase == PREPROCESSING) { ++I; continue; };
+ if (finalPhase == PREPROCESSING) { continue; };
/// TRANSLATION PHASE
action = cd->Translator;
if (!action.program.isEmpty()) {
if (action.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
if (finalPhase == TRANSLATION) {
- OutFile.appendSuffix("o");
- actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("o");
+ actions.push_back(GetAction(cd,InFile,OutFile,TRANSLATION));
+ } else {
+ actions.push_back(GetAction(cd,InFile,Output,TRANSLATION));
+ }
} else {
sys::Path TempFile(MakeTempFile(I->first.getBasename(),"trans"));
actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
/// We need to translate it to bytecode
Action* action = new Action();
action->program.setFile("llvm-as");
- action->args.push_back(InFile.get());
+ action->args.push_back(InFile.toString());
action->args.push_back("-o");
InFile.appendSuffix("bc");
- action->args.push_back(InFile.get());
+ action->args.push_back(InFile.toString());
actions.push_back(action);
}
}
}
// Short-circuit remaining actions if all they want is translation
- if (finalPhase == TRANSLATION) { ++I; continue; }
+ if (finalPhase == TRANSLATION) { continue; }
/// OPTIMIZATION PHASE
action = cd->Optimizer;
if (!action.program.isEmpty()) {
if (action.isSet(REQUIRED_FLAG) || finalPhase == OPTIMIZATION) {
if (finalPhase == OPTIMIZATION) {
- OutFile.appendSuffix("o");
- actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("o");
+ actions.push_back(GetAction(cd,InFile,OutFile,OPTIMIZATION));
+ } else {
+ actions.push_back(GetAction(cd,InFile,Output,OPTIMIZATION));
+ }
} else {
sys::Path TempFile(MakeTempFile(I->first.getBasename(),"opt"));
actions.push_back(GetAction(cd,InFile,TempFile,OPTIMIZATION));
/// We need to translate it to bytecode with llvm-as
Action* action = new Action();
action->program.setFile("llvm-as");
- action->args.push_back(InFile.get());
+ action->args.push_back(InFile.toString());
action->args.push_back("-f");
action->args.push_back("-o");
InFile.appendSuffix("bc");
- action->args.push_back(InFile.get());
+ action->args.push_back(InFile.toString());
actions.push_back(action);
}
}
}
// Short-circuit remaining actions if all they want is optimization
- if (finalPhase == OPTIMIZATION) { ++I; continue; }
+ if (finalPhase == OPTIMIZATION) { continue; }
/// ASSEMBLY PHASE
action = cd->Assembler;
if (finalPhase == ASSEMBLY) {
+
+ // Build either a native compilation action or a disassembly action
+ Action* action = new Action();
if (isSet(EMIT_NATIVE_FLAG)) {
// Use llc to get the native assembly file
- Action* action = new Action();
action->program.setFile("llc");
- action->args.push_back(InFile.get());
+ action->args.push_back(InFile.toString());
action->args.push_back("-f");
action->args.push_back("-o");
- OutFile.appendSuffix("s");
- action->args.push_back(OutFile.get());
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("o");
+ action->args.push_back(OutFile.toString());
+ } else {
+ action->args.push_back(Output.toString());
+ }
+ actions.push_back(action);
} else {
// Just convert back to llvm assembly with llvm-dis
- Action* action = new Action();
action->program.setFile("llvm-dis");
- action->args.push_back(InFile.get());
+ action->args.push_back(InFile.toString());
action->args.push_back("-f");
action->args.push_back("-o");
- OutFile.appendSuffix("ll");
- action->args.push_back(OutFile.get());
- actions.push_back(action);
+ if (Output.isEmpty()) {
+ OutFile.appendSuffix("ll");
+ action->args.push_back(OutFile.toString());
+ } else {
+ action->args.push_back(Output.toString());
+ }
}
+ // Put the action on the list
+ actions.push_back(action);
+
// Short circuit the rest of the loop, we don't want to link
- ++I;
continue;
}
// Register the result of the actions as a link candidate
LinkageItems.insert(InFile);
- // Go to next file to be processed
- ++I;
} // end while loop over each input file
/// RUN THE COMPILATION ACTIONS
if (finalPhase == LINKING) {
// Insert the platform-specific system libraries to the path list
- LibraryPaths.push_back(sys::Path::GetSystemLibraryPath1());
- LibraryPaths.push_back(sys::Path::GetSystemLibraryPath2());
+ std::vector<sys::Path> SysLibs;
+ sys::Path::GetSystemLibraryPaths(SysLibs);
+ LibraryPaths.insert(LibraryPaths.end(), SysLibs.begin(), SysLibs.end());
// Set up the linking action with llvm-ld
Action* link = new Action();
// -l arguments specified.
for (PathVector::const_iterator I=LinkageItems.begin(),
E=LinkageItems.end(); I != E; ++I )
- link->args.push_back(I->get());
+ link->args.push_back(I->toString());
// Add in all the libraries we found.
- for (std::vector<std::string>::const_iterator I=LibFiles.begin(),
+ for (StringVector::const_iterator I=LibFiles.begin(),
E=LibFiles.end(); I != E; ++I )
link->args.push_back(std::string("-l")+*I);
// Add in all the library paths to the command line
for (PathVector::const_iterator I=LibraryPaths.begin(),
E=LibraryPaths.end(); I != E; ++I)
- link->args.push_back( std::string("-L") + I->get());
+ link->args.push_back( std::string("-L") + I->toString());
// Add in the additional linker arguments requested
for (StringVector::const_iterator I=AdditionalArgs[LINKING].begin(),
// Add in mandatory flags
link->args.push_back("-o");
- link->args.push_back(Output.get());
+ link->args.push_back(Output.toString());
// Execute the link
if (!DoAction(link))