[Options] Add prefixes to options.

Each option has a set of prefixes. When matching an argument such as
-funroll-loops. First the leading - is removed as it is a prefix. Then
a lower_bound search for "funroll-loops" is done against the option table by
option name. From there each option prefix + option name combination is tested
against the argument.

This allows us to support Microsoft style options where both / and - are valid
prefixes. It also simplifies the cases we already have where options come in
both - and -- forms. Almost every option for gnu-ld happens to have this form.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166444 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp
index 9b4bc29..f095a28 100644
--- a/utils/TableGen/OptParserEmitter.cpp
+++ b/utils/TableGen/OptParserEmitter.cpp
@@ -7,9 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/TableGenBackend.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+
+#include <map>
+
 using namespace llvm;
 
 static int StrCmpOptionName(const char *A, const char *B) {
@@ -47,10 +53,32 @@
                                    B->getValueAsString("Name").c_str()))
     return Cmp;
 
+  if (!ASent) {
+    std::vector<std::string> APrefixes = A->getValueAsListOfStrings("Prefixes");
+    std::vector<std::string> BPrefixes = B->getValueAsListOfStrings("Prefixes");
+
+    for (std::vector<std::string>::const_iterator APre = APrefixes.begin(),
+                                                  AEPre = APrefixes.end(),
+                                                  BPre = BPrefixes.begin(),
+                                                  BEPre = BPrefixes.end();
+                                                  APre != AEPre &&
+                                                  BPre != BEPre;
+                                                  ++APre, ++BPre) {
+      if (int Cmp = StrCmpOptionName(APre->c_str(), BPre->c_str()))
+        return Cmp;
+    }
+  }
+
   // Then by the kind precedence;
   int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence");
   int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence");
-  assert(APrec != BPrec && "Options are equivalent!");
+  if (APrec == BPrec &&
+      A->getValueAsListOfStrings("Prefixes") ==
+      B->getValueAsListOfStrings("Prefixes")) {
+    PrintError(A->getLoc(), Twine("Option is equivilent to"));
+    PrintError(B->getLoc(), Twine("Other defined here"));
+    throw "Eqivilant Options found.";
+  }
   return APrec < BPrec ? -1 : 1;
 }
 
@@ -86,6 +114,48 @@
 
   array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);
   if (GenDefs) {
+    // Generate prefix groups.
+    typedef SmallVector<SmallString<2>, 2> PrefixKeyT;
+    typedef std::map<PrefixKeyT, std::string> PrefixesT;
+    PrefixesT Prefixes;
+    Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
+    unsigned CurPrefix = 0;
+    for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
+      const Record &R = *Opts[i];
+      std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
+      PrefixKeyT prfkey(prf.begin(), prf.end());
+      unsigned NewPrefix = CurPrefix + 1;
+      if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") +
+                                               Twine(NewPrefix)).str())).second)
+        CurPrefix = NewPrefix;
+    }
+
+    OS << "#ifndef PREFIX\n";
+    OS << "#error \"Define PREFIX prior to including this file!\"\n";
+    OS << "#endif\n\n";
+
+    // Dump prefixes.
+    OS << "/////////\n";
+    OS << "// Prefixes\n\n";
+    OS << "#define COMMA ,\n";
+    for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end();
+                                   I != E; ++I) {
+      OS << "PREFIX(";
+
+      // Prefix name.
+      OS << I->second;
+
+      // Prefix values.
+      OS << ", {";
+      for (PrefixKeyT::const_iterator PI = I->first.begin(),
+                                      PE = I->first.end(); PI != PE; ++PI) {
+        OS << "\"" << *PI << "\" COMMA ";
+      }
+      OS << "0})\n";
+    }
+    OS << "#undef COMMA\n";
+    OS << "\n";
+
     OS << "#ifndef OPTION\n";
     OS << "#error \"Define OPTION prior to including this file!\"\n";
     OS << "#endif\n\n";
@@ -98,8 +168,11 @@
       // Start a single option entry.
       OS << "OPTION(";
 
+      // The option prefix;
+      OS << "0";
+
       // The option string.
-      OS << '"' << R.getValueAsString("Name") << '"';
+      OS << ", \"" << R.getValueAsString("Name") << '"';
 
       // The option identifier name.
       OS  << ", "<< getOptionName(R);
@@ -138,6 +211,10 @@
       // Start a single option entry.
       OS << "OPTION(";
 
+      // The option prefix;
+      std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
+      OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
+
       // The option string.
       write_cstring(OS, R.getValueAsString("Name"));