Add support for option aliases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51749 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index 08f008e..f527def 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -93,7 +93,9 @@
// A command-line option can have one of the following types:
//
-// Switch - a simple switch w/o arguments, e.g. -O2
+// Alias - an alias for another option.
+//
+// Switch - a simple switch without arguments, e.g. -O2
//
// Parameter - an option that takes one(and only one) argument, e.g. -o file,
// --output=file
@@ -105,10 +107,11 @@
// e.g. -Wa,-foo,-bar, -DNAME=VALUE
//
// PrefixList - same as Prefix, but more than one option occurence is
-// allowed
+// allowed.
namespace OptionType {
- enum OptionType { Switch, Parameter, ParameterList, Prefix, PrefixList};
+ enum OptionType { Alias, Switch,
+ Parameter, ParameterList, Prefix, PrefixList};
}
bool IsListOptionType (OptionType::OptionType t) {
@@ -133,6 +136,8 @@
const char* GenTypeDeclaration() const {
switch (Type) {
+ case OptionType::Alias:
+ return "cl::alias";
case OptionType::PrefixList:
case OptionType::ParameterList:
return "cl::list<std::string>";
@@ -164,18 +169,20 @@
std::string GenVariableName() const {
const std::string& EscapedName = EscapeVariableName(Name);
switch (Type) {
+ case OptionType::Alias:
+ return "AutoGeneratedAlias" + EscapedName;
case OptionType::Switch:
- return "AutoGeneratedSwitch" + EscapedName;
- case OptionType::Prefix:
- return "AutoGeneratedPrefix" + EscapedName;
- case OptionType::PrefixList:
- return "AutoGeneratedPrefixList" + EscapedName;
- case OptionType::Parameter:
- return "AutoGeneratedParameter" + EscapedName;
- case OptionType::ParameterList:
- default:
- return "AutoGeneratedParameterList" + EscapedName;
- }
+ return "AutoGeneratedSwitch" + EscapedName;
+ case OptionType::Prefix:
+ return "AutoGeneratedPrefix" + EscapedName;
+ case OptionType::PrefixList:
+ return "AutoGeneratedPrefixList" + EscapedName;
+ case OptionType::Parameter:
+ return "AutoGeneratedParameter" + EscapedName;
+ case OptionType::ParameterList:
+ default:
+ return "AutoGeneratedParameterList" + EscapedName;
+ }
}
};
@@ -195,8 +202,9 @@
GlobalOptionDescription() : OptionDescription(), Flags(0)
{}
- GlobalOptionDescription (OptionType::OptionType t, const std::string& n)
- : OptionDescription(t, n), Help(DefaultHelpString), Flags(0)
+ GlobalOptionDescription (OptionType::OptionType t, const std::string& n,
+ const std::string& h = DefaultHelpString)
+ : OptionDescription(t, n), Help(h), Flags(0)
{}
bool isRequired() const {
@@ -399,6 +407,7 @@
&CollectProperties::onPrefixList;
propertyHandlers_["sink"] = &CollectProperties::onSink;
propertyHandlers_["switch_option"] = &CollectProperties::onSwitch;
+ propertyHandlers_["alias_option"] = &CollectProperties::onAlias;
// Init option property handlers
optionPropertyHandlers_["append_cmd"] = &CollectProperties::onAppendCmd;
@@ -492,6 +501,15 @@
toolProps_.setSink();
}
+ void onAlias (const DagInit* d) {
+ checkNumberOfArguments(d, 2);
+ // We just need a GlobalOptionDescription for the aliases.
+ insertDescription
+ (GlobalOptionDescription(OptionType::Alias,
+ InitPtrToString(d->getArg(0)),
+ InitPtrToString(d->getArg(1))));
+ }
+
void onSwitch (const DagInit* d) {
addOption(d, OptionType::Switch);
}
@@ -842,6 +860,9 @@
<< Indent4 << "vec.push_back(*B);\n"
<< Indent3 << "}\n";
break;
+ case OptionType::Alias:
+ default:
+ throw std::string("Aliases are not allowed in tool option descriptions!");
}
}
@@ -1191,11 +1212,18 @@
void EmitOptionDescriptions (const GlobalOptionDescriptions& descs,
std::ostream& O)
{
+ std::vector<GlobalOptionDescription> Aliases;
+
// Emit static cl::Option variables
for (GlobalOptionDescriptions::const_iterator B = descs.begin(),
E = descs.end(); B!=E; ++B) {
const GlobalOptionDescription& val = B->second;
+ if (val.Type == OptionType::Alias) {
+ Aliases.push_back(val);
+ continue;
+ }
+
O << val.GenTypeDeclaration() << ' '
<< val.GenVariableName()
<< "(\"" << val.Name << '\"';
@@ -1214,9 +1242,32 @@
}
}
- O << ", cl::desc(\"" << val.Help << "\"));\n";
+ if (!val.Help.empty())
+ O << ", cl::desc(\"" << val.Help << "\")";
+
+ O << ");\n";
}
+ // Emit the aliases (they should go after all the 'proper' options).
+ for (std::vector<GlobalOptionDescription>::const_iterator
+ B = Aliases.begin(), E = Aliases.end(); B != E; ++B) {
+ const GlobalOptionDescription& val = *B;
+
+ O << val.GenTypeDeclaration() << ' '
+ << val.GenVariableName()
+ << "(\"" << val.Name << '\"';
+
+ GlobalOptionDescriptions::container_type
+ ::const_iterator F = descs.Descriptions.find(val.Help);
+ if (F != descs.Descriptions.end())
+ O << ", cl::aliasopt(" << F->second.GenVariableName() << ")";
+ else
+ throw val.Name + ": alias to an unknown option!";
+
+ O << ", cl::desc(\"" << "An alias for -" + val.Help << "\"));\n";
+ }
+
+ // Emit the sink option.
if (descs.HasSink)
O << "cl::list<std::string> " << SinkOptionName << "(cl::Sink);\n";