#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"
// (Currently not perfect, but best-effort.)
void PrintOptionValues();
-// MarkOptionsChanged - Internal helper function.
-void MarkOptionsChanged();
-
//===----------------------------------------------------------------------===//
// Flags permitted to be passed to command line arguments
//
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;
//-------------------------------------------------------------------------===
// 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; }
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; }
/// 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;
};
public:
+ 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
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) {
// 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));
}
//
// If this is the case, we cannot allow a value.
//
- if (hasArgStr)
+ if (Owner.hasArgStr())
return ValueRequired;
else
return ValueDisallowed;
unsigned findOption(const char *Name);
protected:
- bool hasArgStr;
+ Option &Owner;
};
// Default parser implementation - This implementation depends on having a
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
// 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;
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.
//
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 {
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;
//
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;
};
// parser<bool>
//
template <> class parser<bool> : public basic_parser<bool> {
- const char *ArgStr;
-
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;
// 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);
//
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);
//
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);
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);
//
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);
//
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);
//
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();
//
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];
void done() {
addArgument();
- Parser.initialize(*this);
+ Parser.initialize();
}
+ // Command line options should not be copyable
+ opt(const opt &) LLVM_DELETED_FUNCTION;
+ opt &operator=(const opt &) LLVM_DELETED_FUNCTION;
+
public:
// setInitialValue - Used by the cl::init modifier...
void setInitialValue(const DataType &V) { this->setValue(V, true); }
// One option...
template <class M0t>
explicit opt(const M0t &M0)
- : Option(Optional, NotHidden) {
+ : Option(Optional, NotHidden), Parser(*this) {
apply(M0, this);
done();
}
// Two options...
template <class M0t, class M1t>
opt(const M0t &M0, const M1t &M1)
- : Option(Optional, NotHidden) {
+ : Option(Optional, NotHidden), Parser(*this) {
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) {
+ : Option(Optional, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
// 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) {
+ : Option(Optional, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
// 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) {
+ : Option(Optional, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(Optional, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(Optional, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(Optional, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
void done() {
addArgument();
- Parser.initialize(*this);
+ Parser.initialize();
}
+ // Command line options should not be copyable
+ list(const list &) LLVM_DELETED_FUNCTION;
+ list &operator=(const list &) LLVM_DELETED_FUNCTION;
+
public:
ParserClass &getParser() { return Parser; }
// One option...
template <class M0t>
explicit list(const M0t &M0)
- : Option(ZeroOrMore, NotHidden) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
done();
}
// Two options...
template <class M0t, class M1t>
list(const M0t &M0, const M1t &M1)
- : Option(ZeroOrMore, NotHidden) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
// 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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
void done() {
addArgument();
- Parser.initialize(*this);
+ Parser.initialize();
}
+ // Command line options should not be copyable
+ bits(const bits &) LLVM_DELETED_FUNCTION;
+ bits &operator=(const bits &) LLVM_DELETED_FUNCTION;
+
public:
ParserClass &getParser() { return Parser; }
// One option...
template <class M0t>
explicit bits(const M0t &M0)
- : Option(ZeroOrMore, NotHidden) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
done();
}
// Two options...
template <class M0t, class M1t>
bits(const M0t &M0, const M1t &M1)
- : Option(ZeroOrMore, NotHidden) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
// 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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
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) {
+ : Option(ZeroOrMore, NotHidden), Parser(*this) {
apply(M0, this);
apply(M1, this);
apply(M2, this);
addArgument();
}
+ // Command line options should not be copyable
+ alias(const alias &) LLVM_DELETED_FUNCTION;
+ alias &operator=(const alias &) LLVM_DELETED_FUNCTION;
+
public:
void setAliasFor(Option &O) {
if (AliasFor)
/// \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.
/// 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
/// 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.
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);
+
+/// \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);
+
} // End namespace cl
} // End namespace llvm