diff options
Diffstat (limited to 'include/llvm/Support/CommandLine.h')
-rw-r--r-- | include/llvm/Support/CommandLine.h | 854 |
1 files changed, 346 insertions, 508 deletions
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 2b5c9c5..64c5d96 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -20,6 +20,7 @@ #ifndef LLVM_SUPPORT_COMMANDLINE_H #define LLVM_SUPPORT_COMMANDLINE_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" @@ -40,7 +41,7 @@ namespace cl { //===----------------------------------------------------------------------===// // ParseCommandLineOptions - Command line option processing entry point. // -void ParseCommandLineOptions(int argc, const char * const *argv, +void ParseCommandLineOptions(int argc, const char *const *argv, const char *Overview = nullptr); //===----------------------------------------------------------------------===// @@ -66,25 +67,33 @@ void SetVersionPrinter(void (*func)()); /// information specific to the tool. void AddExtraVersionPrinter(void (*func)()); - // PrintOptionValues - Print option values. // With -print-options print the difference between option values and defaults. // With -print-all-options print all option values. // (Currently not perfect, but best-effort.) void PrintOptionValues(); -// MarkOptionsChanged - Internal helper function. -void MarkOptionsChanged(); +// Forward declaration - AddLiteralOption needs to be up here to make gcc happy. +class Option; + +/// \brief Adds a new option for parsing and provides the option it refers to. +/// +/// \param O pointer to the option +/// \param Name the string name for the option to handle during parsing +/// +/// Literal options are used by some parsers to register special option values. +/// This is how the PassNameParser registers pass names for opt. +void AddLiteralOption(Option &O, const char *Name); //===----------------------------------------------------------------------===// // Flags permitted to be passed to command line arguments // -enum NumOccurrencesFlag { // Flags for the number of occurrences allowed - Optional = 0x00, // Zero or One occurrence - ZeroOrMore = 0x01, // Zero or more occurrences allowed - Required = 0x02, // One occurrence required - OneOrMore = 0x03, // One or more occurrences required +enum NumOccurrencesFlag { // Flags for the number of occurrences allowed + Optional = 0x00, // Zero or One occurrence + ZeroOrMore = 0x01, // Zero or more occurrences allowed + Required = 0x02, // One occurrence required + OneOrMore = 0x03, // One or more occurrences required // ConsumeAfter - Indicates that this option is fed anything that follows the // last positional argument required by the application (it is an error if @@ -93,20 +102,20 @@ enum NumOccurrencesFlag { // Flags for the number of occurrences allowed // found. Once a filename is found, all of the succeeding arguments are // passed, unprocessed, to the ConsumeAfter option. // - ConsumeAfter = 0x04 + ConsumeAfter = 0x04 }; -enum ValueExpected { // Is a value required for the option? +enum ValueExpected { // Is a value required for the option? // zero reserved for the unspecified value - ValueOptional = 0x01, // The value can appear... or not - ValueRequired = 0x02, // The value is required to appear! - ValueDisallowed = 0x03 // A value may not be specified (for flags) + ValueOptional = 0x01, // The value can appear... or not + ValueRequired = 0x02, // The value is required to appear! + ValueDisallowed = 0x03 // A value may not be specified (for flags) }; -enum OptionHidden { // Control whether -help shows this option - NotHidden = 0x00, // Option included in -help & -help-hidden - Hidden = 0x01, // -help doesn't, but -help-hidden does - ReallyHidden = 0x02 // Neither -help nor -help-hidden show this arg +enum OptionHidden { // Control whether -help shows this option + NotHidden = 0x00, // Option included in -help & -help-hidden + Hidden = 0x01, // -help doesn't, but -help-hidden does + ReallyHidden = 0x02 // Neither -help nor -help-hidden show this arg }; // Formatting flags - This controls special features that the option might have @@ -125,16 +134,16 @@ enum OptionHidden { // Control whether -help shows this option // enum FormattingFlags { - NormalFormatting = 0x00, // Nothing special - Positional = 0x01, // Is a positional argument, no '-' required - Prefix = 0x02, // Can this option directly prefix its value? - Grouping = 0x03 // Can this option group with other options? + NormalFormatting = 0x00, // Nothing special + Positional = 0x01, // Is a positional argument, no '-' required + Prefix = 0x02, // Can this option directly prefix its value? + Grouping = 0x03 // Can this option group with other options? }; -enum MiscFlags { // Miscellaneous flags to adjust argument - CommaSeparated = 0x01, // Should this cl::list split between commas? - PositionalEatsArgs = 0x02, // Should this positional cl::list eat -args? - Sink = 0x04 // Should this cl::list eat all unknown options? +enum MiscFlags { // Miscellaneous flags to adjust argument + CommaSeparated = 0x01, // Should this cl::list split between commas? + PositionalEatsArgs = 0x02, // Should this positional cl::list eat -args? + Sink = 0x04 // Should this cl::list eat all unknown options? }; //===----------------------------------------------------------------------===// @@ -145,9 +154,13 @@ private: const char *const Name; const char *const Description; void registerCategory(); + public: - OptionCategory(const char *const Name, const char *const Description = nullptr) - : Name(Name), Description(Description) { registerCategory(); } + OptionCategory(const char *const Name, + const char *const Description = nullptr) + : Name(Name), Description(Description) { + registerCategory(); + } const char *getName() const { return Name; } const char *getDescription() const { return Description; } }; @@ -176,7 +189,7 @@ class Option { // Out of line virtual function to provide home for the class. virtual void anchor(); - int NumOccurrences; // The number of times specified + int NumOccurrences; // The number of times specified // Occurrences, HiddenFlag, and Formatting are all enum types but to avoid // problems with signed enums in bitfields. unsigned Occurrences : 3; // enum NumOccurrencesFlag @@ -186,22 +199,21 @@ class Option { unsigned HiddenFlag : 2; // enum OptionHidden unsigned Formatting : 2; // enum FormattingFlags unsigned Misc : 3; - unsigned Position; // Position of last occurrence of the option - unsigned AdditionalVals;// Greater than 0 for multi-valued option. - Option *NextRegistered; // Singly linked list of registered options. + unsigned Position; // Position of last occurrence of the option + unsigned AdditionalVals; // Greater than 0 for multi-valued option. public: const char *ArgStr; // The argument string itself (ex: "help", "o") const char *HelpStr; // The descriptive text message for -help const char *ValueStr; // String describing what the value of this option is OptionCategory *Category; // The Category this option belongs to + bool FullyInitialized; // Has addArguemnt been called? inline enum NumOccurrencesFlag getNumOccurrencesFlag() const { return (enum NumOccurrencesFlag)Occurrences; } inline enum ValueExpected getValueExpectedFlag() const { - return Value ? ((enum ValueExpected)Value) - : getValueExpectedFlagDefault(); + return Value ? ((enum ValueExpected)Value) : getValueExpectedFlagDefault(); } inline enum OptionHidden getOptionHiddenFlag() const { return (enum OptionHidden)HiddenFlag; @@ -209,9 +221,7 @@ public: inline enum FormattingFlags getFormattingFlag() const { return (enum FormattingFlags)Formatting; } - inline unsigned getMiscFlags() const { - return Misc; - } + inline unsigned getMiscFlags() const { return Misc; } inline unsigned getPosition() const { return Position; } inline unsigned getNumAdditionalVals() const { return AdditionalVals; } @@ -221,28 +231,27 @@ public: //-------------------------------------------------------------------------=== // Accessor functions set by OptionModifiers // - void setArgStr(const char *S) { ArgStr = S; } + void setArgStr(const char *S); void setDescription(const char *S) { HelpStr = S; } void setValueStr(const char *S) { ValueStr = S; } - void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { - Occurrences = Val; - } + void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { Occurrences = Val; } void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; } void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; } void setFormattingFlag(enum FormattingFlags V) { Formatting = V; } void setMiscFlag(enum MiscFlags M) { Misc |= M; } void setPosition(unsigned pos) { Position = pos; } void setCategory(OptionCategory &C) { Category = &C; } + protected: explicit Option(enum NumOccurrencesFlag OccurrencesFlag, enum OptionHidden Hidden) - : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), - HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), - Position(0), AdditionalVals(0), NextRegistered(nullptr), - ArgStr(""), HelpStr(""), ValueStr(""), Category(&GeneralCategory) { - } + : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), + HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), Position(0), + AdditionalVals(0), ArgStr(""), HelpStr(""), ValueStr(""), + Category(&GeneralCategory), FullyInitialized(false) {} inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } + public: // addArgument - Register this argument with the commandline system. // @@ -254,8 +263,6 @@ public: /// For testing purposes only. void removeArgument(); - Option *getNextRegisteredOption() const { return NextRegistered; } - // Return the width of the option tag for printing... virtual size_t getOptionWidth() const = 0; @@ -266,12 +273,12 @@ public: virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0; - virtual void getExtraOptionNames(SmallVectorImpl<const char*> &) {} + virtual void getExtraOptionNames(SmallVectorImpl<const char *> &) {} // addOccurrence - Wrapper around handleOccurrence that enforces Flags. // - virtual bool addOccurrence(unsigned pos, StringRef ArgName, - StringRef Value, bool MultiArg = false); + virtual bool addOccurrence(unsigned pos, StringRef ArgName, StringRef Value, + bool MultiArg = false); // Prints option name followed by message. Always returns true. bool error(const Twine &Message, StringRef ArgName = StringRef()); @@ -281,7 +288,6 @@ public: virtual ~Option() {} }; - //===----------------------------------------------------------------------===// // Command line option modifiers that can be used to modify the behavior of // command line option parsers... @@ -306,36 +312,31 @@ struct value_desc { // the default constructor for the argument type does not give you what you // want. This is only valid on "opt" arguments, not on "list" arguments. // -template<class Ty> -struct initializer { +template <class Ty> struct initializer { const Ty &Init; initializer(const Ty &Val) : Init(Val) {} - template<class Opt> - void apply(Opt &O) const { O.setInitialValue(Init); } + template <class Opt> void apply(Opt &O) const { O.setInitialValue(Init); } }; -template<class Ty> -initializer<Ty> init(const Ty &Val) { +template <class Ty> initializer<Ty> init(const Ty &Val) { return initializer<Ty>(Val); } - // location - Allow the user to specify which external variable they want to // store the results of the command line argument processing into, if they don't // want to store it in the option itself. // -template<class Ty> -struct LocationClass { +template <class Ty> struct LocationClass { Ty &Loc; LocationClass(Ty &L) : Loc(L) {} - template<class Opt> - void apply(Opt &O) const { O.setLocation(O, Loc); } + template <class Opt> void apply(Opt &O) const { O.setLocation(O, Loc); } }; -template<class Ty> -LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); } +template <class Ty> LocationClass<Ty> location(Ty &L) { + return LocationClass<Ty>(L); +} // cat - Specifiy the Option category for the command line argument to belong // to. @@ -343,11 +344,9 @@ struct cat { OptionCategory &Category; cat(OptionCategory &c) : Category(c) {} - template<class Opt> - void apply(Opt &O) const { O.setCategory(Category); } + template <class Opt> void apply(Opt &O) const { O.setCategory(Category); } }; - //===----------------------------------------------------------------------===// // OptionValue class @@ -360,11 +359,11 @@ private: virtual void anchor(); }; -template<class DataType> struct OptionValue; +template <class DataType> struct OptionValue; // The default value safely does nothing. Option value printing is only // best-effort. -template<class DataType, bool isClass> +template <class DataType, bool isClass> struct OptionValueBase : public GenericOptionValue { // Temporary storage for argument passing. typedef OptionValue<DataType> WrapperType; @@ -374,21 +373,20 @@ struct OptionValueBase : public GenericOptionValue { const DataType &getValue() const { llvm_unreachable("no default value"); } // Some options may take their value from a different data type. - template<class DT> - void setValue(const DT& /*V*/) {} + template <class DT> void setValue(const DT & /*V*/) {} - bool compare(const DataType &/*V*/) const { return false; } + bool compare(const DataType & /*V*/) const { return false; } - bool compare(const GenericOptionValue& /*V*/) const override { + bool compare(const GenericOptionValue & /*V*/) const override { return false; } }; // Simple copy of the option value. -template<class DataType> -class OptionValueCopy : public GenericOptionValue { +template <class DataType> class OptionValueCopy : public GenericOptionValue { DataType Value; bool Valid; + public: OptionValueCopy() : Valid(false) {} @@ -399,37 +397,36 @@ public: return Value; } - void setValue(const DataType &V) { Valid = true; Value = V; } - - bool compare(const DataType &V) const { - return Valid && (Value != V); + void setValue(const DataType &V) { + Valid = true; + Value = V; } + bool compare(const DataType &V) const { return Valid && (Value != V); } + bool compare(const GenericOptionValue &V) const override { const OptionValueCopy<DataType> &VC = - static_cast< const OptionValueCopy<DataType>& >(V); - if (!VC.hasValue()) return false; + static_cast<const OptionValueCopy<DataType> &>(V); + if (!VC.hasValue()) + return false; return compare(VC.getValue()); } }; // Non-class option values. -template<class DataType> +template <class DataType> struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> { typedef DataType WrapperType; }; // Top-level option class. -template<class DataType> +template <class DataType> struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> { OptionValue() {} - OptionValue(const DataType& V) { - this->setValue(V); - } + OptionValue(const DataType &V) { this->setValue(V); } // Some options may take their value from a different data type. - template<class DT> - OptionValue<DataType> &operator=(const DT& V) { + template <class DT> OptionValue<DataType> &operator=(const DT &V) { this->setValue(V); return *this; } @@ -437,36 +434,33 @@ struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> { // Other safe-to-copy-by-value common option types. enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE }; -template<> +template <> struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> { typedef cl::boolOrDefault WrapperType; OptionValue() {} - OptionValue(const cl::boolOrDefault& V) { - this->setValue(V); - } - OptionValue<cl::boolOrDefault> &operator=(const cl::boolOrDefault& V) { + OptionValue(const cl::boolOrDefault &V) { this->setValue(V); } + OptionValue<cl::boolOrDefault> &operator=(const cl::boolOrDefault &V) { setValue(V); return *this; } + private: void anchor() override; }; -template<> -struct OptionValue<std::string> : OptionValueCopy<std::string> { +template <> struct OptionValue<std::string> : OptionValueCopy<std::string> { typedef StringRef WrapperType; OptionValue() {} - OptionValue(const std::string& V) { - this->setValue(V); - } - OptionValue<std::string> &operator=(const std::string& V) { + OptionValue(const std::string &V) { this->setValue(V); } + OptionValue<std::string> &operator=(const std::string &V) { setValue(V); return *this; } + private: void anchor() override; }; @@ -476,20 +470,20 @@ private: // #define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC #define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC -#define clEnumValEnd (reinterpret_cast<void*>(0)) +#define clEnumValEnd (reinterpret_cast<void *>(0)) // values - For custom data types, allow specifying a group of values together // as the values that go into the mapping that the option handler uses. Note // that the values list must always have a 0 at the end of the list to indicate // that the list has ended. // -template<class DataType> -class ValuesClass { +template <class DataType> class ValuesClass { // Use a vector instead of a map, because the lists should be short, // the overhead is less, and most importantly, it keeps them in the order // inserted so we can print our option out nicely. - SmallVector<std::pair<const char *, std::pair<int, const char *> >,4> Values; + SmallVector<std::pair<const char *, std::pair<int, const char *>>, 4> Values; void processValues(va_list Vals); + public: ValuesClass(const char *EnumName, DataType Val, const char *Desc, va_list ValueArgs) { @@ -500,13 +494,12 @@ public: while (const char *enumName = va_arg(ValueArgs, const char *)) { DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int)); const char *EnumDesc = va_arg(ValueArgs, const char *); - Values.push_back(std::make_pair(enumName, // Add value to value map + Values.push_back(std::make_pair(enumName, // Add value to value map std::make_pair(EnumVal, EnumDesc))); } } - template<class Opt> - void apply(Opt &O) const { + template <class Opt> void apply(Opt &O) const { for (size_t i = 0, e = Values.size(); i != e; ++i) O.getParser().addLiteralOption(Values[i].first, Values[i].second.first, Values[i].second.second); @@ -516,11 +509,11 @@ public: template <class DataType> ValuesClass<DataType> LLVM_END_WITH_NULL values(const char *Arg, DataType Val, const char *Desc, ...) { - va_list ValueArgs; - va_start(ValueArgs, Desc); - ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs); - va_end(ValueArgs); - return Vals; + va_list ValueArgs; + va_start(ValueArgs, Desc); + ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs); + va_end(ValueArgs); + return Vals; } //===----------------------------------------------------------------------===// @@ -539,13 +532,16 @@ class generic_parser_base { protected: class GenericOptionInfo { public: - GenericOptionInfo(const char *name, const char *helpStr) : - Name(name), HelpStr(helpStr) {} + GenericOptionInfo(const char *name, const char *helpStr) + : Name(name), HelpStr(helpStr) {} const char *Name; const char *HelpStr; }; + public: - virtual ~generic_parser_base() {} // Base class should have virtual-dtor + generic_parser_base(Option &O) : Owner(O) {} + + virtual ~generic_parser_base() {} // Base class should have virtual-dtor // getNumOptions - Virtual function implemented by generic subclass to // indicate how many entries are in Values. @@ -576,30 +572,24 @@ public: // // Template definition ensures that the option and default have the same // DataType (via the same AnyOptionValue). - template<class AnyOptionValue> + template <class AnyOptionValue> void printOptionDiff(const Option &O, const AnyOptionValue &V, const AnyOptionValue &Default, size_t GlobalWidth) const { printGenericOptionDiff(O, V, Default, GlobalWidth); } - void initialize(Option &O) { - // All of the modifiers for the option have been processed by now, so the - // argstr field should be stable, copy it down now. - // - hasArgStr = O.hasArgStr(); - } + void initialize() {} - void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) { + void getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) { // If there has been no argstr specified, that means that we need to add an // argument for every possible option. This ensures that our options are // vectored to us. - if (!hasArgStr) + if (!Owner.hasArgStr()) for (unsigned i = 0, e = getNumOptions(); i != e; ++i) OptionNames.push_back(getOption(i)); } - enum ValueExpected getValueExpectedFlagDefault() const { // If there is an ArgStr specified, then we are of the form: // @@ -612,7 +602,7 @@ public: // // If this is the case, we cannot allow a value. // - if (hasArgStr) + if (Owner.hasArgStr()) return ValueRequired; else return ValueDisallowed; @@ -624,7 +614,7 @@ public: unsigned findOption(const char *Name); protected: - bool hasArgStr; + Option &Owner; }; // Default parser implementation - This implementation depends on having a @@ -633,17 +623,18 @@ protected: // command line option for -help. Because this is a simple mapping parser, the // data type can be any unsupported type. // -template <class DataType> -class parser : public generic_parser_base { +template <class DataType> class parser : public generic_parser_base { protected: class OptionInfo : public GenericOptionInfo { public: - OptionInfo(const char *name, DataType v, const char *helpStr) : - GenericOptionInfo(name, helpStr), V(v) {} + OptionInfo(const char *name, DataType v, const char *helpStr) + : GenericOptionInfo(name, helpStr), V(v) {} OptionValue<DataType> V; }; SmallVector<OptionInfo, 8> Values; + public: + parser(Option &O) : generic_parser_base(O) {} typedef DataType parser_data_type; // Implement virtual functions needed by generic_parser_base @@ -661,7 +652,7 @@ public: // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) { StringRef ArgVal; - if (hasArgStr) + if (Owner.hasArgStr()) ArgVal = Arg; else ArgVal = ArgName; @@ -682,7 +673,7 @@ public: assert(findOption(Name) == Values.size() && "Option already exists!"); OptionInfo X(Name, static_cast<DataType>(V), HelpStr); Values.push_back(X); - MarkOptionsChanged(); + AddLiteralOption(Owner, Name); } /// removeLiteralOption - Remove the specified option. @@ -690,24 +681,26 @@ public: void removeLiteralOption(const char *Name) { unsigned N = findOption(Name); assert(N != Values.size() && "Option not found!"); - Values.erase(Values.begin()+N); + Values.erase(Values.begin() + N); } }; //-------------------------------------------------- // basic_parser - Super class of parsers to provide boilerplate code // -class basic_parser_impl { // non-template implementation of basic_parser<t> +class basic_parser_impl { // non-template implementation of basic_parser<t> public: + basic_parser_impl(Option &O) {} + virtual ~basic_parser_impl() {} enum ValueExpected getValueExpectedFlagDefault() const { return ValueRequired; } - void getExtraOptionNames(SmallVectorImpl<const char*> &) {} + void getExtraOptionNames(SmallVectorImpl<const char *> &) {} - void initialize(Option &) {} + void initialize() {} // Return the width of the option tag for printing... size_t getOptionWidth(const Option &O) const; @@ -735,9 +728,9 @@ protected: // basic_parser - The real basic parser is just a template wrapper that provides // a typedef for the provided data type. // -template<class DataType> -class basic_parser : public basic_parser_impl { +template <class DataType> class basic_parser : public basic_parser_impl { public: + basic_parser(Option &O) : basic_parser_impl(O) {} typedef DataType parser_data_type; typedef OptionValue<DataType> OptVal; }; @@ -745,18 +738,14 @@ public: //-------------------------------------------------- // parser<bool> // -template<> -class parser<bool> : public basic_parser<bool> { - const char *ArgStr; +template <> class parser<bool> : public basic_parser<bool> { public: + parser(Option &O) : basic_parser(O) {} // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val); - template <class Opt> - void initialize(Opt &O) { - ArgStr = O.ArgStr; - } + void initialize() {} enum ValueExpected getValueExpectedFlagDefault() const { return ValueOptional; @@ -776,9 +765,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>); //-------------------------------------------------- // parser<boolOrDefault> -template<> -class parser<boolOrDefault> : public basic_parser<boolOrDefault> { +template <> class parser<boolOrDefault> : public basic_parser<boolOrDefault> { public: + parser(Option &O) : basic_parser(O) {} + // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val); @@ -801,9 +791,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>); //-------------------------------------------------- // parser<int> // -template<> -class parser<int> : public basic_parser<int> { +template <> class parser<int> : public basic_parser<int> { public: + parser(Option &O) : basic_parser(O) {} + // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val); @@ -819,13 +810,13 @@ public: EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>); - //-------------------------------------------------- // parser<unsigned> // -template<> -class parser<unsigned> : public basic_parser<unsigned> { +template <> class parser<unsigned> : public basic_parser<unsigned> { public: + parser(Option &O) : basic_parser(O) {} + // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val); @@ -844,9 +835,11 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>); //-------------------------------------------------- // parser<unsigned long long> // -template<> +template <> class parser<unsigned long long> : public basic_parser<unsigned long long> { public: + parser(Option &O) : basic_parser(O) {} + // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned long long &Val); @@ -866,9 +859,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>); //-------------------------------------------------- // parser<double> // -template<> -class parser<double> : public basic_parser<double> { +template <> class parser<double> : public basic_parser<double> { public: + parser(Option &O) : basic_parser(O) {} + // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val); @@ -887,9 +881,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>); //-------------------------------------------------- // parser<float> // -template<> -class parser<float> : public basic_parser<float> { +template <> class parser<float> : public basic_parser<float> { public: + parser(Option &O) : basic_parser(O) {} + // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val); @@ -908,9 +903,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>); //-------------------------------------------------- // parser<std::string> // -template<> -class parser<std::string> : public basic_parser<std::string> { +template <> class parser<std::string> : public basic_parser<std::string> { public: + parser(Option &O) : basic_parser(O) {} + // parse - Return true on error. bool parse(Option &, StringRef, StringRef Arg, std::string &Value) { Value = Arg.str(); @@ -932,9 +928,10 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>); //-------------------------------------------------- // parser<char> // -template<> -class parser<char> : public basic_parser<char> { +template <> class parser<char> : public basic_parser<char> { public: + parser(Option &O) : basic_parser(O) {} + // parse - Return true on error. bool parse(Option &, StringRef, StringRef Arg, char &Value) { Value = Arg[0]; @@ -960,7 +957,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>); // parser to handle all the template nastiness. // This overloaded function is selected by the generic parser. -template<class ParserClass, class DT> +template <class ParserClass, class DT> void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V, const OptionValue<DT> &Default, size_t GlobalWidth) { OptionValue<DT> OV = V; @@ -969,18 +966,16 @@ void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V, // This is instantiated for basic parsers when the parsed value has a different // type than the option value. e.g. HelpPrinter. -template<class ParserDT, class ValDT> -struct OptionDiffPrinter { - void print(const Option &O, const parser<ParserDT> P, const ValDT &/*V*/, - const OptionValue<ValDT> &/*Default*/, size_t GlobalWidth) { +template <class ParserDT, class ValDT> struct OptionDiffPrinter { + void print(const Option &O, const parser<ParserDT> P, const ValDT & /*V*/, + const OptionValue<ValDT> & /*Default*/, size_t GlobalWidth) { P.printOptionNoValue(O, GlobalWidth); } }; // This is instantiated for basic parsers when the parsed value has the same // type as the option value. -template<class DT> -struct OptionDiffPrinter<DT, DT> { +template <class DT> struct OptionDiffPrinter<DT, DT> { void print(const Option &O, const parser<DT> P, const DT &V, const OptionValue<DT> &Default, size_t GlobalWidth) { P.printOptionDiff(O, V, Default, GlobalWidth); @@ -989,15 +984,14 @@ struct OptionDiffPrinter<DT, DT> { // This overloaded function is selected by the basic parser, which may parse a // different type than the option type. -template<class ParserClass, class ValDT> +template <class ParserClass, class ValDT> void printOptionDiff( - const Option &O, - const basic_parser<typename ParserClass::parser_data_type> &P, - const ValDT &V, const OptionValue<ValDT> &Default, - size_t GlobalWidth) { + const Option &O, + const basic_parser<typename ParserClass::parser_data_type> &P, + const ValDT &V, const OptionValue<ValDT> &Default, size_t GlobalWidth) { OptionDiffPrinter<typename ParserClass::parser_data_type, ValDT> printer; - printer.print(O, static_cast<const ParserClass&>(P), V, Default, + printer.print(O, static_cast<const ParserClass &>(P), V, Default, GlobalWidth); } @@ -1007,46 +1001,53 @@ void printOptionDiff( // not correctly respond to the apply method). Because the syntax to use this // is a pain, we have the 'apply' method below to handle the nastiness... // -template<class Mod> struct applicator { - template<class Opt> - static void opt(const Mod &M, Opt &O) { M.apply(O); } +template <class Mod> struct applicator { + template <class Opt> static void opt(const Mod &M, Opt &O) { M.apply(O); } }; // Handle const char* as a special case... -template<unsigned n> struct applicator<char[n]> { - template<class Opt> - static void opt(const char *Str, Opt &O) { O.setArgStr(Str); } +template <unsigned n> struct applicator<char[n]> { + template <class Opt> static void opt(const char *Str, Opt &O) { + O.setArgStr(Str); + } }; -template<unsigned n> struct applicator<const char[n]> { - template<class Opt> - static void opt(const char *Str, Opt &O) { O.setArgStr(Str); } +template <unsigned n> struct applicator<const char[n]> { + template <class Opt> static void opt(const char *Str, Opt &O) { + O.setArgStr(Str); + } }; -template<> struct applicator<const char*> { - template<class Opt> - static void opt(const char *Str, Opt &O) { O.setArgStr(Str); } +template <> struct applicator<const char *> { + template <class Opt> static void opt(const char *Str, Opt &O) { + O.setArgStr(Str); + } }; -template<> struct applicator<NumOccurrencesFlag> { +template <> struct applicator<NumOccurrencesFlag> { static void opt(NumOccurrencesFlag N, Option &O) { O.setNumOccurrencesFlag(N); } }; -template<> struct applicator<ValueExpected> { +template <> struct applicator<ValueExpected> { static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); } }; -template<> struct applicator<OptionHidden> { +template <> struct applicator<OptionHidden> { static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); } }; -template<> struct applicator<FormattingFlags> { +template <> struct applicator<FormattingFlags> { static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); } }; -template<> struct applicator<MiscFlags> { +template <> struct applicator<MiscFlags> { static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); } }; -// apply method - Apply a modifier to an option in a type safe way. -template<class Mod, class Opt> -void apply(const Mod &M, Opt *O) { +// apply method - Apply modifiers to an option in a type safe way. +template <class Opt, class Mod, class... Mods> +void apply(Opt *O, const Mod &M, const Mods &... Ms) { + applicator<Mod>::opt(M, *O); + apply(O, Ms...); +} + +template <class Opt, class Mod> void apply(Opt *O, const Mod &M) { applicator<Mod>::opt(M, *O); } @@ -1057,16 +1058,17 @@ void apply(const Mod &M, Opt *O) { // assumes the user will specify a variable to store the data into with the // cl::location(x) modifier. // -template<class DataType, bool ExternalStorage, bool isClass> +template <class DataType, bool ExternalStorage, bool isClass> class opt_storage { - DataType *Location; // Where to store the object... + DataType *Location; // Where to store the object... OptionValue<DataType> Default; void check_location() const { assert(Location && "cl::location(...) not specified for a command " - "line option with external storage, " - "or cl::init specified before cl::location()!!"); + "line option with external storage, " + "or cl::init specified before cl::location()!!"); } + public: opt_storage() : Location(nullptr) {} @@ -1078,16 +1080,21 @@ public: return false; } - template<class T> - void setValue(const T &V, bool initial = false) { + template <class T> void setValue(const T &V, bool initial = false) { check_location(); *Location = V; if (initial) Default = V; } - DataType &getValue() { check_location(); return *Location; } - const DataType &getValue() const { check_location(); return *Location; } + DataType &getValue() { + check_location(); + return *Location; + } + const DataType &getValue() const { + check_location(); + return *Location; + } operator DataType() const { return this->getValue(); } @@ -1098,13 +1105,12 @@ public: // inherit from a class, we do so. This makes us exactly compatible with the // object in all cases that it is used. // -template<class DataType> -class opt_storage<DataType,false,true> : public DataType { +template <class DataType> +class opt_storage<DataType, false, true> : public DataType { public: OptionValue<DataType> Default; - template<class T> - void setValue(const T &V, bool initial = false) { + template <class T> void setValue(const T &V, bool initial = false) { DataType::operator=(V); if (initial) Default = V; @@ -1120,8 +1126,7 @@ public: // this case, we store an instance through containment, and overload operators // to get at the value. // -template<class DataType> -class opt_storage<DataType, false, false> { +template <class DataType> class opt_storage<DataType, false, false> { public: DataType Value; OptionValue<DataType> Default; @@ -1130,8 +1135,7 @@ public: // type. opt_storage() : Value(DataType()), Default(DataType()) {} - template<class T> - void setValue(const T &V, bool initial = false) { + template <class T> void setValue(const T &V, bool initial = false) { Value = V; if (initial) Default = V; @@ -1147,12 +1151,11 @@ public: DataType operator->() const { return Value; } }; - //===----------------------------------------------------------------------===// // opt - A scalar command line option. // template <class DataType, bool ExternalStorage = false, - class ParserClass = parser<DataType> > + class ParserClass = parser<DataType>> class opt : public Option, public opt_storage<DataType, ExternalStorage, std::is_class<DataType>::value> { @@ -1161,9 +1164,9 @@ class opt : public Option, bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg) override { typename ParserClass::parser_data_type Val = - typename ParserClass::parser_data_type(); + typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) - return true; // Parse error! + return true; // Parse error! this->setValue(Val); this->setPosition(pos); return false; @@ -1172,102 +1175,50 @@ class opt : public Option, enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override { + void + getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } // Forward printing stuff to the parser... - size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);} + size_t getOptionWidth() const override { + return Parser.getOptionWidth(*this); + } void printOptionInfo(size_t GlobalWidth) const override { Parser.printOptionInfo(*this, GlobalWidth); } void printOptionValue(size_t GlobalWidth, bool Force) const override { if (Force || this->getDefault().compare(this->getValue())) { - cl::printOptionDiff<ParserClass>( - *this, Parser, this->getValue(), this->getDefault(), GlobalWidth); + cl::printOptionDiff<ParserClass>(*this, Parser, this->getValue(), + this->getDefault(), GlobalWidth); } } void done() { addArgument(); - Parser.initialize(*this); + Parser.initialize(); } + + // Command line options should not be copyable + opt(const opt &) = delete; + opt &operator=(const opt &) = delete; + public: // setInitialValue - Used by the cl::init modifier... void setInitialValue(const DataType &V) { this->setValue(V, true); } ParserClass &getParser() { return Parser; } - template<class T> - DataType &operator=(const T &Val) { + template <class T> DataType &operator=(const T &Val) { this->setValue(Val); return this->getValue(); } - // One option... - template<class M0t> - explicit opt(const M0t &M0) : Option(Optional, NotHidden) { - apply(M0, this); - done(); - } - - // Two options... - template<class M0t, class M1t> - opt(const M0t &M0, const M1t &M1) : Option(Optional, NotHidden) { - apply(M0, this); apply(M1, this); - done(); - } - - // Three options... - template<class M0t, class M1t, class M2t> - opt(const M0t &M0, const M1t &M1, - const M2t &M2) : Option(Optional, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); - done(); - } - // Four options... - template<class M0t, class M1t, class M2t, class M3t> - opt(const M0t &M0, const M1t &M1, const M2t &M2, - const M3t &M3) : Option(Optional, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - done(); - } - // Five options... - template<class M0t, class M1t, class M2t, class M3t, class M4t> - opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4) : Option(Optional, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); - done(); - } - // Six options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t> - opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5) : Option(Optional, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); - done(); - } - // Seven options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t, class M6t> - opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5, - const M6t &M6) : Option(Optional, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); apply(M6, this); - done(); - } - // Eight options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t, class M6t, class M7t> - opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5, const M6t &M6, - const M7t &M7) : Option(Optional, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this); + template <class... Mods> + explicit opt(const Mods &... Ms) + : Option(Optional, NotHidden), Parser(*this) { + apply(this, Ms...); done(); } }; @@ -1285,9 +1236,8 @@ EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>); // assumes the user will specify a variable to store the data into with the // cl::location(x) modifier. // -template<class DataType, class StorageClass> -class list_storage { - StorageClass *Location; // Where to store the object... +template <class DataType, class StorageClass> class list_storage { + StorageClass *Location; // Where to store the object... public: list_storage() : Location(0) {} @@ -1299,32 +1249,30 @@ public: return false; } - template<class T> - void addValue(const T &V) { + template <class T> void addValue(const T &V) { assert(Location != 0 && "cl::location(...) not specified for a command " - "line option with external storage!"); + "line option with external storage!"); Location->push_back(V); } }; - // Define how to hold a class type object, such as a string. Since we can // inherit from a class, we do so. This makes us exactly compatible with the // object in all cases that it is used. // -template<class DataType> +template <class DataType> class list_storage<DataType, bool> : public std::vector<DataType> { public: - template<class T> - void addValue(const T &V) { std::vector<DataType>::push_back(V); } + template <class T> void addValue(const T &V) { + std::vector<DataType>::push_back(V); + } }; - //===----------------------------------------------------------------------===// // list - A list of command line options. // template <class DataType, class Storage = bool, - class ParserClass = parser<DataType> > + class ParserClass = parser<DataType>> class list : public Option, public list_storage<DataType, Storage> { std::vector<unsigned> Positions; ParserClass Parser; @@ -1332,16 +1280,17 @@ class list : public Option, public list_storage<DataType, Storage> { enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override { + void + getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg) override { typename ParserClass::parser_data_type Val = - typename ParserClass::parser_data_type(); + typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) - return true; // Parse Error! + return true; // Parse Error! list_storage<DataType, Storage>::addValue(Val); setPosition(pos); Positions.push_back(pos); @@ -1349,19 +1298,26 @@ class list : public Option, public list_storage<DataType, Storage> { } // Forward printing stuff to the parser... - size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);} + size_t getOptionWidth() const override { + return Parser.getOptionWidth(*this); + } void printOptionInfo(size_t GlobalWidth) const override { Parser.printOptionInfo(*this, GlobalWidth); } // Unimplemented: list options don't currently store their default value. - void printOptionValue(size_t /*GlobalWidth*/, - bool /*Force*/) const override {} + void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { + } void done() { addArgument(); - Parser.initialize(*this); + Parser.initialize(); } + + // Command line options should not be copyable + list(const list &) = delete; + list &operator=(const list &) = delete; + public: ParserClass &getParser() { return Parser; } @@ -1370,71 +1326,12 @@ public: return Positions[optnum]; } - void setNumAdditionalVals(unsigned n) { - Option::setNumAdditionalVals(n); - } + void setNumAdditionalVals(unsigned n) { Option::setNumAdditionalVals(n); } - // One option... - template<class M0t> - explicit list(const M0t &M0) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); - done(); - } - // Two options... - template<class M0t, class M1t> - list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); - done(); - } - // Three options... - template<class M0t, class M1t, class M2t> - list(const M0t &M0, const M1t &M1, const M2t &M2) - : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); - done(); - } - // Four options... - template<class M0t, class M1t, class M2t, class M3t> - list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) - : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - done(); - } - // Five options... - template<class M0t, class M1t, class M2t, class M3t, class M4t> - list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); - done(); - } - // Six options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t> - list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); - done(); - } - // Seven options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t, class M6t> - list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5, const M6t &M6) - : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); apply(M6, this); - done(); - } - // Eight options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t, class M6t, class M7t> - list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5, const M6t &M6, - const M7t &M7) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this); + template <class... Mods> + explicit list(const Mods &... Ms) + : Option(ZeroOrMore, NotHidden), Parser(*this) { + apply(this, Ms...); done(); } }; @@ -1445,10 +1342,11 @@ struct multi_val { explicit multi_val(unsigned N) : AdditionalVals(N) {} template <typename D, typename S, typename P> - void apply(list<D, S, P> &L) const { L.setNumAdditionalVals(AdditionalVals); } + void apply(list<D, S, P> &L) const { + L.setNumAdditionalVals(AdditionalVals); + } }; - //===----------------------------------------------------------------------===// // bits_storage class @@ -1456,15 +1354,13 @@ struct multi_val { // assumes the user will specify a variable to store the data into with the // cl::location(x) modifier. // -template<class DataType, class StorageClass> -class bits_storage { - unsigned *Location; // Where to store the bits... +template <class DataType, class StorageClass> class bits_storage { + unsigned *Location; // Where to store the bits... - template<class T> - static unsigned Bit(const T &V) { + template <class T> static unsigned Bit(const T &V) { unsigned BitPos = reinterpret_cast<unsigned>(V); assert(BitPos < sizeof(unsigned) * CHAR_BIT && - "enum exceeds width of bit vector!"); + "enum exceeds width of bit vector!"); return 1 << BitPos; } @@ -1478,57 +1374,45 @@ public: return false; } - template<class T> - void addValue(const T &V) { + template <class T> void addValue(const T &V) { assert(Location != 0 && "cl::location(...) not specified for a command " - "line option with external storage!"); + "line option with external storage!"); *Location |= Bit(V); } unsigned getBits() { return *Location; } - template<class T> - bool isSet(const T &V) { + template <class T> bool isSet(const T &V) { return (*Location & Bit(V)) != 0; } }; - // Define how to hold bits. Since we can inherit from a class, we do so. // This makes us exactly compatible with the bits in all cases that it is used. // -template<class DataType> -class bits_storage<DataType, bool> { - unsigned Bits; // Where to store the bits... +template <class DataType> class bits_storage<DataType, bool> { + unsigned Bits; // Where to store the bits... - template<class T> - static unsigned Bit(const T &V) { + template <class T> static unsigned Bit(const T &V) { unsigned BitPos = (unsigned)V; assert(BitPos < sizeof(unsigned) * CHAR_BIT && - "enum exceeds width of bit vector!"); + "enum exceeds width of bit vector!"); return 1 << BitPos; } public: - template<class T> - void addValue(const T &V) { - Bits |= Bit(V); - } + template <class T> void addValue(const T &V) { Bits |= Bit(V); } unsigned getBits() { return Bits; } - template<class T> - bool isSet(const T &V) { - return (Bits & Bit(V)) != 0; - } + template <class T> bool isSet(const T &V) { return (Bits & Bit(V)) != 0; } }; - //===----------------------------------------------------------------------===// // bits - A bit vector of command options. // template <class DataType, class Storage = bool, - class ParserClass = parser<DataType> > + class ParserClass = parser<DataType>> class bits : public Option, public bits_storage<DataType, Storage> { std::vector<unsigned> Positions; ParserClass Parser; @@ -1536,16 +1420,17 @@ class bits : public Option, public bits_storage<DataType, Storage> { enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override { + void + getExtraOptionNames(SmallVectorImpl<const char *> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg) override { typename ParserClass::parser_data_type Val = - typename ParserClass::parser_data_type(); + typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) - return true; // Parse Error! + return true; // Parse Error! this->addValue(Val); setPosition(pos); Positions.push_back(pos); @@ -1553,19 +1438,26 @@ class bits : public Option, public bits_storage<DataType, Storage> { } // Forward printing stuff to the parser... - size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);} + size_t getOptionWidth() const override { + return Parser.getOptionWidth(*this); + } void printOptionInfo(size_t GlobalWidth) const override { Parser.printOptionInfo(*this, GlobalWidth); } // Unimplemented: bits options don't currently store their default values. - void printOptionValue(size_t /*GlobalWidth*/, - bool /*Force*/) const override {} + void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { + } void done() { addArgument(); - Parser.initialize(*this); + Parser.initialize(); } + + // Command line options should not be copyable + bits(const bits &) = delete; + bits &operator=(const bits &) = delete; + public: ParserClass &getParser() { return Parser; } @@ -1574,67 +1466,10 @@ public: return Positions[optnum]; } - // One option... - template<class M0t> - explicit bits(const M0t &M0) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); - done(); - } - // Two options... - template<class M0t, class M1t> - bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); - done(); - } - // Three options... - template<class M0t, class M1t, class M2t> - bits(const M0t &M0, const M1t &M1, const M2t &M2) - : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); - done(); - } - // Four options... - template<class M0t, class M1t, class M2t, class M3t> - bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) - : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - done(); - } - // Five options... - template<class M0t, class M1t, class M2t, class M3t, class M4t> - bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); - done(); - } - // Six options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t> - bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); - done(); - } - // Seven options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t, class M6t> - bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5, const M6t &M6) - : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); apply(M6, this); - done(); - } - // Eight options... - template<class M0t, class M1t, class M2t, class M3t, - class M4t, class M5t, class M6t, class M7t> - bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5, const M6t &M6, - const M7t &M7) : Option(ZeroOrMore, NotHidden) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); - apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this); + template <class... Mods> + explicit bits(const Mods &... Ms) + : Option(ZeroOrMore, NotHidden), Parser(*this) { + apply(this, Ms...); done(); } }; @@ -1646,11 +1481,11 @@ public: class alias : public Option { Option *AliasFor; bool handleOccurrence(unsigned pos, StringRef /*ArgName*/, - StringRef Arg) override { + StringRef Arg) override { return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg); } - bool addOccurrence(unsigned pos, StringRef /*ArgName*/, - StringRef Value, bool MultiArg = false) override { + bool addOccurrence(unsigned pos, StringRef /*ArgName*/, StringRef Value, + bool MultiArg = false) override { return AliasFor->addOccurrence(pos, AliasFor->ArgStr, Value, MultiArg); } // Handle printing stuff... @@ -1658,8 +1493,8 @@ class alias : public Option { void printOptionInfo(size_t GlobalWidth) const override; // Aliases do not need to print their values. - void printOptionValue(size_t /*GlobalWidth*/, - bool /*Force*/) const override {} + void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { + } ValueExpected getValueExpectedFlagDefault() const override { return AliasFor->getValueExpectedFlag(); @@ -1670,8 +1505,13 @@ class alias : public Option { error("cl::alias must have argument name specified!"); if (!AliasFor) error("cl::alias must have an cl::aliasopt(option) specified!"); - addArgument(); + addArgument(); } + + // Command line options should not be copyable + alias(const alias &) = delete; + alias &operator=(const alias &) = delete; + public: void setAliasFor(Option &O) { if (AliasFor) @@ -1679,31 +1519,10 @@ public: AliasFor = &O; } - // One option... - template<class M0t> - explicit alias(const M0t &M0) : Option(Optional, Hidden), AliasFor(nullptr) { - apply(M0, this); - done(); - } - // Two options... - template<class M0t, class M1t> - alias(const M0t &M0, const M1t &M1) - : Option(Optional, Hidden), AliasFor(nullptr) { - apply(M0, this); apply(M1, this); - done(); - } - // Three options... - template<class M0t, class M1t, class M2t> - alias(const M0t &M0, const M1t &M1, const M2t &M2) - : Option(Optional, Hidden), AliasFor(nullptr) { - apply(M0, this); apply(M1, this); apply(M2, this); - done(); - } - // Four options... - template<class M0t, class M1t, class M2t, class M3t> - alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) - : Option(Optional, Hidden), AliasFor(nullptr) { - apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this); + template <class... Mods> + explicit alias(const Mods &... Ms) + : Option(Optional, Hidden), AliasFor(nullptr) { + apply(this, Ms...); done(); } }; @@ -1720,8 +1539,8 @@ struct aliasopt { // printed to stderr at the end of the regular help, just before // exit is called. struct extrahelp { - const char * morehelp; - explicit extrahelp(const char* help); + const char *morehelp; + explicit extrahelp(const char *help); }; void PrintVersionMessage(); @@ -1733,8 +1552,7 @@ void PrintVersionMessage(); /// /// \param Hidden if true will print hidden options /// \param Categorized if true print options in categories -void PrintHelpMessage(bool Hidden=false, bool Categorized=false); - +void PrintHelpMessage(bool Hidden = false, bool Categorized = false); //===----------------------------------------------------------------------===// // Public interface for accessing registered options. @@ -1743,9 +1561,7 @@ void PrintHelpMessage(bool Hidden=false, bool Categorized=false); /// \brief Use this to get a StringMap to all registered named options /// (e.g. -help). Note \p Map Should be an empty StringMap. /// -/// \param [out] Map will be filled with mappings where the key is the -/// Option argument string (e.g. "help") and value is the corresponding -/// Option*. +/// \return A reference to the StringMap used by the cl APIs to parse options. /// /// Access to unnamed arguments (i.e. positional) are not provided because /// it is expected that the client already has access to these. @@ -1753,8 +1569,7 @@ void PrintHelpMessage(bool Hidden=false, bool Categorized=false); /// Typical usage: /// \code /// main(int argc,char* argv[]) { -/// StringMap<llvm::cl::Option*> opts; -/// llvm::cl::getRegisteredOptions(opts); +/// StringMap<llvm::cl::Option*> &opts = llvm::cl::getRegisteredOptions(); /// assert(opts.count("help") == 1) /// opts["help"]->setDescription("Show alphabetical help information") /// // More code @@ -1766,7 +1581,11 @@ void PrintHelpMessage(bool Hidden=false, bool Categorized=false); /// This interface is useful for modifying options in libraries that are out of /// the control of the client. The options should be modified before calling /// llvm::cl::ParseCommandLineOptions(). -void getRegisteredOptions(StringMap<Option*> &Map); +/// +/// Hopefully this API can be depricated soon. Any situation where options need +/// to be modified by tools or libraries should be handled by sane APIs rather +/// than just handing around a global list. +StringMap<Option *> &getRegisteredOptions(); //===----------------------------------------------------------------------===// // Standalone command line processing utilities. @@ -1776,9 +1595,10 @@ void getRegisteredOptions(StringMap<Option*> &Map); /// raw character pointer. class StringSaver { virtual void anchor(); + public: virtual const char *SaveString(const char *Str) = 0; - virtual ~StringSaver() {}; // Pacify -Wnon-virtual-dtor. + virtual ~StringSaver(){}; // Pacify -Wnon-virtual-dtor. }; /// \brief Tokenizes a command line that can contain escapes and quotes. @@ -1836,6 +1656,24 @@ bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &Argv, bool MarkEOLs = false); +/// \brief Mark all options not part of this category as cl::ReallyHidden. +/// +/// \param Category the category of options to keep displaying +/// +/// Some tools (like clang-format) like to be able to hide all options that are +/// not specific to the tool. This function allows a tool to specify a single +/// option category to display in the -help output. +void HideUnrelatedOptions(cl::OptionCategory &Category); + +/// \brief Mark all options not part of the categories as cl::ReallyHidden. +/// +/// \param Categories the categories of options to keep displaying. +/// +/// Some tools (like clang-format) like to be able to hide all options that are +/// not specific to the tool. This function allows a tool to specify a single +/// option category to display in the -help output. +void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories); + } // End namespace cl } // End namespace llvm |