Option parsing: add support for alias arguments.

This makes option aliases more powerful by enabling them to
pass along arguments to the option they're aliasing.

For example, if we have a joined option "-foo=", we can now
specify a flag option "-bar" to be an alias of that, with the
argument "baz".

This is especially useful for the cl.exe compatible clang driver,
where many options are aliases. For example, this patch enables
us to alias "/Ox" to "-O3" (-O is a joined option), and "/WX" to
"-Werror" (again, -W is a joined option).

Differential Revision: http://llvm-reviews.chandlerc.com/D1245

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187537 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp
index 0c1f623..d37939f 100644
--- a/utils/TableGen/OptParserEmitter.cpp
+++ b/utils/TableGen/OptParserEmitter.cpp
@@ -152,11 +152,22 @@
   OS << "/////////\n";
   OS << "// Groups\n\n";
   OS << "#ifdef OPTION\n";
+
+  // FIXME: Remove when option parsing clients are updated.
+  OS << "#ifdef SUPPORT_ALIASARGS\n";
+  OS << "#define OPTIONX OPTION\n";
+  OS << "#else\n";
+  OS << "#define OPTIONX(prefix, name, id, kind, group, alias, aliasargs, "
+     << "flags, param, helptext, metavar) "
+     << "OPTION(prefix, name, id, kind, "
+     << "group, alias, flags, param, helptext, metavar)\n";
+  OS << "#endif\n";
+
   for (unsigned i = 0, e = Groups.size(); i != e; ++i) {
     const Record &R = *Groups[i];
 
     // Start a single option entry.
-    OS << "OPTION(";
+    OS << "OPTIONX(";
 
     // The option prefix;
     OS << "0";
@@ -178,7 +189,7 @@
       OS << "INVALID";
 
     // The other option arguments (unused for groups).
-    OS << ", INVALID, 0, 0";
+    OS << ", INVALID, 0, 0, 0";
 
     // The option help text.
     if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
@@ -199,7 +210,7 @@
     const Record &R = *Opts[i];
 
     // Start a single option entry.
-    OS << "OPTION(";
+    OS << "OPTIONX(";
 
     // The option prefix;
     std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
@@ -228,6 +239,21 @@
     else
       OS << "INVALID";
 
+    // The option alias arguments (if any).
+    // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
+    // would become "foo\0bar\0". Note that the compiler adds an implicit
+    // terminating \0 at the end.
+    OS << ", ";
+    std::vector<std::string> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
+    if (AliasArgs.size() == 0) {
+      OS << "0";
+    } else {
+      OS << "\"";
+      for (size_t i = 0, e = AliasArgs.size(); i != e; ++i)
+        OS << AliasArgs[i] << "\\0";
+      OS << "\"";
+    }
+
     // The option flags.
     const ListInit *LI = R.getValueAsListInit("Flags");
     if (LI->empty()) {
@@ -261,6 +287,7 @@
 
     OS << ")\n";
   }
+  OS << "#undef OPTIONX\n"; // FIXME: Remove when option clients are updated.
   OS << "#endif\n";
 }
 } // end namespace llvm