From 842227a2e28f6e522f10955802a00523af158606 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Thu, 18 Oct 2012 20:33:42 +0000 Subject: [PATCH] [Options] make Option a value type. llvm-svn: 166223 --- clang/include/clang/Driver/Arg.h | 13 ++++---- clang/include/clang/Driver/ArgList.h | 17 +++++----- clang/include/clang/Driver/OptTable.h | 23 +------------- clang/include/clang/Driver/Option.h | 45 +++++++++++++++++++++------ clang/lib/Driver/Arg.cpp | 10 +++--- clang/lib/Driver/ArgList.cpp | 16 +++++----- clang/lib/Driver/OptTable.cpp | 34 +++++++++----------- clang/lib/Driver/Option.cpp | 29 ++++++++--------- clang/lib/Driver/ToolChains.cpp | 14 ++++----- 9 files changed, 102 insertions(+), 99 deletions(-) diff --git a/clang/include/clang/Driver/Arg.h b/clang/include/clang/Driver/Arg.h index 70f07415209c..bd4fa872eadc 100644 --- a/clang/include/clang/Driver/Arg.h +++ b/clang/include/clang/Driver/Arg.h @@ -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 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. diff --git a/clang/include/clang/Driver/ArgList.h b/clang/include/clang/Driver/ArgList.h index b2570b01dd46..72ed7bf58604 100644 --- a/clang/include/clang/Driver/ArgList.h +++ b/clang/include/clang/Driver/ArgList.h @@ -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; /// @} diff --git a/clang/include/clang/Driver/OptTable.h b/clang/include/clang/Driver/OptTable.h index ea7e57b12be1..678d9676595d 100644 --- a/clang/include/clang/Driver/OptTable.h +++ b/clang/include/clang/Driver/OptTable.h @@ -47,15 +47,6 @@ 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; - /// 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). unsigned FirstSearchableIndex; @@ -67,8 +58,6 @@ namespace driver { return OptionInfos[id - 1]; } - Option *CreateOption(unsigned id) const; - protected: OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos); public: @@ -81,17 +70,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 { diff --git a/clang/include/clang/Driver/Option.h b/clang/include/clang/Driver/Option.h index 6fc8bef5daaa..9cda2801d450 100644 --- a/clang/include/clang/Driver/Option.h +++ b/clang/include/clang/Driver/Option.h @@ -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 diff --git a/clang/lib/Driver/Arg.cpp b/clang/lib/Driver/Arg.cpp index c0a2a506a6ba..b156d7cf7146 100644 --- a/clang/lib/Driver/Arg.cpp +++ b/clang/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 @@ 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))); diff --git a/clang/lib/Driver/ArgList.cpp b/clang/lib/Driver/ArgList.cpp index 7fd439e63082..3b824f7c8190 100644 --- a/clang/lib/Driver/ArgList.cpp +++ b/clang/lib/Driver/ArgList.cpp @@ -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; diff --git a/clang/lib/Driver/OptTable.cpp b/clang/lib/Driver/OptTable.cpp index e108106fa7e9..433c3869b5ce 100644 --- a/clang/lib/Driver/OptTable.cpp +++ b/clang/lib/Driver/OptTable.cpp @@ -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 @@ -79,22 +80,16 @@ 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) + 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; @@ -115,8 +110,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,26 +119,27 @@ OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos) } OptTable::~OptTable() { - for (unsigned i = 0, e = getNumOptions(); i != e; ++i) - delete Options[i]; - delete[] Options; +} + +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); } 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(TheInputOption, Index++, Str); + return new Arg(getOption(options::OPT_INPUT), Index++, Str); const Info *Start = OptionInfos + FirstSearchableIndex; const Info *End = OptionInfos + getNumOptions(); @@ -169,7 +165,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 +173,7 @@ Arg *OptTable::ParseOneArg(const ArgList &Args, unsigned &Index) const { return 0; } - return new Arg(TheUnknownOption, Index++, Str); + return new Arg(getOption(options::OPT_UNKNOWN), Index++, Str); } InputArgList *OptTable::ParseArgs(const char* const *ArgBegin, diff --git a/clang/lib/Driver/Option.cpp b/clang/lib/Driver/Option.cpp index 117021b880ce..116dbca5b0f4 100644 --- a/clang/lib/Driver/Option.cpp +++ b/clang/lib/Driver/Option.cpp @@ -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. diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 529f7bff48b6..de18f53fbe0e 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -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.