From: Daniel Dunbar Date: Thu, 19 Nov 2009 04:14:53 +0000 (+0000) Subject: Driver: Introduce OptSpecifier class for protecting access to an option id. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9e1f98260a1842df4bb8e6de0b592a1622dcfdc0;p=clang Driver: Introduce OptSpecifier class for protecting access to an option id. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89310 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h index 28d4648105..281a89b448 100644 --- a/include/clang/Driver/ArgList.h +++ b/include/clang/Driver/ArgList.h @@ -10,8 +10,8 @@ #ifndef CLANG_DRIVER_ARGLIST_H_ #define CLANG_DRIVER_ARGLIST_H_ +#include "clang/Driver/OptSpecifier.h" #include "clang/Driver/Options.h" - #include "clang/Driver/Util.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -78,27 +78,26 @@ namespace driver { /// hasArg - Does the arg list contain any option matching \arg Id. /// /// \arg Claim Whether the argument should be claimed, if it exists. - bool hasArgNoClaim(options::ID Id) const { + bool hasArgNoClaim(OptSpecifier Id) const { return getLastArgNoClaim(Id) != 0; } - bool hasArg(options::ID Id) const { + bool hasArg(OptSpecifier Id) const { return getLastArg(Id) != 0; } - bool hasArg(options::ID Id0, options::ID Id1) const { + bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const { return getLastArg(Id0, Id1) != 0; } - bool hasArg(options::ID Id0, options::ID Id1, options::ID Id2) const { + bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { return getLastArg(Id0, Id1, Id2) != 0; } /// getLastArg - Return the last argument matching \arg Id, or null. /// /// \arg Claim Whether the argument should be claimed, if it exists. - Arg *getLastArgNoClaim(options::ID Id) const; - Arg *getLastArg(options::ID Id) const; - Arg *getLastArg(options::ID Id0, options::ID Id1) const; - Arg *getLastArg(options::ID Id0, options::ID Id1, - options::ID Id2) const; + Arg *getLastArgNoClaim(OptSpecifier Id) const; + Arg *getLastArg(OptSpecifier Id) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const; + Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const; /// getArgString - Return the input argument string at \arg Index. virtual const char *getArgString(unsigned Index) const = 0; @@ -110,24 +109,24 @@ namespace driver { /// negation is present, and \arg Default if neither option is /// given. If both the option and its negation are present, the /// last one wins. - bool hasFlag(options::ID Pos, options::ID Neg, bool Default=true) const; + bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const; /// AddLastArg - Render only the last argument match \arg Id0, if /// present. - void AddLastArg(ArgStringList &Output, options::ID Id0) const; + void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; /// AddAllArgs - Render all arguments matching the given ids. - void AddAllArgs(ArgStringList &Output, options::ID Id0) const; - void AddAllArgs(ArgStringList &Output, options::ID Id0, - options::ID Id1) const; - void AddAllArgs(ArgStringList &Output, options::ID Id0, options::ID Id1, - options::ID Id2) const; + void AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const; + void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1) const; + void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1, + OptSpecifier Id2) const; /// AddAllArgValues - Render the argument values of all arguments /// matching the given ids. - void AddAllArgValues(ArgStringList &Output, options::ID Id0) const; - void AddAllArgValues(ArgStringList &Output, options::ID Id0, - options::ID Id1) const; + void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const; + void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1) const; /// AddAllArgsTranslated - Render all the arguments matching the /// given ids, but forced to separate args and using the provided @@ -135,13 +134,13 @@ namespace driver { /// /// \param Joined - If true, render the argument as joined with /// the option specifier. - void AddAllArgsTranslated(ArgStringList &Output, options::ID Id0, + void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, const char *Translation, bool Joined = false) const; /// ClaimAllArgs - Claim all arguments which match the given /// option id. - void ClaimAllArgs(options::ID Id0) const; + void ClaimAllArgs(OptSpecifier Id0) const; /// @} /// @name Arg Synthesis diff --git a/include/clang/Driver/OptSpecifier.h b/include/clang/Driver/OptSpecifier.h new file mode 100644 index 0000000000..c38b36c2f7 --- /dev/null +++ b/include/clang/Driver/OptSpecifier.h @@ -0,0 +1,36 @@ +//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_DRIVER_OPTSPECIFIER_H +#define CLANG_DRIVER_OPTSPECIFIER_H + +namespace clang { +namespace driver { + class Option; + + /// OptSpecifier - Wrapper class for abstracting references to option IDs. + class OptSpecifier { + unsigned ID; + + private: + explicit OptSpecifier(bool); // DO NOT IMPLEMENT + + public: + /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {} + /*implicit*/ OptSpecifier(const Option *Opt); + + unsigned getID() const { return ID; } + + bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); } + bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); } + }; +} +} + +#endif diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h index 58a0c5389d..46e3889d5d 100644 --- a/include/clang/Driver/OptTable.h +++ b/include/clang/Driver/OptTable.h @@ -10,6 +10,7 @@ #ifndef CLANG_DRIVER_OPTTABLE_H #define CLANG_DRIVER_OPTTABLE_H +#include "clang/Driver/OptSpecifier.h" #include namespace clang { @@ -37,9 +38,6 @@ namespace options { /// be needed at runtime; the OptTable class maintains enough information to /// parse command lines without instantiating Options, while letting other /// parts of the driver still use Option instances where convenient. - // - // FIXME: Introduce an OptionSpecifier class to wrap the option ID - // variant? class OptTable { public: /// Info - Entry for a single option instance in the option data table. @@ -73,7 +71,8 @@ namespace options { unsigned FirstSearchableIndex; private: - const Info &getInfo(unsigned id) const { + const Info &getInfo(OptSpecifier Opt) const { + unsigned id = Opt.getID(); assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID."); return OptionInfos[id - 1]; } @@ -92,7 +91,8 @@ namespace options { /// if necessary. /// /// \return The option, or null for the INVALID option id. - const Option *getOption(unsigned id) const { + const Option *getOption(OptSpecifier Opt) const { + unsigned id = Opt.getID(); if (id == 0) return 0; @@ -104,23 +104,23 @@ namespace options { } /// getOptionName - Lookup the name of the given option. - const char *getOptionName(unsigned id) const { + const char *getOptionName(OptSpecifier id) const { return getInfo(id).Name; } /// getOptionKind - Get the kind of the given option. - unsigned getOptionKind(unsigned id) const { + unsigned getOptionKind(OptSpecifier id) const { return getInfo(id).Kind; } /// getOptionHelpText - Get the help text to use to describe this option. - const char *getOptionHelpText(unsigned id) const { + const char *getOptionHelpText(OptSpecifier id) const { return getInfo(id).HelpText; } /// getOptionMetaVar - Get the meta-variable name to use when describing /// this options values in the help text. - const char *getOptionMetaVar(unsigned id) const { + const char *getOptionMetaVar(OptSpecifier id) const { return getInfo(id).MetaVar; } diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h index 3c6961e71b..5daeef942e 100644 --- a/include/clang/Driver/Option.h +++ b/include/clang/Driver/Option.h @@ -10,6 +10,7 @@ #ifndef CLANG_DRIVER_OPTION_H_ #define CLANG_DRIVER_OPTION_H_ +#include "clang/Driver/OptSpecifier.h" #include "llvm/Support/Casting.h" using llvm::isa; using llvm::cast; @@ -52,7 +53,8 @@ namespace driver { private: OptionClass Kind; - unsigned ID; + /// The option ID. + OptSpecifier ID; /// The option name. const char *Name; @@ -87,12 +89,12 @@ namespace driver { bool NoArgumentUnused : 1; protected: - Option(OptionClass Kind, unsigned ID, const char *Name, + Option(OptionClass Kind, OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); public: virtual ~Option(); - unsigned getId() const { return ID; } + unsigned getID() const { return ID.getID(); } OptionClass getKind() const { return Kind; } const char *getName() const { return Name; } const OptionGroup *getGroup() const { return Group; } @@ -140,8 +142,7 @@ namespace driver { /// Note that matches against options which are an alias should never be /// done -- aliases do not participate in matching and so such a query will /// always be false. - bool matches(const Option *Opt) const; - bool matches(unsigned Id) const; + bool matches(OptSpecifier ID) const; /// accept - Potentially accept the current argument, returning a /// new Arg instance, or 0 if the option does not accept this @@ -161,7 +162,7 @@ namespace driver { /// by the driver. class OptionGroup : public Option { public: - OptionGroup(unsigned ID, const char *Name, const OptionGroup *Group); + OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -203,7 +204,7 @@ namespace driver { class FlagOption : public Option { public: - FlagOption(unsigned ID, const char *Name, const OptionGroup *Group, + FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -216,7 +217,7 @@ namespace driver { class JoinedOption : public Option { public: - JoinedOption(unsigned ID, const char *Name, const OptionGroup *Group, + JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -229,8 +230,8 @@ namespace driver { class SeparateOption : public Option { public: - SeparateOption(unsigned ID, const char *Name, const OptionGroup *Group, - const Option *Alias); + SeparateOption(OptSpecifier ID, const char *Name, + const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -242,7 +243,7 @@ namespace driver { class CommaJoinedOption : public Option { public: - CommaJoinedOption(unsigned ID, const char *Name, + CommaJoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -261,7 +262,7 @@ namespace driver { unsigned NumArgs; public: - MultiArgOption(unsigned ID, const char *Name, const OptionGroup *Group, + MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias, unsigned NumArgs); unsigned getNumArgs() const { return NumArgs; } @@ -278,7 +279,7 @@ namespace driver { /// prefixes its (non-empty) value, or is follwed by a value. class JoinedOrSeparateOption : public Option { public: - JoinedOrSeparateOption(unsigned ID, const char *Name, + JoinedOrSeparateOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; @@ -293,7 +294,7 @@ namespace driver { /// value and is followed by another value. class JoinedAndSeparateOption : public Option { public: - JoinedAndSeparateOption(unsigned ID, const char *Name, + JoinedAndSeparateOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias); virtual Arg *accept(const InputArgList &Args, unsigned &Index) const; diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp index c6c1ee60da..ea75c34ea5 100644 --- a/lib/Driver/ArgList.cpp +++ b/lib/Driver/ArgList.cpp @@ -27,7 +27,7 @@ void ArgList::append(Arg *A) { Args.push_back(A); } -Arg *ArgList::getLastArgNoClaim(options::ID Id) const { +Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const { // FIXME: Make search efficient? for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) if ((*it)->getOption().matches(Id)) @@ -35,14 +35,14 @@ Arg *ArgList::getLastArgNoClaim(options::ID Id) const { return 0; } -Arg *ArgList::getLastArg(options::ID Id) const { +Arg *ArgList::getLastArg(OptSpecifier Id) const { Arg *A = getLastArgNoClaim(Id); if (A) A->claim(); return A; } -Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1) const { +Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const { Arg *Res, *A0 = getLastArgNoClaim(Id0), *A1 = getLastArgNoClaim(Id1); if (A0 && A1) @@ -56,8 +56,8 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1) const { return Res; } -Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, - options::ID Id2) const { +Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, + OptSpecifier Id2) const { Arg *Res = 0; Arg *A0 = getLastArgNoClaim(Id0); Arg *A1 = getLastArgNoClaim(Id1); @@ -85,20 +85,20 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, return Res; } -bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const { +bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { if (Arg *A = getLastArg(Pos, Neg)) return A->getOption().matches(Pos); return Default; } -void ArgList::AddLastArg(ArgStringList &Output, options::ID Id) const { +void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { if (Arg *A = getLastArg(Id)) { A->claim(); A->render(*this, Output); } } -void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const { +void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const { // FIXME: Make fast. for (const_iterator it = begin(), ie = end(); it != ie; ++it) { const Arg *A = *it; @@ -109,8 +109,8 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const { } } -void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0, - options::ID Id1) const { +void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1) const { // FIXME: Make fast. for (const_iterator it = begin(), ie = end(); it != ie; ++it) { const Arg *A = *it; @@ -121,8 +121,8 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0, } } -void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0, - options::ID Id1, options::ID Id2) const { +void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1, OptSpecifier Id2) const { // FIXME: Make fast. for (const_iterator it = begin(), ie = end(); it != ie; ++it) { const Arg *A = *it; @@ -134,7 +134,7 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0, } } -void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const { +void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const { // FIXME: Make fast. for (const_iterator it = begin(), ie = end(); it != ie; ++it) { const Arg *A = *it; @@ -146,8 +146,8 @@ void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const { } } -void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0, - options::ID Id1) const { +void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1) const { // FIXME: Make fast. for (const_iterator it = begin(), ie = end(); it != ie; ++it) { const Arg *A = *it; @@ -159,7 +159,7 @@ void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0, } } -void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0, +void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, const char *Translation, bool Joined) const { // FIXME: Make fast. @@ -180,7 +180,7 @@ void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0, } } -void ArgList::ClaimAllArgs(options::ID Id0) const { +void ArgList::ClaimAllArgs(OptSpecifier Id0) const { // FIXME: Make fast. for (const_iterator it = begin(), ie = end(); it != ie; ++it) { const Arg *A = *it; diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp index 74937a7188..fae7f75f37 100644 --- a/lib/Driver/OptTable.cpp +++ b/lib/Driver/OptTable.cpp @@ -71,6 +71,10 @@ static inline bool operator<(const char *Name, const OptTable::Info &I) { // +OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {} + +// + OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos) : OptionInfos(_OptionInfos), NumOptionInfos(_NumOptionInfos), Options(new Option*[NumOptionInfos]), diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp index 47a0652965..89e99999cf 100644 --- a/lib/Driver/Option.cpp +++ b/lib/Driver/Option.cpp @@ -16,9 +16,9 @@ #include using namespace clang::driver; -Option::Option(OptionClass _Kind, unsigned _ID, const char *_Name, +Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name, const OptionGroup *_Group, const Option *_Alias) - : Kind(_Kind), ID(_ID), Name(_Name), Group(_Group), Alias(_Alias), + : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias), Unsupported(false), LinkerInput(false), NoOptAsInput(false), ForceSeparateRender(false), ForceJoinedRender(false), DriverOption(false), NoArgumentUnused(false) { @@ -70,12 +70,13 @@ void Option::dump() const { llvm::errs() << ">\n"; } -bool Option::matches(const Option *Opt) const { +bool Option::matches(OptSpecifier Opt) const { // Aliases are never considered in matching, look through them. if (Alias) return Alias->matches(Opt); - if (this == Opt) + // Check exact match. + if (ID == Opt) return true; if (Group) @@ -83,20 +84,7 @@ bool Option::matches(const Option *Opt) const { return false; } -bool Option::matches(unsigned Id) const { - // Aliases are never considered in matching, look through them. - if (Alias) - return Alias->matches(Id); - - if (ID == Id) - return true; - - if (Group) - return Group->matches(Id); - return false; -} - -OptionGroup::OptionGroup(unsigned ID, const char *Name, +OptionGroup::OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group) : Option(Option::GroupClass, ID, Name, Group, 0) { } @@ -124,7 +112,7 @@ Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const { return 0; } -FlagOption::FlagOption(unsigned ID, const char *Name, +FlagOption::FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias) : Option(Option::FlagClass, ID, Name, Group, Alias) { } @@ -138,7 +126,7 @@ Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const { return new FlagArg(this, Index++); } -JoinedOption::JoinedOption(unsigned ID, const char *Name, +JoinedOption::JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias) : Option(Option::JoinedClass, ID, Name, Group, Alias) { } @@ -148,7 +136,7 @@ Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const { return new JoinedArg(this, Index++); } -CommaJoinedOption::CommaJoinedOption(unsigned ID, const char *Name, +CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias) : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) { @@ -165,7 +153,7 @@ Arg *CommaJoinedOption::accept(const InputArgList &Args, return new CommaJoinedArg(this, Index++, Suffix); } -SeparateOption::SeparateOption(unsigned ID, const char *Name, +SeparateOption::SeparateOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias) : Option(Option::SeparateClass, ID, Name, Group, Alias) { } @@ -183,7 +171,7 @@ Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const { return new SeparateArg(this, Index - 2, 1); } -MultiArgOption::MultiArgOption(unsigned ID, const char *Name, +MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias, unsigned _NumArgs) : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) { @@ -203,7 +191,7 @@ Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const { return new SeparateArg(this, Index - 1 - NumArgs, NumArgs); } -JoinedOrSeparateOption::JoinedOrSeparateOption(unsigned ID, const char *Name, +JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias) : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) { @@ -224,7 +212,7 @@ Arg *JoinedOrSeparateOption::accept(const InputArgList &Args, return new SeparateArg(this, Index - 2, 1); } -JoinedAndSeparateOption::JoinedAndSeparateOption(unsigned ID, +JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID, const char *Name, const OptionGroup *Group, const Option *Alias) diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 8242d31c51..a9a2d0fbc3 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -366,7 +366,7 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args, // Sob. These is strictly gcc compatible for the time being. Apple // gcc translates options twice, which means that self-expanding // options add duplicates. - switch ((options::ID) A->getOption().getId()) { + switch ((options::ID) A->getOption().getID()) { default: DAL->append(A); break;