summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorMikhail Glushenkov <foldr@codedgers.com>2009-10-21 02:13:13 +0000
committerMikhail Glushenkov <foldr@codedgers.com>2009-10-21 02:13:13 +0000
commit4858a1d51e579331ac4285243e187b3dfd5c2806 (patch)
tree1b30687de567e235d9df71fb7e8539e022d2498e /utils/TableGen
parentc1ae8c9b8f426b74215abf0f7e46bffecc6f52d9 (diff)
downloadllvm-4858a1d51e579331ac4285243e187b3dfd5c2806.tar.gz
llvm-4858a1d51e579331ac4285243e187b3dfd5c2806.tar.bz2
llvm-4858a1d51e579331ac4285243e187b3dfd5c2806.tar.xz
Implement any_[not_]empty and list versions of switch_on and [not_]empty.
Useful for OptionPreprocessor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84728 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/LLVMCConfigurationEmitter.cpp206
1 files changed, 146 insertions, 60 deletions
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index 309983aeeb..4293c95fd2 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -146,6 +146,18 @@ void checkedIncrement(I& P, I E, S ErrorString) {
throw ErrorString;
}
+// apply is needed because C++'s syntax doesn't let us construct a function
+// object and call it in the same statement.
+template<typename F, typename T0>
+void apply(F Fun, T0& Arg0) {
+ return Fun(Arg0);
+}
+
+template<typename F, typename T0, typename T1>
+void apply(F Fun, T0& Arg0, T1& Arg1) {
+ return Fun(Arg0, Arg1);
+}
+
//===----------------------------------------------------------------------===//
/// Back-end specific code
@@ -157,6 +169,10 @@ namespace OptionType {
enum OptionType { Alias, Switch, Parameter, ParameterList,
Prefix, PrefixList};
+ bool IsAlias(OptionType t) {
+ return (t == Alias);
+ }
+
bool IsList (OptionType t) {
return (t == ParameterList || t == PrefixList);
}
@@ -245,12 +261,12 @@ struct OptionDescription {
bool isReallyHidden() const;
void setReallyHidden();
- bool isParameter() const
- { return OptionType::IsParameter(this->Type); }
-
bool isSwitch() const
{ return OptionType::IsSwitch(this->Type); }
+ bool isParameter() const
+ { return OptionType::IsParameter(this->Type); }
+
bool isList() const
{ return OptionType::IsList(this->Type); }
@@ -272,7 +288,7 @@ void OptionDescription::Merge (const OptionDescription& other)
}
bool OptionDescription::isAlias() const {
- return Type == OptionType::Alias;
+ return OptionType::IsAlias(this->Type);
}
bool OptionDescription::isMultiVal() const {
@@ -365,9 +381,14 @@ class OptionDescriptions {
public:
/// FindOption - exception-throwing wrapper for find().
const OptionDescription& FindOption(const std::string& OptName) const;
- /// FindSwitch - wrapper for FindOption that throws in case the option is not
- /// a switch.
+
+ // Wrappers for FindOption that throw an exception in case the option has a
+ // wrong type.
const OptionDescription& FindSwitch(const std::string& OptName) const;
+ const OptionDescription& FindParameter(const std::string& OptName) const;
+ const OptionDescription& FindList(const std::string& OptName) const;
+ const OptionDescription&
+ FindListOrParameter(const std::string& OptName) const;
/// insertDescription - Insert new OptionDescription into
/// OptionDescriptions list
@@ -380,8 +401,7 @@ public:
};
const OptionDescription&
-OptionDescriptions::FindOption(const std::string& OptName) const
-{
+OptionDescriptions::FindOption(const std::string& OptName) const {
const_iterator I = Descriptions.find(OptName);
if (I != Descriptions.end())
return I->second;
@@ -390,16 +410,39 @@ OptionDescriptions::FindOption(const std::string& OptName) const
}
const OptionDescription&
-OptionDescriptions::FindSwitch(const std::string& OptName) const
-{
+OptionDescriptions::FindSwitch(const std::string& OptName) const {
const OptionDescription& OptDesc = this->FindOption(OptName);
if (!OptDesc.isSwitch())
throw OptName + ": incorrect option type - should be a switch!";
return OptDesc;
}
-void OptionDescriptions::InsertDescription (const OptionDescription& o)
-{
+const OptionDescription&
+OptionDescriptions::FindList(const std::string& OptName) const {
+ const OptionDescription& OptDesc = this->FindOption(OptName);
+ if (!OptDesc.isList())
+ throw OptName + ": incorrect option type - should be a list!";
+ return OptDesc;
+}
+
+const OptionDescription&
+OptionDescriptions::FindParameter(const std::string& OptName) const {
+ const OptionDescription& OptDesc = this->FindOption(OptName);
+ if (!OptDesc.isParameter())
+ throw OptName + ": incorrect option type - should be a parameter!";
+ return OptDesc;
+}
+
+const OptionDescription&
+OptionDescriptions::FindListOrParameter(const std::string& OptName) const {
+ const OptionDescription& OptDesc = this->FindOption(OptName);
+ if (!OptDesc.isList() && !OptDesc.isParameter())
+ throw OptName
+ + ": incorrect option type - should be a list or parameter!";
+ return OptDesc;
+}
+
+void OptionDescriptions::InsertDescription (const OptionDescription& o) {
container_type::iterator I = Descriptions.find(o.Name);
if (I != Descriptions.end()) {
OptionDescription& D = I->second;
@@ -1067,49 +1110,57 @@ bool EmitCaseTest0Args(const std::string& TestName, raw_ostream& O) {
return false;
}
-/// EmitCaseTest1ArgStr - Helper function used by EmitCaseTest1Arg();
-bool EmitCaseTest1ArgStr(const std::string& TestName,
- const DagInit& d,
- const OptionDescriptions& OptDescs,
- raw_ostream& O) {
- const std::string& OptName = InitPtrToString(d.getArg(0));
+/// EmitListTest - Helper function used by EmitCaseTest1ArgList().
+template <typename F>
+void EmitListTest(const ListInit& L, const char* LogicOp,
+ F Callback, raw_ostream& O)
+{
+ // This is a lot like EmitLogicalOperationTest, but works on ListInits instead
+ // of Dags...
+ bool isFirst = true;
+ for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B) {
+ if (isFirst)
+ isFirst = false;
+ else
+ O << " || ";
+ Callback(InitPtrToString(*B), O);
+ }
+}
- if (TestName == "switch_on") {
- const OptionDescription& OptDesc = OptDescs.FindSwitch(OptName);
+// Callbacks for use with EmitListTest.
+
+class EmitSwitchOn {
+ const OptionDescriptions& OptDescs_;
+public:
+ EmitSwitchOn(const OptionDescriptions& OptDescs) : OptDescs_(OptDescs)
+ {}
+
+ void operator()(const std::string& OptName, raw_ostream& O) const {
+ const OptionDescription& OptDesc = OptDescs_.FindSwitch(OptName);
O << OptDesc.GenVariableName();
- return true;
- }
- else if (TestName == "input_languages_contain") {
- O << "InLangs.count(\"" << OptName << "\") != 0";
- return true;
}
- else if (TestName == "in_language") {
- // This works only for single-argument Tool::GenerateAction. Join
- // tools can process several files in different languages simultaneously.
+};
- // TODO: make this work with Edge::Weight (if possible).
- O << "LangMap.GetLanguage(inFile) == \"" << OptName << '\"';
- return true;
- }
- else if (TestName == "not_empty" || TestName == "empty") {
- const char* Test = (TestName == "empty") ? "" : "!";
+class EmitEmptyTest {
+ bool EmitNegate_;
+ const OptionDescriptions& OptDescs_;
+public:
+ EmitEmptyTest(bool EmitNegate, const OptionDescriptions& OptDescs)
+ : EmitNegate_(EmitNegate), OptDescs_(OptDescs)
+ {}
+ void operator()(const std::string& OptName, raw_ostream& O) const {
+ const char* Neg = (EmitNegate_ ? "!" : "");
if (OptName == "o") {
- O << Test << "OutputFilename.empty()";
- return true;
+ O << Neg << "OutputFilename.empty()";
}
else {
- const OptionDescription& OptDesc = OptDescs.FindOption(OptName);
- if (OptDesc.isSwitch())
- throw OptName
- + ": incorrect option type - should be a list or parameter!";
- O << Test << OptDesc.GenVariableName() << ".empty()";
- return true;
+ const OptionDescription& OptDesc = OptDescs_.FindListOrParameter(OptName);
+ O << Neg << OptDesc.GenVariableName() << ".empty()";
}
}
+};
- return false;
-}
/// EmitCaseTest1ArgList - Helper function used by EmitCaseTest1Arg();
bool EmitCaseTest1ArgList(const std::string& TestName,
@@ -1119,23 +1170,61 @@ bool EmitCaseTest1ArgList(const std::string& TestName,
const ListInit& L = *static_cast<ListInit*>(d.getArg(0));
if (TestName == "any_switch_on") {
- bool isFirst = true;
+ EmitListTest(L, "||", EmitSwitchOn(OptDescs), O);
+ return true;
+ }
+ else if (TestName == "switch_on") {
+ EmitListTest(L, "&&", EmitSwitchOn(OptDescs), O);
+ return true;
+ }
+ else if (TestName == "any_not_empty") {
+ EmitListTest(L, "||", EmitEmptyTest(true, OptDescs), O);
+ return true;
+ }
+ else if (TestName == "any_empty") {
+ EmitListTest(L, "||", EmitEmptyTest(false, OptDescs), O);
+ return true;
+ }
+ else if (TestName == "not_empty") {
+ EmitListTest(L, "&&", EmitEmptyTest(true, OptDescs), O);
+ return true;
+ }
+ else if (TestName == "empty") {
+ EmitListTest(L, "&&", EmitEmptyTest(false, OptDescs), O);
+ return true;
+ }
- for (ListInit::const_iterator B = L.begin(), E = L.end(); B != E; ++B) {
- const std::string& OptName = InitPtrToString(*B);
- const OptionDescription& OptDesc = OptDescs.FindSwitch(OptName);
+ return false;
+}
- if (isFirst)
- isFirst = false;
- else
- O << " || ";
- O << OptDesc.GenVariableName();
- }
+/// EmitCaseTest1ArgStr - Helper function used by EmitCaseTest1Arg();
+bool EmitCaseTest1ArgStr(const std::string& TestName,
+ const DagInit& d,
+ const OptionDescriptions& OptDescs,
+ raw_ostream& O) {
+ const std::string& OptName = InitPtrToString(d.getArg(0));
+ if (TestName == "switch_on") {
+ apply(EmitSwitchOn(OptDescs), OptName, O);
+ return true;
+ }
+ else if (TestName == "input_languages_contain") {
+ O << "InLangs.count(\"" << OptName << "\") != 0";
return true;
}
+ else if (TestName == "in_language") {
+ // This works only for single-argument Tool::GenerateAction. Join
+ // tools can process several files in different languages simultaneously.
- // TODO: implement any_not_empty, any_empty, switch_on [..], empty [..]
+ // TODO: make this work with Edge::Weight (if possible).
+ O << "LangMap.GetLanguage(inFile) == \"" << OptName << '\"';
+ return true;
+ }
+ else if (TestName == "not_empty" || TestName == "empty") {
+ bool EmitNegate = (TestName == "not_empty");
+ apply(EmitEmptyTest(EmitNegate, OptDescs), OptName, O);
+ return true;
+ }
return false;
}
@@ -1161,17 +1250,14 @@ bool EmitCaseTest2Args(const std::string& TestName,
checkNumberOfArguments(&d, 2);
const std::string& OptName = InitPtrToString(d.getArg(0));
const std::string& OptArg = InitPtrToString(d.getArg(1));
- const OptionDescription& OptDesc = OptDescs.FindOption(OptName);
if (TestName == "parameter_equals") {
- if (!OptDesc.isParameter())
- throw OptName + ": incorrect option type - should be a parameter!";
+ const OptionDescription& OptDesc = OptDescs.FindParameter(OptName);
O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
return true;
}
else if (TestName == "element_in_list") {
- if (!OptDesc.isList())
- throw OptName + ": incorrect option type - should be a list!";
+ const OptionDescription& OptDesc = OptDescs.FindList(OptName);
const std::string& VarName = OptDesc.GenVariableName();
O << "std::find(" << VarName << ".begin(),\n";
O.indent(IndentLevel + Indent1)