Make 'extern' an option property.

Makes (forward) work better.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60667 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp
index eda45c7..8e672ad 100644
--- a/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -85,7 +85,7 @@
 // checkNumberOfArguments - Ensure that the number of args in d is
 // less than or equal to min_arguments, otherwise throw an exception.
 void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) {
-  if (d->getNumArgs() < min_arguments)
+  if (!d || d->getNumArgs() < min_arguments)
     throw "Property " + d->getOperator()->getAsString()
       + " has too few arguments!";
 }
@@ -127,19 +127,18 @@
 /// Extern* options are those that are defined in some other plugin.
 namespace OptionType {
   enum OptionType { Alias, Switch, Parameter, ParameterList,
-                    Prefix, PrefixList,
-                    ExternSwitch, ExternParameter, ExternList };
+                    Prefix, PrefixList};
 
 bool IsList (OptionType t) {
-  return (t == ParameterList || t == PrefixList || t == ExternList);
+  return (t == ParameterList || t == PrefixList);
 }
 
 bool IsSwitch (OptionType t) {
-  return (t == Switch || t == ExternSwitch);
+  return (t == Switch);
 }
 
 bool IsParameter (OptionType t) {
-  return (t == Parameter || t == Prefix || t == ExternParameter);
+  return (t == Parameter || t == Prefix);
 }
 
 }
@@ -157,19 +156,13 @@
     return OptionType::Prefix;
   else if (T == "prefix_list_option")
     return OptionType::PrefixList;
-  else if (T == "extern_switch")
-    return OptionType::ExternSwitch;
-  else if (T == "extern_parameter")
-    return OptionType::ExternParameter;
-  else if (T == "extern_list")
-    return OptionType::ExternList;
   else
     throw "Unknown option type: " + T + '!';
 }
 
 namespace OptionDescriptionFlags {
   enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
-                                ReallyHidden = 0x4 };
+                                ReallyHidden = 0x4, Extern = 0x8 };
 }
 
 /// OptionDescription - Represents data contained in a single
@@ -200,7 +193,9 @@
   // Misc convenient getters/setters.
 
   bool isAlias() const;
+
   bool isExtern() const;
+  void setExtern();
 
   bool isRequired() const;
   void setRequired();
@@ -232,8 +227,10 @@
 }
 
 bool OptionDescription::isExtern() const {
-  return (Type == OptionType::ExternList || Type == OptionType::ExternParameter
-          || Type == OptionType::ExternSwitch);
+  return Flags & OptionDescriptionFlags::Extern;
+}
+void OptionDescription::setExtern() {
+  Flags |= OptionDescriptionFlags::Extern;
 }
 
 bool OptionDescription::isRequired() const {
@@ -261,14 +258,11 @@
   switch (Type) {
   case OptionType::Alias:
     return "cl::alias";
-  case OptionType::ExternList:
   case OptionType::PrefixList:
   case OptionType::ParameterList:
     return "cl::list<std::string>";
   case OptionType::Switch:
-  case OptionType::ExternSwitch:
     return "cl::opt<bool>";
-  case OptionType::ExternParameter:
   case OptionType::Parameter:
   case OptionType::Prefix:
   default:
@@ -283,12 +277,9 @@
     return "AutoGeneratedAlias_" + EscapedName;
   case OptionType::PrefixList:
   case OptionType::ParameterList:
-  case OptionType::ExternList:
     return "AutoGeneratedList_" + EscapedName;
-  case OptionType::ExternSwitch:
   case OptionType::Switch:
     return "AutoGeneratedSwitch_" + EscapedName;
-  case OptionType::ExternParameter:
   case OptionType::Prefix:
   case OptionType::Parameter:
   default:
@@ -402,6 +393,7 @@
     : HandlerTable<CollectOptionProperties>(this), optDesc_(OD)
   {
     if (!staticMembersInitialized_) {
+      AddHandler("extern", &CollectOptionProperties::onExtern);
       AddHandler("help", &CollectOptionProperties::onHelp);
       AddHandler("hidden", &CollectOptionProperties::onHidden);
       AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden);
@@ -416,39 +408,31 @@
   /// Option property handlers --
   /// Methods that handle option properties such as (help) or (hidden).
 
+  void onExtern (const DagInit* d) {
+    checkNumberOfArguments(d, 0);
+    optDesc_.setExtern();
+  }
+
   void onHelp (const DagInit* d) {
     checkNumberOfArguments(d, 1);
-    const std::string& help_message = InitPtrToString(d->getArg(0));
-    optDesc_.Help = help_message;
+    optDesc_.Help = InitPtrToString(d->getArg(0));
   }
 
   void onHidden (const DagInit* d) {
     checkNumberOfArguments(d, 0);
-    checkToolProps(d);
     optDesc_.setHidden();
   }
 
   void onReallyHidden (const DagInit* d) {
     checkNumberOfArguments(d, 0);
-    checkToolProps(d);
     optDesc_.setReallyHidden();
   }
 
   void onRequired (const DagInit* d) {
     checkNumberOfArguments(d, 0);
-    checkToolProps(d);
     optDesc_.setRequired();
   }
 
-  // Helper functions
-
-  /// checkToolProps - Throw an error if toolProps_ == 0.
-  void checkToolProps(const DagInit* d) {
-    if (!d)
-      throw "Option property " + d->getOperator()->getAsString()
-        + " can't be used in this context";
-  }
-
 };
 
 /// AddOption - A function object that is applied to every option
@@ -1163,11 +1147,9 @@
 
   switch (D.Type) {
   case OptionType::Switch:
-  case OptionType::ExternSwitch:
     O << Indent << "vec.push_back(\"" << Name << "\");\n";
     break;
   case OptionType::Parameter:
-  case OptionType::ExternParameter:
     O << Indent << "vec.push_back(\"" << Name << "\");\n";
     O << Indent << "vec.push_back(" << D.GenVariableName() << ");\n";
     break;
@@ -1183,7 +1165,6 @@
       << "*B);\n";
     break;
   case OptionType::ParameterList:
-  case OptionType::ExternList:
     O << Indent << "for (" << D.GenTypeDeclaration()
       << "::iterator B = " << D.GenVariableName() << ".begin(),\n"
       << Indent << "E = " << D.GenVariableName()