mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-15 19:24:33 +00:00
More Functionality:
- cleaned up lexical scanner - added support for "lang.optN" configuration items - added temporary file support (ala lib/System) - corrected logic for deciding which phases to run - consolidated the Action and ActionPattern classes git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15765 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
//===------------------------------------------------------------------------===
|
//===------------------------------------------------------------------------===
|
||||||
|
|
||||||
#include "CompilerDriver.h"
|
#include "CompilerDriver.h"
|
||||||
|
#include "ConfigLexer.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@@ -32,7 +33,7 @@ namespace {
|
|||||||
|
|
||||||
const char OutputSuffix[] = ".o";
|
const char OutputSuffix[] = ".o";
|
||||||
|
|
||||||
void WriteAction(CompilerDriver::Action* a) {
|
void WriteAction(CompilerDriver::Action* a ) {
|
||||||
std::cerr << a->program;
|
std::cerr << a->program;
|
||||||
std::vector<std::string>::iterator I = a->args.begin();
|
std::vector<std::string>::iterator I = a->args.begin();
|
||||||
while (I != a->args.end()) {
|
while (I != a->args.end()) {
|
||||||
@@ -42,24 +43,32 @@ namespace {
|
|||||||
std::cerr << "\n";
|
std::cerr << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DumpAction(CompilerDriver::Action* a) {
|
||||||
|
std::cerr << "command = " << a->program;
|
||||||
|
std::vector<std::string>::iterator I = a->args.begin();
|
||||||
|
while (I != a->args.end()) {
|
||||||
|
std::cerr << " " + *I;
|
||||||
|
++I;
|
||||||
|
}
|
||||||
|
std::cerr << "\n";
|
||||||
|
std::cerr << "flags = " << a->flags << "\n";
|
||||||
|
std::cerr << "inputAt = " << a->inputAt << "\n";
|
||||||
|
std::cerr << "outputAt = " << a->outputAt << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
void DumpConfigData(CompilerDriver::ConfigData* cd, const std::string& type ){
|
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";
|
<< ")\n";
|
||||||
std::cerr << "translator.preprocesses=" << cd->TranslatorPreprocesses
|
|
||||||
<< "\n";
|
|
||||||
std::cerr << "translator.groks_dash_O=" << cd->TranslatorGroksDashO << "\n";
|
|
||||||
std::cerr << "translator.optimizes=" << cd->TranslatorOptimizes << "\n";
|
|
||||||
std::cerr << "preprocessor.needed=" << cd->PreprocessorNeeded << "\n";
|
|
||||||
std::cerr << "PreProcessor: ";
|
std::cerr << "PreProcessor: ";
|
||||||
WriteAction(&cd->PreProcessor);
|
DumpAction(&cd->PreProcessor);
|
||||||
std::cerr << "Translator: ";
|
std::cerr << "Translator: ";
|
||||||
WriteAction(&cd->Translator);
|
DumpAction(&cd->Translator);
|
||||||
std::cerr << "Optimizer: ";
|
std::cerr << "Optimizer: ";
|
||||||
WriteAction(&cd->Optimizer);
|
DumpAction(&cd->Optimizer);
|
||||||
std::cerr << "Assembler: ";
|
std::cerr << "Assembler: ";
|
||||||
WriteAction(&cd->Assembler);
|
DumpAction(&cd->Assembler);
|
||||||
std::cerr << "Linker: ";
|
std::cerr << "Linker: ";
|
||||||
WriteAction(&cd->Linker);
|
DumpAction(&cd->Linker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,16 +84,26 @@ CompilerDriver::CompilerDriver(ConfigDataProvider& confDatProv )
|
|||||||
, emitRawCode(false)
|
, emitRawCode(false)
|
||||||
, emitNativeCode(false)
|
, emitNativeCode(false)
|
||||||
, machine()
|
, machine()
|
||||||
, libPaths()
|
, LibraryPaths()
|
||||||
|
, PreprocessorOptions()
|
||||||
|
, TranslatorOptions()
|
||||||
|
, OptimizerOptions()
|
||||||
|
, AssemblerOptions()
|
||||||
|
, LinkerOptions()
|
||||||
{
|
{
|
||||||
// FIXME: These libraries are platform specific
|
// FIXME: These libraries are platform specific
|
||||||
libPaths.push_back("/lib");
|
LibraryPaths.push_back("/lib");
|
||||||
libPaths.push_back("/usr/lib");
|
LibraryPaths.push_back("/usr/lib");
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilerDriver::~CompilerDriver() {
|
CompilerDriver::~CompilerDriver() {
|
||||||
cdp = 0;
|
cdp = 0;
|
||||||
libPaths.clear();
|
LibraryPaths.clear();
|
||||||
|
PreprocessorOptions.clear();
|
||||||
|
TranslatorOptions.clear();
|
||||||
|
OptimizerOptions.clear();
|
||||||
|
AssemblerOptions.clear();
|
||||||
|
LinkerOptions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerDriver::error( const std::string& errmsg ) {
|
void CompilerDriver::error( const std::string& errmsg ) {
|
||||||
@@ -92,12 +111,27 @@ void CompilerDriver::error( const std::string& errmsg ) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string makeDashO(CompilerDriver::OptimizationLevels lev) {
|
||||||
|
if (lev == CompilerDriver::OPT_NONE) return "";
|
||||||
|
std::string result("-O");
|
||||||
|
switch (lev) {
|
||||||
|
case CompilerDriver::OPT_FAST_COMPILE : result.append("1"); break;
|
||||||
|
case CompilerDriver::OPT_SIMPLE: result.append("2"); break;
|
||||||
|
case CompilerDriver::OPT_AGGRESSIVE: result.append("3"); break;
|
||||||
|
case CompilerDriver::OPT_LINK_TIME: result.append("4"); break;
|
||||||
|
case CompilerDriver::OPT_AGGRESSIVE_LINK_TIME: result.append("5"); break;
|
||||||
|
default: assert(!"Invalid optimization level!");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
CompilerDriver::Action* CompilerDriver::GetAction(ConfigData* cd,
|
CompilerDriver::Action* CompilerDriver::GetAction(ConfigData* cd,
|
||||||
const std::string& input,
|
const std::string& input,
|
||||||
const std::string& output,
|
const std::string& output,
|
||||||
Phases phase)
|
Phases phase)
|
||||||
{
|
{
|
||||||
Action* pat = 0;
|
Action* pat = 0;
|
||||||
|
// Get the action pattern
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
case PREPROCESSING: pat = &cd->PreProcessor; break;
|
case PREPROCESSING: pat = &cd->PreProcessor; break;
|
||||||
case TRANSLATION: pat = &cd->Translator; break;
|
case TRANSLATION: pat = &cd->Translator; break;
|
||||||
@@ -109,11 +143,57 @@ CompilerDriver::Action* CompilerDriver::GetAction(ConfigData* cd,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert(pat != 0 && "Invalid command pattern");
|
assert(pat != 0 && "Invalid command pattern");
|
||||||
|
|
||||||
|
// Create the resulting action
|
||||||
Action* a = new Action(*pat);
|
Action* a = new Action(*pat);
|
||||||
|
|
||||||
|
// Replace the substitution arguments
|
||||||
if (pat->inputAt < a->args.size())
|
if (pat->inputAt < a->args.size())
|
||||||
a->args[pat->inputAt] = input;
|
a->args[pat->inputAt] = input;
|
||||||
if (pat->outputAt < a->args.size())
|
if (pat->outputAt < a->args.size())
|
||||||
a->args[pat->outputAt] = output;
|
a->args[pat->outputAt] = output;
|
||||||
|
|
||||||
|
// Insert specific options for each kind of action type
|
||||||
|
switch (phase) {
|
||||||
|
case PREPROCESSING:
|
||||||
|
a->args.insert(a->args.begin(), PreprocessorOptions.begin(),
|
||||||
|
PreprocessorOptions.end());
|
||||||
|
break;
|
||||||
|
case TRANSLATION:
|
||||||
|
a->args.insert(a->args.begin(), TranslatorOptions.begin(),
|
||||||
|
TranslatorOptions.end());
|
||||||
|
if (a->isSet(GROKS_DASH_O_FLAG))
|
||||||
|
a->args.insert(a->args.begin(), makeDashO(optLevel));
|
||||||
|
else if (a->isSet(GROKS_O10N_FLAG))
|
||||||
|
a->args.insert(a->args.begin(), cd->opts[optLevel].begin(),
|
||||||
|
cd->opts[optLevel].end());
|
||||||
|
break;
|
||||||
|
case OPTIMIZATION:
|
||||||
|
a->args.insert(a->args.begin(), OptimizerOptions.begin(),
|
||||||
|
OptimizerOptions.end());
|
||||||
|
if (a->isSet(GROKS_DASH_O_FLAG))
|
||||||
|
a->args.insert(a->args.begin(), makeDashO(optLevel));
|
||||||
|
else if (a->isSet(GROKS_O10N_FLAG))
|
||||||
|
a->args.insert(a->args.begin(), cd->opts[optLevel].begin(),
|
||||||
|
cd->opts[optLevel].end());
|
||||||
|
break;
|
||||||
|
case ASSEMBLY:
|
||||||
|
a->args.insert(a->args.begin(), AssemblerOptions.begin(),
|
||||||
|
AssemblerOptions.end());
|
||||||
|
break;
|
||||||
|
case LINKING:
|
||||||
|
a->args.insert(a->args.begin(), LinkerOptions.begin(),
|
||||||
|
LinkerOptions.end());
|
||||||
|
if (a->isSet(GROKS_DASH_O_FLAG))
|
||||||
|
a->args.insert(a->args.begin(), makeDashO(optLevel));
|
||||||
|
else if (a->isSet(GROKS_O10N_FLAG))
|
||||||
|
a->args.insert(a->args.begin(), cd->opts[optLevel].begin(),
|
||||||
|
cd->opts[optLevel].end());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(!"Invalid driver phase!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,18 +202,20 @@ void CompilerDriver::DoAction(Action*a)
|
|||||||
if (isVerbose)
|
if (isVerbose)
|
||||||
WriteAction(a);
|
WriteAction(a);
|
||||||
if (!isDryRun) {
|
if (!isDryRun) {
|
||||||
std::cerr << "execve(\"" << a->program << "\",[\n";
|
std::cerr << "execve(\"" << a->program << "\",[\"";
|
||||||
std::vector<std::string>::iterator I = a->args.begin();
|
std::vector<std::string>::iterator I = a->args.begin();
|
||||||
while (I != a->args.end()) {
|
while (I != a->args.end()) {
|
||||||
std::cerr << " \"" << *I << "\",\n";
|
std::cerr << *I;
|
||||||
++I;
|
++I;
|
||||||
|
if (I != a->args.end())
|
||||||
|
std::cerr << "\",\"";
|
||||||
}
|
}
|
||||||
std::cerr << "],ENV);\n";
|
std::cerr << "\"],ENV);\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CompilerDriver::execute(const InputList& InpList,
|
int CompilerDriver::execute(const InputList& InpList,
|
||||||
const std::string& Output ) {
|
const sys::Path& Output ) {
|
||||||
// Echo the configuration of options if we're running verbose
|
// Echo the configuration of options if we're running verbose
|
||||||
if (isDebug)
|
if (isDebug)
|
||||||
{
|
{
|
||||||
@@ -162,8 +244,17 @@ int CompilerDriver::execute(const InputList& InpList,
|
|||||||
if (finalPhase == LINKING && Output.empty())
|
if (finalPhase == LINKING && Output.empty())
|
||||||
error("An output file name must be specified for linker output");
|
error("An output file name must be specified for linker output");
|
||||||
|
|
||||||
|
// This vector holds all the resulting actions of the following loop.
|
||||||
std::vector<Action*> actions;
|
std::vector<Action*> actions;
|
||||||
|
|
||||||
|
// Create a temporary directory for our temporary files
|
||||||
|
sys::Path TempDir(sys::Path::CONSTRUCT_TEMP_DIR);
|
||||||
|
sys::Path TempPreprocessorOut;
|
||||||
|
sys::Path TempTranslatorOut;
|
||||||
|
sys::Path TempOptimizerOut;
|
||||||
|
sys::Path TempAssemblerOut;
|
||||||
|
sys::Path TempLinkerOut;
|
||||||
|
|
||||||
/// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
|
/// PRE-PROCESSING / TRANSLATION / OPTIMIZATION / ASSEMBLY phases
|
||||||
// for each input item
|
// for each input item
|
||||||
std::vector<std::string> LinkageItems;
|
std::vector<std::string> LinkageItems;
|
||||||
@@ -207,28 +298,59 @@ int CompilerDriver::execute(const InputList& InpList,
|
|||||||
OutFile = Output;
|
OutFile = Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PRE-PROCESSING PHASE
|
// PRE-PROCESSING PHASE
|
||||||
if (finalPhase == PREPROCESSING) {
|
Action& a = cd->PreProcessor;
|
||||||
if (cd->PreProcessor.program.empty())
|
|
||||||
error(cd->langName + " does not support pre-processing");
|
|
||||||
else
|
|
||||||
actions.push_back(GetAction(cd,I->first,OutFile,PREPROCESSING));
|
|
||||||
} else if (cd->PreprocessorNeeded && !cd->TranslatorPreprocesses) {
|
|
||||||
if (!cd->PreProcessor.program.empty()) {
|
|
||||||
actions.push_back(GetAction(cd,I->first,OutFile,PREPROCESSING));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Get the preprocessing action, if needed, or error if appropriate
|
||||||
|
if (!a.program.empty()) {
|
||||||
|
if (a.isSet(REQUIRED_FLAG) || finalPhase == PREPROCESSING) {
|
||||||
|
TempPreprocessorOut = TempDir;
|
||||||
|
TempPreprocessorOut.append_file("preproc.out");
|
||||||
|
actions.push_back(GetAction(cd,I->first,
|
||||||
|
TempPreprocessorOut,PREPROCESSING));
|
||||||
|
}
|
||||||
|
} else if (finalPhase == PREPROCESSING) {
|
||||||
|
error(cd->langName + " does not support pre-processing");
|
||||||
|
} else if (a.isSet(REQUIRED_FLAG)) {
|
||||||
|
error(std::string("Don't know how to pre-process ") +
|
||||||
|
cd->langName + " files");
|
||||||
|
}
|
||||||
// Short-circuit remaining actions if all they want is pre-processing
|
// Short-circuit remaining actions if all they want is pre-processing
|
||||||
if (finalPhase == PREPROCESSING) { ++I; continue; };
|
if (finalPhase == PREPROCESSING) { ++I; continue; };
|
||||||
|
|
||||||
/// TRANSLATION PHASE
|
/// TRANSLATION PHASE
|
||||||
actions.push_back(GetAction(cd,I->first,OutFile,TRANSLATION));
|
a = cd->Translator;
|
||||||
|
|
||||||
|
// Get the translation action, if needed, or error if appropriate
|
||||||
|
if (!a.program.empty()) {
|
||||||
|
if (a.isSet(REQUIRED_FLAG) || finalPhase == TRANSLATION) {
|
||||||
|
TempTranslatorOut = TempDir;
|
||||||
|
TempTranslatorOut.append_file("trans.out");
|
||||||
|
actions.push_back(GetAction(cd,I->first,TempTranslatorOut,TRANSLATION));
|
||||||
|
}
|
||||||
|
} else if (finalPhase == TRANSLATION) {
|
||||||
|
error(cd->langName + " does not support translation");
|
||||||
|
} else if (a.isSet(REQUIRED_FLAG)) {
|
||||||
|
error(std::string("Don't know how to translate ") +
|
||||||
|
cd->langName + " files");
|
||||||
|
}
|
||||||
// Short-circuit remaining actions if all they want is translation
|
// Short-circuit remaining actions if all they want is translation
|
||||||
if (finalPhase == TRANSLATION) { ++I; continue; }
|
if (finalPhase == TRANSLATION) { ++I; continue; }
|
||||||
|
|
||||||
/// OPTIMIZATION PHASE
|
/// OPTIMIZATION PHASE
|
||||||
actions.push_back(GetAction(cd,I->first,OutFile,OPTIMIZATION));
|
a = cd->Optimizer;
|
||||||
|
|
||||||
|
// Get the optimization action, if needed, or error if appropriate
|
||||||
|
if (!a.program.empty()) {
|
||||||
|
TempOptimizerOut = TempDir;
|
||||||
|
TempOptimizerOut.append_file("trans.out");
|
||||||
|
actions.push_back(GetAction(cd,I->first,TempOptimizerOut,OPTIMIZATION));
|
||||||
|
} else if (finalPhase == OPTIMIZATION) {
|
||||||
|
error(cd->langName + " does not support optimization");
|
||||||
|
} else if (a.isSet(REQUIRED_FLAG)) {
|
||||||
|
error(std::string("Don't know how to optimize ") +
|
||||||
|
cd->langName + " files");
|
||||||
|
}
|
||||||
// Short-circuit remaining actions if all they want is optimization
|
// Short-circuit remaining actions if all they want is optimization
|
||||||
if (finalPhase == OPTIMIZATION) { ++I; continue; }
|
if (finalPhase == OPTIMIZATION) { ++I; continue; }
|
||||||
|
|
||||||
@@ -244,6 +366,16 @@ int CompilerDriver::execute(const InputList& InpList,
|
|||||||
aIter++;
|
aIter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup files
|
||||||
|
if (TempPreprocessorOut.exists())
|
||||||
|
TempPreprocessorOut.remove_file();
|
||||||
|
if (TempTranslatorOut.exists())
|
||||||
|
TempTranslatorOut.remove_file();
|
||||||
|
if (TempOptimizerOut.exists())
|
||||||
|
TempOptimizerOut.remove_file();
|
||||||
|
if (TempDir.exists())
|
||||||
|
TempDir.remove_directory();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#ifndef LLVM_TOOLS_LLVMC_COMPILERDRIVER_H
|
#ifndef LLVM_TOOLS_LLVMC_COMPILERDRIVER_H
|
||||||
#define LLVM_TOOLS_LLVMC_COMPILERDRIVER_H
|
#define LLVM_TOOLS_LLVMC_COMPILERDRIVER_H
|
||||||
|
|
||||||
|
#include "llvm/System/Path.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -29,6 +30,10 @@ namespace llvm {
|
|||||||
/// @name Types
|
/// @name Types
|
||||||
/// @{
|
/// @{
|
||||||
public:
|
public:
|
||||||
|
/// @brief A vector of strings, commonly used
|
||||||
|
typedef std::vector<std::string> StringVector;
|
||||||
|
|
||||||
|
/// @brief The phases of processing that llvmc understands
|
||||||
enum Phases {
|
enum Phases {
|
||||||
PREPROCESSING, ///< Source language combining, filtering, substitution
|
PREPROCESSING, ///< Source language combining, filtering, substitution
|
||||||
TRANSLATION, ///< Translate source -> LLVM bytecode/assembly
|
TRANSLATION, ///< Translate source -> LLVM bytecode/assembly
|
||||||
@@ -37,20 +42,31 @@ namespace llvm {
|
|||||||
ASSEMBLY, ///< Convert program to executable
|
ASSEMBLY, ///< Convert program to executable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief The levels of optimization llvmc understands
|
||||||
enum OptimizationLevels {
|
enum OptimizationLevels {
|
||||||
OPT_NONE, ///< Zippo optimizations, nada, nil, none.
|
|
||||||
OPT_FAST_COMPILE, ///< Optimize to make >compile< go faster
|
OPT_FAST_COMPILE, ///< Optimize to make >compile< go faster
|
||||||
OPT_SIMPLE, ///< Standard/simple optimizations
|
OPT_SIMPLE, ///< Standard/simple optimizations
|
||||||
OPT_AGGRESSIVE, ///< Aggressive optimizations
|
OPT_AGGRESSIVE, ///< Aggressive optimizations
|
||||||
OPT_LINK_TIME, ///< Aggressive + LinkTime optimizations
|
OPT_LINK_TIME, ///< Aggressive + LinkTime optimizations
|
||||||
OPT_AGGRESSIVE_LINK_TIME ///< Make it go way fast!
|
OPT_AGGRESSIVE_LINK_TIME, ///< Make it go way fast!
|
||||||
|
OPT_NONE ///< No optimizations. Keep this at the end!
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @brief Action specific flags
|
||||||
|
enum ConfigurationFlags {
|
||||||
|
REQUIRED_FLAG = 0x0001, ///< Should the action always be run?
|
||||||
|
GROKS_DASH_O_FLAG = 0x0002, ///< Understands the -On options?
|
||||||
|
PREPROCESSES_FLAG = 0x0004, ///< Does this action preprocess?
|
||||||
|
OPTIMIZES_FLAG = 0x0008, ///< Does this action optimize?
|
||||||
|
GROKS_O10N_FLAG = 0x0010, ///< Understands optimization options?
|
||||||
|
FLAGS_MASK = 0x001F, ///< Union of all flags
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This type is the input list to the CompilerDriver. It provides
|
/// This type is the input list to the CompilerDriver. It provides
|
||||||
/// a vector of filename/filetype pairs. The filetype is used to look up
|
/// a vector of filename/filetype pairs. The filetype is used to look up
|
||||||
/// the configuration of the actions to be taken by the driver.
|
/// the configuration of the actions to be taken by the driver.
|
||||||
/// @brief The Input Data to the execute method
|
/// @brief The Input Data to the execute method
|
||||||
typedef std::vector<std::pair<std::string,std::string> > InputList;
|
typedef std::vector<std::pair<sys::Path,std::string> > InputList;
|
||||||
|
|
||||||
/// This type is read from configuration files or otherwise provided to
|
/// This type is read from configuration files or otherwise provided to
|
||||||
/// the CompilerDriver through a "ConfigDataProvider". It serves as both
|
/// the CompilerDriver through a "ConfigDataProvider". It serves as both
|
||||||
@@ -58,28 +74,25 @@ namespace llvm {
|
|||||||
/// @brief A structure to hold the action data for a given source
|
/// @brief A structure to hold the action data for a given source
|
||||||
/// language.
|
/// language.
|
||||||
struct Action {
|
struct Action {
|
||||||
Action() : inputAt(0) , outputAt(0) {}
|
Action() : inputAt(0) , outputAt(0), flags(0) {}
|
||||||
std::string program; ///< The program to execve
|
sys::Path program; ///< The program to execve
|
||||||
std::vector<std::string> args; ///< Arguments to the program
|
StringVector args; ///< Arguments to the program
|
||||||
size_t inputAt; ///< Argument index to insert input file
|
size_t inputAt; ///< Argument index to insert input file
|
||||||
size_t outputAt; ///< Argument index to insert output file
|
size_t outputAt; ///< Argument index to insert output file
|
||||||
|
unsigned flags; ///< Action specific flags
|
||||||
|
void set(unsigned fl ) { flags |= fl; }
|
||||||
|
void clear(unsigned fl) { flags &= (FLAGS_MASK ^ fl); }
|
||||||
|
bool isSet(unsigned fl) { return flags&fl != 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConfigData {
|
struct ConfigData {
|
||||||
ConfigData() : TranslatorPreprocesses(false),
|
std::string langName; ///< The name of the source language
|
||||||
TranslatorOptimizes(false),
|
std::vector<StringVector> opts; ///< The o10n options for each level
|
||||||
TranslatorGroksDashO(false),
|
Action PreProcessor; ///< PreProcessor command line
|
||||||
PreprocessorNeeded(false) {}
|
Action Translator; ///< Translator command line
|
||||||
std::string langName; ///< The name of the source language
|
Action Optimizer; ///< Optimizer command line
|
||||||
bool TranslatorPreprocesses;///< Translator program will pre-process
|
Action Assembler; ///< Assembler command line
|
||||||
bool TranslatorOptimizes; ///< Translator program will optimize too
|
Action Linker; ///< Linker command line
|
||||||
bool TranslatorGroksDashO; ///< Translator understands -O arguments
|
|
||||||
bool PreprocessorNeeded; ///< Preprocessor is needed for translation
|
|
||||||
Action PreProcessor; ///< PreProcessor command line
|
|
||||||
Action Translator; ///< Translator command line
|
|
||||||
Action Optimizer; ///< Optimizer command line
|
|
||||||
Action Assembler; ///< Assembler command line
|
|
||||||
Action Linker; ///< Linker command line
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This pure virtual interface class defines the interface between the
|
/// This pure virtual interface class defines the interface between the
|
||||||
@@ -109,7 +122,7 @@ namespace llvm {
|
|||||||
virtual void error(const std::string& errmsg);
|
virtual void error(const std::string& errmsg);
|
||||||
|
|
||||||
/// @brief Execute the actions requested for the given input list.
|
/// @brief Execute the actions requested for the given input list.
|
||||||
virtual int execute(const InputList& list, const std::string& output);
|
virtual int execute(const InputList& list, const sys::Path& output);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Mutators
|
/// @name Mutators
|
||||||
@@ -148,10 +161,40 @@ namespace llvm {
|
|||||||
machine = machineName;
|
machine = machineName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Set Preprocessor specific options
|
||||||
|
void setPreprocessorOptions(const std::vector<std::string>& opts) {
|
||||||
|
PreprocessorOptions = opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set Translator specific options
|
||||||
|
void setTranslatorOptions(const std::vector<std::string>& opts) {
|
||||||
|
TranslatorOptions = opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set Optimizer specific options
|
||||||
|
void setOptimizerOptions(const std::vector<std::string>& opts) {
|
||||||
|
OptimizerOptions = opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set Assembler specific options
|
||||||
|
void setAssemblerOptions(const std::vector<std::string>& opts) {
|
||||||
|
AssemblerOptions = opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set Linker specific options
|
||||||
|
void setLinkerOptions(const std::vector<std::string>& opts) {
|
||||||
|
LinkerOptions = opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Set Library Paths
|
||||||
|
void setLibraryPaths(const std::vector<std::string>& paths) {
|
||||||
|
LibraryPaths = paths;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Set the list of library paths to be searched for
|
/// @brief Set the list of library paths to be searched for
|
||||||
/// libraries.
|
/// libraries.
|
||||||
void addLibraryPath( const std::string& libPath ) {
|
void addLibraryPath( const std::string& libPath ) {
|
||||||
libPaths.push_back(libPath);
|
LibraryPaths.push_back(libPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
@@ -176,7 +219,12 @@ namespace llvm {
|
|||||||
bool emitRawCode; ///< Emit Raw (unoptimized) code?
|
bool emitRawCode; ///< Emit Raw (unoptimized) code?
|
||||||
bool emitNativeCode; ///< Emit native code instead of bytecode?
|
bool emitNativeCode; ///< Emit native code instead of bytecode?
|
||||||
std::string machine; ///< Target machine name
|
std::string machine; ///< Target machine name
|
||||||
std::vector<std::string> libPaths; ///< list of dirs to find libraries
|
std::vector<std::string> LibraryPaths;
|
||||||
|
std::vector<std::string> PreprocessorOptions;
|
||||||
|
std::vector<std::string> TranslatorOptions;
|
||||||
|
std::vector<std::string> OptimizerOptions;
|
||||||
|
std::vector<std::string> AssemblerOptions;
|
||||||
|
std::vector<std::string> LinkerOptions;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
@@ -21,16 +21,15 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
extern int ::Configlex();
|
extern int ::Configlineno;
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
ConfigLexerInfo ConfigLexerData;
|
ConfigLexerInfo ConfigLexerData;
|
||||||
InputProvider* ConfigLexerInput = 0;
|
InputProvider* ConfigLexerInput = 0;
|
||||||
unsigned ConfigLexerLine = 1;
|
|
||||||
|
|
||||||
InputProvider::~InputProvider() {}
|
InputProvider::~InputProvider() {}
|
||||||
void InputProvider::error(const std::string& msg) {
|
void InputProvider::error(const std::string& msg) {
|
||||||
std::cerr << name << ":" << ConfigLexerLine << ": Error: " << msg << "\n";
|
std::cerr << name << ":" << Configlineno << ": Error: " << msg << "\n";
|
||||||
errCount++;
|
errCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,9 +65,9 @@ namespace {
|
|||||||
std::ifstream F;
|
std::ifstream F;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParseContext
|
struct Parser
|
||||||
{
|
{
|
||||||
int token;
|
ConfigLexerTokens token;
|
||||||
InputProvider* provider;
|
InputProvider* provider;
|
||||||
CompilerDriver::ConfigData* confDat;
|
CompilerDriver::ConfigData* confDat;
|
||||||
CompilerDriver::Action* action;
|
CompilerDriver::Action* action;
|
||||||
@@ -131,38 +130,47 @@ namespace {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseLang() {
|
void parseOptionList(CompilerDriver::StringVector& optList ) {
|
||||||
if ( next() == NAME ) {
|
while (next_is_real()) {
|
||||||
confDat->langName = parseName();
|
if (token == STRING || token == OPTION)
|
||||||
} else if (token == TRANSLATOR) {
|
optList.push_back(ConfigLexerData.StringVal);
|
||||||
switch (next()) {
|
else {
|
||||||
case PREPROCESSES:
|
error("Expecting a program option", false);
|
||||||
confDat->TranslatorPreprocesses = parseBoolean();
|
break;
|
||||||
break;
|
|
||||||
case OPTIMIZES:
|
|
||||||
confDat->TranslatorOptimizes = parseBoolean();
|
|
||||||
break;
|
|
||||||
case GROKS_DASH_O:
|
|
||||||
confDat->TranslatorGroksDashO = parseBoolean();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error("Invalid lang.translator identifier");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (token == PREPROCESSOR) {
|
}
|
||||||
if (next() == NEEDED)
|
|
||||||
confDat->PreprocessorNeeded = parseBoolean();
|
void parseLang() {
|
||||||
}
|
switch (next() ) {
|
||||||
else {
|
case NAME:
|
||||||
error("Expecting valid identifier after 'lang.'");
|
confDat->langName = parseName();
|
||||||
|
break;
|
||||||
|
case OPT1:
|
||||||
|
parseOptionList(confDat->opts[CompilerDriver::OPT_FAST_COMPILE]);
|
||||||
|
break;
|
||||||
|
case OPT2:
|
||||||
|
parseOptionList(confDat->opts[CompilerDriver::OPT_SIMPLE]);
|
||||||
|
break;
|
||||||
|
case OPT3:
|
||||||
|
parseOptionList(confDat->opts[CompilerDriver::OPT_AGGRESSIVE]);
|
||||||
|
break;
|
||||||
|
case OPT4:
|
||||||
|
parseOptionList(confDat->opts[CompilerDriver::OPT_LINK_TIME]);
|
||||||
|
break;
|
||||||
|
case OPT5:
|
||||||
|
parseOptionList(
|
||||||
|
confDat->opts[CompilerDriver::OPT_AGGRESSIVE_LINK_TIME]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'name' or 'optN' after 'lang.'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseCommand(CompilerDriver::Action& action) {
|
void parseCommand(CompilerDriver::Action& action) {
|
||||||
if (next() == EQUALS) {
|
if (next() == EQUALS) {
|
||||||
next();
|
if (next() == EOLTOK) {
|
||||||
if (token == EOLTOK) {
|
|
||||||
// no value (valid)
|
// no value (valid)
|
||||||
action.program.clear();
|
action.program.clear();
|
||||||
action.args.clear();
|
action.args.clear();
|
||||||
@@ -175,79 +183,161 @@ namespace {
|
|||||||
error("Expecting a program name");
|
error("Expecting a program name");
|
||||||
}
|
}
|
||||||
while (next_is_real()) {
|
while (next_is_real()) {
|
||||||
if (token == STRING || token == OPTION)
|
if (token == STRING || token == OPTION) {
|
||||||
action.args.push_back(ConfigLexerData.StringVal);
|
action.args.push_back(ConfigLexerData.StringVal);
|
||||||
else if (token == IN_SUBST) {
|
} else if (token == IN_SUBST) {
|
||||||
action.inputAt = action.args.size();
|
action.inputAt = action.args.size();
|
||||||
action.args.push_back("in");
|
action.args.push_back("@in@");
|
||||||
} else if (token == OUT_SUBST) {
|
} else if (token == OUT_SUBST) {
|
||||||
action.outputAt = action.args.size();
|
action.outputAt = action.args.size();
|
||||||
action.args.push_back("out");
|
action.args.push_back("@out@");
|
||||||
} else
|
} else {
|
||||||
error("Expecting a program argument", false);
|
error("Expecting a program argument", false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parsePreProcessor() {
|
void parsePreprocessor() {
|
||||||
if (next() != COMMAND) {
|
switch (next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->PreProcessor);
|
||||||
|
break;
|
||||||
|
case REQUIRED:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->PreProcessor.set(CompilerDriver::REQUIRED_FLAG);
|
||||||
|
else
|
||||||
|
confDat->PreProcessor.clear(CompilerDriver::REQUIRED_FLAG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command' or 'required'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->PreProcessor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseTranslator() {
|
void parseTranslator() {
|
||||||
if (next() != COMMAND) {
|
switch (next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->Translator);
|
||||||
|
break;
|
||||||
|
case REQUIRED:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::REQUIRED_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::REQUIRED_FLAG);
|
||||||
|
break;
|
||||||
|
case PREPROCESSES:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::PREPROCESSES_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::PREPROCESSES_FLAG);
|
||||||
|
break;
|
||||||
|
case OPTIMIZES:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::OPTIMIZES_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::OPTIMIZES_FLAG);
|
||||||
|
break;
|
||||||
|
case GROKS_DASH_O:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
break;
|
||||||
|
case GROKS_O10N:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command', 'required', 'preprocesses', "
|
||||||
|
"'groks_dash_O' or 'optimizes'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->Translator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseOptimizer() {
|
void parseOptimizer() {
|
||||||
if (next() != COMMAND) {
|
switch (next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->Optimizer);
|
||||||
|
break;
|
||||||
|
case GROKS_DASH_O:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Optimizer.set(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Optimizer.clear(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
break;
|
||||||
|
case GROKS_O10N:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Optimizer.set(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Optimizer.clear(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command' or 'groks_dash_O'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->Optimizer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseAssembler() {
|
void parseAssembler() {
|
||||||
if (next() != COMMAND) {
|
switch(next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->Assembler);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->Assembler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseLinker() {
|
void parseLinker() {
|
||||||
if (next() != COMMAND) {
|
switch(next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->Linker);
|
||||||
|
break;
|
||||||
|
case GROKS_DASH_O:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Linker.set(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Linker.clear(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
break;
|
||||||
|
case GROKS_O10N:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Linker.set(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Linker.clear(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->Linker);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseAssignment() {
|
void parseAssignment() {
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case LANG: return parseLang();
|
case LANG: parseLang(); break;
|
||||||
case PREPROCESSOR: return parsePreProcessor();
|
case PREPROCESSOR: parsePreprocessor(); break;
|
||||||
case TRANSLATOR: return parseTranslator();
|
case TRANSLATOR: parseTranslator(); break;
|
||||||
case OPTIMIZER: return parseOptimizer();
|
case OPTIMIZER: parseOptimizer(); break;
|
||||||
case ASSEMBLER: return parseAssembler();
|
case ASSEMBLER: parseAssembler(); break;
|
||||||
case LINKER: return parseLinker();
|
case LINKER: parseLinker(); break;
|
||||||
case EOLTOK: break; // just ignore
|
case EOLTOK: break; // just ignore
|
||||||
case ERRORTOK:
|
case ERRORTOK:
|
||||||
default:
|
default:
|
||||||
error("Invalid top level configuration item identifier");
|
error("Invalid top level configuration item");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseFile() {
|
void parseFile() {
|
||||||
while ( next() != 0 ) {
|
while ( next() != EOFTOK ) {
|
||||||
parseAssignment();
|
if (token == ERRORTOK)
|
||||||
|
error("Invalid token");
|
||||||
|
else if (token != EOLTOK)
|
||||||
|
parseAssignment();
|
||||||
}
|
}
|
||||||
provider->checkErrors();
|
provider->checkErrors();
|
||||||
}
|
}
|
||||||
@@ -255,12 +345,12 @@ namespace {
|
|||||||
|
|
||||||
void
|
void
|
||||||
ParseConfigData(InputProvider& provider, CompilerDriver::ConfigData& confDat) {
|
ParseConfigData(InputProvider& provider, CompilerDriver::ConfigData& confDat) {
|
||||||
ParseContext ctxt;
|
Parser p;
|
||||||
ctxt.token = 0;
|
p.token = EOFTOK;
|
||||||
ctxt.provider = &provider;
|
p.provider = &provider;
|
||||||
ctxt.confDat = &confDat;
|
p.confDat = &confDat;
|
||||||
ctxt.action = 0;
|
p.action = 0;
|
||||||
ctxt.parseFile();
|
p.parseFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,7 +25,6 @@ struct ConfigLexerInfo
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern ConfigLexerInfo ConfigLexerData;
|
extern ConfigLexerInfo ConfigLexerData;
|
||||||
extern unsigned ConfigLexerLine;
|
|
||||||
|
|
||||||
class InputProvider {
|
class InputProvider {
|
||||||
public:
|
public:
|
||||||
@@ -65,13 +64,21 @@ enum ConfigLexerTokens {
|
|||||||
ASSEMBLER, ///< The item "assembler" (and case variants)
|
ASSEMBLER, ///< The item "assembler" (and case variants)
|
||||||
LINKER, ///< The item "linker" (and case variants)
|
LINKER, ///< The item "linker" (and case variants)
|
||||||
NAME, ///< The item "name" (and case variants)
|
NAME, ///< The item "name" (and case variants)
|
||||||
NEEDED, ///< The item "needed" (and case variants)
|
REQUIRED, ///< The item "required" (and case variants)
|
||||||
COMMAND, ///< The item "command" (and case variants)
|
COMMAND, ///< The item "command" (and case variants)
|
||||||
PREPROCESSES, ///< The item "preprocesses" (and case variants)
|
PREPROCESSES, ///< The item "preprocesses" (and case variants)
|
||||||
GROKS_DASH_O, ///< The item "groks_dash_O" (and case variants)
|
GROKS_DASH_O, ///< The item "groks_dash_O" (and case variants)
|
||||||
|
GROKS_O10N, ///< The item "groks_optimization" (and case variants)
|
||||||
OPTIMIZES, ///< The item "optimizes" (and case variants)
|
OPTIMIZES, ///< The item "optimizes" (and case variants)
|
||||||
|
OPT1, ///< The item "opt1" (and case variants)
|
||||||
|
OPT2, ///< The item "opt2" (and case variants)
|
||||||
|
OPT3, ///< The item "opt3" (and case variants)
|
||||||
|
OPT4, ///< The item "opt4" (and case variants)
|
||||||
|
OPT5, ///< The item "opt5" (and case variants)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern ConfigLexerTokens Configlex();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -38,6 +38,10 @@
|
|||||||
if (result == 0 ) result = YY_NULL; \
|
if (result == 0 ) result = YY_NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define YY_DECL ConfigLexerTokens llvm::Configlex()
|
||||||
|
|
||||||
|
#define yyterminate() { return EOFTOK; }
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
/* Conversion of text ints to binary */
|
/* Conversion of text ints to binary */
|
||||||
@@ -62,11 +66,17 @@ OPTIMIZER optimizer|Optimizer|OPTIMIZER
|
|||||||
ASSEMBLER assembler|Assembler|ASSEMBLER
|
ASSEMBLER assembler|Assembler|ASSEMBLER
|
||||||
LINKER linker|Linker|LINKER
|
LINKER linker|Linker|LINKER
|
||||||
NAME name|Name|NAME
|
NAME name|Name|NAME
|
||||||
NEEDED needed|Needed|NEEDED
|
REQUIRED required|Required|REQUIRED
|
||||||
COMMAND command|Command|COMMAND
|
COMMAND command|Command|COMMAND
|
||||||
PREPROCESSES preprocesses|PreProcesses|PREPROCESSES
|
PREPROCESSES preprocesses|PreProcesses|PREPROCESSES
|
||||||
GROKS_DASH_O groks_dash_O|Groks_Dash_O|GROKS_DASH_O
|
GROKS_DASH_O groks_dash_O|Groks_Dash_O|GROKS_DASH_O
|
||||||
|
GROKS_O10N groks_optimization|Groks_Optimization|GROKS_OPTIMIZATION
|
||||||
OPTIMIZES optimizes|Optimizes|OPTIMIZES
|
OPTIMIZES optimizes|Optimizes|OPTIMIZES
|
||||||
|
OPT1 opt1|Opt1|OPT1
|
||||||
|
OPT2 opt2|Opt2|OPT2
|
||||||
|
OPT3 opt3|Opt3|OPT3
|
||||||
|
OPT4 opt4|Opt4|OPT4
|
||||||
|
OPT5 opt5|Opt5|OPT5
|
||||||
Comment \#[^\n]*
|
Comment \#[^\n]*
|
||||||
NewLine \n
|
NewLine \n
|
||||||
White [ \t]*
|
White [ \t]*
|
||||||
@@ -84,7 +94,8 @@ No no|No|NO
|
|||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
{NewLine} { in_value = false; ConfigLexerLine++; return EOLTOK; }
|
{NewLine} { in_value = false; return EOLTOK; }
|
||||||
|
{Eq} { in_value = true; return EQUALS; }
|
||||||
{Comment} { /* Ignore comments */ }
|
{Comment} { /* Ignore comments */ }
|
||||||
{White} { /* Ignore whitespace */ }
|
{White} { /* Ignore whitespace */ }
|
||||||
|
|
||||||
@@ -102,19 +113,29 @@ No no|No|NO
|
|||||||
return OPTION; } else return LINKER; }
|
return OPTION; } else return LINKER; }
|
||||||
{NAME} { if (in_value) { ConfigLexerData.StringVal = "name";
|
{NAME} { if (in_value) { ConfigLexerData.StringVal = "name";
|
||||||
return OPTION; } else return NAME; }
|
return OPTION; } else return NAME; }
|
||||||
{NEEDED} { if (in_value) { ConfigLexerData.StringVal = "needed";
|
{REQUIRED} { if (in_value) { ConfigLexerData.StringVal = "required";
|
||||||
return OPTION; } else return NEEDED; }
|
return OPTION; } else return REQUIRED; }
|
||||||
{COMMAND} { if (in_value) { ConfigLexerData.StringVal = "command";
|
{COMMAND} { if (in_value) { ConfigLexerData.StringVal = "command";
|
||||||
return OPTION; } else return COMMAND; }
|
return OPTION; } else return COMMAND; }
|
||||||
{PREPROCESSES} { if (in_value) { ConfigLexerData.StringVal = "preprocesses";
|
{PREPROCESSES} { if (in_value) { ConfigLexerData.StringVal = "preprocesses";
|
||||||
return OPTION; } else return PREPROCESSES; }
|
return OPTION; } else return PREPROCESSES; }
|
||||||
{GROKS_DASH_O} { if (in_value) { ConfigLexerData.StringVal = "groks_dash_O";
|
{GROKS_DASH_O} { if (in_value) { ConfigLexerData.StringVal = "groks_dash_O";
|
||||||
return OPTION; } else return GROKS_DASH_O; }
|
return OPTION; } else return GROKS_DASH_O; }
|
||||||
|
{GROKS_O10N} { if (in_value) { ConfigLexerData.StringVal =
|
||||||
|
"groks_optimization"; return OPTION; }
|
||||||
|
else return GROKS_O10N; }
|
||||||
{OPTIMIZES} { if (in_value) { ConfigLexerData.StringVal = "optimizes";
|
{OPTIMIZES} { if (in_value) { ConfigLexerData.StringVal = "optimizes";
|
||||||
return OPTION; } else return OPTIMIZES; }
|
return OPTION; } else return OPTIMIZES; }
|
||||||
{Sep} { if (in_value) { ConfigLexerData.StringVal = yytext;
|
{OPT1} { if (in_value) { ConfigLexerData.StringVal = "opt1";
|
||||||
return OPTION; } }
|
return OPTION; } else return OPT1; }
|
||||||
|
{OPT2} { if (in_value) { ConfigLexerData.StringVal = "opt2";
|
||||||
|
return OPTION; } else return OPT2; }
|
||||||
|
{OPT3} { if (in_value) { ConfigLexerData.StringVal = "opt3";
|
||||||
|
return OPTION; } else return OPT3; }
|
||||||
|
{OPT4} { if (in_value) { ConfigLexerData.StringVal = "opt4";
|
||||||
|
return OPTION; } else return OPT4; }
|
||||||
|
{OPT5} { if (in_value) { ConfigLexerData.StringVal = "opt5";
|
||||||
|
return OPTION; } else return OPT5; }
|
||||||
@in@ { if (in_value) return IN_SUBST; else return ERRORTOK; }
|
@in@ { if (in_value) return IN_SUBST; else return ERRORTOK; }
|
||||||
@out@ { if (in_value) return OUT_SUBST; else return ERRORTOK; }
|
@out@ { if (in_value) return OUT_SUBST; else return ERRORTOK; }
|
||||||
{True} { if (in_value) return TRUETOK; else return ERRORTOK; }
|
{True} { if (in_value) return TRUETOK; else return ERRORTOK; }
|
||||||
@@ -124,12 +145,14 @@ No no|No|NO
|
|||||||
{Off} { if (in_value) return FALSETOK; else return ERRORTOK; }
|
{Off} { if (in_value) return FALSETOK; else return ERRORTOK; }
|
||||||
{No} { if (in_value) return FALSETOK; else return ERRORTOK; }
|
{No} { if (in_value) return FALSETOK; else return ERRORTOK; }
|
||||||
|
|
||||||
{Eq} { in_value = true; return EQUALS; }
|
|
||||||
{Option} { ConfigLexerData.StringVal = yytext; return OPTION; }
|
{Option} { ConfigLexerData.StringVal = yytext; return OPTION; }
|
||||||
{Integer} { ConfigLexerData.IntegerVal = IntToVal(yytext); return INTEGER; }
|
{Integer} { ConfigLexerData.IntegerVal = IntToVal(yytext); return INTEGER; }
|
||||||
{String} { yytext[yyleng-1] = 0; // nuke end quote
|
{String} { yytext[yyleng-1] = 0; // nuke end quote
|
||||||
ConfigLexerData.StringVal = yytext+1; // Nuke start quote
|
ConfigLexerData.StringVal = yytext+1; // Nuke start quote
|
||||||
return STRING;
|
return STRING;
|
||||||
}
|
}
|
||||||
|
{Sep} { if (in_value) { ConfigLexerData.StringVal = yytext;
|
||||||
|
return OPTION; } }
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@@ -21,16 +21,15 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
extern int ::Configlex();
|
extern int ::Configlineno;
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
ConfigLexerInfo ConfigLexerData;
|
ConfigLexerInfo ConfigLexerData;
|
||||||
InputProvider* ConfigLexerInput = 0;
|
InputProvider* ConfigLexerInput = 0;
|
||||||
unsigned ConfigLexerLine = 1;
|
|
||||||
|
|
||||||
InputProvider::~InputProvider() {}
|
InputProvider::~InputProvider() {}
|
||||||
void InputProvider::error(const std::string& msg) {
|
void InputProvider::error(const std::string& msg) {
|
||||||
std::cerr << name << ":" << ConfigLexerLine << ": Error: " << msg << "\n";
|
std::cerr << name << ":" << Configlineno << ": Error: " << msg << "\n";
|
||||||
errCount++;
|
errCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,9 +65,9 @@ namespace {
|
|||||||
std::ifstream F;
|
std::ifstream F;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParseContext
|
struct Parser
|
||||||
{
|
{
|
||||||
int token;
|
ConfigLexerTokens token;
|
||||||
InputProvider* provider;
|
InputProvider* provider;
|
||||||
CompilerDriver::ConfigData* confDat;
|
CompilerDriver::ConfigData* confDat;
|
||||||
CompilerDriver::Action* action;
|
CompilerDriver::Action* action;
|
||||||
@@ -131,38 +130,47 @@ namespace {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseLang() {
|
void parseOptionList(CompilerDriver::StringVector& optList ) {
|
||||||
if ( next() == NAME ) {
|
while (next_is_real()) {
|
||||||
confDat->langName = parseName();
|
if (token == STRING || token == OPTION)
|
||||||
} else if (token == TRANSLATOR) {
|
optList.push_back(ConfigLexerData.StringVal);
|
||||||
switch (next()) {
|
else {
|
||||||
case PREPROCESSES:
|
error("Expecting a program option", false);
|
||||||
confDat->TranslatorPreprocesses = parseBoolean();
|
break;
|
||||||
break;
|
|
||||||
case OPTIMIZES:
|
|
||||||
confDat->TranslatorOptimizes = parseBoolean();
|
|
||||||
break;
|
|
||||||
case GROKS_DASH_O:
|
|
||||||
confDat->TranslatorGroksDashO = parseBoolean();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error("Invalid lang.translator identifier");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (token == PREPROCESSOR) {
|
}
|
||||||
if (next() == NEEDED)
|
|
||||||
confDat->PreprocessorNeeded = parseBoolean();
|
void parseLang() {
|
||||||
}
|
switch (next() ) {
|
||||||
else {
|
case NAME:
|
||||||
error("Expecting valid identifier after 'lang.'");
|
confDat->langName = parseName();
|
||||||
|
break;
|
||||||
|
case OPT1:
|
||||||
|
parseOptionList(confDat->opts[CompilerDriver::OPT_FAST_COMPILE]);
|
||||||
|
break;
|
||||||
|
case OPT2:
|
||||||
|
parseOptionList(confDat->opts[CompilerDriver::OPT_SIMPLE]);
|
||||||
|
break;
|
||||||
|
case OPT3:
|
||||||
|
parseOptionList(confDat->opts[CompilerDriver::OPT_AGGRESSIVE]);
|
||||||
|
break;
|
||||||
|
case OPT4:
|
||||||
|
parseOptionList(confDat->opts[CompilerDriver::OPT_LINK_TIME]);
|
||||||
|
break;
|
||||||
|
case OPT5:
|
||||||
|
parseOptionList(
|
||||||
|
confDat->opts[CompilerDriver::OPT_AGGRESSIVE_LINK_TIME]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'name' or 'optN' after 'lang.'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseCommand(CompilerDriver::Action& action) {
|
void parseCommand(CompilerDriver::Action& action) {
|
||||||
if (next() == EQUALS) {
|
if (next() == EQUALS) {
|
||||||
next();
|
if (next() == EOLTOK) {
|
||||||
if (token == EOLTOK) {
|
|
||||||
// no value (valid)
|
// no value (valid)
|
||||||
action.program.clear();
|
action.program.clear();
|
||||||
action.args.clear();
|
action.args.clear();
|
||||||
@@ -175,79 +183,161 @@ namespace {
|
|||||||
error("Expecting a program name");
|
error("Expecting a program name");
|
||||||
}
|
}
|
||||||
while (next_is_real()) {
|
while (next_is_real()) {
|
||||||
if (token == STRING || token == OPTION)
|
if (token == STRING || token == OPTION) {
|
||||||
action.args.push_back(ConfigLexerData.StringVal);
|
action.args.push_back(ConfigLexerData.StringVal);
|
||||||
else if (token == IN_SUBST) {
|
} else if (token == IN_SUBST) {
|
||||||
action.inputAt = action.args.size();
|
action.inputAt = action.args.size();
|
||||||
action.args.push_back("in");
|
action.args.push_back("@in@");
|
||||||
} else if (token == OUT_SUBST) {
|
} else if (token == OUT_SUBST) {
|
||||||
action.outputAt = action.args.size();
|
action.outputAt = action.args.size();
|
||||||
action.args.push_back("out");
|
action.args.push_back("@out@");
|
||||||
} else
|
} else {
|
||||||
error("Expecting a program argument", false);
|
error("Expecting a program argument", false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parsePreProcessor() {
|
void parsePreprocessor() {
|
||||||
if (next() != COMMAND) {
|
switch (next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->PreProcessor);
|
||||||
|
break;
|
||||||
|
case REQUIRED:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->PreProcessor.set(CompilerDriver::REQUIRED_FLAG);
|
||||||
|
else
|
||||||
|
confDat->PreProcessor.clear(CompilerDriver::REQUIRED_FLAG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command' or 'required'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->PreProcessor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseTranslator() {
|
void parseTranslator() {
|
||||||
if (next() != COMMAND) {
|
switch (next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->Translator);
|
||||||
|
break;
|
||||||
|
case REQUIRED:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::REQUIRED_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::REQUIRED_FLAG);
|
||||||
|
break;
|
||||||
|
case PREPROCESSES:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::PREPROCESSES_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::PREPROCESSES_FLAG);
|
||||||
|
break;
|
||||||
|
case OPTIMIZES:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::OPTIMIZES_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::OPTIMIZES_FLAG);
|
||||||
|
break;
|
||||||
|
case GROKS_DASH_O:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
break;
|
||||||
|
case GROKS_O10N:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Translator.set(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Translator.clear(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command', 'required', 'preprocesses', "
|
||||||
|
"'groks_dash_O' or 'optimizes'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->Translator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseOptimizer() {
|
void parseOptimizer() {
|
||||||
if (next() != COMMAND) {
|
switch (next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->Optimizer);
|
||||||
|
break;
|
||||||
|
case GROKS_DASH_O:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Optimizer.set(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Optimizer.clear(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
break;
|
||||||
|
case GROKS_O10N:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Optimizer.set(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Optimizer.clear(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command' or 'groks_dash_O'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->Optimizer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseAssembler() {
|
void parseAssembler() {
|
||||||
if (next() != COMMAND) {
|
switch(next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->Assembler);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->Assembler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseLinker() {
|
void parseLinker() {
|
||||||
if (next() != COMMAND) {
|
switch(next()) {
|
||||||
error("Expecting 'command'");
|
case COMMAND:
|
||||||
return;
|
parseCommand(confDat->Linker);
|
||||||
|
break;
|
||||||
|
case GROKS_DASH_O:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Linker.set(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Linker.clear(CompilerDriver::GROKS_DASH_O_FLAG);
|
||||||
|
break;
|
||||||
|
case GROKS_O10N:
|
||||||
|
if (parseBoolean())
|
||||||
|
confDat->Linker.set(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
else
|
||||||
|
confDat->Linker.clear(CompilerDriver::GROKS_O10N_FLAG);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Expecting 'command'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
parseCommand(confDat->Linker);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseAssignment() {
|
void parseAssignment() {
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case LANG: return parseLang();
|
case LANG: parseLang(); break;
|
||||||
case PREPROCESSOR: return parsePreProcessor();
|
case PREPROCESSOR: parsePreprocessor(); break;
|
||||||
case TRANSLATOR: return parseTranslator();
|
case TRANSLATOR: parseTranslator(); break;
|
||||||
case OPTIMIZER: return parseOptimizer();
|
case OPTIMIZER: parseOptimizer(); break;
|
||||||
case ASSEMBLER: return parseAssembler();
|
case ASSEMBLER: parseAssembler(); break;
|
||||||
case LINKER: return parseLinker();
|
case LINKER: parseLinker(); break;
|
||||||
case EOLTOK: break; // just ignore
|
case EOLTOK: break; // just ignore
|
||||||
case ERRORTOK:
|
case ERRORTOK:
|
||||||
default:
|
default:
|
||||||
error("Invalid top level configuration item identifier");
|
error("Invalid top level configuration item");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseFile() {
|
void parseFile() {
|
||||||
while ( next() != 0 ) {
|
while ( next() != EOFTOK ) {
|
||||||
parseAssignment();
|
if (token == ERRORTOK)
|
||||||
|
error("Invalid token");
|
||||||
|
else if (token != EOLTOK)
|
||||||
|
parseAssignment();
|
||||||
}
|
}
|
||||||
provider->checkErrors();
|
provider->checkErrors();
|
||||||
}
|
}
|
||||||
@@ -255,12 +345,12 @@ namespace {
|
|||||||
|
|
||||||
void
|
void
|
||||||
ParseConfigData(InputProvider& provider, CompilerDriver::ConfigData& confDat) {
|
ParseConfigData(InputProvider& provider, CompilerDriver::ConfigData& confDat) {
|
||||||
ParseContext ctxt;
|
Parser p;
|
||||||
ctxt.token = 0;
|
p.token = EOFTOK;
|
||||||
ctxt.provider = &provider;
|
p.provider = &provider;
|
||||||
ctxt.confDat = &confDat;
|
p.confDat = &confDat;
|
||||||
ctxt.action = 0;
|
p.action = 0;
|
||||||
ctxt.parseFile();
|
p.parseFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,6 @@
|
|||||||
##===----------------------------------------------------------------------===##
|
##===----------------------------------------------------------------------===##
|
||||||
LEVEL = ../..
|
LEVEL = ../..
|
||||||
TOOLNAME = llvmc
|
TOOLNAME = llvmc
|
||||||
USEDLIBS = asmparser bcreader bcwriter vmcore support.a
|
USEDLIBS = asmparser bcreader bcwriter vmcore support.a system.a
|
||||||
|
|
||||||
include $(LEVEL)/Makefile.common
|
include $(LEVEL)/Makefile.common
|
||||||
|
@@ -69,19 +69,23 @@ static cl::opt<CompilerDriver::OptimizationLevels> OptLevel(
|
|||||||
//=== TOOL OPTIONS
|
//=== TOOL OPTIONS
|
||||||
//===------------------------------------------------------------------------===
|
//===------------------------------------------------------------------------===
|
||||||
|
|
||||||
static cl::opt<std::string> PPToolOpts("Tpp", cl::ZeroOrMore,
|
static cl::list<std::string> PreprocessorToolOpts("Tpre", cl::ZeroOrMore,
|
||||||
cl::desc("Pass specific options to the pre-processor"),
|
cl::desc("Pass specific options to the pre-processor"),
|
||||||
cl::value_desc("option"));
|
cl::value_desc("option"));
|
||||||
|
|
||||||
static cl::opt<std::string> AsmToolOpts("Tasm", cl::ZeroOrMore,
|
static cl::list<std::string> TranslatorToolOpts("Ttrn", cl::ZeroOrMore,
|
||||||
cl::desc("Pass specific options to the assembler"),
|
cl::desc("Pass specific options to the assembler"),
|
||||||
cl::value_desc("option"));
|
cl::value_desc("option"));
|
||||||
|
|
||||||
static cl::opt<std::string> OptToolOpts("Topt", cl::ZeroOrMore,
|
static cl::list<std::string> AssemblerToolOpts("Tasm", cl::ZeroOrMore,
|
||||||
|
cl::desc("Pass specific options to the assembler"),
|
||||||
|
cl::value_desc("option"));
|
||||||
|
|
||||||
|
static cl::list<std::string> OptimizerToolOpts("Topt", cl::ZeroOrMore,
|
||||||
cl::desc("Pass specific options to the optimizer"),
|
cl::desc("Pass specific options to the optimizer"),
|
||||||
cl::value_desc("option"));
|
cl::value_desc("option"));
|
||||||
|
|
||||||
static cl::opt<std::string> LinkToolOpts("Tlink", cl::ZeroOrMore,
|
static cl::list<std::string> LinkerToolOpts("Tlnk", cl::ZeroOrMore,
|
||||||
cl::desc("Pass specific options to the linker"),
|
cl::desc("Pass specific options to the linker"),
|
||||||
cl::value_desc("option"));
|
cl::value_desc("option"));
|
||||||
|
|
||||||
@@ -142,9 +146,12 @@ static cl::opt<std::string> ConfigDir("config-dir", cl::Optional,
|
|||||||
cl::desc("Specify a configuration directory to override defaults"),
|
cl::desc("Specify a configuration directory to override defaults"),
|
||||||
cl::value_desc("directory"));
|
cl::value_desc("directory"));
|
||||||
|
|
||||||
static cl::opt<bool> EmitRawCode("emit-raw-code", cl::Hidden,
|
static cl::opt<bool> EmitRawCode("emit-raw-code", cl::Hidden, cl::Optional,
|
||||||
cl::desc("Emit raw, unoptimized code"));
|
cl::desc("Emit raw, unoptimized code"));
|
||||||
|
|
||||||
|
static cl::opt<bool> PipeCommands("pipe", cl::Optional,
|
||||||
|
cl::desc("Invoke sub-commands by linking input/output with pipes"));
|
||||||
|
|
||||||
//===------------------------------------------------------------------------===
|
//===------------------------------------------------------------------------===
|
||||||
//=== POSITIONAL OPTIONS
|
//=== POSITIONAL OPTIONS
|
||||||
//===------------------------------------------------------------------------===
|
//===------------------------------------------------------------------------===
|
||||||
@@ -200,6 +207,8 @@ int main(int argc, char **argv) {
|
|||||||
std::cerr << argv[0] << ": Not implemented yet: -native";
|
std::cerr << argv[0] << ": Not implemented yet: -native";
|
||||||
if (EmitRawCode)
|
if (EmitRawCode)
|
||||||
std::cerr << argv[0] << ": Not implemented yet: -emit-raw-code";
|
std::cerr << argv[0] << ": Not implemented yet: -emit-raw-code";
|
||||||
|
if (PipeCommands)
|
||||||
|
std::cerr << argv[0] << ": Not implemented yet: -pipe";
|
||||||
|
|
||||||
// Default the output file, only if we're going to try to link
|
// Default the output file, only if we're going to try to link
|
||||||
if (OutputFilename.empty() && OptLevel == CompilerDriver::LINKING)
|
if (OutputFilename.empty() && OptLevel == CompilerDriver::LINKING)
|
||||||
@@ -221,10 +230,12 @@ int main(int argc, char **argv) {
|
|||||||
CD.setOutputMachine(OutputMachine);
|
CD.setOutputMachine(OutputMachine);
|
||||||
CD.setEmitNativeCode(Native);
|
CD.setEmitNativeCode(Native);
|
||||||
CD.setEmitRawCode(EmitRawCode);
|
CD.setEmitRawCode(EmitRawCode);
|
||||||
std::vector<std::string>::iterator pathIt = LibPaths.begin();
|
CD.setLibraryPaths(LibPaths);
|
||||||
while ( pathIt != LibPaths.end() ) {
|
CD.setPreprocessorOptions(PreprocessorToolOpts);
|
||||||
CD.addLibraryPath( *pathIt++ );
|
CD.setTranslatorOptions(TranslatorToolOpts);
|
||||||
}
|
CD.setOptimizerOptions(OptimizerToolOpts);
|
||||||
|
CD.setAssemblerOptions(AssemblerToolOpts);
|
||||||
|
CD.setLinkerOptions(LinkerToolOpts);
|
||||||
|
|
||||||
// Prepare the list of files to be compiled by the CompilerDriver.
|
// Prepare the list of files to be compiled by the CompilerDriver.
|
||||||
CompilerDriver::InputList InpList;
|
CompilerDriver::InputList InpList;
|
||||||
|
Reference in New Issue
Block a user