[llvm-commits] [llvm] r51728 - in /llvm/trunk: tools/llvmc2/Action.h tools/llvmc2/Common.td tools/llvmc2/CompilationGraph.cpp tools/llvmc2/CompilationGraph.h tools/llvmc2/StringSet.h tools/llvmc2/Tool.h tools/llvmc2/Tools.td utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Thu May 29 23:10:19 PDT 2008


Author: foldr
Date: Fri May 30 01:10:19 2008
New Revision: 51728

URL: http://llvm.org/viewvc/llvm-project?rev=51728&view=rev
Log:
Make it possible to use the generalised 'case' construct in the cmd_line property.

Added:
    llvm/trunk/tools/llvmc2/StringSet.h
Modified:
    llvm/trunk/tools/llvmc2/Action.h
    llvm/trunk/tools/llvmc2/Common.td
    llvm/trunk/tools/llvmc2/CompilationGraph.cpp
    llvm/trunk/tools/llvmc2/CompilationGraph.h
    llvm/trunk/tools/llvmc2/Tool.h
    llvm/trunk/tools/llvmc2/Tools.td
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Modified: llvm/trunk/tools/llvmc2/Action.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Action.h?rev=51728&r1=51727&r2=51728&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Action.h (original)
+++ llvm/trunk/tools/llvmc2/Action.h Fri May 30 01:10:19 2008
@@ -25,9 +25,10 @@
   class Action {
     /// Command_ - The actual command (for example, 'ls').
     std::string Command_;
-    /// Args_ - Command arguments. Stdout redirection is allowed.
+    /// Args_ - Command arguments. Stdout redirection ("> file") is allowed.
     std::vector<std::string> Args_;
   public:
+    Action() {}
     Action (const std::string& C,
             const StringVector& A)
       : Command_(C), Args_(A)

Modified: llvm/trunk/tools/llvmc2/Common.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Common.td?rev=51728&r1=51727&r2=51728&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Common.td (original)
+++ llvm/trunk/tools/llvmc2/Common.td Fri May 30 01:10:19 2008
@@ -56,6 +56,7 @@
 def parameter_equals;
 def element_in_list;
 def input_languages_contain;
+def default;
 
 // Boolean operators.
 def and;

Modified: llvm/trunk/tools/llvmc2/CompilationGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/CompilationGraph.cpp?rev=51728&r1=51727&r2=51728&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/CompilationGraph.cpp (original)
+++ llvm/trunk/tools/llvmc2/CompilationGraph.cpp Fri May 30 01:10:19 2008
@@ -177,7 +177,7 @@
       Out = MakeTempFile(TempDir, In.getBasename(), CurTool->OutputSuffix());
     }
 
-    if (int ret = CurTool->GenerateAction(In, Out).Execute())
+    if (int ret = CurTool->GenerateAction(In, Out, InLangs).Execute())
       throw error_code(ret);
 
     if (Last)
@@ -343,7 +343,7 @@
       Out = MakeTempFile(TempDir, "tmp", JT->OutputSuffix());
     }
 
-    if (int ret = JT->GenerateAction(Out).Execute())
+    if (int ret = JT->GenerateAction(Out, InLangs).Execute())
       throw error_code(ret);
 
     if (!IsLast) {

Modified: llvm/trunk/tools/llvmc2/CompilationGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/CompilationGraph.h?rev=51728&r1=51727&r2=51728&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/CompilationGraph.h (original)
+++ llvm/trunk/tools/llvmc2/CompilationGraph.h Fri May 30 01:10:19 2008
@@ -16,6 +16,7 @@
 
 #include "AutoGenerated.h"
 #include "Tool.h"
+#include "StringSet.h"
 
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -29,21 +30,6 @@
 
 namespace llvmc {
 
-  /// StringSet - A wrapper for StringMap that provides set-like
-  /// functionality.  Only insert() and count() methods are used by my
-  /// code.
-  template <class AllocatorTy = llvm::MallocAllocator>
-  class StringSet : public llvm::StringMap<char, AllocatorTy> {
-    typedef llvm::StringMap<char, AllocatorTy> base;
-  public:
-    void insert (const std::string& InLang) {
-      assert(!InLang.empty());
-      const char* KeyStart = &InLang[0];
-      const char* KeyEnd = KeyStart + InLang.size();
-      base::insert(llvm::StringMapEntry<char>::
-                   Create(KeyStart, KeyEnd, base::getAllocator(), '+'));
-    }
-  };
   typedef StringSet<> InputLanguagesSet;
 
   /// Edge - Represents an edge of the compilation graph.

Added: llvm/trunk/tools/llvmc2/StringSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/StringSet.h?rev=51728&view=auto

==============================================================================
--- llvm/trunk/tools/llvmc2/StringSet.h (added)
+++ llvm/trunk/tools/llvmc2/StringSet.h Fri May 30 01:10:19 2008
@@ -0,0 +1,40 @@
+//===--- StringSet.h - The LLVM Compiler Driver -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open
+// Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  StringSet - A set-like wrapper for the StringMap.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMC2_STRINGSET_H
+#define LLVM_TOOLS_LLVMC2_STRINGSET_H
+
+#include "llvm/ADT/StringMap.h"
+
+#include <cassert>
+
+namespace llvmc {
+
+  /// StringSet - A wrapper for StringMap that provides set-like
+  /// functionality.  Only insert() and count() methods are used by my
+  /// code.
+  template <class AllocatorTy = llvm::MallocAllocator>
+  class StringSet : public llvm::StringMap<char, AllocatorTy> {
+    typedef llvm::StringMap<char, AllocatorTy> base;
+  public:
+    void insert (const std::string& InLang) {
+      assert(!InLang.empty());
+      const char* KeyStart = &InLang[0];
+      const char* KeyEnd = KeyStart + InLang.size();
+      base::insert(llvm::StringMapEntry<char>::
+                   Create(KeyStart, KeyEnd, base::getAllocator(), '+'));
+    }
+  };
+}
+
+#endif //LLVM_TOOLS_LLVMC2_STRINGSET_H

Modified: llvm/trunk/tools/llvmc2/Tool.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Tool.h?rev=51728&r1=51727&r2=51728&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Tool.h (original)
+++ llvm/trunk/tools/llvmc2/Tool.h Fri May 30 01:10:19 2008
@@ -15,6 +15,7 @@
 #define LLVM_TOOLS_LLVMC2_TOOL_H
 
 #include "Action.h"
+#include "StringSet.h"
 
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/System/Path.h"
@@ -33,10 +34,12 @@
     virtual ~Tool() {}
 
     virtual Action GenerateAction (const PathVector& inFiles,
-                                   const llvm::sys::Path& outFile) const = 0;
+                                   const llvm::sys::Path& outFile,
+                                   const StringSet<>& InLangs) const = 0;
 
     virtual Action GenerateAction (const llvm::sys::Path& inFile,
-                                   const llvm::sys::Path& outFile) const = 0;
+                                   const llvm::sys::Path& outFile,
+                                   const StringSet<>& InLangs) const = 0;
 
     virtual const char* Name() const = 0;
     virtual const char* InputLanguage() const = 0;
@@ -54,8 +57,10 @@
     void ClearJoinList() { JoinList_.clear(); }
     bool JoinListEmpty() const { return JoinList_.empty(); }
 
-    Action GenerateAction(const llvm::sys::Path& outFile) const
-    { return GenerateAction(JoinList_, outFile); }
+    Action GenerateAction(const llvm::sys::Path& outFile,
+                          const StringSet<>& InLangs) const {
+      return GenerateAction(JoinList_, outFile, InLangs);
+    }
     // We shouldn't shadow base class's version of GenerateAction.
     using Tool::GenerateAction;
 

Modified: llvm/trunk/tools/llvmc2/Tools.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Tools.td?rev=51728&r1=51727&r2=51728&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Tools.td (original)
+++ llvm/trunk/tools/llvmc2/Tools.td Fri May 30 01:10:19 2008
@@ -25,8 +25,15 @@
 [(in_language "c"),
  (out_language "llvm-bitcode"),
  (output_suffix "bc"),
- (cmd_line "llvm-gcc -c -x c $INFILE -o $OUTFILE -emit-llvm"),
+ (cmd_line (case
+            (switch_on "E"),
+              "llvm-g++ -E -x c $INFILE -o $OUTFILE -emit-llvm",
+            (default),
+              "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm")),
+ // TOFIX: Preprocessed files currently have suffix ".bc".
  (switch_option "E", (stop_compilation),
+    // Make this possible:
+    // (output_suffix "i"),
    (help "Stop after the preprocessing stage, do not run the compiler")),
  (sink)
 ]>;
@@ -35,7 +42,11 @@
 [(in_language "c++"),
  (out_language "llvm-bitcode"),
  (output_suffix "bc"),
- (cmd_line "llvm-g++ -c -x c++ $INFILE -o $OUTFILE -emit-llvm"),
+ (cmd_line (case
+            (switch_on "E"),
+              "llvm-g++ -E -x c++ $INFILE -o $OUTFILE -emit-llvm",
+            (default),
+              "llvm-g++ -c -x c++ $INFILE -o $OUTFILE -emit-llvm")),
  (switch_option "E", (stop_compilation)),
  (sink)
 ]>;

Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=51728&r1=51727&r2=51728&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Fri May 30 01:10:19 2008
@@ -53,18 +53,18 @@
 //===----------------------------------------------------------------------===//
 /// Helper functions
 
-std::string InitPtrToString(Init* ptr) {
-  StringInit& val = dynamic_cast<StringInit&>(*ptr);
+const std::string& InitPtrToString(const Init* ptr) {
+  const StringInit& val = dynamic_cast<const StringInit&>(*ptr);
   return val.getValue();
 }
 
-int InitPtrToInt(Init* ptr) {
-  IntInit& val = dynamic_cast<IntInit&>(*ptr);
+int InitPtrToInt(const Init* ptr) {
+  const IntInit& val = dynamic_cast<const IntInit&>(*ptr);
   return val.getValue();
 }
 
-const DagInit& InitPtrToDagInitRef(Init* ptr) {
-  DagInit& val = dynamic_cast<DagInit&>(*ptr);
+const DagInit& InitPtrToDagInitRef(const Init* ptr) {
+  const DagInit& val = dynamic_cast<const DagInit&>(*ptr);
   return val;
 }
 
@@ -307,7 +307,7 @@
 
 struct ToolProperties : public RefCountedBase<ToolProperties> {
   std::string Name;
-  StrVector CmdLine;
+  Init* CmdLine;
   std::string InLanguage;
   std::string OutLanguage;
   std::string OutputSuffix;
@@ -432,9 +432,7 @@
 
   void onCmdLine (const DagInit* d) {
     checkNumberOfArguments(d, 1);
-    SplitString(InitPtrToString(d->getArg(0)), toolProps_.CmdLine);
-    if (toolProps_.CmdLine.empty())
-      throw "Tool " + toolProps_.Name + " has empty command line!";
+    toolProps_.CmdLine = d->getArg(0);
   }
 
   void onInLanguage (const DagInit* d) {
@@ -610,6 +608,138 @@
   }
 }
 
+/// EmitCaseTest1Arg - Helper function used by
+/// EmitCaseConstructHandler.
+bool EmitCaseTest1Arg(const std::string& TestName,
+                      const DagInit& d,
+                      const GlobalOptionDescriptions& OptDescs,
+                      std::ostream& O) {
+  checkNumberOfArguments(&d, 1);
+  const std::string& OptName = InitPtrToString(d.getArg(0));
+  if (TestName == "switch_on") {
+    const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
+    if (OptDesc.Type != OptionType::Switch)
+      throw OptName + ": incorrect option type!";
+    O << OptDesc.GenVariableName();
+    return true;
+  } else if (TestName == "input_languages_contain") {
+    O << "InLangs.count(\"" << OptName << "\") != 0";
+    return true;
+  }
+
+  return false;
+}
+
+/// EmitCaseTest2Args - Helper function used by
+/// EmitCaseConstructHandler.
+bool EmitCaseTest2Args(const std::string& TestName,
+                       const DagInit& d,
+                       const char* IndentLevel,
+                       const GlobalOptionDescriptions& OptDescs,
+                       std::ostream& O) {
+  checkNumberOfArguments(&d, 2);
+  const std::string& OptName = InitPtrToString(d.getArg(0));
+  const std::string& OptArg = InitPtrToString(d.getArg(1));
+  const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
+
+  if (TestName == "parameter_equals") {
+    if (OptDesc.Type != OptionType::Parameter
+        && OptDesc.Type != OptionType::Prefix)
+      throw OptName + ": incorrect option type!";
+    O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
+    return true;
+  }
+  else if (TestName == "element_in_list") {
+    if (OptDesc.Type != OptionType::ParameterList
+        && OptDesc.Type != OptionType::PrefixList)
+      throw OptName + ": incorrect option type!";
+    const std::string& VarName = OptDesc.GenVariableName();
+    O << "std::find(" << VarName << ".begin(),\n"
+      << IndentLevel << Indent1 << VarName << ".end(), \""
+      << OptArg << "\") != " << VarName << ".end()";
+    return true;
+  }
+
+  return false;
+}
+
+// Forward declaration.
+// EmitLogicalOperationTest and EmitCaseTest are mutually recursive.
+void EmitCaseTest(const DagInit& d, const char* IndentLevel,
+                  const GlobalOptionDescriptions& OptDescs,
+                  std::ostream& O);
+
+/// EmitLogicalOperationTest - Helper function used by
+/// EmitCaseConstructHandler.
+void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
+                              const char* IndentLevel,
+                              const GlobalOptionDescriptions& OptDescs,
+                              std::ostream& O) {
+  O << '(';
+  for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
+    const DagInit& InnerTest = InitPtrToDagInitRef(d.getArg(j));
+    EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
+    if (j != NumArgs - 1)
+      O << ")\n" << IndentLevel << Indent1 << ' ' << LogicOp << " (";
+    else
+      O << ')';
+  }
+}
+
+/// EmitCaseTest - Helper function used by EmitCaseConstructHandler.
+void EmitCaseTest(const DagInit& d, const char* IndentLevel,
+                  const GlobalOptionDescriptions& OptDescs,
+                  std::ostream& O) {
+  const std::string& TestName = d.getOperator()->getAsString();
+
+  if (TestName == "and")
+    EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
+  else if (TestName == "or")
+    EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O);
+  else if (EmitCaseTest1Arg(TestName, d, OptDescs, O))
+    return;
+  else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
+    return;
+  else
+    throw TestName + ": unknown edge property!";
+}
+
+// Emit code that handles the 'case' construct.
+// Takes a function object that should emit code for every case clause.
+// Callback's type is
+// void F(Init* Statement, const char* IndentLevel, std::ostream& O).
+template <typename F>
+void EmitCaseConstructHandler(const DagInit* d, const char* IndentLevel,
+                              const F& Callback,
+                              const GlobalOptionDescriptions& OptDescs,
+                              std::ostream& O) {
+  assert(d->getOperator()->getAsString() == "case");
+
+  for (unsigned i = 0, numArgs = d->getNumArgs(); i != numArgs; ++i) {
+    const DagInit& Test = InitPtrToDagInitRef(d->getArg(i));
+
+    if (Test.getOperator()->getAsString() == "default") {
+      if (i+2 != numArgs)
+        throw std::string("The 'default' clause should be the last in the"
+                          "'case' construct!");
+      O << IndentLevel << "else {\n";
+    }
+    else {
+      O << IndentLevel << "if (";
+      EmitCaseTest(Test, IndentLevel, OptDescs, O);
+      O << ") {\n";
+    }
+
+    ++i;
+    if (i == numArgs)
+      throw "Case construct handler: no corresponding action "
+        "found for the test " + Test.getAsString() + '!';
+
+    Callback(d->getArg(i), IndentLevel, O);
+    O << IndentLevel << "}\n";
+  }
+}
+
 /// EmitForwardOptionPropertyHandlingCode - Helper function used to
 /// implement EmitOptionPropertyHandlingCode(). Emits code for
 /// handling the (forward) option property.
@@ -698,7 +828,6 @@
         << D.GenVariableName() << ", vec, \",\");\n";
     }
     else {
-      // TOFIX: move this to the type-checking phase
       throw std::string("Switches can't have unpack_values property!");
     }
   }
@@ -707,34 +836,25 @@
   O << Indent2 << "}\n";
 }
 
-// EmitGenerateActionMethod - Emit one of two versions of the
-// Tool::GenerateAction() method.
-void EmitGenerateActionMethod (const ToolProperties& P, bool V, std::ostream& O)
-{
-  if (V)
-    O << Indent1 << "Action GenerateAction(const PathVector& inFiles,\n";
-  else
-    O << Indent1 << "Action GenerateAction(const sys::Path& inFile,\n";
-
-  O << Indent2 << "const sys::Path& outFile) const\n"
-    << Indent1 << "{\n"
-    << Indent2 << "std::vector<std::string> vec;\n";
-
-  // Parse CmdLine tool property
-  if(P.CmdLine.empty())
-    throw "Tool " + P.Name + " has empty command line!";
+void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
+                        bool Version, const char* IndentLevel,
+                        std::ostream& O) {
+  StrVector StrVec;
+  SplitString(InitPtrToString(CmdLine), StrVec);
+  if (InitPtrToString(CmdLine).empty())
+    throw "Tool " + ToolName + " has empty command line!";
 
-  StrVector::const_iterator I = P.CmdLine.begin();
+  StrVector::const_iterator I = StrVec.begin();
   ++I;
-  for (StrVector::const_iterator E = P.CmdLine.end(); I != E; ++I) {
+  for (StrVector::const_iterator E = StrVec.end(); I != E; ++I) {
     const std::string& cmd = *I;
-    O << Indent2;
+    O << IndentLevel;
     if (cmd == "$INFILE") {
-      if (V)
+      if (Version)
         O << "for (PathVector::const_iterator B = inFiles.begin()"
           << ", E = inFiles.end();\n"
-          << Indent2 << "B != E; ++B)\n"
-          << Indent3 << "vec.push_back(B->toString());\n";
+          << IndentLevel << "B != E; ++B)\n"
+          << IndentLevel << Indent1 << "vec.push_back(B->toString());\n";
       else
         O << "vec.push_back(inFile.toString());\n";
     }
@@ -745,6 +865,46 @@
       O << "vec.push_back(\"" << cmd << "\");\n";
     }
   }
+  O << IndentLevel << "ret = Action(\"" << StrVec.at(0) << "\", vec);\n";
+}
+
+class EmitCmdLineVecFillCallback {
+  bool Version;
+  const std::string& ToolName;
+ public:
+  EmitCmdLineVecFillCallback(bool Ver, const std::string& TN)
+    : Version(Ver), ToolName(TN) {}
+
+  void operator()(const Init* Statement, const char* IndentLevel,
+                  std::ostream& O) const
+  {
+    EmitCmdLineVecFill(Statement, ToolName, Version, IndentLevel, O);
+  }
+};
+
+// EmitGenerateActionMethod - Emit one of two versions of the
+// Tool::GenerateAction() method.
+void EmitGenerateActionMethod (const ToolProperties& P,
+                               const GlobalOptionDescriptions& OptDescs,
+                               bool Version, std::ostream& O) {
+  if (Version)
+    O << Indent1 << "Action GenerateAction(const PathVector& inFiles,\n";
+  else
+    O << Indent1 << "Action GenerateAction(const sys::Path& inFile,\n";
+
+  O << Indent2 << "const sys::Path& outFile,\n"
+    << Indent2 << "const InputLanguagesSet& InLangs) const\n"
+    << Indent1 << "{\n"
+    << Indent2 << "Action ret;\n"
+    << Indent2 << "std::vector<std::string> vec;\n";
+
+  // cmd_line is either a string or a 'case' construct.
+  if (typeid(*P.CmdLine) == typeid(StringInit))
+    EmitCmdLineVecFill(P.CmdLine, P.Name, Version, Indent2, O);
+  else
+    EmitCaseConstructHandler(&InitPtrToDagInitRef(P.CmdLine), Indent2,
+                             EmitCmdLineVecFillCallback(Version, P.Name),
+                             OptDescs, O);
 
   // For every understood option, emit handling code.
   for (ToolOptionDescriptions::const_iterator B = P.OptDescs.begin(),
@@ -761,25 +921,27 @@
       << Indent2 << "}\n";
   }
 
-  O << Indent2 << "return Action(\"" << P.CmdLine.at(0) << "\", vec);\n"
+  O << Indent2 << "return ret;\n"
     << Indent1 << "}\n\n";
 }
 
 /// EmitGenerateActionMethods - Emit two GenerateAction() methods for
 /// a given Tool class.
-void EmitGenerateActionMethods (const ToolProperties& P, std::ostream& O) {
-
+void EmitGenerateActionMethods (const ToolProperties& P,
+                                const GlobalOptionDescriptions& OptDescs,
+                                std::ostream& O) {
   if (!P.isJoin())
     O << Indent1 << "Action GenerateAction(const PathVector& inFiles,\n"
-      << Indent2 << "const llvm::sys::Path& outFile) const\n"
+      << Indent2 << "const llvm::sys::Path& outFile,\n"
+      << Indent2 << "const InputLanguagesSet& InLangs) const\n"
       << Indent1 << "{\n"
       << Indent2 << "throw std::runtime_error(\"" << P.Name
       << " is not a Join tool!\");\n"
       << Indent1 << "}\n\n";
   else
-    EmitGenerateActionMethod(P, true, O);
+    EmitGenerateActionMethod(P, OptDescs, true, O);
 
-  EmitGenerateActionMethod(P, false, O);
+  EmitGenerateActionMethod(P, OptDescs, false, O);
 }
 
 /// EmitIsLastMethod - Emit the IsLast() method for a given Tool
@@ -841,9 +1003,10 @@
 }
 
 /// EmitToolClassDefinition - Emit a Tool class definition.
-void EmitToolClassDefinition (const ToolProperties& P, std::ostream& O) {
-
-  if(P.Name == "root")
+void EmitToolClassDefinition (const ToolProperties& P,
+                              const GlobalOptionDescriptions& OptDescs,
+                              std::ostream& O) {
+  if (P.Name == "root")
     return;
 
   // Header
@@ -858,7 +1021,7 @@
   EmitInOutLanguageMethods(P, O);
   EmitOutputSuffixMethod(P, O);
   EmitIsJoinMethod(P, O);
-  EmitGenerateActionMethods(P, O);
+  EmitGenerateActionMethods(P, OptDescs, O);
   EmitIsLastMethod(P, O);
 
   // Close class definition
@@ -965,144 +1128,22 @@
     Record* B = Edge->getValueAsDef("b");
     StringMap<std::string>::iterator IA = ToolToOutLang.find(A->getName());
     StringMap<std::string>::iterator IB = ToolToInLang.find(B->getName());
-    if(IA == IAE)
+    if (IA == IAE)
       throw A->getName() + ": no such tool!";
-    if(IB == IBE)
+    if (IB == IBE)
       throw B->getName() + ": no such tool!";
-    if(A->getName() != "root" && IA->second != IB->second)
+    if (A->getName() != "root" && IA->second != IB->second)
       throw "Edge " + A->getName() + "->" + B->getName()
         + ": output->input language mismatch";
-    if(B->getName() == "root")
+    if (B->getName() == "root")
       throw std::string("Edges back to the root are not allowed!");
   }
 }
 
-/// EmitCaseTest1Arg - Helper function used by
-/// EmitCaseConstructHandler.
-bool EmitCaseTest1Arg(const std::string& TestName,
-                      const DagInit& d,
-                      const GlobalOptionDescriptions& OptDescs,
-                      std::ostream& O) {
-  checkNumberOfArguments(&d, 1);
-  const std::string& OptName = InitPtrToString(d.getArg(0));
-  if (TestName == "switch_on") {
-    const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
-    if (OptDesc.Type != OptionType::Switch)
-      throw OptName + ": incorrect option type!";
-    O << OptDesc.GenVariableName();
-    return true;
-  } else if (TestName == "input_languages_contain") {
-    O << "InLangs.count(\"" << OptName << "\") != 0";
-    return true;
-  }
-
-  return false;
-}
-
-/// EmitCaseTest2Args - Helper function used by
-/// EmitCaseConstructHandler.
-bool EmitCaseTest2Args(const std::string& TestName,
-                       const DagInit& d,
-                       const char* IndentLevel,
-                       const GlobalOptionDescriptions& OptDescs,
-                       std::ostream& O) {
-  checkNumberOfArguments(&d, 2);
-  const std::string& OptName = InitPtrToString(d.getArg(0));
-  const std::string& OptArg = InitPtrToString(d.getArg(1));
-  const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
-
-  if (TestName == "parameter_equals") {
-    if (OptDesc.Type != OptionType::Parameter
-        && OptDesc.Type != OptionType::Prefix)
-      throw OptName + ": incorrect option type!";
-    O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
-    return true;
-  }
-  else if (TestName == "element_in_list") {
-    if (OptDesc.Type != OptionType::ParameterList
-        && OptDesc.Type != OptionType::PrefixList)
-      throw OptName + ": incorrect option type!";
-    const std::string& VarName = OptDesc.GenVariableName();
-    O << "std::find(" << VarName << ".begin(),\n"
-      << IndentLevel << Indent1 << VarName << ".end(), \""
-      << OptArg << "\") != " << VarName << ".end()";
-    return true;
-  }
-
-  return false;
-}
-
-// Forward declaration.
-// EmitLogicalOperationTest and EmitCaseTest are mutually recursive.
-void EmitCaseTest(const DagInit& d, const char* IndentLevel,
-                  const GlobalOptionDescriptions& OptDescs,
-                  std::ostream& O);
-
-/// EmitLogicalOperationTest - Helper function used by
-/// EmitCaseConstructHandler.
-void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
-                              const char* IndentLevel,
-                              const GlobalOptionDescriptions& OptDescs,
-                              std::ostream& O) {
-  O << '(';
-  for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
-    const DagInit& InnerTest = InitPtrToDagInitRef(d.getArg(j));
-    EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
-    if (j != NumArgs - 1)
-      O << ")\n" << IndentLevel << Indent1 << ' ' << LogicOp << " (";
-    else
-      O << ')';
-  }
-}
-
-/// EmitCaseTest - Helper function used by EmitCaseConstructHandler.
-void EmitCaseTest(const DagInit& d, const char* IndentLevel,
-                  const GlobalOptionDescriptions& OptDescs,
-                  std::ostream& O) {
-  const std::string& TestName = d.getOperator()->getAsString();
-
-  if (TestName == "and")
-    EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
-  else if (TestName == "or")
-    EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O);
-  else if (EmitCaseTest1Arg(TestName, d, OptDescs, O))
-    return;
-  else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
-    return;
-  else
-    throw TestName + ": unknown edge property!";
-}
-
-// Emit code that handles the 'case' construct.
-// Takes a function object that should emit code for every case clause.
-template <typename F>
-void EmitCaseConstructHandler(DagInit* d, const char* IndentLevel,
-                              const F& Callback,
-                              const GlobalOptionDescriptions& OptDescs,
-                              std::ostream& O) {
-  assert(d->getOperator()->getAsString() == "case");
-
-  for (DagInit::arg_iterator B = d->arg_begin(), E = d->arg_end();
-       B != E; ++B) {
-    const DagInit& Test = InitPtrToDagInitRef(*B);
-    O << IndentLevel << "if (";
-    EmitCaseTest(Test, IndentLevel, OptDescs, O);
-    O << ") {\n";
-
-    ++B;
-    if (B == E)
-      throw "Case construct handler: no corresponding action "
-        "found for the test " + Test.getAsString() + '!';
-
-    const DagInit& Action = InitPtrToDagInitRef(*B);
-    Callback(IndentLevel, Action, O);
-    O << IndentLevel << "}\n";
-  }
-}
-
 // Helper function passed to EmitCaseConstructHandler by EmitEdgeClass.
-void IncDecWeight(const char* IndentLevel,
-                  const DagInit& d, std::ostream& O) {
+void IncDecWeight (const Init* i, const char* IndentLevel,
+                   std::ostream& O) {
+  const DagInit& d = InitPtrToDagInitRef(i);
   const std::string& OpName = d.getOperator()->getAsString();
 
   if (OpName == "inc_weight")
@@ -1120,9 +1161,9 @@
 }
 
 /// EmitEdgeClass - Emit a single Edge# class.
-void EmitEdgeClass(unsigned N, const std::string& Target,
-                   DagInit* Case, const GlobalOptionDescriptions& OptDescs,
-                   std::ostream& O) {
+void EmitEdgeClass (unsigned N, const std::string& Target,
+                    DagInit* Case, const GlobalOptionDescriptions& OptDescs,
+                    std::ostream& O) {
 
   // Class constructor.
   O << "class Edge" << N << ": public Edge {\n"
@@ -1178,7 +1219,7 @@
 
   for (RecordVector::iterator B = Tools.begin(), E = Tools.end(); B != E; ++B) {
     const std::string& Name = (*B)->getName();
-    if(Name != "root")
+    if (Name != "root")
       O << Indent1 << "G.insertNode(new "
         << Name << "());\n";
   }
@@ -1235,7 +1276,7 @@
   // Emit Tool classes.
   for (ToolPropertiesList::const_iterator B = tool_props.begin(),
          E = tool_props.end(); B!=E; ++B)
-    EmitToolClassDefinition(*(*B), O);
+    EmitToolClassDefinition(*(*B), opt_descs, O);
 
   Record* CompilationGraphRecord = Records.getDef("CompilationGraph");
   if (!CompilationGraphRecord)





More information about the llvm-commits mailing list