[llvm-commits] [llvm] r84450 - /llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Sun Oct 18 15:51:33 PDT 2009


Author: foldr
Date: Sun Oct 18 17:51:30 2009
New Revision: 84450

URL: http://llvm.org/viewvc/llvm-project?rev=84450&view=rev
Log:
Refactoring, no functionality change.

Modified:
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

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

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Sun Oct 18 17:51:30 2009
@@ -56,8 +56,14 @@
 
 /// Id - An 'identity' function object.
 struct Id {
-  template<typename T>
-  void operator()(const T&) const {
+  template<typename T0>
+  void operator()(const T0&) const {
+  }
+  template<typename T0, typename T1>
+  void operator()(const T0&, const T1&) const {
+  }
+  template<typename T0, typename T1, typename T2>
+  void operator()(const T0&, const T1&, const T2&) const {
   }
 };
 
@@ -81,16 +87,24 @@
   return val;
 }
 
+const std::string GetOperatorName(const DagInit* D) {
+  return D->getOperator()->getAsString();
+}
+
+const std::string GetOperatorName(const DagInit& D) {
+  return GetOperatorName(&D);
+}
+
 // checkNumberOfArguments - Ensure that the number of args in d is
 // greater than or equal to min_arguments, otherwise throw an exception.
 void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) {
   if (!d || d->getNumArgs() < min_arguments)
-    throw d->getOperator()->getAsString() + ": too few arguments!";
+    throw GetOperatorName(d) + ": too few arguments!";
 }
 
 // isDagEmpty - is this DAG marked with an empty marker?
 bool isDagEmpty (const DagInit* d) {
-  return d->getOperator()->getAsString() == "empty_dag_marker";
+  return GetOperatorName(d) == "empty_dag_marker";
 }
 
 // EscapeVariableName - Escape commas and other symbols not allowed
@@ -421,7 +435,7 @@
   /// handler.
   void operator() (Init* i) {
     const DagInit& property = InitPtrToDag(i);
-    const std::string& property_name = property.getOperator()->getAsString();
+    const std::string& property_name = GetOperatorName(property);
     typename HandlerMap::iterator method = Handlers_.find(property_name);
 
     if (method != Handlers_.end()) {
@@ -570,7 +584,7 @@
     checkNumberOfArguments(&d, 1);
 
     const OptionType::OptionType Type =
-      stringToOptionType(d.getOperator()->getAsString());
+      stringToOptionType(GetOperatorName(d));
     const std::string& Name = InitPtrToString(d.getArg(0));
 
     OptionDescription OD(Type, Name);
@@ -690,7 +704,7 @@
     checkNumberOfArguments(d, 1);
     Init* Case = d->getArg(0);
     if (typeid(*Case) != typeid(DagInit) ||
-        static_cast<DagInit*>(Case)->getOperator()->getAsString() != "case")
+        GetOperatorName(static_cast<DagInit*>(Case)) != "case")
       throw
         std::string("The argument to (actions) should be a 'case' construct!");
     toolDesc_.Actions = Case;
@@ -892,22 +906,60 @@
 /// WalkCase - Walks the 'case' expression DAG and invokes
 /// TestCallback on every test, and StatementCallback on every
 /// statement. Handles 'case' nesting, but not the 'and' and 'or'
-/// combinators.
-// TODO: Re-implement EmitCaseConstructHandler on top of this function?
+/// combinators (that is, they are passed directly to TestCallback).
+/// TestCallback must have type 'void TestCallback(const DagInit*, unsigned
+/// IndentLevel, bool FirstTest)'.
+/// StatementCallback must have type 'void StatementCallback(const Init*,
+/// unsigned IndentLevel)'.
 template <typename F1, typename F2>
-void WalkCase(Init* Case, F1 TestCallback, F2 StatementCallback) {
+void WalkCase(const Init* Case, F1 TestCallback, F2 StatementCallback,
+              unsigned IndentLevel = 0)
+{
   const DagInit& d = InitPtrToDag(Case);
+
+  // Error checks.
+  if (GetOperatorName(d) != "case")
+    throw std::string("WalkCase should be invoked only on 'case' expressions!");
+
+  if (d.getNumArgs() < 2)
+    throw "There should be at least one clause in the 'case' expression:\n"
+      + d.getAsString();
+
+  // Main loop.
   bool even = false;
+  const unsigned numArgs = d.getNumArgs();
+  unsigned i = 1;
   for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end();
        B != E; ++B) {
     Init* arg = *B;
-    if (even && dynamic_cast<DagInit*>(arg)
-        && static_cast<DagInit*>(arg)->getOperator()->getAsString() == "case")
-      WalkCase(arg, TestCallback, StatementCallback);
-    else if (!even)
-      TestCallback(arg);
+
+    if (!even)
+    {
+      // Handle test.
+      const DagInit& Test = InitPtrToDag(arg);
+
+      if (GetOperatorName(Test) == "default" && (i+1 != numArgs))
+        throw std::string("The 'default' clause should be the last in the"
+                          "'case' construct!");
+      if (i == numArgs)
+        throw "Case construct handler: no corresponding action "
+          "found for the test " + Test.getAsString() + '!';
+
+      TestCallback(&Test, IndentLevel, (i == 1));
+    }
     else
-      StatementCallback(arg);
+    {
+      if (dynamic_cast<DagInit*>(arg)
+          && GetOperatorName(static_cast<DagInit*>(arg)) == "case") {
+        // Nested 'case'.
+        WalkCase(arg, TestCallback, StatementCallback, IndentLevel + Indent1);
+      }
+
+      // Handle statement.
+      StatementCallback(arg, IndentLevel);
+    }
+
+    ++i;
     even = !even;
   }
 }
@@ -919,7 +971,7 @@
 
   void processDag(const Init* Statement) {
     const DagInit& Stmt = InitPtrToDag(Statement);
-    const std::string& ActionName = Stmt.getOperator()->getAsString();
+    const std::string& ActionName = GetOperatorName(Stmt);
     if (ActionName == "forward" || ActionName == "forward_as" ||
         ActionName == "unpack_values" || ActionName == "switch_on" ||
         ActionName == "parameter_equals" || ActionName == "element_in_list" ||
@@ -950,6 +1002,13 @@
       this->processDag(Statement);
     }
   }
+
+  void operator()(const DagInit* Test, unsigned, bool) {
+    this->operator()(Test);
+  }
+  void operator()(const Init* Statement, unsigned) {
+    this->operator()(Statement);
+  }
 };
 
 /// CheckForSuperfluousOptions - Check that there are no side
@@ -1164,7 +1223,7 @@
 void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
                   const OptionDescriptions& OptDescs,
                   raw_ostream& O) {
-  const std::string& TestName = d.getOperator()->getAsString();
+  const std::string& TestName = GetOperatorName(d);
 
   if (TestName == "and")
     EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
@@ -1182,63 +1241,70 @@
     throw TestName + ": unknown edge property!";
 }
 
+
+/// EmitCaseTestCallback - Callback used by EmitCaseConstructHandler.
+class EmitCaseTestCallback {
+  bool EmitElseIf_;
+  const OptionDescriptions& OptDescs_;
+  raw_ostream& O_;
+public:
+
+  EmitCaseTestCallback(bool EmitElseIf,
+                       const OptionDescriptions& OptDescs, raw_ostream& O)
+    : EmitElseIf_(EmitElseIf), OptDescs_(OptDescs), O_(O)
+  {}
+
+  void operator()(const DagInit* Test, unsigned IndentLevel, bool FirstTest)
+  {
+    if (GetOperatorName(Test) == "default") {
+      O_.indent(IndentLevel) << "else {\n";
+    }
+    else {
+      O_.indent(IndentLevel)
+        << ((!FirstTest && EmitElseIf_) ? "else if (" : "if (");
+      EmitCaseTest(*Test, IndentLevel, OptDescs_, O_);
+      O_ << ") {\n";
+    }
+  }
+};
+
+/// EmitCaseStatementCallback - Callback used by EmitCaseConstructHandler.
+template <typename F>
+class EmitCaseStatementCallback {
+  F Callback_;
+  raw_ostream& O_;
+public:
+
+  EmitCaseStatementCallback(F Callback, raw_ostream& O)
+    : Callback_(Callback), O_(O)
+  {}
+
+  // TODO: Handle lists here.
+  void operator() (const Init* Statement, unsigned IndentLevel) {
+    // Ignore nested 'case' DAG.
+    if (!(dynamic_cast<const DagInit*>(Statement) &&
+          GetOperatorName(static_cast<const DagInit*>(Statement)) == "case"))
+      Callback_(Statement, (IndentLevel + Indent1), O_);
+    O_.indent(IndentLevel) << "}\n";
+  }
+
+};
+
 /// EmitCaseConstructHandler - Emit code that handles the 'case'
 /// construct. Takes a function object that should emit code for every case
-/// clause.
+/// clause. Implemented on top of WalkCase.
 /// Callback's type is void F(Init* Statement, unsigned IndentLevel,
 /// raw_ostream& O).
 /// EmitElseIf parameter controls the type of condition that is emitted ('if
-/// (..) {...} else if (...) {} ... else {...}' vs. 'if (..)  {...} if(...)
-/// {...} ...').
+/// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..)  {..}
+/// .. else {..}').
 template <typename F>
-void EmitCaseConstructHandler(const Init* Dag, unsigned IndentLevel,
+void EmitCaseConstructHandler(const Init* Case, unsigned IndentLevel,
                               F Callback, bool EmitElseIf,
                               const OptionDescriptions& OptDescs,
                               raw_ostream& O) {
-  const DagInit* d = &InitPtrToDag(Dag);
-  if (d->getOperator()->getAsString() != "case")
-    throw std::string("EmitCaseConstructHandler should be invoked"
-                      " only on 'case' expressions!");
-
-  unsigned numArgs = d->getNumArgs();
-  if (d->getNumArgs() < 2)
-    throw "There should be at least one clause in the 'case' expression:\n"
-      + d->getAsString();
-
-  for (unsigned i = 0; i != numArgs; ++i) {
-    const DagInit& Test = InitPtrToDag(d->getArg(i));
-
-    // Emit the test.
-    if (Test.getOperator()->getAsString() == "default") {
-      if (i+2 != numArgs)
-        throw std::string("The 'default' clause should be the last in the"
-                          "'case' construct!");
-      O.indent(IndentLevel) << "else {\n";
-    }
-    else {
-      O.indent(IndentLevel) << ((i != 0 && EmitElseIf) ? "else if (" : "if (");
-      EmitCaseTest(Test, IndentLevel, OptDescs, O);
-      O << ") {\n";
-    }
-
-    // Emit the corresponding statement.
-    ++i;
-    if (i == numArgs)
-      throw "Case construct handler: no corresponding action "
-        "found for the test " + Test.getAsString() + '!';
-
-    Init* arg = d->getArg(i);
-    const DagInit* nd = dynamic_cast<DagInit*>(arg);
-    if (nd && (nd->getOperator()->getAsString() == "case")) {
-      // Handle the nested 'case'.
-      EmitCaseConstructHandler(nd, (IndentLevel + Indent1),
-                               Callback, EmitElseIf, OptDescs, O);
-    }
-    else {
-      Callback(arg, (IndentLevel + Indent1), O);
-    }
-    O.indent(IndentLevel) << "}\n";
-  }
+  WalkCase(Case, EmitCaseTestCallback(EmitElseIf, OptDescs, O),
+           EmitCaseStatementCallback<F>(Callback, O), IndentLevel);
 }
 
 /// TokenizeCmdline - converts from "$CALL(HookName, 'Arg1', 'Arg2')/path" to
@@ -1546,7 +1612,7 @@
                         raw_ostream& O) const
   {
     const DagInit& Dag = InitPtrToDag(Statement);
-    const std::string& ActionName = Dag.getOperator()->getAsString();
+    const std::string& ActionName = GetOperatorName(Dag);
 
     if (ActionName == "append_cmd") {
       checkNumberOfArguments(&Dag, 1);
@@ -1655,9 +1721,20 @@
   {}
 
   void operator()(const Init* CmdLine) {
+    // Ignore nested 'case' DAG.
+    if (typeid(*CmdLine) == typeid(DagInit))
+      return;
+
     if (IsOutFileIndexCheckRequiredStr(CmdLine))
       *ret_ = true;
   }
+
+  void operator()(const DagInit* Test, unsigned, bool) {
+    this->operator()(Test);
+  }
+  void operator()(const Init* Statement, unsigned) {
+    this->operator()(Statement);
+  }
 };
 
 bool IsOutFileIndexCheckRequiredCase (Init* CmdLine) {
@@ -1958,7 +2035,7 @@
   void processDag(const Init* I, unsigned IndentLevel, raw_ostream& O)
   {
     const DagInit& d = InitPtrToDag(I);
-    const std::string& OpName = d.getOperator()->getAsString();
+    const std::string& OpName = GetOperatorName(d);
 
     // TOFIX: there is some duplication between this function and
     // EmitActionHandler.
@@ -2067,7 +2144,7 @@
 void IncDecWeight (const Init* i, unsigned IndentLevel,
                    raw_ostream& O) {
   const DagInit& d = InitPtrToDag(i);
-  const std::string& OpName = d.getOperator()->getAsString();
+  const std::string& OpName = GetOperatorName(d);
 
   if (OpName == "inc_weight") {
     O.indent(IndentLevel) << "ret += ";
@@ -2183,6 +2260,11 @@
 
   void operator()(const Init* CmdLine) {
     StrVector cmds;
+
+    // Ignore nested 'case' DAG.
+    if (typeid(*CmdLine) == typeid(DagInit))
+      return;
+
     TokenizeCmdline(InitPtrToString(CmdLine), cmds);
     for (StrVector::const_iterator B = cmds.begin(), E = cmds.end();
          B != E; ++B) {
@@ -2212,6 +2294,13 @@
       }
     }
   }
+
+  void operator()(const DagInit* Test, unsigned, bool) {
+    this->operator()(Test);
+  }
+  void operator()(const Init* Statement, unsigned) {
+    this->operator()(Statement);
+  }
 };
 
 /// FillInHookNames - Actually extract the hook names from all command





More information about the llvm-commits mailing list