[llvm-commits] CVS: llvm/tools/llvmc/CompilerDriver.cpp CompilerDriver.h ConfigData.cpp ConfigLexer.h ConfigLexer.l Makefile llvmc.cpp
Reid Spencer
reid at x10sys.com
Sun Aug 15 01:19:58 PDT 2004
Changes in directory llvm/tools/llvmc:
CompilerDriver.cpp updated: 1.3 -> 1.4
CompilerDriver.h updated: 1.3 -> 1.4
ConfigData.cpp updated: 1.2 -> 1.3
ConfigLexer.h updated: 1.1 -> 1.2
ConfigLexer.l updated: 1.1 -> 1.2
Makefile updated: 1.1 -> 1.2
llvmc.cpp updated: 1.4 -> 1.5
---
Log message:
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
---
Diffs of the changes: (+458 -147)
Index: llvm/tools/llvmc/CompilerDriver.cpp
diff -u llvm/tools/llvmc/CompilerDriver.cpp:1.3 llvm/tools/llvmc/CompilerDriver.cpp:1.4
--- llvm/tools/llvmc/CompilerDriver.cpp:1.3 Sat Aug 14 04:37:15 2004
+++ llvm/tools/llvmc/CompilerDriver.cpp Sun Aug 15 03:19:46 2004
@@ -13,6 +13,7 @@
//===------------------------------------------------------------------------===
#include "CompilerDriver.h"
+#include "ConfigLexer.h"
#include <iostream>
using namespace llvm;
@@ -32,7 +33,7 @@
const char OutputSuffix[] = ".o";
- void WriteAction(CompilerDriver::Action* a) {
+ void WriteAction(CompilerDriver::Action* a ) {
std::cerr << a->program;
std::vector<std::string>::iterator I = a->args.begin();
while (I != a->args.end()) {
@@ -42,24 +43,32 @@
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 ){
std::cerr << "Configuration Data For '" << cd->langName << "' (" << type
<< ")\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: ";
- WriteAction(&cd->PreProcessor);
+ DumpAction(&cd->PreProcessor);
std::cerr << "Translator: ";
- WriteAction(&cd->Translator);
+ DumpAction(&cd->Translator);
std::cerr << "Optimizer: ";
- WriteAction(&cd->Optimizer);
+ DumpAction(&cd->Optimizer);
std::cerr << "Assembler: ";
- WriteAction(&cd->Assembler);
+ DumpAction(&cd->Assembler);
std::cerr << "Linker: ";
- WriteAction(&cd->Linker);
+ DumpAction(&cd->Linker);
}
}
@@ -75,16 +84,26 @@
, emitRawCode(false)
, emitNativeCode(false)
, machine()
- , libPaths()
+ , LibraryPaths()
+ , PreprocessorOptions()
+ , TranslatorOptions()
+ , OptimizerOptions()
+ , AssemblerOptions()
+ , LinkerOptions()
{
// FIXME: These libraries are platform specific
- libPaths.push_back("/lib");
- libPaths.push_back("/usr/lib");
+ LibraryPaths.push_back("/lib");
+ LibraryPaths.push_back("/usr/lib");
}
CompilerDriver::~CompilerDriver() {
cdp = 0;
- libPaths.clear();
+ LibraryPaths.clear();
+ PreprocessorOptions.clear();
+ TranslatorOptions.clear();
+ OptimizerOptions.clear();
+ AssemblerOptions.clear();
+ LinkerOptions.clear();
}
void CompilerDriver::error( const std::string& errmsg ) {
@@ -92,12 +111,27 @@
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,
const std::string& input,
const std::string& output,
Phases phase)
{
Action* pat = 0;
+ // Get the action pattern
switch (phase) {
case PREPROCESSING: pat = &cd->PreProcessor; break;
case TRANSLATION: pat = &cd->Translator; break;
@@ -109,11 +143,57 @@
break;
}
assert(pat != 0 && "Invalid command pattern");
+
+ // Create the resulting action
Action* a = new Action(*pat);
+
+ // Replace the substitution arguments
if (pat->inputAt < a->args.size())
a->args[pat->inputAt] = input;
if (pat->outputAt < a->args.size())
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;
}
@@ -122,18 +202,20 @@
if (isVerbose)
WriteAction(a);
if (!isDryRun) {
- std::cerr << "execve(\"" << a->program << "\",[\n";
+ std::cerr << "execve(\"" << a->program << "\",[\"";
std::vector<std::string>::iterator I = a->args.begin();
while (I != a->args.end()) {
- std::cerr << " \"" << *I << "\",\n";
+ std::cerr << *I;
++I;
+ if (I != a->args.end())
+ std::cerr << "\",\"";
}
- std::cerr << "],ENV);\n";
+ std::cerr << "\"],ENV);\n";
}
}
int CompilerDriver::execute(const InputList& InpList,
- const std::string& Output ) {
+ const sys::Path& Output ) {
// Echo the configuration of options if we're running verbose
if (isDebug)
{
@@ -162,8 +244,17 @@
if (finalPhase == LINKING && Output.empty())
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;
+ // 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
// for each input item
std::vector<std::string> LinkageItems;
@@ -207,28 +298,59 @@
OutFile = Output;
}
- /// PRE-PROCESSING PHASE
- if (finalPhase == PREPROCESSING) {
- 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));
+ // PRE-PROCESSING PHASE
+ Action& a = cd->PreProcessor;
+
+ // 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
if (finalPhase == PREPROCESSING) { ++I; continue; };
/// 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
if (finalPhase == TRANSLATION) { ++I; continue; }
/// 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
if (finalPhase == OPTIMIZATION) { ++I; continue; }
@@ -244,6 +366,16 @@
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;
}
Index: llvm/tools/llvmc/CompilerDriver.h
diff -u llvm/tools/llvmc/CompilerDriver.h:1.3 llvm/tools/llvmc/CompilerDriver.h:1.4
--- llvm/tools/llvmc/CompilerDriver.h:1.3 Sat Aug 14 04:37:15 2004
+++ llvm/tools/llvmc/CompilerDriver.h Sun Aug 15 03:19:46 2004
@@ -14,6 +14,7 @@
#ifndef LLVM_TOOLS_LLVMC_COMPILERDRIVER_H
#define LLVM_TOOLS_LLVMC_COMPILERDRIVER_H
+#include "llvm/System/Path.h"
#include <string>
#include <vector>
@@ -29,6 +30,10 @@
/// @name Types
/// @{
public:
+ /// @brief A vector of strings, commonly used
+ typedef std::vector<std::string> StringVector;
+
+ /// @brief The phases of processing that llvmc understands
enum Phases {
PREPROCESSING, ///< Source language combining, filtering, substitution
TRANSLATION, ///< Translate source -> LLVM bytecode/assembly
@@ -37,20 +42,31 @@
ASSEMBLY, ///< Convert program to executable
};
+ /// @brief The levels of optimization llvmc understands
enum OptimizationLevels {
- OPT_NONE, ///< Zippo optimizations, nada, nil, none.
OPT_FAST_COMPILE, ///< Optimize to make >compile< go faster
OPT_SIMPLE, ///< Standard/simple optimizations
OPT_AGGRESSIVE, ///< Aggressive 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
/// a vector of filename/filetype pairs. The filetype is used to look up
/// the configuration of the actions to be taken by the driver.
/// @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
/// the CompilerDriver through a "ConfigDataProvider". It serves as both
@@ -58,28 +74,25 @@
/// @brief A structure to hold the action data for a given source
/// language.
struct Action {
- Action() : inputAt(0) , outputAt(0) {}
- std::string program; ///< The program to execve
- std::vector<std::string> args; ///< Arguments to the program
- size_t inputAt; ///< Argument index to insert input file
- size_t outputAt; ///< Argument index to insert output file
+ Action() : inputAt(0) , outputAt(0), flags(0) {}
+ sys::Path program; ///< The program to execve
+ StringVector args; ///< Arguments to the program
+ size_t inputAt; ///< Argument index to insert input 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 {
- ConfigData() : TranslatorPreprocesses(false),
- TranslatorOptimizes(false),
- TranslatorGroksDashO(false),
- PreprocessorNeeded(false) {}
- std::string langName; ///< The name of the source language
- bool TranslatorPreprocesses;///< Translator program will pre-process
- bool TranslatorOptimizes; ///< Translator program will optimize too
- 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
+ std::string langName; ///< The name of the source language
+ std::vector<StringVector> opts; ///< The o10n options for each level
+ 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
@@ -109,7 +122,7 @@
virtual void error(const std::string& errmsg);
/// @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
@@ -148,10 +161,40 @@
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
/// libraries.
void addLibraryPath( const std::string& libPath ) {
- libPaths.push_back(libPath);
+ LibraryPaths.push_back(libPath);
}
/// @}
@@ -176,7 +219,12 @@
bool emitRawCode; ///< Emit Raw (unoptimized) code?
bool emitNativeCode; ///< Emit native code instead of bytecode?
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;
/// @}
Index: llvm/tools/llvmc/ConfigData.cpp
diff -u llvm/tools/llvmc/ConfigData.cpp:1.2 llvm/tools/llvmc/ConfigData.cpp:1.3
--- llvm/tools/llvmc/ConfigData.cpp:1.2 Sat Aug 14 04:37:15 2004
+++ llvm/tools/llvmc/ConfigData.cpp Sun Aug 15 03:19:46 2004
@@ -21,16 +21,15 @@
using namespace llvm;
-extern int ::Configlex();
+extern int ::Configlineno;
namespace llvm {
ConfigLexerInfo ConfigLexerData;
InputProvider* ConfigLexerInput = 0;
- unsigned ConfigLexerLine = 1;
InputProvider::~InputProvider() {}
void InputProvider::error(const std::string& msg) {
- std::cerr << name << ":" << ConfigLexerLine << ": Error: " << msg << "\n";
+ std::cerr << name << ":" << Configlineno << ": Error: " << msg << "\n";
errCount++;
}
@@ -66,9 +65,9 @@
std::ifstream F;
};
- struct ParseContext
+ struct Parser
{
- int token;
+ ConfigLexerTokens token;
InputProvider* provider;
CompilerDriver::ConfigData* confDat;
CompilerDriver::Action* action;
@@ -131,38 +130,47 @@
return result;
}
- void parseLang() {
- if ( next() == NAME ) {
- confDat->langName = parseName();
- } else if (token == TRANSLATOR) {
- switch (next()) {
- case PREPROCESSES:
- confDat->TranslatorPreprocesses = parseBoolean();
- break;
- case OPTIMIZES:
- confDat->TranslatorOptimizes = parseBoolean();
- break;
- case GROKS_DASH_O:
- confDat->TranslatorGroksDashO = parseBoolean();
- break;
- default:
- error("Invalid lang.translator identifier");
- break;
+ void parseOptionList(CompilerDriver::StringVector& optList ) {
+ while (next_is_real()) {
+ if (token == STRING || token == OPTION)
+ optList.push_back(ConfigLexerData.StringVal);
+ else {
+ error("Expecting a program option", false);
+ break;
}
}
- else if (token == PREPROCESSOR) {
- if (next() == NEEDED)
- confDat->PreprocessorNeeded = parseBoolean();
- }
- else {
- error("Expecting valid identifier after 'lang.'");
+ }
+
+ void parseLang() {
+ switch (next() ) {
+ case NAME:
+ 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) {
if (next() == EQUALS) {
- next();
- if (token == EOLTOK) {
+ if (next() == EOLTOK) {
// no value (valid)
action.program.clear();
action.args.clear();
@@ -175,79 +183,161 @@
error("Expecting a program name");
}
while (next_is_real()) {
- if (token == STRING || token == OPTION)
+ if (token == STRING || token == OPTION) {
action.args.push_back(ConfigLexerData.StringVal);
- else if (token == IN_SUBST) {
+ } else if (token == IN_SUBST) {
action.inputAt = action.args.size();
- action.args.push_back("in");
+ action.args.push_back("@in@");
} else if (token == OUT_SUBST) {
action.outputAt = action.args.size();
- action.args.push_back("out");
- } else
+ action.args.push_back("@out@");
+ } else {
error("Expecting a program argument", false);
+ break;
+ }
}
}
}
}
- void parsePreProcessor() {
- if (next() != COMMAND) {
- error("Expecting 'command'");
- return;
+ void parsePreprocessor() {
+ switch (next()) {
+ case COMMAND:
+ 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() {
- if (next() != COMMAND) {
- error("Expecting 'command'");
- return;
+ switch (next()) {
+ case COMMAND:
+ 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() {
- if (next() != COMMAND) {
- error("Expecting 'command'");
- return;
+ switch (next()) {
+ case COMMAND:
+ 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() {
- if (next() != COMMAND) {
- error("Expecting 'command'");
- return;
+ switch(next()) {
+ case COMMAND:
+ parseCommand(confDat->Assembler);
+ break;
+ default:
+ error("Expecting 'command'");
+ break;
}
- parseCommand(confDat->Assembler);
}
void parseLinker() {
- if (next() != COMMAND) {
- error("Expecting 'command'");
- return;
+ switch(next()) {
+ case COMMAND:
+ 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() {
switch (token) {
- case LANG: return parseLang();
- case PREPROCESSOR: return parsePreProcessor();
- case TRANSLATOR: return parseTranslator();
- case OPTIMIZER: return parseOptimizer();
- case ASSEMBLER: return parseAssembler();
- case LINKER: return parseLinker();
+ case LANG: parseLang(); break;
+ case PREPROCESSOR: parsePreprocessor(); break;
+ case TRANSLATOR: parseTranslator(); break;
+ case OPTIMIZER: parseOptimizer(); break;
+ case ASSEMBLER: parseAssembler(); break;
+ case LINKER: parseLinker(); break;
case EOLTOK: break; // just ignore
case ERRORTOK:
default:
- error("Invalid top level configuration item identifier");
+ error("Invalid top level configuration item");
+ break;
}
}
void parseFile() {
- while ( next() != 0 ) {
- parseAssignment();
+ while ( next() != EOFTOK ) {
+ if (token == ERRORTOK)
+ error("Invalid token");
+ else if (token != EOLTOK)
+ parseAssignment();
}
provider->checkErrors();
}
@@ -255,12 +345,12 @@
void
ParseConfigData(InputProvider& provider, CompilerDriver::ConfigData& confDat) {
- ParseContext ctxt;
- ctxt.token = 0;
- ctxt.provider = &provider;
- ctxt.confDat = &confDat;
- ctxt.action = 0;
- ctxt.parseFile();
+ Parser p;
+ p.token = EOFTOK;
+ p.provider = &provider;
+ p.confDat = &confDat;
+ p.action = 0;
+ p.parseFile();
}
}
Index: llvm/tools/llvmc/ConfigLexer.h
diff -u llvm/tools/llvmc/ConfigLexer.h:1.1 llvm/tools/llvmc/ConfigLexer.h:1.2
--- llvm/tools/llvmc/ConfigLexer.h:1.1 Sat Aug 14 04:37:15 2004
+++ llvm/tools/llvmc/ConfigLexer.h Sun Aug 15 03:19:46 2004
@@ -25,7 +25,6 @@
};
extern ConfigLexerInfo ConfigLexerData;
-extern unsigned ConfigLexerLine;
class InputProvider {
public:
@@ -65,13 +64,21 @@
ASSEMBLER, ///< The item "assembler" (and case variants)
LINKER, ///< The item "linker" (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)
PREPROCESSES, ///< The item "preprocesses" (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)
+ 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
Index: llvm/tools/llvmc/ConfigLexer.l
diff -u llvm/tools/llvmc/ConfigLexer.l:1.1 llvm/tools/llvmc/ConfigLexer.l:1.2
--- llvm/tools/llvmc/ConfigLexer.l:1.1 Sat Aug 14 04:37:15 2004
+++ llvm/tools/llvmc/ConfigLexer.l Sun Aug 15 03:19:46 2004
@@ -38,6 +38,10 @@
if (result == 0 ) result = YY_NULL; \
}
+#define YY_DECL ConfigLexerTokens llvm::Configlex()
+
+#define yyterminate() { return EOFTOK; }
+
using namespace llvm;
/* Conversion of text ints to binary */
@@ -62,11 +66,17 @@
ASSEMBLER assembler|Assembler|ASSEMBLER
LINKER linker|Linker|LINKER
NAME name|Name|NAME
-NEEDED needed|Needed|NEEDED
+REQUIRED required|Required|REQUIRED
COMMAND command|Command|COMMAND
PREPROCESSES preprocesses|PreProcesses|PREPROCESSES
GROKS_DASH_O groks_dash_O|Groks_Dash_O|GROKS_DASH_O
+GROKS_O10N groks_optimization|Groks_Optimization|GROKS_OPTIMIZATION
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]*
NewLine \n
White [ \t]*
@@ -84,7 +94,8 @@
%%
-{NewLine} { in_value = false; ConfigLexerLine++; return EOLTOK; }
+{NewLine} { in_value = false; return EOLTOK; }
+{Eq} { in_value = true; return EQUALS; }
{Comment} { /* Ignore comments */ }
{White} { /* Ignore whitespace */ }
@@ -102,19 +113,29 @@
return OPTION; } else return LINKER; }
{NAME} { if (in_value) { ConfigLexerData.StringVal = "name";
return OPTION; } else return NAME; }
-{NEEDED} { if (in_value) { ConfigLexerData.StringVal = "needed";
- return OPTION; } else return NEEDED; }
+{REQUIRED} { if (in_value) { ConfigLexerData.StringVal = "required";
+ return OPTION; } else return REQUIRED; }
{COMMAND} { if (in_value) { ConfigLexerData.StringVal = "command";
return OPTION; } else return COMMAND; }
{PREPROCESSES} { if (in_value) { ConfigLexerData.StringVal = "preprocesses";
return OPTION; } else return PREPROCESSES; }
{GROKS_DASH_O} { if (in_value) { ConfigLexerData.StringVal = "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";
return OPTION; } else return OPTIMIZES; }
-{Sep} { if (in_value) { ConfigLexerData.StringVal = yytext;
- return OPTION; } }
-
+{OPT1} { if (in_value) { ConfigLexerData.StringVal = "opt1";
+ 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; }
@out@ { if (in_value) return OUT_SUBST; else return ERRORTOK; }
{True} { if (in_value) return TRUETOK; else return ERRORTOK; }
@@ -124,12 +145,14 @@
{Off} { 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; }
{Integer} { ConfigLexerData.IntegerVal = IntToVal(yytext); return INTEGER; }
{String} { yytext[yyleng-1] = 0; // nuke end quote
ConfigLexerData.StringVal = yytext+1; // Nuke start quote
return STRING;
}
+{Sep} { if (in_value) { ConfigLexerData.StringVal = yytext;
+ return OPTION; } }
+
%%
Index: llvm/tools/llvmc/Makefile
diff -u llvm/tools/llvmc/Makefile:1.1 llvm/tools/llvmc/Makefile:1.2
--- llvm/tools/llvmc/Makefile:1.1 Tue Aug 10 11:27:08 2004
+++ llvm/tools/llvmc/Makefile Sun Aug 15 03:19:46 2004
@@ -8,6 +8,6 @@
##===----------------------------------------------------------------------===##
LEVEL = ../..
TOOLNAME = llvmc
-USEDLIBS = asmparser bcreader bcwriter vmcore support.a
+USEDLIBS = asmparser bcreader bcwriter vmcore support.a system.a
include $(LEVEL)/Makefile.common
Index: llvm/tools/llvmc/llvmc.cpp
diff -u llvm/tools/llvmc/llvmc.cpp:1.4 llvm/tools/llvmc/llvmc.cpp:1.5
--- llvm/tools/llvmc/llvmc.cpp:1.4 Sat Aug 14 04:37:15 2004
+++ llvm/tools/llvmc/llvmc.cpp Sun Aug 15 03:19:46 2004
@@ -69,19 +69,23 @@
//=== 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::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::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::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::value_desc("option"));
@@ -142,9 +146,12 @@
cl::desc("Specify a configuration directory to override defaults"),
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"));
+static cl::opt<bool> PipeCommands("pipe", cl::Optional,
+ cl::desc("Invoke sub-commands by linking input/output with pipes"));
+
//===------------------------------------------------------------------------===
//=== POSITIONAL OPTIONS
//===------------------------------------------------------------------------===
@@ -200,6 +207,8 @@
std::cerr << argv[0] << ": Not implemented yet: -native";
if (EmitRawCode)
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
if (OutputFilename.empty() && OptLevel == CompilerDriver::LINKING)
@@ -221,10 +230,12 @@
CD.setOutputMachine(OutputMachine);
CD.setEmitNativeCode(Native);
CD.setEmitRawCode(EmitRawCode);
- std::vector<std::string>::iterator pathIt = LibPaths.begin();
- while ( pathIt != LibPaths.end() ) {
- CD.addLibraryPath( *pathIt++ );
- }
+ CD.setLibraryPaths(LibPaths);
+ CD.setPreprocessorOptions(PreprocessorToolOpts);
+ CD.setTranslatorOptions(TranslatorToolOpts);
+ CD.setOptimizerOptions(OptimizerToolOpts);
+ CD.setAssemblerOptions(AssemblerToolOpts);
+ CD.setLinkerOptions(LinkerToolOpts);
// Prepare the list of files to be compiled by the CompilerDriver.
CompilerDriver::InputList InpList;
More information about the llvm-commits
mailing list