[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