2121#define LLVM_SUPPORT_COMMANDLINE_H
2222
2323#include " llvm/ADT/ArrayRef.h"
24+ #include " llvm/ADT/SmallPtrSet.h"
2425#include " llvm/ADT/SmallVector.h"
2526#include " llvm/ADT/StringMap.h"
2627#include " llvm/ADT/Twine.h"
2728#include " llvm/Support/Compiler.h"
29+ #include " llvm/Support/ManagedStatic.h"
2830#include < cassert>
2931#include < climits>
3032#include < cstdarg>
@@ -44,8 +46,9 @@ namespace cl {
4446// ===----------------------------------------------------------------------===//
4547// ParseCommandLineOptions - Command line option processing entry point.
4648//
47- void ParseCommandLineOptions (int argc, const char *const *argv,
48- const char *Overview = nullptr );
49+ bool ParseCommandLineOptions (int argc, const char *const *argv,
50+ const char *Overview = nullptr ,
51+ bool IgnoreErrors = false );
4952
5053// ===----------------------------------------------------------------------===//
5154// ParseEnvironmentOptions - Environment variable option processing alternate
@@ -131,6 +134,9 @@ enum OptionHidden { // Control whether -help shows this option
131134// enabled, and used, the value for the flag comes from the suffix of the
132135// argument.
133136//
137+ // AlwaysPrefix - Only allow the behavior enabled by the Prefix flag and reject
138+ // the Option=Value form.
139+ //
134140// Grouping - With this option enabled, multiple letter options are allowed to
135141// bunch together with only a single hyphen for the whole group. This allows
136142// emulation of the behavior that ls uses for example: ls -la === ls -l -a
@@ -140,7 +146,8 @@ enum FormattingFlags {
140146 NormalFormatting = 0x00 , // Nothing special
141147 Positional = 0x01 , // Is a positional argument, no '-' required
142148 Prefix = 0x02 , // Can this option directly prefix its value?
143- Grouping = 0x03 // Can this option group with other options?
149+ AlwaysPrefix = 0x03 , // Can this option only directly prefix its value?
150+ Grouping = 0x04 // Can this option group with other options?
144151};
145152
146153enum MiscFlags { // Miscellaneous flags to adjust argument
@@ -171,6 +178,45 @@ class OptionCategory {
171178// The general Option Category (used as default category).
172179extern OptionCategory *GeneralCategory; // HLSL Change - GeneralCategory is now a pointer
173180
181+ // ===----------------------------------------------------------------------===//
182+ // SubCommand class
183+ //
184+ class SubCommand {
185+ private:
186+ const char *const Name = nullptr ;
187+ const char *const Description = nullptr ;
188+
189+ protected:
190+ void registerSubCommand ();
191+ void unregisterSubCommand ();
192+
193+ public:
194+ SubCommand (const char *const Name, const char *const Description = nullptr )
195+ : Name(Name), Description(Description) {
196+ registerSubCommand ();
197+ }
198+ SubCommand () {}
199+
200+ void reset ();
201+
202+ operator bool () const ;
203+
204+ const char *getName () const { return Name; }
205+ const char *getDescription () const { return Description; }
206+
207+ SmallVector<Option *, 4 > PositionalOpts;
208+ SmallVector<Option *, 4 > SinkOpts;
209+ StringMap<Option *> OptionsMap;
210+
211+ Option *ConsumeAfterOpt = nullptr ; // The ConsumeAfter option if it exists.
212+ };
213+
214+ // A special subcommand representing no subcommand
215+ extern ManagedStatic<SubCommand> TopLevelSubCommand;
216+
217+ // A special subcommand that can be used to put an option into all subcommands.
218+ extern ManagedStatic<SubCommand> AllSubCommands;
219+
174220// ===----------------------------------------------------------------------===//
175221// Option Base class
176222//
@@ -200,16 +246,17 @@ class Option {
200246 // detail representing the non-value
201247 unsigned Value : 2 ;
202248 unsigned HiddenFlag : 2 ; // enum OptionHidden
203- unsigned Formatting : 2 ; // enum FormattingFlags
249+ unsigned Formatting : 3 ; // enum FormattingFlags
204250 unsigned Misc : 3 ;
205251 unsigned Position; // Position of last occurrence of the option
206252 unsigned AdditionalVals; // Greater than 0 for multi-valued option.
207253
208254public:
209- const char * ArgStr; // The argument string itself (ex: "help", "o")
210- const char * HelpStr; // The descriptive text message for -help
211- const char * ValueStr; // String describing what the value of this option is
255+ StringRef ArgStr; // The argument string itself (ex: "help", "o")
256+ StringRef HelpStr; // The descriptive text message for -help
257+ StringRef ValueStr; // String describing what the value of this option is
212258 OptionCategory *Category; // The Category this option belongs to
259+ SmallPtrSet<SubCommand *, 4 > Subs; // The subcommands this option belongs to.
213260 bool FullyInitialized; // Has addArguemnt been called?
214261
215262 inline enum NumOccurrencesFlag getNumOccurrencesFlag () const {
@@ -229,21 +276,32 @@ class Option {
229276 inline unsigned getNumAdditionalVals () const { return AdditionalVals; }
230277
231278 // hasArgStr - Return true if the argstr != ""
232- bool hasArgStr () const { return ArgStr[0 ] != 0 ; }
279+ bool hasArgStr () const { return !ArgStr.empty (); }
280+ bool isPositional () const { return getFormattingFlag () == cl::Positional; }
281+ bool isSink () const { return getMiscFlags () & cl::Sink; }
282+ bool isConsumeAfter () const {
283+ return getNumOccurrencesFlag () == cl::ConsumeAfter;
284+ }
285+ bool isInAllSubCommands () const {
286+ return std::any_of (Subs.begin (), Subs.end (), [](const SubCommand *SC) {
287+ return SC == &*AllSubCommands;
288+ });
289+ }
233290
234291 // -------------------------------------------------------------------------===
235292 // Accessor functions set by OptionModifiers
236293 //
237- void setArgStr (const char * S);
238- void setDescription (const char * S) { HelpStr = S; }
239- void setValueStr (const char * S) { ValueStr = S; }
294+ void setArgStr (StringRef S);
295+ void setDescription (StringRef S) { HelpStr = S; }
296+ void setValueStr (StringRef S) { ValueStr = S; }
240297 void setNumOccurrencesFlag (enum NumOccurrencesFlag Val) { Occurrences = Val; }
241298 void setValueExpectedFlag (enum ValueExpected Val) { Value = Val; }
242299 void setHiddenFlag (enum OptionHidden Val) { HiddenFlag = Val; }
243300 void setFormattingFlag (enum FormattingFlags V) { Formatting = V; }
244301 void setMiscFlag (enum MiscFlags M) { Misc |= M; }
245302 void setPosition (unsigned pos) { Position = pos; }
246303 void setCategory (OptionCategory &C) { Category = &C; }
304+ void addSubCommand (SubCommand &S) { Subs.insert (&S); }
247305
248306protected:
249307 explicit Option (enum NumOccurrencesFlag OccurrencesFlag,
@@ -276,7 +334,7 @@ class Option {
276334
277335 virtual void printOptionValue (size_t GlobalWidth, bool Force) const = 0;
278336
279- virtual void getExtraOptionNames (SmallVectorImpl<const char * > &) {}
337+ virtual void getExtraOptionNames (SmallVectorImpl<StringRef > &) {}
280338
281339 // addOccurrence - Wrapper around handleOccurrence that enforces Flags.
282340 //
@@ -288,6 +346,7 @@ class Option {
288346
289347public:
290348 inline int getNumOccurrences () const { return NumOccurrences; }
349+ inline void reset () { NumOccurrences = 0 ; }
291350 virtual ~Option () {}
292351};
293352
@@ -350,6 +409,14 @@ struct cat {
350409 template <class Opt > void apply (Opt &O) const { O.setCategory (Category); }
351410};
352411
412+ // sub - Specify the subcommand that this option belongs to.
413+ struct sub {
414+ SubCommand ⋐
415+ sub (SubCommand &S) : Sub(S) {}
416+
417+ template <class Opt > void apply (Opt &O) const { O.addSubCommand (Sub); }
418+ };
419+
353420// ===----------------------------------------------------------------------===//
354421// OptionValue class
355422
@@ -606,7 +673,7 @@ class generic_parser_base {
606673
607674 void initialize () {}
608675
609- void getExtraOptionNames (SmallVectorImpl<const char * > &OptionNames) {
676+ void getExtraOptionNames (SmallVectorImpl<StringRef > &OptionNames) {
610677 // If there has been no argstr specified, that means that we need to add an
611678 // argument for every possible option. This ensures that our options are
612679 // vectored to us.
@@ -722,7 +789,7 @@ class basic_parser_impl { // non-template implementation of basic_parser<t>
722789 return ValueRequired;
723790 }
724791
725- void getExtraOptionNames (SmallVectorImpl<const char * > &) {}
792+ void getExtraOptionNames (SmallVectorImpl<StringRef > &) {}
726793
727794 void initialize () {}
728795
@@ -1206,8 +1273,7 @@ class opt : public Option,
12061273 enum ValueExpected getValueExpectedFlagDefault () const override {
12071274 return Parser.getValueExpectedFlagDefault ();
12081275 }
1209- void
1210- getExtraOptionNames (SmallVectorImpl<const char *> &OptionNames) override {
1276+ void getExtraOptionNames (SmallVectorImpl<StringRef> &OptionNames) override {
12111277 return Parser.getExtraOptionNames (OptionNames);
12121278 }
12131279
@@ -1368,8 +1434,7 @@ class list : public Option, public list_storage<DataType, StorageClass> {
13681434 enum ValueExpected getValueExpectedFlagDefault () const override {
13691435 return Parser.getValueExpectedFlagDefault ();
13701436 }
1371- void
1372- getExtraOptionNames (SmallVectorImpl<const char *> &OptionNames) override {
1437+ void getExtraOptionNames (SmallVectorImpl<StringRef> &OptionNames) override {
13731438 return Parser.getExtraOptionNames (OptionNames);
13741439 }
13751440
@@ -1508,8 +1573,7 @@ class bits : public Option, public bits_storage<DataType, Storage> {
15081573 enum ValueExpected getValueExpectedFlagDefault () const override {
15091574 return Parser.getValueExpectedFlagDefault ();
15101575 }
1511- void
1512- getExtraOptionNames (SmallVectorImpl<const char *> &OptionNames) override {
1576+ void getExtraOptionNames (SmallVectorImpl<StringRef> &OptionNames) override {
15131577 return Parser.getExtraOptionNames (OptionNames);
15141578 }
15151579
@@ -1593,6 +1657,7 @@ class alias : public Option {
15931657 error (" cl::alias must have argument name specified!" );
15941658 if (!AliasFor)
15951659 error (" cl::alias must have an cl::aliasopt(option) specified!" );
1660+ Subs = AliasFor->Subs ;
15961661 addArgument ();
15971662 }
15981663
@@ -1673,9 +1738,9 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false);
16731738// / Hopefully this API can be depricated soon. Any situation where options need
16741739// / to be modified by tools or libraries should be handled by sane APIs rather
16751740// / than just handing around a global list.
1676- StringMap<Option *> &getRegisteredOptions ();
1677- // //
1678- // /////////////////////////////////////////////////////////////////////////// //
1741+ StringMap<Option *> &getRegisteredOptions (SubCommand &Sub );
1742+
1743+ // ===----------------------------------------------------------------------=== //
16791744// Standalone command line processing utilities.
16801745//
16811746
@@ -1741,7 +1806,8 @@ bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
17411806// / Some tools (like clang-format) like to be able to hide all options that are
17421807// / not specific to the tool. This function allows a tool to specify a single
17431808// / option category to display in the -help output.
1744- void HideUnrelatedOptions (cl::OptionCategory &Category);
1809+ void HideUnrelatedOptions (cl::OptionCategory &Category,
1810+ SubCommand &Sub = *TopLevelSubCommand);
17451811
17461812// / \brief Mark all options not part of the categories as cl::ReallyHidden.
17471813// /
@@ -1750,7 +1816,19 @@ void HideUnrelatedOptions(cl::OptionCategory &Category);
17501816// / Some tools (like clang-format) like to be able to hide all options that are
17511817// / not specific to the tool. This function allows a tool to specify a single
17521818// / option category to display in the -help output.
1753- void HideUnrelatedOptions (ArrayRef<const cl::OptionCategory *> Categories);
1819+ void HideUnrelatedOptions (ArrayRef<const cl::OptionCategory *> Categories,
1820+ SubCommand &Sub = *TopLevelSubCommand);
1821+
1822+ // / \brief Reset all command line options to a state that looks as if they have
1823+ // / never appeared on the command line. This is useful for being able to parse
1824+ // / a command line multiple times (especially useful for writing tests).
1825+ void ResetAllOptionOccurrences ();
1826+
1827+ // / \brief Reset the command line parser back to its initial state. This
1828+ // / removes
1829+ // / all options, categories, and subcommands and returns the parser to a state
1830+ // / where no options are supported.
1831+ void ResetCommandLineParser ();
17541832
17551833} // End namespace cl
17561834
0 commit comments