summaryrefslogtreecommitdiff
path: root/include/llvm/Support/CommandLine.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support/CommandLine.h')
-rw-r--r--include/llvm/Support/CommandLine.h89
1 files changed, 83 insertions, 6 deletions
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 943d2df377089..70465a0e3fd35 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -21,10 +21,12 @@
#define LLVM_SUPPORT_COMMANDLINE_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ManagedStatic.h"
#include <cassert>
#include <climits>
#include <cstdarg>
@@ -43,8 +45,9 @@ namespace cl {
//===----------------------------------------------------------------------===//
// ParseCommandLineOptions - Command line option processing entry point.
//
-void ParseCommandLineOptions(int argc, const char *const *argv,
- const char *Overview = nullptr);
+bool ParseCommandLineOptions(int argc, const char *const *argv,
+ const char *Overview = nullptr,
+ bool IgnoreErrors = false);
//===----------------------------------------------------------------------===//
// ParseEnvironmentOptions - Environment variable option processing alternate
@@ -171,6 +174,45 @@ public:
extern OptionCategory GeneralCategory;
//===----------------------------------------------------------------------===//
+// SubCommand class
+//
+class SubCommand {
+private:
+ const char *const Name = nullptr;
+ const char *const Description = nullptr;
+
+protected:
+ void registerSubCommand();
+ void unregisterSubCommand();
+
+public:
+ SubCommand(const char *const Name, const char *const Description = nullptr)
+ : Name(Name), Description(Description) {
+ registerSubCommand();
+ }
+ SubCommand() {}
+
+ void reset();
+
+ operator bool() const;
+
+ const char *getName() const { return Name; }
+ const char *getDescription() const { return Description; }
+
+ SmallVector<Option *, 4> PositionalOpts;
+ SmallVector<Option *, 4> SinkOpts;
+ StringMap<Option *> OptionsMap;
+
+ Option *ConsumeAfterOpt = nullptr; // The ConsumeAfter option if it exists.
+};
+
+// A special subcommand representing no subcommand
+extern ManagedStatic<SubCommand> TopLevelSubCommand;
+
+// A special subcommand that can be used to put an option into all subcommands.
+extern ManagedStatic<SubCommand> AllSubCommands;
+
+//===----------------------------------------------------------------------===//
// Option Base class
//
class alias;
@@ -209,6 +251,7 @@ public:
StringRef HelpStr; // The descriptive text message for -help
StringRef ValueStr; // String describing what the value of this option is
OptionCategory *Category; // The Category this option belongs to
+ SmallPtrSet<SubCommand *, 4> Subs; // The subcommands this option belongs to.
bool FullyInitialized; // Has addArguemnt been called?
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
@@ -229,6 +272,16 @@ public:
// hasArgStr - Return true if the argstr != ""
bool hasArgStr() const { return !ArgStr.empty(); }
+ bool isPositional() const { return getFormattingFlag() == cl::Positional; }
+ bool isSink() const { return getMiscFlags() & cl::Sink; }
+ bool isConsumeAfter() const {
+ return getNumOccurrencesFlag() == cl::ConsumeAfter;
+ }
+ bool isInAllSubCommands() const {
+ return std::any_of(Subs.begin(), Subs.end(), [](const SubCommand *SC) {
+ return SC == &*AllSubCommands;
+ });
+ }
//-------------------------------------------------------------------------===
// Accessor functions set by OptionModifiers
@@ -243,6 +296,7 @@ public:
void setMiscFlag(enum MiscFlags M) { Misc |= M; }
void setPosition(unsigned pos) { Position = pos; }
void setCategory(OptionCategory &C) { Category = &C; }
+ void addSubCommand(SubCommand &S) { Subs.insert(&S); }
protected:
explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
@@ -287,6 +341,7 @@ public:
public:
inline int getNumOccurrences() const { return NumOccurrences; }
+ inline void reset() { NumOccurrences = 0; }
virtual ~Option() {}
};
@@ -349,6 +404,14 @@ struct cat {
template <class Opt> void apply(Opt &O) const { O.setCategory(Category); }
};
+// sub - Specify the subcommand that this option belongs to.
+struct sub {
+ SubCommand &Sub;
+ sub(SubCommand &S) : Sub(S) {}
+
+ template <class Opt> void apply(Opt &O) const { O.addSubCommand(Sub); }
+};
+
//===----------------------------------------------------------------------===//
// OptionValue class
@@ -946,7 +1009,7 @@ public:
// getValueName - Overload in subclass to provide a better default value.
const char *getValueName() const override { return "string"; }
- void printOptionDiff(const Option &O, StringRef V, OptVal Default,
+ void printOptionDiff(const Option &O, StringRef V, const OptVal &Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
@@ -1589,6 +1652,7 @@ class alias : public Option {
error("cl::alias must have argument name specified!");
if (!AliasFor)
error("cl::alias must have an cl::aliasopt(option) specified!");
+ Subs = AliasFor->Subs;
addArgument();
}
@@ -1669,7 +1733,7 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false);
/// 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();
+StringMap<Option *> &getRegisteredOptions(SubCommand &Sub = *TopLevelSubCommand);
//===----------------------------------------------------------------------===//
// Standalone command line processing utilities.
@@ -1737,7 +1801,8 @@ bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
/// 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);
+void HideUnrelatedOptions(cl::OptionCategory &Category,
+ SubCommand &Sub = *TopLevelSubCommand);
/// \brief Mark all options not part of the categories as cl::ReallyHidden.
///
@@ -1746,7 +1811,19 @@ void HideUnrelatedOptions(cl::OptionCategory &Category);
/// 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);
+void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,
+ SubCommand &Sub = *TopLevelSubCommand);
+
+/// \brief Reset all command line options to a state that looks as if they have
+/// never appeared on the command line. This is useful for being able to parse
+/// a command line multiple times (especially useful for writing tests).
+void ResetAllOptionOccurrences();
+
+/// \brief Reset the command line parser back to its initial state. This
+/// removes
+/// all options, categories, and subcommands and returns the parser to a state
+/// where no options are supported.
+void ResetCommandLineParser();
} // End namespace cl