//===- CompilerDriver.cpp - The LLVM Compiler Driver ------------*- C++ -*-===//
//
-//
+//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Reid Spencer and is distributed under the
+// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the bulk of the LLVM Compiler Driver (llvmc).
#include "llvm/System/Signals.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Config/alloca.h"
#include <iostream>
-
using namespace llvm;
namespace {
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";
}
void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
- std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
+ std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
<< ")\n";
std::cerr << "PreProcessor: ";
DumpAction(&cd->PreProcessor);
/// This specifies the passes to run for OPT_FAST_COMPILE (-O1)
/// which should reduce the volume of code and make compilation
-/// faster. This is also safe on any llvm module.
+/// faster. This is also safe on any llvm module.
static const char* DefaultFastCompileOptimizations[] = {
"-simplifycfg", "-mem2reg", "-instcombine"
};
CompilerDriverImpl(ConfigDataProvider& confDatProv )
: cdp(&confDatProv)
, finalPhase(LINKING)
- , optLevel(OPT_FAST_COMPILE)
+ , optLevel(OPT_FAST_COMPILE)
, Flags(0)
, machine()
, LibraryPaths()
/// @name Methods
/// @{
public:
- virtual void setFinalPhase( Phases phase ) {
- finalPhase = phase;
+ virtual void setFinalPhase( Phases phase ) {
+ finalPhase = phase;
}
- virtual void setOptimization( OptimizationLevels level ) {
- optLevel = level;
+ virtual void setOptimization( OptimizationLevels level ) {
+ optLevel = level;
}
virtual void setDriverFlags( unsigned flags ) {
- Flags = flags & DRIVER_FLAGS_MASK;
+ Flags = flags & DRIVER_FLAGS_MASK;
}
virtual void setOutputMachine( const std::string& machineName ) {
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";
}
}
- sys::Path MakeTempFile(const std::string& basename,
+ sys::Path MakeTempFile(const std::string& basename,
const std::string& suffix ) {
sys::Path result(TempDir);
if (!result.appendFile(basename))
return result;
}
- Action* GetAction(ConfigData* cd,
- const sys::Path& input,
+ Action* GetAction(ConfigData* cd,
+ const sys::Path& input,
const sys::Path& output,
Phases phase)
{
// Get specific options for each kind of action type
StringVector& addargs = AdditionalArgs[phase];
// Add specific options for each kind of action type
- action->args.insert(action->args.end(), addargs.begin(),
+ action->args.insert(action->args.end(), addargs.begin(),
addargs.end());
}
} else
case 'f':
if (*PI == "%fOpts%") {
if (!fOptions.empty())
- action->args.insert(action->args.end(), fOptions.begin(),
+ 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) &&
+ if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
!cd->opts[optLevel].empty())
- action->args.insert(action->args.end(),
+ action->args.insert(action->args.end(),
cd->opts[optLevel].begin(),
cd->opts[optLevel].end());
else
- throw std::string("Optimization options for level ") +
+ throw std::string("Optimization options for level ") +
utostr(unsigned(optLevel)) + " were not specified";
}
} else
case 'M':
if (*PI == "%Mopts%") {
if (!MOptions.empty())
- action->args.insert(action->args.end(), MOptions.begin(),
+ action->args.insert(action->args.end(), MOptions.begin(),
MOptions.end());
} else
found = false;
}
if (!found) {
// Did it even look like a substitution?
- if (PI->length()>1 && (*PI)[0] == '%' &&
+ if (PI->length()>1 && (*PI)[0] == '%' &&
(*PI)[PI->length()-1] == '%') {
throw std::string("Invalid substitution token: '") + *PI +
- "' for command '" + pat->program.get() + "'";
+ "' for command '" + pat->program.toString() + "'";
} else if (!PI->empty()) {
// It's not a legal substitution, just pass it through
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 '"+action->program.get()+"'");
+ throw std::string("Can't find program '" +
+ action->program.toString()+"'");
else if (progpath.executable())
action->program = progpath;
else
- throw std::string("Program '"+action->program.get()+
+ 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;
}
fullpath.setFile(link_item);
if (fullpath.readable())
return fullpath;
- for (PathVector::iterator PI = LibraryPaths.begin(),
+ for (PathVector::iterator PI = LibraryPaths.begin(),
PE = LibraryPaths.end(); PI != PE; ++PI) {
- fullpath.setDirectory(PI->get());
+ fullpath.setDirectory(PI->toString());
fullpath.appendFile(link_item);
if (fullpath.readable())
return fullpath;
fullpath.appendSuffix("a");
} else {
fullpath.appendSuffix("bc");
- if (fullpath.readable())
+ if (fullpath.readable())
return fullpath;
fullpath.elideSuffix();
fullpath.appendSuffix("o");
- if (fullpath.readable())
+ if (fullpath.readable())
return fullpath;
fullpath = *PI;
fullpath.appendFile(std::string("lib") + link_item);
if (!link_item.readable()) {
// look for the library using the -L arguments specified
// on the command line.
- fullpath = GetPathForLinkageItem(link_item.get());
+ fullpath = GetPathForLinkageItem(link_item.toString());
// If we didn't find the file in any of the library search paths
// we have to bail. No where else to look.
if (fullpath.isEmpty()) {
- err =
- std::string("Can't find linkage item '") + link_item.get() + "'";
+ err =
+ 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();
while ( LI != LE ) {
if (!ProcessLinkageItem(sys::Path(*LI),set,err)) {
if (err.empty()) {
- err = std::string("Library '") + *LI +
+ 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();
+ "The dependent libraries could not be extracted from '") +
+ 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();
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;
- // If its a library, bytecode file, or object file, save
- // it for linking below and short circuit the
+ // If its a library, bytecode file, or object file, save
+ // it for linking below and short circuit the
// pre-processing/translation/assembly phases
if (ftype.empty() || ftype == "o" || ftype == "bc" || ftype=="a") {
- // We shouldn't get any of these types of files unless we're
+ // We shouldn't get any of these types of files unless we're
// later going to link. Enforce this limit now.
if (finalPhase != LINKING) {
throw std::string(
"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);
continue; // short circuit remainder of loop
// for this kind of file.
ConfigData* cd = cdp->ProvideConfigData(I->second);
if (cd == 0)
- throw std::string("Files of type '") + I->second +
- "' are not recognized.";
+ throw std::string("Files of type '") + I->second +
+ "' are not recognized.";
if (isSet(DEBUG_FLAG))
DumpConfigData(cd,I->second);
} else if (finalPhase == PREPROCESSING) {
throw cd->langName + " does not support pre-processing";
} else if (action.isSet(REQUIRED_FLAG)) {
- throw std::string("Don't know how to pre-process ") +
+ throw std::string("Don't know how to pre-process ") +
cd->langName + " files";
}
- // Short-circuit remaining actions if all they want is
+ // Short-circuit remaining actions if all they want is
// pre-processing
if (finalPhase == PREPROCESSING) { continue; };
actions.push_back(GetAction(cd,InFile,Output,TRANSLATION));
}
} else {
- sys::Path TempFile(MakeTempFile(I->first.getBasename(),"trans"));
+ sys::Path TempFile(MakeTempFile(I->first.getBasename(),"trans"));
actions.push_back(GetAction(cd,InFile,TempFile,TRANSLATION));
InFile = TempFile;
}
/// 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);
}
}
} else if (finalPhase == TRANSLATION) {
throw cd->langName + " does not support translation";
} else if (action.isSet(REQUIRED_FLAG)) {
- throw std::string("Don't know how to translate ") +
+ throw std::string("Don't know how to translate ") +
cd->langName + " files";
}
/// 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);
}
}
} else if (finalPhase == OPTIMIZATION) {
throw cd->langName + " does not support optimization";
} else if (action.isSet(REQUIRED_FLAG)) {
- throw std::string("Don't know how to optimize ") +
+ throw std::string("Don't know how to optimize ") +
cd->langName + " files";
}
}
if (isSet(EMIT_NATIVE_FLAG)) {
// Use llc to get the native assembly file
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");
if (Output.isEmpty()) {
OutFile.appendSuffix("o");
- action->args.push_back(OutFile.get());
+ action->args.push_back(OutFile.toString());
} else {
- action->args.push_back(Output.get());
+ action->args.push_back(Output.toString());
}
actions.push_back(action);
} else {
// Just convert back to llvm assembly with llvm-dis
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");
if (Output.isEmpty()) {
OutFile.appendSuffix("ll");
- action->args.push_back(OutFile.get());
+ action->args.push_back(OutFile.toString());
} else {
- action->args.push_back(Output.get());
+ 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
+ // Short circuit the rest of the loop, we don't want to link
continue;
}
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();
// Add in all the linkage items we generated. This includes the
// output from the translation/optimization phases as well as any
// -l arguments specified.
- for (PathVector::const_iterator I=LinkageItems.begin(),
+ 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))