Revert "[Options] make Option a value type."

Author: Michael J. Spencer <bigcheesegs@gmail.com>
Date:   Wed Oct 10 21:48:26 2012 +0000

    [Options] make Option a value type.

    git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165663 91177308-0d34-0410-b5e6-96231b3b80d8

This reverts commit 0464fd5e4ce2193e786e5adcab6b828f9366dae3.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165667 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/Arg.cpp b/lib/Driver/Arg.cpp
index b156d7c..c0a2a50 100644
--- a/lib/Driver/Arg.cpp
+++ b/lib/Driver/Arg.cpp
@@ -16,19 +16,19 @@
 
 using namespace clang::driver;
 
-Arg::Arg(const Option _Opt, unsigned _Index, const Arg *_BaseArg)
+Arg::Arg(const Option *_Opt, unsigned _Index, const Arg *_BaseArg)
   : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
     Claimed(false), OwnsValues(false) {
 }
 
-Arg::Arg(const Option _Opt, unsigned _Index,
+Arg::Arg(const Option *_Opt, unsigned _Index, 
          const char *Value0, const Arg *_BaseArg)
   : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
     Claimed(false), OwnsValues(false) {
   Values.push_back(Value0);
 }
 
-Arg::Arg(const Option _Opt, unsigned _Index,
+Arg::Arg(const Option *_Opt, unsigned _Index, 
          const char *Value0, const char *Value1, const Arg *_BaseArg)
   : Opt(_Opt), BaseArg(_BaseArg), Index(_Index),
     Claimed(false), OwnsValues(false) {
@@ -47,7 +47,7 @@
   llvm::errs() << "<";
 
   llvm::errs() << " Opt:";
-  Opt.dump();
+  Opt->dump();
 
   llvm::errs() << " Index:" << Index;
 
@@ -104,7 +104,7 @@
     Output.push_back(Args.MakeArgString(OS.str()));
     break;
   }
-
+ 
  case Option::RenderJoinedStyle:
     Output.push_back(Args.GetOrMakeJoinedArgString(
                        getIndex(), getOption().getName(), getValue(Args, 0)));
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 3b824f7..7fd439e 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -362,13 +362,13 @@
   return BaseArgs.MakeArgString(Str);
 }
 
-Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
-  Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt.getName()), BaseArg);
+Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
+  Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
   SynthesizedArgs.push_back(A);
   return A;
 }
 
-Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
+Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
                                        StringRef Value) const {
   unsigned Index = BaseArgs.MakeIndex(Value);
   Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg);
@@ -376,19 +376,19 @@
   return A;
 }
 
-Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
+Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
                                      StringRef Value) const {
-  unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
+  unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value);
   Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg);
   SynthesizedArgs.push_back(A);
   return A;
 }
 
-Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
+Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
                                    StringRef Value) const {
-  unsigned Index = BaseArgs.MakeIndex(Opt.getName().str() + Value.str());
+  unsigned Index = BaseArgs.MakeIndex(Opt->getName().str() + Value.str());
   Arg *A = new Arg(Opt, Index,
-                   BaseArgs.getArgString(Index) + Opt.getName().size(),
+                   BaseArgs.getArgString(Index) + Opt->getName().size(),
                    BaseArg);
   SynthesizedArgs.push_back(A);
   return A;
diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
index 433c386..e108106 100644
--- a/lib/Driver/OptTable.cpp
+++ b/lib/Driver/OptTable.cpp
@@ -11,7 +11,6 @@
 #include "clang/Driver/Arg.h"
 #include "clang/Driver/ArgList.h"
 #include "clang/Driver/Option.h"
-#include "clang/Driver/Options.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <algorithm>
@@ -80,16 +79,22 @@
 
 OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
   : OptionInfos(_OptionInfos), NumOptionInfos(_NumOptionInfos),
-    FirstSearchableIndex(0)
+    Options(new Option*[NumOptionInfos]),
+    TheInputOption(0), TheUnknownOption(0), FirstSearchableIndex(0)
 {
   // Explicitly zero initialize the error to work around a bug in array
   // value-initialization on MinGW with gcc 4.3.5.
+  memset(Options, 0, sizeof(*Options) * NumOptionInfos);
 
   // Find start of normal options.
   for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
     unsigned Kind = getInfo(i + 1).Kind;
     if (Kind == Option::InputClass) {
+      assert(!TheInputOption && "Cannot have multiple input options!");
+      TheInputOption = getOption(i + 1);
     } else if (Kind == Option::UnknownClass) {
+      assert(!TheUnknownOption && "Cannot have multiple input options!");
+      TheUnknownOption = getOption(i + 1);
     } else if (Kind != Option::GroupClass) {
       FirstSearchableIndex = i;
       break;
@@ -110,8 +115,8 @@
   // Check that options are in order.
   for (unsigned i = FirstSearchableIndex+1, e = getNumOptions(); i != e; ++i) {
     if (!(getInfo(i) < getInfo(i + 1))) {
-      getOption(i).dump();
-      getOption(i + 1).dump();
+      getOption(i)->dump();
+      getOption(i + 1)->dump();
       llvm_unreachable("Options are not in order!");
     }
   }
@@ -119,27 +124,26 @@
 }
 
 OptTable::~OptTable() {
-}
-
-const Option OptTable::getOption(OptSpecifier Opt) const {
-  unsigned id = Opt.getID();
-  if (id == 0)
-    return Option(0, 0);
-  assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
-  return Option(&getInfo(id), this);
+  for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+    delete Options[i];
+  delete[] Options;
 }
 
 bool OptTable::isOptionHelpHidden(OptSpecifier id) const {
   return getInfo(id).Flags & options::HelpHidden;
 }
 
+Option *OptTable::CreateOption(unsigned id) const {
+  return new Option(&getInfo(id), this);
+}
+
 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(options::OPT_INPUT), Index++, Str);
+    return new Arg(TheInputOption, Index++, Str);
 
   const Info *Start = OptionInfos + FirstSearchableIndex;
   const Info *End = OptionInfos + getNumOptions();
@@ -165,7 +169,7 @@
       break;
 
     // See if this option matches.
-    if (Arg *A = getOption(Start - OptionInfos + 1).accept(Args, Index))
+    if (Arg *A = getOption(Start - OptionInfos + 1)->accept(Args, Index))
       return A;
 
     // Otherwise, see if this argument was missing values.
@@ -173,7 +177,7 @@
       return 0;
   }
 
-  return new Arg(getOption(options::OPT_UNKNOWN), Index++, Str);
+  return new Arg(TheUnknownOption, Index++, Str);
 }
 
 InputArgList *OptTable::ParseArgs(const char* const *ArgBegin,
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
index a250d87..117021b 100644
--- a/lib/Driver/Option.cpp
+++ b/lib/Driver/Option.cpp
@@ -23,8 +23,7 @@
   // Multi-level aliases are not supported, and alias options cannot
   // have groups. This just simplifies option tracking, it is not an
   // inherent limitation.
-  assert((!getAlias().isValid() || (!getAlias().getAlias().isValid() &&
-         !getGroup().isValid())) &&
+  assert((!getAlias() || (!getAlias()->getAlias() && !getGroup())) &&
          "Multi-level aliases and aliases with groups are unsupported.");
 }
 
@@ -50,16 +49,16 @@
 
   llvm::errs() << " Name:\"" << getName() << '"';
 
-  const Option Group = getGroup();
-  if (Group.isValid()) {
+  const Option *Group = getGroup();
+  if (Group) {
     llvm::errs() << " Group:";
-    Group.dump();
+    Group->dump();
   }
 
-  const Option Alias = getAlias();
-  if (Alias.isValid()) {
+  const Option *Alias = getAlias();
+  if (Alias) {
     llvm::errs() << " Alias:";
-    Alias.dump();
+    Alias->dump();
   }
 
   if (getKind() == MultiArgClass)
@@ -70,17 +69,17 @@
 
 bool Option::matches(OptSpecifier Opt) const {
   // Aliases are never considered in matching, look through them.
-  const Option Alias = getAlias();
-  if (Alias.isValid())
-    return Alias.matches(Opt);
+  const Option *Alias = getAlias();
+  if (Alias)
+    return Alias->matches(Opt);
 
   // Check exact match.
   if (getID() == Opt.getID())
     return true;
 
-  const Option Group = getGroup();
-  if (Group.isValid())
-    return Group.matches(Opt);
+  const Option *Group = getGroup();
+  if (Group)
+    return Group->matches(Opt);
   return false;
 }
 
@@ -156,7 +155,7 @@
     // FIXME: Avoid strlen.
     if (getName().size() != strlen(Args.getArgString(Index))) {
       const char *Value = Args.getArgString(Index) + getName().size();
-      return new Arg(*this, Index++, Value);
+      return new Arg(this, Index++, Value);
     }
 
     // Otherwise it must be separate.
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index de18f53..529f7bf 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -485,7 +485,7 @@
         }
         // When using the define to indicate the simulator, we force
         // 10.6 macosx target.
-        const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+        const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
         OSXVersion = Args.MakeJoinedArg(0, O, "10.6");
         Args.append(OSXVersion);
         break;
@@ -559,21 +559,21 @@
     }
 
     if (!OSXTarget.empty()) {
-      const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+      const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
       OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
       Args.append(OSXVersion);
     } else if (!iOSTarget.empty()) {
-      const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
+      const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
       iOSVersion = Args.MakeJoinedArg(0, O, iOSTarget);
       Args.append(iOSVersion);
     } else if (!iOSSimTarget.empty()) {
-      const Option O = Opts.getOption(
+      const Option *O = Opts.getOption(
         options::OPT_mios_simulator_version_min_EQ);
       iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget);
       Args.append(iOSSimVersion);
     } else {
       // Otherwise, assume we are targeting OS X.
-      const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
+      const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
       OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
       Args.append(OSXVersion);
     }
@@ -835,8 +835,8 @@
   // how the driver driver works.
   if (BoundArch) {
     StringRef Name = BoundArch;
-    const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
-    const Option MArch = Opts.getOption(options::OPT_march_EQ);
+    const Option *MCpu = Opts.getOption(options::OPT_mcpu_EQ);
+    const Option *MArch = Opts.getOption(options::OPT_march_EQ);
 
     // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
     // which defines the list of which architectures we accept.