summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorMikhail Glushenkov <foldr@codedgers.com>2009-10-18 22:51:30 +0000
committerMikhail Glushenkov <foldr@codedgers.com>2009-10-18 22:51:30 +0000
commit4d21ae7cf40704c7f4f8b9c9bdaa97ead532b412 (patch)
tree6970d0324d4caf6084c583d28f395ee94e1dbcf1 /utils/TableGen
parent38bdfc69cbe370ce5f623df4449afa32cda97422 (diff)
downloadllvm-4d21ae7cf40704c7f4f8b9c9bdaa97ead532b412.tar.gz
llvm-4d21ae7cf40704c7f4f8b9c9bdaa97ead532b412.tar.bz2
llvm-4d21ae7cf40704c7f4f8b9c9bdaa97ead532b412.tar.xz
Refactoring, no functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84450 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp227
1 files changed, 158 insertions, 69 deletions
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index a8eaa3a16a..f73c09acce 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -56,8 +56,14 @@ const char * SinkOptionName = "AutoGeneratedSinkOption";
/// 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 @@ const DagInit& InitPtrToDag(const Init* ptr) {
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 @@ public:
/// 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 @@ public:
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 @@ private:
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 @@ void TypecheckGraph (const RecordVector& EdgeVector,
/// 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 @@ class ExtractOptionNames {
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 @@ public:
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 EmitLogicalNot(const DagInit& d, unsigned IndentLevel,
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 @@ void EmitCaseTest(const DagInit& d, unsigned IndentLevel,
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 @@ class EmitActionHandler {
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 @@ public:
{}
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 @@ class PreprocessOptionsCallback {
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 EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
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 @@ public:
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 @@ public:
}
}
}
+
+ 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