X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FCommandLine.h;h=c6d430115427e38ff9dd6f8284a3e82ddb2935e4;hp=c0e9d972498c997726b7f79f8d2391c412bddad8;hb=9cc5055248bdde9e0f61dfa818bfd0be7a347afd;hpb=f96362358fa60eefabed395a309d57c65af0270f diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index c0e9d972498..c6d43011542 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -73,8 +73,17 @@ void AddExtraVersionPrinter(void (*func)()); // (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 @@ -192,13 +201,13 @@ class Option { 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. 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; @@ -222,7 +231,7 @@ 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; } @@ -238,8 +247,8 @@ protected: 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) {} + AdditionalVals(0), ArgStr(""), HelpStr(""), ValueStr(""), + Category(&GeneralCategory), FullyInitialized(false) {} inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } @@ -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; @@ -345,9 +352,14 @@ struct cat { // Support value comparison outside the template. struct GenericOptionValue { - virtual ~GenericOptionValue() {} virtual bool compare(const GenericOptionValue &V) const = 0; +protected: + ~GenericOptionValue() = default; + GenericOptionValue() = default; + GenericOptionValue(const GenericOptionValue&) = default; + GenericOptionValue &operator=(const GenericOptionValue &) = default; + private: virtual void anchor(); }; @@ -373,6 +385,9 @@ struct OptionValueBase : public GenericOptionValue { bool compare(const GenericOptionValue & /*V*/) const override { return false; } + +protected: + ~OptionValueBase() = default; }; // Simple copy of the option value. @@ -380,6 +395,11 @@ template class OptionValueCopy : public GenericOptionValue { DataType Value; bool Valid; +protected: + ~OptionValueCopy() = default; + OptionValueCopy(const OptionValueCopy&) = default; + OptionValueCopy &operator=(const OptionValueCopy&) = default; + public: OptionValueCopy() : Valid(false) {} @@ -410,12 +430,19 @@ public: template struct OptionValueBase : OptionValueCopy { typedef DataType WrapperType; + +protected: + ~OptionValueBase() = default; + OptionValueBase() = default; + OptionValueBase(const OptionValueBase&) = default; + OptionValueBase &operator=(const OptionValueBase&) = default; }; // Top-level option class. template -struct OptionValue : OptionValueBase::value> { - OptionValue() {} +struct OptionValue final + : OptionValueBase::value> { + OptionValue() = default; OptionValue(const DataType &V) { this->setValue(V); } // Some options may take their value from a different data type. @@ -428,7 +455,8 @@ struct OptionValue : OptionValueBase::value> { // Other safe-to-copy-by-value common option types. enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE }; template <> -struct OptionValue : OptionValueCopy { +struct OptionValue final + : OptionValueCopy { typedef cl::boolOrDefault WrapperType; OptionValue() {} @@ -443,7 +471,8 @@ private: void anchor() override; }; -template <> struct OptionValue : OptionValueCopy { +template <> +struct OptionValue final : OptionValueCopy { typedef StringRef WrapperType; OptionValue() {} @@ -666,7 +695,7 @@ public: assert(findOption(Name) == Values.size() && "Option already exists!"); OptionInfo X(Name, static_cast(V), HelpStr); Values.push_back(X); - MarkOptionsChanged(); + AddLiteralOption(Owner, Name); } /// removeLiteralOption - Remove the specified option. @@ -685,7 +714,6 @@ class basic_parser_impl { // non-template implementation of basic_parser public: basic_parser_impl(Option &O) {} - virtual ~basic_parser_impl() {} enum ValueExpected getValueExpectedFlagDefault() const { return ValueRequired; @@ -714,6 +742,7 @@ public: virtual void anchor(); protected: + ~basic_parser_impl() = default; // A helper for basic_parser::printOptionDiff. void printOptionName(const Option &O, size_t GlobalWidth) const; }; @@ -726,12 +755,16 @@ public: basic_parser(Option &O) : basic_parser_impl(O) {} typedef DataType parser_data_type; typedef OptionValue OptVal; + +protected: + // Workaround Clang PR22793 + ~basic_parser() {} }; //-------------------------------------------------- // parser // -template <> class parser : public basic_parser { +template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -758,7 +791,8 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); //-------------------------------------------------- // parser -template <> class parser : public basic_parser { +template <> +class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -784,7 +818,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); //-------------------------------------------------- // parser // -template <> class parser : public basic_parser { +template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -806,7 +840,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); //-------------------------------------------------- // parser // -template <> class parser : public basic_parser { +template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -829,7 +863,8 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); // parser // template <> -class parser : public basic_parser { +class parser final + : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -852,7 +887,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); //-------------------------------------------------- // parser // -template <> class parser : public basic_parser { +template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -874,7 +909,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); //-------------------------------------------------- // parser // -template <> class parser : public basic_parser { +template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -896,7 +931,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); //-------------------------------------------------- // parser // -template <> class parser : public basic_parser { +template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -921,7 +956,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); //-------------------------------------------------- // parser // -template <> class parser : public basic_parser { +template <> class parser final : public basic_parser { public: parser(Option &O) : basic_parser(O) {} @@ -960,7 +995,7 @@ 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 struct OptionDiffPrinter { - void print(const Option &O, const parser P, const ValDT & /*V*/, + void print(const Option &O, const parser &P, const ValDT & /*V*/, const OptionValue & /*Default*/, size_t GlobalWidth) { P.printOptionNoValue(O, GlobalWidth); } @@ -969,7 +1004,7 @@ template struct OptionDiffPrinter { // This is instantiated for basic parsers when the parsed value has the same // type as the option value. template struct OptionDiffPrinter { - void print(const Option &O, const parser
P, const DT &V, + void print(const Option &O, const parser
&P, const DT &V, const OptionValue
&Default, size_t GlobalWidth) { P.printOptionDiff(O, V, Default, GlobalWidth); } @@ -1033,8 +1068,14 @@ template <> struct applicator { static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); } }; -// apply method - Apply a modifier to an option in a type safe way. -template void apply(const Mod &M, Opt *O) { +// apply method - Apply modifiers to an option in a type safe way. +template +void apply(Opt *O, const Mod &M, const Mods &... Ms) { + applicator::opt(M, *O); + apply(O, Ms...); +} + +template void apply(Opt *O, const Mod &M) { applicator::opt(M, *O); } @@ -1188,8 +1229,8 @@ class opt : public Option, } // Command line options should not be copyable - opt(const opt &) LLVM_DELETED_FUNCTION; - opt &operator=(const opt &) LLVM_DELETED_FUNCTION; + opt(const opt &) = delete; + opt &operator=(const opt &) = delete; public: // setInitialValue - Used by the cl::init modifier... @@ -1202,95 +1243,10 @@ public: return this->getValue(); } - // One option... - template - explicit opt(const M0t &M0) + template + explicit opt(const Mods &... Ms) : Option(Optional, NotHidden), Parser(*this) { - apply(M0, this); - done(); - } - - // Two options... - template - opt(const M0t &M0, const M1t &M1) - : Option(Optional, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - done(); - } - - // Three options... - template - opt(const M0t &M0, const M1t &M1, const M2t &M2) - : Option(Optional, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - done(); - } - // Four options... - template - opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) - : Option(Optional, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - done(); - } - // Five options... - template - opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, const M4t &M4) - : Option(Optional, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - done(); - } - // Six options... - template - opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, const M4t &M4, - const M5t &M5) - : Option(Optional, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - apply(M5, this); - done(); - } - // Seven options... - template - 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), Parser(*this) { - 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 - 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), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - apply(M5, this); - apply(M6, this); - apply(M7, this); + apply(this, Ms...); done(); } }; @@ -1328,24 +1284,74 @@ public: } }; -// 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. +// Define how to hold a class type object, such as a string. +// Originally this code inherited from std::vector. In transitioning to a new +// API for command line options we should change this. The new implementation +// of this list_storage specialization implements the minimum subset of the +// std::vector API required for all the current clients. // -template -class list_storage : public std::vector { +// FIXME: Reduce this API to a more narrow subset of std::vector +// +template class list_storage { + std::vector Storage; + public: - template void addValue(const T &V) { - std::vector::push_back(V); + typedef typename std::vector::iterator iterator; + + iterator begin() { return Storage.begin(); } + iterator end() { return Storage.end(); } + + typedef typename std::vector::const_iterator const_iterator; + const_iterator begin() const { return Storage.begin(); } + const_iterator end() const { return Storage.end(); } + + typedef typename std::vector::size_type size_type; + size_type size() const { return Storage.size(); } + + bool empty() const { return Storage.empty(); } + + void push_back(const DataType &value) { Storage.push_back(value); } + void push_back(DataType &&value) { Storage.push_back(value); } + + typedef typename std::vector::reference reference; + typedef typename std::vector::const_reference const_reference; + reference operator[](size_type pos) { return Storage[pos]; } + const_reference operator[](size_type pos) const { return Storage[pos]; } + + iterator erase(const_iterator pos) { return Storage.erase(pos); } + iterator erase(const_iterator first, const_iterator last) { + return Storage.erase(first, last); + } + + iterator erase(iterator pos) { return Storage.erase(pos); } + iterator erase(iterator first, iterator last) { + return Storage.erase(first, last); } + + iterator insert(const_iterator pos, const DataType &value) { + return Storage.insert(pos, value); + } + iterator insert(const_iterator pos, DataType &&value) { + return Storage.insert(pos, value); + } + + reference front() { return Storage.front(); } + const_reference front() const { return Storage.front(); } + + operator std::vector&() { return Storage; } + operator ArrayRef() { return Storage; } + std::vector *operator&() { return &Storage; } + const std::vector *operator&() const { return &Storage; } + + template void addValue(const T &V) { Storage.push_back(V); } }; //===----------------------------------------------------------------------===// // list - A list of command line options. // -template > -class list : public Option, public list_storage { +class list : public Option, public list_storage { std::vector Positions; ParserClass Parser; @@ -1363,7 +1369,7 @@ class list : public Option, public list_storage { typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) return true; // Parse Error! - list_storage::addValue(Val); + list_storage::addValue(Val); setPosition(pos); Positions.push_back(pos); return false; @@ -1387,8 +1393,8 @@ class list : public Option, public list_storage { } // Command line options should not be copyable - list(const list &) LLVM_DELETED_FUNCTION; - list &operator=(const list &) LLVM_DELETED_FUNCTION; + list(const list &) = delete; + list &operator=(const list &) = delete; public: ParserClass &getParser() { return Parser; } @@ -1400,94 +1406,10 @@ public: void setNumAdditionalVals(unsigned n) { Option::setNumAdditionalVals(n); } - // One option... - template - explicit list(const M0t &M0) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - done(); - } - // Two options... - template - list(const M0t &M0, const M1t &M1) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - done(); - } - // Three options... - template - list(const M0t &M0, const M1t &M1, const M2t &M2) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - done(); - } - // Four options... - template - list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - done(); - } - // Five options... - template - list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4) + template + explicit list(const Mods &... Ms) : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - done(); - } - // Six options... - template - list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - apply(M5, this); - done(); - } - // Seven options... - template - 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), Parser(*this) { - 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 - 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), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - apply(M5, this); - apply(M6, this); - apply(M7, this); + apply(this, Ms...); done(); } }; @@ -1611,8 +1533,8 @@ class bits : public Option, public bits_storage { } // Command line options should not be copyable - bits(const bits &) LLVM_DELETED_FUNCTION; - bits &operator=(const bits &) LLVM_DELETED_FUNCTION; + bits(const bits &) = delete; + bits &operator=(const bits &) = delete; public: ParserClass &getParser() { return Parser; } @@ -1622,94 +1544,10 @@ public: return Positions[optnum]; } - // One option... - template - explicit bits(const M0t &M0) + template + explicit bits(const Mods &... Ms) : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - done(); - } - // Two options... - template - bits(const M0t &M0, const M1t &M1) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - done(); - } - // Three options... - template - bits(const M0t &M0, const M1t &M1, const M2t &M2) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - done(); - } - // Four options... - template - bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - done(); - } - // Five options... - template - bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - done(); - } - // Six options... - template - bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3, - const M4t &M4, const M5t &M5) - : Option(ZeroOrMore, NotHidden), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - apply(M5, this); - done(); - } - // Seven options... - template - 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), Parser(*this) { - 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 - 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), Parser(*this) { - apply(M0, this); - apply(M1, this); - apply(M2, this); - apply(M3, this); - apply(M4, this); - apply(M5, this); - apply(M6, this); - apply(M7, this); + apply(this, Ms...); done(); } }; @@ -1749,8 +1587,8 @@ class alias : public Option { } // Command line options should not be copyable - alias(const alias &) LLVM_DELETED_FUNCTION; - alias &operator=(const alias &) LLVM_DELETED_FUNCTION; + alias(const alias &) = delete; + alias &operator=(const alias &) = delete; public: void setAliasFor(Option &O) { @@ -1759,38 +1597,10 @@ public: AliasFor = &O; } - // One option... - template - explicit alias(const M0t &M0) - : Option(Optional, Hidden), AliasFor(nullptr) { - apply(M0, this); - done(); - } - // Two options... - template - alias(const M0t &M0, const M1t &M1) + template + explicit alias(const Mods &... Ms) : Option(Optional, Hidden), AliasFor(nullptr) { - apply(M0, this); - apply(M1, this); - done(); - } - // Three options... - template - 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 - 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); + apply(this, Ms...); done(); } }; @@ -1829,9 +1639,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. @@ -1839,8 +1647,7 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false); /// Typical usage: /// \code /// main(int argc,char* argv[]) { -/// StringMap opts; -/// llvm::cl::getRegisteredOptions(opts); +/// StringMap &opts = llvm::cl::getRegisteredOptions(); /// assert(opts.count("help") == 1) /// opts["help"]->setDescription("Show alphabetical help information") /// // More code @@ -1852,7 +1659,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