[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/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
index a1c5ecd..db59298 100644
--- a/lib/Driver/OptTable.cpp
+++ b/lib/Driver/OptTable.cpp
@@ -55,6 +55,13 @@
   if (int N = StrCmpOptionName(A.Name, B.Name))
     return N == -1;
 
+  for (const char * const *APre = A.Prefixes,
+                  * const *BPre = B.Prefixes;
+                          *APre != 0 && *BPre != 0; ++APre, ++BPre) {
+    if (int N = StrCmpOptionName(*APre, *BPre))
+      return N == -1;
+  }
+
   // Names are the same, check that classes are in order; exactly one
   // should be joined, and it should succeed the other.
   assert(((A.Kind == Option::JoinedClass) ^ (B.Kind == Option::JoinedClass)) &&
@@ -123,6 +130,26 @@
     }
   }
 #endif
+
+  // Build prefixes.
+  for (unsigned i = FirstSearchableIndex+1, e = getNumOptions(); i != e; ++i) {
+    if (const char *const *P = getInfo(i).Prefixes) {
+      for (; *P != 0; ++P) {
+        PrefixesUnion.insert(*P);
+      }
+    }
+  }
+
+  // Build prefix chars.
+  for (llvm::StringSet<>::const_iterator I = PrefixesUnion.begin(),
+                                         E = PrefixesUnion.end(); I != E; ++I) {
+    StringRef Prefix = I->getKey();
+    for (StringRef::const_iterator C = Prefix.begin(), CE = Prefix.end();
+                                   C != CE; ++C)
+      if (std::find(PrefixChars.begin(), PrefixChars.end(), *C)
+            == PrefixChars.end())
+        PrefixChars.push_back(*C);
+  }
 }
 
 OptTable::~OptTable() {
@@ -140,19 +167,41 @@
   return getInfo(id).Flags & options::HelpHidden;
 }
 
+static bool isInput(const llvm::StringSet<> &Prefixes, StringRef Arg) {
+  if (Arg == "-")
+    return true;
+  for (llvm::StringSet<>::const_iterator I = Prefixes.begin(),
+                                         E = Prefixes.end(); I != E; ++I)
+    if (Arg.startswith(I->getKey()))
+      return false;
+  return true;
+}
+
+/// \returns Matched size. 0 means no match.
+static unsigned matchOption(const OptTable::Info *I, StringRef Str) {
+  for (const char * const *Pre = I->Prefixes; *Pre != 0; ++Pre) {
+    StringRef Prefix(*Pre);
+    if (Str.startswith(Prefix) && Str.substr(Prefix.size()).startswith(I->Name))
+      return Prefix.size() + StringRef(I->Name).size();
+  }
+  return 0;
+}
+
 Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
   unsigned Prev = Index;
   const char *Str = Args.getArgString(Index);
 
-  // Anything that doesn't start with '-' is an input, as is '-' itself.
-  if (Str[0] != '-' || Str[1] == '\0')
-    return new Arg(getOption(TheInputOptionID), Index++, Str);
+  // Anything that doesn't start with PrefixesUnion is an input, as is '-'
+  // itself.
+  if (isInput(PrefixesUnion, Str))
+    return new Arg(getOption(TheInputOptionID), Str, Index++, Str);
 
   const Info *Start = OptionInfos + FirstSearchableIndex;
   const Info *End = OptionInfos + getNumOptions();
+  StringRef Name = StringRef(Str).ltrim(PrefixChars);
 
   // Search for the first next option which could be a prefix.
-  Start = std::lower_bound(Start, End, Str);
+  Start = std::lower_bound(Start, End, Name.data());
 
   // Options are stored in sorted order, with '\0' at the end of the
   // alphabet. Since the only options which can accept a string must
@@ -162,17 +211,17 @@
   // FIXME: This is searching much more than necessary, but I am
   // blanking on the simplest way to make it fast. We can solve this
   // problem when we move to TableGen.
-  StringRef StrRef(Str);
   for (; Start != End; ++Start) {
+    unsigned ArgSize = 0;
     // Scan for first option which is a proper prefix.
     for (; Start != End; ++Start)
-      if (StrRef.startswith(Start->Name))
+      if ((ArgSize = matchOption(Start, Str)))
         break;
     if (Start == End)
       break;
 
     // See if this option matches.
-    if (Arg *A = getOption(Start - OptionInfos + 1).accept(Args, Index))
+    if (Arg *A = Option(Start, this).accept(Args, Index, ArgSize))
       return A;
 
     // Otherwise, see if this argument was missing values.
@@ -180,7 +229,7 @@
       return 0;
   }
 
-  return new Arg(getOption(TheUnknownOptionID), Index++, Str);
+  return new Arg(getOption(TheUnknownOptionID), Str, Index++, Str);
 }
 
 InputArgList *OptTable::ParseArgs(const char* const *ArgBegin,
@@ -220,10 +269,11 @@
 }
 
 static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id) {
-  std::string Name = Opts.getOptionName(Id);
+  const Option O = Opts.getOption(Id);
+  std::string Name = O.getPrefixedName();
 
   // Add metavar, if used.
-  switch (Opts.getOptionKind(Id)) {
+  switch (O.getKind()) {
   case Option::GroupClass: case Option::InputClass: case Option::UnknownClass:
     llvm_unreachable("Invalid option with help text.");