From ca01f9bc6fc72143ed95cea2535085f151a97d41 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Mon, 30 Aug 2004 06:29:06 +0000 Subject: [PATCH] Implement the "setIncludePaths" and "setSymbolDefines" interface methods. Revise token substitution to be a little faster. Clean up exception throwing, make sure its always a std::string. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16116 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvmc/CompilerDriver.cpp | 172 +++++++++++++++++++++++++-------- tools/llvmc/CompilerDriver.h | 6 ++ tools/llvmc/ConfigLexer.h | 3 + tools/llvmc/ConfigLexer.l | 3 + tools/llvmc/Configuration.cpp | 23 +++-- 5 files changed, 157 insertions(+), 50 deletions(-) diff --git a/tools/llvmc/CompilerDriver.cpp b/tools/llvmc/CompilerDriver.cpp index 08559b82461..51164d24678 100644 --- a/tools/llvmc/CompilerDriver.cpp +++ b/tools/llvmc/CompilerDriver.cpp @@ -123,6 +123,21 @@ namespace { AdditionalArgs[phase] = opts; } + virtual void setIncludePaths(const StringVector& paths) { + StringVector::const_iterator I = paths.begin(); + StringVector::const_iterator E = paths.end(); + while (I != E) { + sys::Path tmp; + tmp.set_directory(*I); + IncludePaths.push_back(tmp); + ++I; + } + } + + virtual void setSymbolDefines(const StringVector& defs) { + Defines = defs; + } + virtual void setLibraryPaths(const StringVector& paths) { StringVector::const_iterator I = paths.begin(); StringVector::const_iterator E = paths.end(); @@ -193,45 +208,116 @@ namespace { StringVector::iterator PI = pat->args.begin(); StringVector::iterator PE = pat->args.end(); while (PI != PE) { - if ((*PI)[0] == '%') { - if (*PI == "%in%") { - action->args.push_back(input.get()); - } else if (*PI == "%out%") { - action->args.push_back(output.get()); - } else if (*PI == "%time%") { - if (isSet(TIME_PASSES_FLAG)) - action->args.push_back("-time-passes"); - } else if (*PI == "%stats%") { - if (isSet(SHOW_STATS_FLAG)) - action->args.push_back("-stats"); - } else if (*PI == "%force%") { - if (isSet(FORCE_FLAG)) - action->args.push_back("-f"); - } else if (*PI == "%verbose%") { - if (isSet(VERBOSE_FLAG)) - action->args.push_back("-v"); - } else if (*PI == "%target%") { - // FIXME: Ignore for now - } else if (*PI == "%opt%") { - if (!isSet(EMIT_RAW_FLAG)) { - if (cd->opts.size() > static_cast(optLevel) && - !cd->opts[optLevel].empty()) - action->args.insert(action->args.end(), cd->opts[optLevel].begin(), - cd->opts[optLevel].end()); - else - throw std::string("Optimization options for level ") + - utostr(unsigned(optLevel)) + " were not specified"; + if ((*PI)[0] == '%' && PI->length() >2) { + bool found = true; + switch ((*PI)[1]) { + case 'a': + if (*PI == "%args%") { + if (AdditionalArgs.size() > unsigned(phase)) + if (!AdditionalArgs[phase].empty()) { + // Get specific options for each kind of action type + StringVector& addargs = AdditionalArgs[phase]; + // Add specific options for each kind of action type + action->args.insert(action->args.end(), addargs.begin(), addargs.end()); + } + } else + found = false; + break; + case 'd': + if (*PI == "%defs%") { + StringVector::iterator I = Defines.begin(); + StringVector::iterator E = Defines.end(); + while (I != E) { + action->args.push_back( std::string("-D") + *I); + ++I; + } + } else + found = false; + break; + case 'f': + if (*PI == "%force%") { + if (isSet(FORCE_FLAG)) + action->args.push_back("-f"); + } else + found = false; + break; + case 'i': + if (*PI == "%in%") { + action->args.push_back(input.get()); + } else if (*PI == "%incls%") { + PathVector::iterator I = IncludePaths.begin(); + PathVector::iterator E = IncludePaths.end(); + while (I != E) { + action->args.push_back( std::string("-I") + I->get() ); + ++I; + } + } else + found = false; + break; + case 'l': + if (*PI == "%libs%") { + PathVector::iterator I = LibraryPaths.begin(); + PathVector::iterator E = LibraryPaths.end(); + while (I != E) { + action->args.push_back( std::string("-L") + I->get() ); + ++I; + } + } else + found = false; + break; + case 'o': + if (*PI == "%out%") { + action->args.push_back(output.get()); + } else if (*PI == "%opt%") { + if (!isSet(EMIT_RAW_FLAG)) { + if (cd->opts.size() > static_cast(optLevel) && + !cd->opts[optLevel].empty()) + action->args.insert(action->args.end(), cd->opts[optLevel].begin(), + cd->opts[optLevel].end()); + else + throw std::string("Optimization options for level ") + + utostr(unsigned(optLevel)) + " were not specified"; + } + } else + found = false; + break; + case 's': + if (*PI == "%stats%") { + if (isSet(SHOW_STATS_FLAG)) + action->args.push_back("-stats"); + } else + found = false; + break; + case 't': + if (*PI == "%target%") { + action->args.push_back(std::string("-march=") + machine); + } else if (*PI == "%time%") { + if (isSet(TIME_PASSES_FLAG)) + action->args.push_back("-time-passes"); + } else + found = false; + break; + case 'v': + if (*PI == "%verbose%") { + if (isSet(VERBOSE_FLAG)) + action->args.push_back("-v"); + } else + found = false; + break; + default: + found = false; + break; + } + if (!found) { + // Did it even look like a substitution? + if (PI->length()>1 && (*PI)[0] == '%' && + (*PI)[PI->length()-1] == '%') { + throw std::string("Invalid substitution token: '") + *PI + + "' for command '" + pat->program.get() + "'"; + } else { + // It's not a legal substitution, just pass it through + action->args.push_back(*PI); } - } else if (*PI == "%args%") { - if (AdditionalArgs.size() > unsigned(phase)) - if (!AdditionalArgs[phase].empty()) { - // Get specific options for each kind of action type - StringVector& addargs = AdditionalArgs[phase]; - // Add specific options for each kind of action type - action->args.insert(action->args.end(), addargs.begin(), addargs.end()); - } - } else { - throw "Invalid substitution name" + *PI; } } else { // Its not a substitution, just put it in the action @@ -240,7 +326,6 @@ namespace { PI++; } - // Finally, we're done return action; } @@ -252,7 +337,7 @@ namespace { if (!isSet(DRY_RUN_FLAG)) { action->program = sys::Program::FindProgramByName(action->program.get()); if (action->program.is_empty()) - throw "Can't find program '" + action->program.get() + "'"; + throw std::string("Can't find program '") + action->program.get() + "'"; // Invoke the program return 0 == action->program.ExecuteAndWait(action->args); @@ -571,7 +656,7 @@ namespace { std::vector::iterator AE = actions.end(); while (AI != AE) { if (!DoAction(*AI)) - throw "Action failed"; + throw std::string("Action failed"); AI++; } @@ -579,7 +664,8 @@ namespace { actions.clear(); if (finalPhase == LINKING) { if (isSet(EMIT_NATIVE_FLAG)) { - throw "llvmc doesn't know how to link native code yet"; + throw std::string( + "llvmc doesn't know how to link native code yet"); } else { // First, we need to examine the files to ensure that they all contain // bytecode files. Since the final output is bytecode, we can only @@ -646,6 +732,8 @@ namespace { unsigned Flags; ///< The driver flags std::string machine; ///< Target machine name PathVector LibraryPaths; ///< -L options + PathVector IncludePaths; ///< -I options + StringVector Defines; ///< -D options sys::Path TempDir; ///< Name of the temporary directory. StringTable AdditionalArgs; ///< The -Txyz options diff --git a/tools/llvmc/CompilerDriver.h b/tools/llvmc/CompilerDriver.h index ea999b44d99..4a858ad743d 100644 --- a/tools/llvmc/CompilerDriver.h +++ b/tools/llvmc/CompilerDriver.h @@ -160,6 +160,12 @@ namespace llvm { /// @brief Set Preprocessor specific options virtual void setPhaseArgs(Phases phase, const StringVector& opts) = 0; + /// @brief Set Library Paths + virtual void setIncludePaths(const StringVector& paths) = 0; + + /// @brief Set Library Paths + virtual void setSymbolDefines(const StringVector& paths) = 0; + /// @brief Set Library Paths virtual void setLibraryPaths(const StringVector& paths) = 0; diff --git a/tools/llvmc/ConfigLexer.h b/tools/llvmc/ConfigLexer.h index bb731d3c6f0..7a9693d5b53 100644 --- a/tools/llvmc/ConfigLexer.h +++ b/tools/llvmc/ConfigLexer.h @@ -55,14 +55,17 @@ enum ConfigLexerTokens { ASSEMBLER, ///< The name "assembler" (and variants) BYTECODE, ///< The value "bytecode" (and variants) COMMAND, ///< The name "command" (and variants) + DEFS_SUBST, ///< The substitution item %defs% EQUALS, ///< The equals sign, = FALSETOK, ///< A boolean false value (false/no/off) FORCE_SUBST, ///< The substitution item %force% IN_SUBST, ///< The substitution item %in% + INCLS_SUBST, ///< The substitution item %incls% INTEGER, ///< An integer LANG, ///< The name "lang" (and variants) LIBPATHS, ///< The name "libpaths" (and variants) LIBS, ///< The name "libs" (and variants) + LIBS_SUBST, ///< The substitution item %libs% LINKER, ///< The name "linker" (and variants) NAME, ///< The name "name" (and variants) OPT_SUBST, ///< The substitution item %opt% diff --git a/tools/llvmc/ConfigLexer.l b/tools/llvmc/ConfigLexer.l index 21f5fe1a0bc..481276ef153 100644 --- a/tools/llvmc/ConfigLexer.l +++ b/tools/llvmc/ConfigLexer.l @@ -160,8 +160,11 @@ White [ \t]* {LINKER} { return handleNameContext(LINKER); } %args% { return handleSubstitution(ARGS_SUBST); } +%defs% { return handleSubstitution(DEFS_SUBST); } %force% { return handleSubstitution(FORCE_SUBST); } %in% { return handleSubstitution(IN_SUBST); } +%incls% { return handleSubstitution(INCLS_SUBST); } +%libs% { return handleSubstitution(LIBS_SUBST); } %opt% { return handleSubstitution(OPT_SUBST); } %out% { return handleSubstitution(OUT_SUBST); } %stats% { return handleSubstitution(STATS_SUBST); } diff --git a/tools/llvmc/Configuration.cpp b/tools/llvmc/Configuration.cpp index a8c6791545e..c398e529d74 100644 --- a/tools/llvmc/Configuration.cpp +++ b/tools/llvmc/Configuration.cpp @@ -156,13 +156,16 @@ namespace { bool parseSubstitution(CompilerDriver::StringVector& optList) { switch (token) { case ARGS_SUBST: optList.push_back("%args%"); break; + case DEFS_SUBST: optList.push_back("%defs%"); break; + case FORCE_SUBST: optList.push_back("%force%"); break; case IN_SUBST: optList.push_back("%in%"); break; - case OUT_SUBST: optList.push_back("%out%"); break; - case TIME_SUBST: optList.push_back("%time%"); break; - case STATS_SUBST: optList.push_back("%stats%"); break; + case INCLS_SUBST: optList.push_back("%incls%"); break; + case LIBS_SUBST: optList.push_back("%libs%"); break; case OPT_SUBST: optList.push_back("%opt%"); break; + case OUT_SUBST: optList.push_back("%out%"); break; case TARGET_SUBST: optList.push_back("%target%"); break; - case FORCE_SUBST: optList.push_back("%force%"); break; + case STATS_SUBST: optList.push_back("%stats%"); break; + case TIME_SUBST: optList.push_back("%time%"); break; case VERBOSE_SUBST: optList.push_back("%verbose%"); break; default: return false; @@ -425,7 +428,8 @@ LLVMC_ConfigDataProvider::ReadConfigData(const std::string& ftype) { confFile.set_directory(conf); confFile.append_file(ftype); if (!confFile.readable()) - throw "Configuration file for '" + ftype + "' is not available."; + throw std::string("Configuration file for '") + ftype + + "' is not available."; } else { // Try the user's home directory confFile = sys::Path::GetUserHomeDirectory(); @@ -445,7 +449,8 @@ LLVMC_ConfigDataProvider::ReadConfigData(const std::string& ftype) { confFile = sys::Path::GetLLVMDefaultConfigDir(); confFile.append_file(ftype); if (!confFile.readable()) { - throw "Configuration file for '" + ftype + "' is not available."; + throw std::string("Configuration file for '") + ftype + + "' is not available."; } } } @@ -454,11 +459,13 @@ LLVMC_ConfigDataProvider::ReadConfigData(const std::string& ftype) { confFile = configDir; confFile.append_file(ftype); if (!confFile.readable()) - throw "Configuration file for '" + ftype + "' is not available."; + throw std::string("Configuration file for '") + ftype + + "' is not available."; } FileInputProvider fip( confFile.get() ); if (!fip.okay()) { - throw "Configuration file for '" + ftype + "' is not available."; + throw std::string("Configuration file for '") + ftype + + "' is not available."; } result = new CompilerDriver::ConfigData(); ParseConfigData(fip,*result); -- 2.34.1