]> granicus.if.org Git - clang/commitdiff
[Options] make Option a value type.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Fri, 19 Oct 2012 22:36:40 +0000 (22:36 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Fri, 19 Oct 2012 22:36:40 +0000 (22:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166347 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/Arg.h
include/clang/Driver/ArgList.h
include/clang/Driver/OptTable.h
include/clang/Driver/Option.h
lib/Driver/Arg.cpp
lib/Driver/ArgList.cpp
lib/Driver/OptTable.cpp
lib/Driver/Option.cpp
lib/Driver/ToolChains.cpp

index 70f07415209ce18d749b04e071a447f98d710f3c..bd4fa872eadc58f6fdc2e95eef8afb663baa7dac 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef CLANG_DRIVER_ARG_H_
 #define CLANG_DRIVER_ARG_H_
 
+#include "clang/Driver/Option.h"
+
 #include "Util.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -23,7 +25,6 @@
 namespace clang {
 namespace driver {
   class ArgList;
-  class Option;
 
   /// \brief A concrete instance of a particular driver option.
   ///
@@ -38,7 +39,7 @@ namespace driver {
 
   private:
     /// \brief The option this argument is an instance of.
-    const Option *Opt;
+    const Option Opt;
 
     /// \brief The argument this argument was derived from (during tool chain
     /// argument translation), if any.
@@ -60,14 +61,14 @@ namespace driver {
     SmallVector<const char *, 2> Values;
 
   public:
-    Arg(const Option *Opt, unsigned Index, const Arg *BaseArg = 0);
-    Arg(const Option *Opt, unsigned Index,
+    Arg(const Option Opt, unsigned Index, const Arg *BaseArg = 0);
+    Arg(const Option Opt, unsigned Index,
         const char *Value0, const Arg *BaseArg = 0);
-    Arg(const Option *Opt, unsigned Index,
+    Arg(const Option Opt, unsigned Index,
         const char *Value0, const char *Value1, const Arg *BaseArg = 0);
     ~Arg();
 
-    const Option &getOption() const { return *Opt; }
+    const Option getOption() const { return Opt; }
     unsigned getIndex() const { return Index; }
 
     /// \brief Return the base argument which generated this arg.
index b2570b01dd4633ee620cfc66ab71852f1df3f4ae..72ed7bf586046501b005765a87dd41ed7a1dfbf8 100644 (file)
@@ -11,6 +11,7 @@
 #define CLANG_DRIVER_ARGLIST_H_
 
 #include "clang/Basic/LLVM.h"
+#include "clang/Driver/Option.h"
 #include "clang/Driver/OptSpecifier.h"
 #include "clang/Driver/Util.h"
 #include "llvm/ADT/SmallVector.h"
@@ -374,14 +375,14 @@ namespace driver {
 
     /// AddFlagArg - Construct a new FlagArg for the given option \p Id and
     /// append it to the argument list.
-    void AddFlagArg(const Arg *BaseArg, const Option *Opt) {
+    void AddFlagArg(const Arg *BaseArg, const Option Opt) {
       append(MakeFlagArg(BaseArg, Opt));
     }
 
     /// AddPositionalArg - Construct a new Positional arg for the given option
     /// \p Id, with the provided \p Value and append it to the argument
     /// list.
-    void AddPositionalArg(const Arg *BaseArg, const Option *Opt,
+    void AddPositionalArg(const Arg *BaseArg, const Option Opt,
                           StringRef Value) {
       append(MakePositionalArg(BaseArg, Opt, Value));
     }
@@ -390,7 +391,7 @@ namespace driver {
     /// AddSeparateArg - Construct a new Positional arg for the given option
     /// \p Id, with the provided \p Value and append it to the argument
     /// list.
-    void AddSeparateArg(const Arg *BaseArg, const Option *Opt,
+    void AddSeparateArg(const Arg *BaseArg, const Option Opt,
                         StringRef Value) {
       append(MakeSeparateArg(BaseArg, Opt, Value));
     }
@@ -398,28 +399,28 @@ namespace driver {
 
     /// AddJoinedArg - Construct a new Positional arg for the given option
     /// \p Id, with the provided \p Value and append it to the argument list.
-    void AddJoinedArg(const Arg *BaseArg, const Option *Opt,
+    void AddJoinedArg(const Arg *BaseArg, const Option Opt,
                       StringRef Value) {
       append(MakeJoinedArg(BaseArg, Opt, Value));
     }
 
 
     /// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
-    Arg *MakeFlagArg(const Arg *BaseArg, const Option *Opt) const;
+    Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const;
 
     /// MakePositionalArg - Construct a new Positional arg for the
     /// given option \p Id, with the provided \p Value.
-    Arg *MakePositionalArg(const Arg *BaseArg, const Option *Opt,
+    Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt,
                            StringRef Value) const;
 
     /// MakeSeparateArg - Construct a new Positional arg for the
     /// given option \p Id, with the provided \p Value.
-    Arg *MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
+    Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt,
                          StringRef Value) const;
 
     /// MakeJoinedArg - Construct a new Positional arg for the
     /// given option \p Id, with the provided \p Value.
-    Arg *MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
+    Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt,
                        StringRef Value) const;
 
     /// @}
index ea7e57b12be107ab0fab21f1bfc45cb906299042..51ffe9f9be274967c9e25371f71cd6415fed295a 100644 (file)
@@ -47,14 +47,8 @@ namespace driver {
     const Info *OptionInfos;
     unsigned NumOptionInfos;
 
-    /// \brief The lazily constructed options table, indexed by option::ID - 1.
-    mutable Option **Options;
-
-    /// \brief Prebound input option instance.
-    const Option *TheInputOption;
-
-    /// \brief Prebound unknown option instance.
-    const Option *TheUnknownOption;
+    unsigned TheInputOptionID;
+    unsigned TheUnknownOptionID;
 
     /// The index of the first option which can be parsed (i.e., is not a
     /// special option like 'input' or 'unknown', and is not an option group).
@@ -67,8 +61,6 @@ namespace driver {
       return OptionInfos[id - 1];
     }
 
-    Option *CreateOption(unsigned id) const;
-
   protected:
     OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos);
   public:
@@ -81,17 +73,7 @@ namespace driver {
     /// if necessary.
     ///
     /// \return The option, or null for the INVALID option id.
-    const Option *getOption(OptSpecifier Opt) const {
-      unsigned id = Opt.getID();
-      if (id == 0)
-        return 0;
-
-      assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
-      Option *&Entry = Options[id - 1];
-      if (!Entry)
-        Entry = CreateOption(id);
-      return Entry;
-    }
+    const Option getOption(OptSpecifier Opt) const;
 
     /// \brief Lookup the name of the given option.
     const char *getOptionName(OptSpecifier id) const {
index 6fc8bef5daaae48d413200f6b95a310db66198ba..9cda2801d45021e1e0d6b3176017c72708d20bd1 100644 (file)
@@ -76,11 +76,36 @@ namespace options {
     Option(const OptTable::Info *Info, const OptTable *Owner);
     ~Option();
 
-    unsigned getID() const { return Info->ID; }
-    OptionClass getKind() const { return OptionClass(Info->Kind); }
-    StringRef getName() const { return Info->Name; }
-    const Option *getGroup() const { return Owner->getOption(Info->GroupID); }
-    const Option *getAlias() const { return Owner->getOption(Info->AliasID); }
+    bool isValid() const {
+      return Info != 0;
+    }
+
+    unsigned getID() const {
+      assert(Info && "Must have a valid info!");
+      return Info->ID;
+    }
+    
+    OptionClass getKind() const {
+      assert(Info && "Must have a valid info!");
+      return OptionClass(Info->Kind);
+    }
+    
+    StringRef getName() const {
+      assert(Info && "Must have a valid info!");
+      return Info->Name;
+    }
+    
+    const Option getGroup() const {
+      assert(Info && "Must have a valid info!");
+      assert(Owner && "Must have a valid owner!");
+      return Owner->getOption(Info->GroupID);
+    }
+    
+    const Option getAlias() const {
+      assert(Info && "Must have a valid info!");
+      assert(Owner && "Must have a valid owner!");
+      return Owner->getOption(Info->AliasID);
+    }
 
     unsigned getNumArgs() const { return Info->Param; }
 
@@ -130,16 +155,16 @@ namespace options {
 
     /// getUnaliasedOption - Return the final option this option
     /// aliases (itself, if the option has no alias).
-    const Option *getUnaliasedOption() const {
-      const Option *Alias = getAlias();
-      if (Alias) return Alias->getUnaliasedOption();
-      return this;
+    const Option getUnaliasedOption() const {
+      const Option Alias = getAlias();
+      if (Alias.isValid()) return Alias.getUnaliasedOption();
+      return *this;
     }
 
     /// getRenderName - Return the name to use when rendering this
     /// option.
     StringRef getRenderName() const {
-      return getUnaliasedOption()->getName();
+      return getUnaliasedOption().getName();
     }
 
     /// matches - Predicate for whether this option is part of the
index c0a2a506a6ba151e91e33039884ead343ac711c8..b156d7cf714614ce28e34a6f39eddd4bb2514a86 100644 (file)
 
 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 @@ void Arg::dump() const {
   llvm::errs() << "<";
 
   llvm::errs() << " Opt:";
-  Opt->dump();
+  Opt.dump();
 
   llvm::errs() << " Index:" << Index;
 
@@ -104,7 +104,7 @@ void Arg::render(const ArgList &Args, ArgStringList &Output) const {
     Output.push_back(Args.MakeArgString(OS.str()));
     break;
   }
+
  case Option::RenderJoinedStyle:
     Output.push_back(Args.GetOrMakeJoinedArgString(
                        getIndex(), getOption().getName(), getValue(Args, 0)));
index 7fd439e630828de4c3c53441b3d2a6f7ab15cd74..3b824f7c8190e1ffc14d8d0c951099db74c5b6ba 100644 (file)
@@ -362,13 +362,13 @@ const char *DerivedArgList::MakeArgString(StringRef Str) const {
   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 @@ Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
   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;
index e108106fa7e97996f6159b4dd31a41ceee98964d..a1c5ecd8e605bbc51b53fb9154b86eb25c1252f7 100644 (file)
@@ -11,6 +11,7 @@
 #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>
@@ -78,23 +79,24 @@ OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {}
 //
 
 OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
-  : OptionInfos(_OptionInfos), NumOptionInfos(_NumOptionInfos),
-    Options(new Option*[NumOptionInfos]),
-    TheInputOption(0), TheUnknownOption(0), FirstSearchableIndex(0)
+  : OptionInfos(_OptionInfos),
+    NumOptionInfos(_NumOptionInfos),
+    TheInputOptionID(0),
+    TheUnknownOptionID(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);
+      assert(!TheInputOptionID && "Cannot have multiple input options!");
+      TheInputOptionID = getInfo(i + 1).ID;
     } else if (Kind == Option::UnknownClass) {
-      assert(!TheUnknownOption && "Cannot have multiple input options!");
-      TheUnknownOption = getOption(i + 1);
+      assert(!TheUnknownOptionID && "Cannot have multiple unknown options!");
+      TheUnknownOptionID = getInfo(i + 1).ID;
     } else if (Kind != Option::GroupClass) {
       FirstSearchableIndex = i;
       break;
@@ -115,8 +117,8 @@ OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
   // 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!");
     }
   }
@@ -124,17 +126,18 @@ OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
 }
 
 OptTable::~OptTable() {
-  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;
+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);
 }
 
-Option *OptTable::CreateOption(unsigned id) const {
-  return new Option(&getInfo(id), this);
+bool OptTable::isOptionHelpHidden(OptSpecifier id) const {
+  return getInfo(id).Flags & options::HelpHidden;
 }
 
 Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
@@ -143,7 +146,7 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
 
   // Anything that doesn't start with '-' is an input, as is '-' itself.
   if (Str[0] != '-' || Str[1] == '\0')
-    return new Arg(TheInputOption, Index++, Str);
+    return new Arg(getOption(TheInputOptionID), Index++, Str);
 
   const Info *Start = OptionInfos + FirstSearchableIndex;
   const Info *End = OptionInfos + getNumOptions();
@@ -169,7 +172,7 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
       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.
@@ -177,7 +180,7 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const {
       return 0;
   }
 
-  return new Arg(TheUnknownOption, Index++, Str);
+  return new Arg(getOption(TheUnknownOptionID), Index++, Str);
 }
 
 InputArgList *OptTable::ParseArgs(const char* const *ArgBegin,
index 117021b880ce4a5071321e94041024ad6244b90a..116dbca5b0f44d6206580b767b1b7ac1cbf4adb5 100644 (file)
@@ -23,7 +23,8 @@ Option::Option(const OptTable::Info *info, const OptTable *owner)
   // 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() || (!getAlias()->getAlias() && !getGroup())) &&
+  assert(!Info || (!getAlias().isValid() || (!getAlias().getAlias().isValid() &&
+         !getGroup().isValid())) &&
          "Multi-level aliases and aliases with groups are unsupported.");
 }
 
@@ -49,16 +50,16 @@ void Option::dump() const {
 
   llvm::errs() << " Name:\"" << getName() << '"';
 
-  const Option *Group = getGroup();
-  if (Group) {
+  const Option Group = getGroup();
+  if (Group.isValid()) {
     llvm::errs() << " Group:";
-    Group->dump();
+    Group.dump();
   }
 
-  const Option *Alias = getAlias();
-  if (Alias) {
+  const Option Alias = getAlias();
+  if (Alias.isValid()) {
     llvm::errs() << " Alias:";
-    Alias->dump();
+    Alias.dump();
   }
 
   if (getKind() == MultiArgClass)
@@ -69,17 +70,17 @@ void Option::dump() const {
 
 bool Option::matches(OptSpecifier Opt) const {
   // Aliases are never considered in matching, look through them.
-  const Option *Alias = getAlias();
-  if (Alias)
-    return Alias->matches(Opt);
+  const Option Alias = getAlias();
+  if (Alias.isValid())
+    return Alias.matches(Opt);
 
   // Check exact match.
   if (getID() == Opt.getID())
     return true;
 
-  const Option *Group = getGroup();
-  if (Group)
-    return Group->matches(Opt);
+  const Option Group = getGroup();
+  if (Group.isValid())
+    return Group.matches(Opt);
   return false;
 }
 
@@ -155,7 +156,7 @@ Arg *Option::accept(const ArgList &Args, unsigned &Index) const {
     // 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.
index 529f7bff48b667579e1402721a47999c09b53613..de18f53fbe0edea063a6254d79562e3d1b8c975f 100644 (file)
@@ -485,7 +485,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
         }
         // 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 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
     }
 
     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 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
   // 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.