Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 14 | pmbaty | 1 | //===- llvm/Support/CommandLine.h - Command line handler --------*- C++ -*-===// | 
| 2 | // | ||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| 4 | // See https://llvm.org/LICENSE.txt for license information. | ||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| 6 | // | ||
| 7 | //===----------------------------------------------------------------------===// | ||
| 8 | // | ||
| 9 | // This class implements a command line argument processor that is useful when | ||
| 10 | // creating a tool.  It provides a simple, minimalistic interface that is easily | ||
| 11 | // extensible and supports nonlocal (library) command line options. | ||
| 12 | // | ||
| 13 | // Note that rather than trying to figure out what this code does, you should | ||
| 14 | // read the library documentation located in docs/CommandLine.html or looks at | ||
| 15 | // the many example usages in tools/*/*.cpp | ||
| 16 | // | ||
| 17 | //===----------------------------------------------------------------------===// | ||
| 18 | |||
| 19 | #ifndef LLVM_SUPPORT_COMMANDLINE_H | ||
| 20 | #define LLVM_SUPPORT_COMMANDLINE_H | ||
| 21 | |||
| 22 | #include "llvm/ADT/ArrayRef.h" | ||
| 23 | #include "llvm/ADT/STLExtras.h" | ||
| 24 | #include "llvm/ADT/SmallPtrSet.h" | ||
| 25 | #include "llvm/ADT/SmallVector.h" | ||
| 26 | #include "llvm/ADT/StringMap.h" | ||
| 27 | #include "llvm/ADT/StringRef.h" | ||
| 28 | #include "llvm/ADT/Twine.h" | ||
| 29 | #include "llvm/ADT/iterator_range.h" | ||
| 30 | #include "llvm/Support/ErrorHandling.h" | ||
| 31 | #include "llvm/Support/ManagedStatic.h" | ||
| 32 | #include "llvm/Support/StringSaver.h" | ||
| 33 | #include "llvm/Support/raw_ostream.h" | ||
| 34 | #include <cassert> | ||
| 35 | #include <climits> | ||
| 36 | #include <cstddef> | ||
| 37 | #include <functional> | ||
| 38 | #include <initializer_list> | ||
| 39 | #include <string> | ||
| 40 | #include <type_traits> | ||
| 41 | #include <vector> | ||
| 42 | |||
| 43 | namespace llvm { | ||
| 44 | |||
| 45 | namespace vfs { | ||
| 46 | class FileSystem; | ||
| 47 | } | ||
| 48 | |||
| 49 | class StringSaver; | ||
| 50 | |||
| 51 | /// This namespace contains all of the command line option processing machinery. | ||
| 52 | /// It is intentionally a short name to make qualified usage concise. | ||
| 53 | namespace cl { | ||
| 54 | |||
| 55 | //===----------------------------------------------------------------------===// | ||
| 56 | // Command line option processing entry point. | ||
| 57 | // | ||
| 58 | // Returns true on success. Otherwise, this will print the error message to | ||
| 59 | // stderr and exit if \p Errs is not set (nullptr by default), or print the | ||
| 60 | // error message to \p Errs and return false if \p Errs is provided. | ||
| 61 | // | ||
| 62 | // If EnvVar is not nullptr, command-line options are also parsed from the | ||
| 63 | // environment variable named by EnvVar.  Precedence is given to occurrences | ||
| 64 | // from argv.  This precedence is currently implemented by parsing argv after | ||
| 65 | // the environment variable, so it is only implemented correctly for options | ||
| 66 | // that give precedence to later occurrences.  If your program supports options | ||
| 67 | // that give precedence to earlier occurrences, you will need to extend this | ||
| 68 | // function to support it correctly. | ||
| 69 | bool ParseCommandLineOptions(int argc, const char *const *argv, | ||
| 70 | StringRef Overview = "", | ||
| 71 | raw_ostream *Errs = nullptr, | ||
| 72 | const char *EnvVar = nullptr, | ||
| 73 | bool LongOptionsUseDoubleDash = false); | ||
| 74 | |||
| 75 | // Function pointer type for printing version information. | ||
| 76 | using VersionPrinterTy = std::function<void(raw_ostream &)>; | ||
| 77 | |||
| 78 | ///===---------------------------------------------------------------------===// | ||
| 79 | /// Override the default (LLVM specific) version printer used to print out the | ||
| 80 | /// version when --version is given on the command line. This allows other | ||
| 81 | /// systems using the CommandLine utilities to print their own version string. | ||
| 82 | void SetVersionPrinter(VersionPrinterTy func); | ||
| 83 | |||
| 84 | ///===---------------------------------------------------------------------===// | ||
| 85 | /// Add an extra printer to use in addition to the default one. This can be | ||
| 86 | /// called multiple times, and each time it adds a new function to the list | ||
| 87 | /// which will be called after the basic LLVM version printing is complete. | ||
| 88 | /// Each can then add additional information specific to the tool. | ||
| 89 | void AddExtraVersionPrinter(VersionPrinterTy func); | ||
| 90 | |||
| 91 | // Print option values. | ||
| 92 | // With -print-options print the difference between option values and defaults. | ||
| 93 | // With -print-all-options print all option values. | ||
| 94 | // (Currently not perfect, but best-effort.) | ||
| 95 | void PrintOptionValues(); | ||
| 96 | |||
| 97 | // Forward declaration - AddLiteralOption needs to be up here to make gcc happy. | ||
| 98 | class Option; | ||
| 99 | |||
| 100 | /// Adds a new option for parsing and provides the option it refers to. | ||
| 101 | /// | ||
| 102 | /// \param O pointer to the option | ||
| 103 | /// \param Name the string name for the option to handle during parsing | ||
| 104 | /// | ||
| 105 | /// Literal options are used by some parsers to register special option values. | ||
| 106 | /// This is how the PassNameParser registers pass names for opt. | ||
| 107 | void AddLiteralOption(Option &O, StringRef Name); | ||
| 108 | |||
| 109 | //===----------------------------------------------------------------------===// | ||
| 110 | // Flags permitted to be passed to command line arguments | ||
| 111 | // | ||
| 112 | |||
| 113 | enum NumOccurrencesFlag { // Flags for the number of occurrences allowed | ||
| 114 | Optional = 0x00, // Zero or One occurrence | ||
| 115 | ZeroOrMore = 0x01, // Zero or more occurrences allowed | ||
| 116 | Required = 0x02, // One occurrence required | ||
| 117 | OneOrMore = 0x03, // One or more occurrences required | ||
| 118 | |||
| 119 |   // Indicates that this option is fed anything that follows the last positional | ||
| 120 |   // argument required by the application (it is an error if there are zero | ||
| 121 |   // positional arguments, and a ConsumeAfter option is used). | ||
| 122 |   // Thus, for example, all arguments to LLI are processed until a filename is | ||
| 123 |   // found.  Once a filename is found, all of the succeeding arguments are | ||
| 124 |   // passed, unprocessed, to the ConsumeAfter option. | ||
| 125 |   // | ||
| 126 | ConsumeAfter = 0x04 | ||
| 127 | }; | ||
| 128 | |||
| 129 | enum ValueExpected { // Is a value required for the option? | ||
| 130 |   // zero reserved for the unspecified value | ||
| 131 | ValueOptional = 0x01, // The value can appear... or not | ||
| 132 | ValueRequired = 0x02, // The value is required to appear! | ||
| 133 | ValueDisallowed = 0x03 // A value may not be specified (for flags) | ||
| 134 | }; | ||
| 135 | |||
| 136 | enum OptionHidden { // Control whether -help shows this option | ||
| 137 | NotHidden = 0x00, // Option included in -help & -help-hidden | ||
| 138 | Hidden = 0x01, // -help doesn't, but -help-hidden does | ||
| 139 | ReallyHidden = 0x02 // Neither -help nor -help-hidden show this arg | ||
| 140 | }; | ||
| 141 | |||
| 142 | // This controls special features that the option might have that cause it to be | ||
| 143 | // parsed differently... | ||
| 144 | // | ||
| 145 | // Prefix - This option allows arguments that are otherwise unrecognized to be | ||
| 146 | // matched by options that are a prefix of the actual value.  This is useful for | ||
| 147 | // cases like a linker, where options are typically of the form '-lfoo' or | ||
| 148 | // '-L../../include' where -l or -L are the actual flags.  When prefix is | ||
| 149 | // enabled, and used, the value for the flag comes from the suffix of the | ||
| 150 | // argument. | ||
| 151 | // | ||
| 152 | // AlwaysPrefix - Only allow the behavior enabled by the Prefix flag and reject | ||
| 153 | // the Option=Value form. | ||
| 154 | // | ||
| 155 | |||
| 156 | enum FormattingFlags { | ||
| 157 | NormalFormatting = 0x00, // Nothing special | ||
| 158 | Positional = 0x01, // Is a positional argument, no '-' required | ||
| 159 | Prefix = 0x02, // Can this option directly prefix its value? | ||
| 160 | AlwaysPrefix = 0x03 // Can this option only directly prefix its value? | ||
| 161 | }; | ||
| 162 | |||
| 163 | enum MiscFlags { // Miscellaneous flags to adjust argument | ||
| 164 | CommaSeparated = 0x01, // Should this cl::list split between commas? | ||
| 165 | PositionalEatsArgs = 0x02, // Should this positional cl::list eat -args? | ||
| 166 | Sink = 0x04, // Should this cl::list eat all unknown options? | ||
| 167 | |||
| 168 |   // Can this option group with other options? | ||
| 169 |   // If this is enabled, multiple letter options are allowed to bunch together | ||
| 170 |   // with only a single hyphen for the whole group.  This allows emulation | ||
| 171 |   // of the behavior that ls uses for example: ls -la === ls -l -a | ||
| 172 | Grouping = 0x08, | ||
| 173 | |||
| 174 |   // Default option | ||
| 175 | DefaultOption = 0x10 | ||
| 176 | }; | ||
| 177 | |||
| 178 | //===----------------------------------------------------------------------===// | ||
| 179 | // | ||
| 180 | class OptionCategory { | ||
| 181 | private: | ||
| 182 | StringRef const Name; | ||
| 183 | StringRef const Description; | ||
| 184 | |||
| 185 | void registerCategory(); | ||
| 186 | |||
| 187 | public: | ||
| 188 | OptionCategory(StringRef const Name, | ||
| 189 | StringRef const Description = "") | ||
| 190 | : Name(Name), Description(Description) { | ||
| 191 | registerCategory(); | ||
| 192 |   } | ||
| 193 | |||
| 194 | StringRef getName() const { return Name; } | ||
| 195 | StringRef getDescription() const { return Description; } | ||
| 196 | }; | ||
| 197 | |||
| 198 | // The general Option Category (used as default category). | ||
| 199 | OptionCategory &getGeneralCategory(); | ||
| 200 | |||
| 201 | //===----------------------------------------------------------------------===// | ||
| 202 | // | ||
| 203 | class SubCommand { | ||
| 204 | private: | ||
| 205 |   StringRef Name; | ||
| 206 |   StringRef Description; | ||
| 207 | |||
| 208 | protected: | ||
| 209 | void registerSubCommand(); | ||
| 210 | void unregisterSubCommand(); | ||
| 211 | |||
| 212 | public: | ||
| 213 | SubCommand(StringRef Name, StringRef Description = "") | ||
| 214 | : Name(Name), Description(Description) { | ||
| 215 | registerSubCommand(); | ||
| 216 |   } | ||
| 217 | SubCommand() = default; | ||
| 218 | |||
| 219 |   // Get the special subcommand representing no subcommand. | ||
| 220 | static SubCommand &getTopLevel(); | ||
| 221 | |||
| 222 |   // Get the special subcommand that can be used to put an option into all | ||
| 223 |   // subcomands. | ||
| 224 | static SubCommand &getAll(); | ||
| 225 | |||
| 226 | void reset(); | ||
| 227 | |||
| 228 | explicit operator bool() const; | ||
| 229 | |||
| 230 | StringRef getName() const { return Name; } | ||
| 231 | StringRef getDescription() const { return Description; } | ||
| 232 | |||
| 233 | SmallVector<Option *, 4> PositionalOpts; | ||
| 234 | SmallVector<Option *, 4> SinkOpts; | ||
| 235 | StringMap<Option *> OptionsMap; | ||
| 236 | |||
| 237 | Option *ConsumeAfterOpt = nullptr; // The ConsumeAfter option if it exists. | ||
| 238 | }; | ||
| 239 | |||
| 240 | // A special subcommand representing no subcommand | ||
| 241 | extern ManagedStatic<SubCommand> TopLevelSubCommand; | ||
| 242 | |||
| 243 | // A special subcommand that can be used to put an option into all subcommands. | ||
| 244 | extern ManagedStatic<SubCommand> AllSubCommands; | ||
| 245 | |||
| 246 | //===----------------------------------------------------------------------===// | ||
| 247 | // | ||
| 248 | class Option { | ||
| 249 | friend class alias; | ||
| 250 | |||
| 251 |   // Overriden by subclasses to handle the value passed into an argument. Should | ||
| 252 |   // return true if there was an error processing the argument and the program | ||
| 253 |   // should exit. | ||
| 254 |   // | ||
| 255 | virtual bool handleOccurrence(unsigned pos, StringRef ArgName, | ||
| 256 | StringRef Arg) = 0; | ||
| 257 | |||
| 258 | virtual enum ValueExpected getValueExpectedFlagDefault() const { | ||
| 259 | return ValueOptional; | ||
| 260 |   } | ||
| 261 | |||
| 262 |   // Out of line virtual function to provide home for the class. | ||
| 263 | virtual void anchor(); | ||
| 264 | |||
| 265 | uint16_t NumOccurrences; // The number of times specified | ||
| 266 |   // Occurrences, HiddenFlag, and Formatting are all enum types but to avoid | ||
| 267 |   // problems with signed enums in bitfields. | ||
| 268 | uint16_t Occurrences : 3; // enum NumOccurrencesFlag | ||
| 269 |   // not using the enum type for 'Value' because zero is an implementation | ||
| 270 |   // detail representing the non-value | ||
| 271 | uint16_t Value : 2; | ||
| 272 | uint16_t HiddenFlag : 2; // enum OptionHidden | ||
| 273 | uint16_t Formatting : 2; // enum FormattingFlags | ||
| 274 | uint16_t Misc : 5; | ||
| 275 | uint16_t FullyInitialized : 1; // Has addArgument been called? | ||
| 276 | uint16_t Position; // Position of last occurrence of the option | ||
| 277 | uint16_t AdditionalVals; // Greater than 0 for multi-valued option. | ||
| 278 | |||
| 279 | public: | ||
| 280 | StringRef ArgStr; // The argument string itself (ex: "help", "o") | ||
| 281 | StringRef HelpStr; // The descriptive text message for -help | ||
| 282 | StringRef ValueStr; // String describing what the value of this option is | ||
| 283 | SmallVector<OptionCategory *, 1> | ||
| 284 | Categories; // The Categories this option belongs to | ||
| 285 | SmallPtrSet<SubCommand *, 1> Subs; // The subcommands this option belongs to. | ||
| 286 | |||
| 287 | inline enum NumOccurrencesFlag getNumOccurrencesFlag() const { | ||
| 288 | return (enum NumOccurrencesFlag)Occurrences; | ||
| 289 |   } | ||
| 290 | |||
| 291 | inline enum ValueExpected getValueExpectedFlag() const { | ||
| 292 | return Value ? ((enum ValueExpected)Value) : getValueExpectedFlagDefault(); | ||
| 293 |   } | ||
| 294 | |||
| 295 | inline enum OptionHidden getOptionHiddenFlag() const { | ||
| 296 | return (enum OptionHidden)HiddenFlag; | ||
| 297 |   } | ||
| 298 | |||
| 299 | inline enum FormattingFlags getFormattingFlag() const { | ||
| 300 | return (enum FormattingFlags)Formatting; | ||
| 301 |   } | ||
| 302 | |||
| 303 | inline unsigned getMiscFlags() const { return Misc; } | ||
| 304 | inline unsigned getPosition() const { return Position; } | ||
| 305 | inline unsigned getNumAdditionalVals() const { return AdditionalVals; } | ||
| 306 | |||
| 307 |   // Return true if the argstr != "" | ||
| 308 | bool hasArgStr() const { return !ArgStr.empty(); } | ||
| 309 | bool isPositional() const { return getFormattingFlag() == cl::Positional; } | ||
| 310 | bool isSink() const { return getMiscFlags() & cl::Sink; } | ||
| 311 | bool isDefaultOption() const { return getMiscFlags() & cl::DefaultOption; } | ||
| 312 | |||
| 313 | bool isConsumeAfter() const { | ||
| 314 | return getNumOccurrencesFlag() == cl::ConsumeAfter; | ||
| 315 |   } | ||
| 316 | |||
| 317 | bool isInAllSubCommands() const { | ||
| 318 | return llvm::is_contained(Subs, &SubCommand::getAll()); | ||
| 319 |   } | ||
| 320 | |||
| 321 |   //-------------------------------------------------------------------------=== | ||
| 322 |   // Accessor functions set by OptionModifiers | ||
| 323 |   // | ||
| 324 | void setArgStr(StringRef S); | ||
| 325 | void setDescription(StringRef S) { HelpStr = S; } | ||
| 326 | void setValueStr(StringRef S) { ValueStr = S; } | ||
| 327 | void setNumOccurrencesFlag(enum NumOccurrencesFlag Val) { Occurrences = Val; } | ||
| 328 | void setValueExpectedFlag(enum ValueExpected Val) { Value = Val; } | ||
| 329 | void setHiddenFlag(enum OptionHidden Val) { HiddenFlag = Val; } | ||
| 330 | void setFormattingFlag(enum FormattingFlags V) { Formatting = V; } | ||
| 331 | void setMiscFlag(enum MiscFlags M) { Misc |= M; } | ||
| 332 | void setPosition(unsigned pos) { Position = pos; } | ||
| 333 | void addCategory(OptionCategory &C); | ||
| 334 | void addSubCommand(SubCommand &S) { Subs.insert(&S); } | ||
| 335 | |||
| 336 | protected: | ||
| 337 | explicit Option(enum NumOccurrencesFlag OccurrencesFlag, | ||
| 338 | enum OptionHidden Hidden) | ||
| 339 | : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), | ||
| 340 | HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), | ||
| 341 | FullyInitialized(false), Position(0), AdditionalVals(0) { | ||
| 342 | Categories.push_back(&getGeneralCategory()); | ||
| 343 |   } | ||
| 344 | |||
| 345 | inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } | ||
| 346 | |||
| 347 | public: | ||
| 348 | virtual ~Option() = default; | ||
| 349 | |||
| 350 |   // Register this argument with the commandline system. | ||
| 351 |   // | ||
| 352 | void addArgument(); | ||
| 353 | |||
| 354 |   /// Unregisters this option from the CommandLine system. | ||
| 355 |   /// | ||
| 356 |   /// This option must have been the last option registered. | ||
| 357 |   /// For testing purposes only. | ||
| 358 | void removeArgument(); | ||
| 359 | |||
| 360 |   // Return the width of the option tag for printing... | ||
| 361 | virtual size_t getOptionWidth() const = 0; | ||
| 362 | |||
| 363 |   // Print out information about this option. The to-be-maintained width is | ||
| 364 |   // specified. | ||
| 365 |   // | ||
| 366 | virtual void printOptionInfo(size_t GlobalWidth) const = 0; | ||
| 367 | |||
| 368 | virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0; | ||
| 369 | |||
| 370 | virtual void setDefault() = 0; | ||
| 371 | |||
| 372 |   // Prints the help string for an option. | ||
| 373 |   // | ||
| 374 |   // This maintains the Indent for multi-line descriptions. | ||
| 375 |   // FirstLineIndentedBy is the count of chars of the first line | ||
| 376 |   //      i.e. the one containing the --<option name>. | ||
| 377 | static void printHelpStr(StringRef HelpStr, size_t Indent, | ||
| 378 | size_t FirstLineIndentedBy); | ||
| 379 | |||
| 380 |   // Prints the help string for an enum value. | ||
| 381 |   // | ||
| 382 |   // This maintains the Indent for multi-line descriptions. | ||
| 383 |   // FirstLineIndentedBy is the count of chars of the first line | ||
| 384 |   //      i.e. the one containing the =<value>. | ||
| 385 | static void printEnumValHelpStr(StringRef HelpStr, size_t Indent, | ||
| 386 | size_t FirstLineIndentedBy); | ||
| 387 | |||
| 388 | virtual void getExtraOptionNames(SmallVectorImpl<StringRef> &) {} | ||
| 389 | |||
| 390 |   // Wrapper around handleOccurrence that enforces Flags. | ||
| 391 |   // | ||
| 392 | virtual bool addOccurrence(unsigned pos, StringRef ArgName, StringRef Value, | ||
| 393 | bool MultiArg = false); | ||
| 394 | |||
| 395 |   // Prints option name followed by message.  Always returns true. | ||
| 396 | bool error(const Twine &Message, StringRef ArgName = StringRef(), raw_ostream &Errs = llvm::errs()); | ||
| 397 | bool error(const Twine &Message, raw_ostream &Errs) { | ||
| 398 | return error(Message, StringRef(), Errs); | ||
| 399 |   } | ||
| 400 | |||
| 401 | inline int getNumOccurrences() const { return NumOccurrences; } | ||
| 402 | void reset(); | ||
| 403 | }; | ||
| 404 | |||
| 405 | //===----------------------------------------------------------------------===// | ||
| 406 | // Command line option modifiers that can be used to modify the behavior of | ||
| 407 | // command line option parsers... | ||
| 408 | // | ||
| 409 | |||
| 410 | // Modifier to set the description shown in the -help output... | ||
| 411 | struct desc { | ||
| 412 |   StringRef Desc; | ||
| 413 | |||
| 414 | desc(StringRef Str) : Desc(Str) {} | ||
| 415 | |||
| 416 | void apply(Option &O) const { O.setDescription(Desc); } | ||
| 417 | }; | ||
| 418 | |||
| 419 | // Modifier to set the value description shown in the -help output... | ||
| 420 | struct value_desc { | ||
| 421 |   StringRef Desc; | ||
| 422 | |||
| 423 | value_desc(StringRef Str) : Desc(Str) {} | ||
| 424 | |||
| 425 | void apply(Option &O) const { O.setValueStr(Desc); } | ||
| 426 | }; | ||
| 427 | |||
| 428 | // Specify a default (initial) value for the command line argument, if the | ||
| 429 | // default constructor for the argument type does not give you what you want. | ||
| 430 | // This is only valid on "opt" arguments, not on "list" arguments. | ||
| 431 | template <class Ty> struct initializer { | ||
| 432 | const Ty &Init; | ||
| 433 | initializer(const Ty &Val) : Init(Val) {} | ||
| 434 | |||
| 435 | template <class Opt> void apply(Opt &O) const { O.setInitialValue(Init); } | ||
| 436 | }; | ||
| 437 | |||
| 438 | template <class Ty> struct list_initializer { | ||
| 439 | ArrayRef<Ty> Inits; | ||
| 440 | list_initializer(ArrayRef<Ty> Vals) : Inits(Vals) {} | ||
| 441 | |||
| 442 | template <class Opt> void apply(Opt &O) const { O.setInitialValues(Inits); } | ||
| 443 | }; | ||
| 444 | |||
| 445 | template <class Ty> initializer<Ty> init(const Ty &Val) { | ||
| 446 | return initializer<Ty>(Val); | ||
| 447 | } | ||
| 448 | |||
| 449 | template <class Ty> | ||
| 450 | list_initializer<Ty> list_init(ArrayRef<Ty> Vals) { | ||
| 451 | return list_initializer<Ty>(Vals); | ||
| 452 | } | ||
| 453 | |||
| 454 | // Allow the user to specify which external variable they want to store the | ||
| 455 | // results of the command line argument processing into, if they don't want to | ||
| 456 | // store it in the option itself. | ||
| 457 | template <class Ty> struct LocationClass { | ||
| 458 | Ty &Loc; | ||
| 459 | |||
| 460 | LocationClass(Ty &L) : Loc(L) {} | ||
| 461 | |||
| 462 | template <class Opt> void apply(Opt &O) const { O.setLocation(O, Loc); } | ||
| 463 | }; | ||
| 464 | |||
| 465 | template <class Ty> LocationClass<Ty> location(Ty &L) { | ||
| 466 | return LocationClass<Ty>(L); | ||
| 467 | } | ||
| 468 | |||
| 469 | // Specify the Option category for the command line argument to belong to. | ||
| 470 | struct cat { | ||
| 471 | OptionCategory &Category; | ||
| 472 | |||
| 473 | cat(OptionCategory &c) : Category(c) {} | ||
| 474 | |||
| 475 | template <class Opt> void apply(Opt &O) const { O.addCategory(Category); } | ||
| 476 | }; | ||
| 477 | |||
| 478 | // Specify the subcommand that this option belongs to. | ||
| 479 | struct sub { | ||
| 480 | SubCommand ⋐ | ||
| 481 | |||
| 482 | sub(SubCommand &S) : Sub(S) {} | ||
| 483 | |||
| 484 | template <class Opt> void apply(Opt &O) const { O.addSubCommand(Sub); } | ||
| 485 | }; | ||
| 486 | |||
| 487 | // Specify a callback function to be called when an option is seen. | ||
| 488 | // Can be used to set other options automatically. | ||
| 489 | template <typename R, typename Ty> struct cb { | ||
| 490 | std::function<R(Ty)> CB; | ||
| 491 | |||
| 492 | cb(std::function<R(Ty)> CB) : CB(CB) {} | ||
| 493 | |||
| 494 | template <typename Opt> void apply(Opt &O) const { O.setCallback(CB); } | ||
| 495 | }; | ||
| 496 | |||
| 497 | namespace detail { | ||
| 498 | template <typename F> | ||
| 499 | struct callback_traits : public callback_traits<decltype(&F::operator())> {}; | ||
| 500 | |||
| 501 | template <typename R, typename C, typename... Args> | ||
| 502 | struct callback_traits<R (C::*)(Args...) const> { | ||
| 503 | using result_type = R; | ||
| 504 | using arg_type = std::tuple_element_t<0, std::tuple<Args...>>; | ||
| 505 | static_assert(sizeof...(Args) == 1, "callback function must have one and only one parameter"); | ||
| 506 | static_assert(std::is_same<result_type, void>::value, | ||
| 507 | "callback return type must be void"); | ||
| 508 | static_assert(std::is_lvalue_reference<arg_type>::value && | ||
| 509 | std::is_const<std::remove_reference_t<arg_type>>::value, | ||
| 510 | "callback arg_type must be a const lvalue reference"); | ||
| 511 | }; | ||
| 512 | } // namespace detail | ||
| 513 | |||
| 514 | template <typename F> | ||
| 515 | cb<typename detail::callback_traits<F>::result_type, | ||
| 516 | typename detail::callback_traits<F>::arg_type> | ||
| 517 | callback(F CB) { | ||
| 518 | using result_type = typename detail::callback_traits<F>::result_type; | ||
| 519 | using arg_type = typename detail::callback_traits<F>::arg_type; | ||
| 520 | return cb<result_type, arg_type>(CB); | ||
| 521 | } | ||
| 522 | |||
| 523 | //===----------------------------------------------------------------------===// | ||
| 524 | |||
| 525 | // Support value comparison outside the template. | ||
| 526 | struct GenericOptionValue { | ||
| 527 | virtual bool compare(const GenericOptionValue &V) const = 0; | ||
| 528 | |||
| 529 | protected: | ||
| 530 | GenericOptionValue() = default; | ||
| 531 | GenericOptionValue(const GenericOptionValue&) = default; | ||
| 532 | GenericOptionValue &operator=(const GenericOptionValue &) = default; | ||
| 533 | ~GenericOptionValue() = default; | ||
| 534 | |||
| 535 | private: | ||
| 536 | virtual void anchor(); | ||
| 537 | }; | ||
| 538 | |||
| 539 | template <class DataType> struct OptionValue; | ||
| 540 | |||
| 541 | // The default value safely does nothing. Option value printing is only | ||
| 542 | // best-effort. | ||
| 543 | template <class DataType, bool isClass> | ||
| 544 | struct OptionValueBase : public GenericOptionValue { | ||
| 545 |   // Temporary storage for argument passing. | ||
| 546 | using WrapperType = OptionValue<DataType>; | ||
| 547 | |||
| 548 | bool hasValue() const { return false; } | ||
| 549 | |||
| 550 | const DataType &getValue() const { llvm_unreachable("no default value"); } | ||
| 551 | |||
| 552 |   // Some options may take their value from a different data type. | ||
| 553 | template <class DT> void setValue(const DT & /*V*/) {} | ||
| 554 | |||
| 555 | bool compare(const DataType & /*V*/) const { return false; } | ||
| 556 | |||
| 557 | bool compare(const GenericOptionValue & /*V*/) const override { | ||
| 558 | return false; | ||
| 559 |   } | ||
| 560 | |||
| 561 | protected: | ||
| 562 | ~OptionValueBase() = default; | ||
| 563 | }; | ||
| 564 | |||
| 565 | // Simple copy of the option value. | ||
| 566 | template <class DataType> class OptionValueCopy : public GenericOptionValue { | ||
| 567 |   DataType Value; | ||
| 568 | bool Valid = false; | ||
| 569 | |||
| 570 | protected: | ||
| 571 | OptionValueCopy(const OptionValueCopy&) = default; | ||
| 572 | OptionValueCopy &operator=(const OptionValueCopy &) = default; | ||
| 573 | ~OptionValueCopy() = default; | ||
| 574 | |||
| 575 | public: | ||
| 576 | OptionValueCopy() = default; | ||
| 577 | |||
| 578 | bool hasValue() const { return Valid; } | ||
| 579 | |||
| 580 | const DataType &getValue() const { | ||
| 581 | assert(Valid && "invalid option value"); | ||
| 582 | return Value; | ||
| 583 |   } | ||
| 584 | |||
| 585 | void setValue(const DataType &V) { | ||
| 586 | Valid = true; | ||
| 587 | Value = V; | ||
| 588 |   } | ||
| 589 | |||
| 590 | bool compare(const DataType &V) const { return Valid && (Value != V); } | ||
| 591 | |||
| 592 | bool compare(const GenericOptionValue &V) const override { | ||
| 593 | const OptionValueCopy<DataType> &VC = | ||
| 594 | static_cast<const OptionValueCopy<DataType> &>(V); | ||
| 595 | if (!VC.hasValue()) | ||
| 596 | return false; | ||
| 597 | return compare(VC.getValue()); | ||
| 598 |   } | ||
| 599 | }; | ||
| 600 | |||
| 601 | // Non-class option values. | ||
| 602 | template <class DataType> | ||
| 603 | struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> { | ||
| 604 | using WrapperType = DataType; | ||
| 605 | |||
| 606 | protected: | ||
| 607 | OptionValueBase() = default; | ||
| 608 | OptionValueBase(const OptionValueBase&) = default; | ||
| 609 | OptionValueBase &operator=(const OptionValueBase &) = default; | ||
| 610 | ~OptionValueBase() = default; | ||
| 611 | }; | ||
| 612 | |||
| 613 | // Top-level option class. | ||
| 614 | template <class DataType> | ||
| 615 | struct OptionValue final | ||
| 616 | : OptionValueBase<DataType, std::is_class<DataType>::value> { | ||
| 617 | OptionValue() = default; | ||
| 618 | |||
| 619 | OptionValue(const DataType &V) { this->setValue(V); } | ||
| 620 | |||
| 621 |   // Some options may take their value from a different data type. | ||
| 622 | template <class DT> OptionValue<DataType> &operator=(const DT &V) { | ||
| 623 | this->setValue(V); | ||
| 624 | return *this; | ||
| 625 |   } | ||
| 626 | }; | ||
| 627 | |||
| 628 | // Other safe-to-copy-by-value common option types. | ||
| 629 | enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE }; | ||
| 630 | template <> | ||
| 631 | struct OptionValue<cl::boolOrDefault> final | ||
| 632 | : OptionValueCopy<cl::boolOrDefault> { | ||
| 633 | using WrapperType = cl::boolOrDefault; | ||
| 634 | |||
| 635 | OptionValue() = default; | ||
| 636 | |||
| 637 | OptionValue(const cl::boolOrDefault &V) { this->setValue(V); } | ||
| 638 | |||
| 639 | OptionValue<cl::boolOrDefault> &operator=(const cl::boolOrDefault &V) { | ||
| 640 | setValue(V); | ||
| 641 | return *this; | ||
| 642 |   } | ||
| 643 | |||
| 644 | private: | ||
| 645 | void anchor() override; | ||
| 646 | }; | ||
| 647 | |||
| 648 | template <> | ||
| 649 | struct OptionValue<std::string> final : OptionValueCopy<std::string> { | ||
| 650 | using WrapperType = StringRef; | ||
| 651 | |||
| 652 | OptionValue() = default; | ||
| 653 | |||
| 654 | OptionValue(const std::string &V) { this->setValue(V); } | ||
| 655 | |||
| 656 | OptionValue<std::string> &operator=(const std::string &V) { | ||
| 657 | setValue(V); | ||
| 658 | return *this; | ||
| 659 |   } | ||
| 660 | |||
| 661 | private: | ||
| 662 | void anchor() override; | ||
| 663 | }; | ||
| 664 | |||
| 665 | //===----------------------------------------------------------------------===// | ||
| 666 | // Enum valued command line option | ||
| 667 | // | ||
| 668 | |||
| 669 | // This represents a single enum value, using "int" as the underlying type. | ||
| 670 | struct OptionEnumValue { | ||
| 671 |   StringRef Name; | ||
| 672 | int Value; | ||
| 673 |   StringRef Description; | ||
| 674 | }; | ||
| 675 | |||
| 676 | #define clEnumVal(ENUMVAL, DESC)                                               \ | ||
| 677 |   llvm::cl::OptionEnumValue { #ENUMVAL, int(ENUMVAL), DESC } | ||
| 678 | #define clEnumValN(ENUMVAL, FLAGNAME, DESC)                                    \ | ||
| 679 |   llvm::cl::OptionEnumValue { FLAGNAME, int(ENUMVAL), DESC } | ||
| 680 | |||
| 681 | // For custom data types, allow specifying a group of values together as the | ||
| 682 | // values that go into the mapping that the option handler uses. | ||
| 683 | // | ||
| 684 | class ValuesClass { | ||
| 685 |   // Use a vector instead of a map, because the lists should be short, | ||
| 686 |   // the overhead is less, and most importantly, it keeps them in the order | ||
| 687 |   // inserted so we can print our option out nicely. | ||
| 688 | SmallVector<OptionEnumValue, 4> Values; | ||
| 689 | |||
| 690 | public: | ||
| 691 | ValuesClass(std::initializer_list<OptionEnumValue> Options) | ||
| 692 | : Values(Options) {} | ||
| 693 | |||
| 694 | template <class Opt> void apply(Opt &O) const { | ||
| 695 | for (const auto &Value : Values) | ||
| 696 | O.getParser().addLiteralOption(Value.Name, Value.Value, | ||
| 697 | Value.Description); | ||
| 698 |   } | ||
| 699 | }; | ||
| 700 | |||
| 701 | /// Helper to build a ValuesClass by forwarding a variable number of arguments | ||
| 702 | /// as an initializer list to the ValuesClass constructor. | ||
| 703 | template <typename... OptsTy> ValuesClass values(OptsTy... Options) { | ||
| 704 | return ValuesClass({Options...}); | ||
| 705 | } | ||
| 706 | |||
| 707 | //===----------------------------------------------------------------------===// | ||
| 708 | // Parameterizable parser for different data types. By default, known data types | ||
| 709 | // (string, int, bool) have specialized parsers, that do what you would expect. | ||
| 710 | // The default parser, used for data types that are not built-in, uses a mapping | ||
| 711 | // table to map specific options to values, which is used, among other things, | ||
| 712 | // to handle enum types. | ||
| 713 | |||
| 714 | //-------------------------------------------------- | ||
| 715 | // This class holds all the non-generic code that we do not need replicated for | ||
| 716 | // every instance of the generic parser.  This also allows us to put stuff into | ||
| 717 | // CommandLine.cpp | ||
| 718 | // | ||
| 719 | class generic_parser_base { | ||
| 720 | protected: | ||
| 721 | class GenericOptionInfo { | ||
| 722 | public: | ||
| 723 | GenericOptionInfo(StringRef name, StringRef helpStr) | ||
| 724 | : Name(name), HelpStr(helpStr) {} | ||
| 725 |     StringRef Name; | ||
| 726 |     StringRef HelpStr; | ||
| 727 | }; | ||
| 728 | |||
| 729 | public: | ||
| 730 | generic_parser_base(Option &O) : Owner(O) {} | ||
| 731 | |||
| 732 | virtual ~generic_parser_base() = default; | ||
| 733 |   // Base class should have virtual-destructor | ||
| 734 | |||
| 735 |   // Virtual function implemented by generic subclass to indicate how many | ||
| 736 |   // entries are in Values. | ||
| 737 |   // | ||
| 738 | virtual unsigned getNumOptions() const = 0; | ||
| 739 | |||
| 740 |   // Return option name N. | ||
| 741 | virtual StringRef getOption(unsigned N) const = 0; | ||
| 742 | |||
| 743 |   // Return description N | ||
| 744 | virtual StringRef getDescription(unsigned N) const = 0; | ||
| 745 | |||
| 746 |   // Return the width of the option tag for printing... | ||
| 747 | virtual size_t getOptionWidth(const Option &O) const; | ||
| 748 | |||
| 749 | virtual const GenericOptionValue &getOptionValue(unsigned N) const = 0; | ||
| 750 | |||
| 751 |   // Print out information about this option. The to-be-maintained width is | ||
| 752 |   // specified. | ||
| 753 |   // | ||
| 754 | virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const; | ||
| 755 | |||
| 756 | void printGenericOptionDiff(const Option &O, const GenericOptionValue &V, | ||
| 757 | const GenericOptionValue &Default, | ||
| 758 | size_t GlobalWidth) const; | ||
| 759 | |||
| 760 |   // Print the value of an option and it's default. | ||
| 761 |   // | ||
| 762 |   // Template definition ensures that the option and default have the same | ||
| 763 |   // DataType (via the same AnyOptionValue). | ||
| 764 | template <class AnyOptionValue> | ||
| 765 | void printOptionDiff(const Option &O, const AnyOptionValue &V, | ||
| 766 | const AnyOptionValue &Default, | ||
| 767 | size_t GlobalWidth) const { | ||
| 768 | printGenericOptionDiff(O, V, Default, GlobalWidth); | ||
| 769 |   } | ||
| 770 | |||
| 771 | void initialize() {} | ||
| 772 | |||
| 773 | void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) { | ||
| 774 |     // If there has been no argstr specified, that means that we need to add an | ||
| 775 |     // argument for every possible option.  This ensures that our options are | ||
| 776 |     // vectored to us. | ||
| 777 | if (!Owner.hasArgStr()) | ||
| 778 | for (unsigned i = 0, e = getNumOptions(); i != e; ++i) | ||
| 779 | OptionNames.push_back(getOption(i)); | ||
| 780 |   } | ||
| 781 | |||
| 782 | enum ValueExpected getValueExpectedFlagDefault() const { | ||
| 783 |     // If there is an ArgStr specified, then we are of the form: | ||
| 784 |     // | ||
| 785 |     //    -opt=O2   or   -opt O2  or  -optO2 | ||
| 786 |     // | ||
| 787 |     // In which case, the value is required.  Otherwise if an arg str has not | ||
| 788 |     // been specified, we are of the form: | ||
| 789 |     // | ||
| 790 |     //    -O2 or O2 or -la (where -l and -a are separate options) | ||
| 791 |     // | ||
| 792 |     // If this is the case, we cannot allow a value. | ||
| 793 |     // | ||
| 794 | if (Owner.hasArgStr()) | ||
| 795 | return ValueRequired; | ||
| 796 |     else | ||
| 797 | return ValueDisallowed; | ||
| 798 |   } | ||
| 799 | |||
| 800 |   // Return the option number corresponding to the specified | ||
| 801 |   // argument string.  If the option is not found, getNumOptions() is returned. | ||
| 802 |   // | ||
| 803 | unsigned findOption(StringRef Name); | ||
| 804 | |||
| 805 | protected: | ||
| 806 | Option &Owner; | ||
| 807 | }; | ||
| 808 | |||
| 809 | // Default parser implementation - This implementation depends on having a | ||
| 810 | // mapping of recognized options to values of some sort.  In addition to this, | ||
| 811 | // each entry in the mapping also tracks a help message that is printed with the | ||
| 812 | // command line option for -help.  Because this is a simple mapping parser, the | ||
| 813 | // data type can be any unsupported type. | ||
| 814 | // | ||
| 815 | template <class DataType> class parser : public generic_parser_base { | ||
| 816 | protected: | ||
| 817 | class OptionInfo : public GenericOptionInfo { | ||
| 818 | public: | ||
| 819 | OptionInfo(StringRef name, DataType v, StringRef helpStr) | ||
| 820 | : GenericOptionInfo(name, helpStr), V(v) {} | ||
| 821 | |||
| 822 | OptionValue<DataType> V; | ||
| 823 | }; | ||
| 824 | SmallVector<OptionInfo, 8> Values; | ||
| 825 | |||
| 826 | public: | ||
| 827 | parser(Option &O) : generic_parser_base(O) {} | ||
| 828 | |||
| 829 | using parser_data_type = DataType; | ||
| 830 | |||
| 831 |   // Implement virtual functions needed by generic_parser_base | ||
| 832 | unsigned getNumOptions() const override { return unsigned(Values.size()); } | ||
| 833 | StringRef getOption(unsigned N) const override { return Values[N].Name; } | ||
| 834 | StringRef getDescription(unsigned N) const override { | ||
| 835 | return Values[N].HelpStr; | ||
| 836 |   } | ||
| 837 | |||
| 838 |   // Return the value of option name N. | ||
| 839 | const GenericOptionValue &getOptionValue(unsigned N) const override { | ||
| 840 | return Values[N].V; | ||
| 841 |   } | ||
| 842 | |||
| 843 |   // Return true on error. | ||
| 844 | bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) { | ||
| 845 |     StringRef ArgVal; | ||
| 846 | if (Owner.hasArgStr()) | ||
| 847 | ArgVal = Arg; | ||
| 848 |     else | ||
| 849 | ArgVal = ArgName; | ||
| 850 | |||
| 851 | for (size_t i = 0, e = Values.size(); i != e; ++i) | ||
| 852 | if (Values[i].Name == ArgVal) { | ||
| 853 | V = Values[i].V.getValue(); | ||
| 854 | return false; | ||
| 855 |       } | ||
| 856 | |||
| 857 | return O.error("Cannot find option named '" + ArgVal + "'!"); | ||
| 858 |   } | ||
| 859 | |||
| 860 |   /// Add an entry to the mapping table. | ||
| 861 |   /// | ||
| 862 | template <class DT> | ||
| 863 | void addLiteralOption(StringRef Name, const DT &V, StringRef HelpStr) { | ||
| 864 | assert(findOption(Name) == Values.size() && "Option already exists!"); | ||
| 865 | OptionInfo X(Name, static_cast<DataType>(V), HelpStr); | ||
| 866 | Values.push_back(X); | ||
| 867 | AddLiteralOption(Owner, Name); | ||
| 868 |   } | ||
| 869 | |||
| 870 |   /// Remove the specified option. | ||
| 871 |   /// | ||
| 872 | void removeLiteralOption(StringRef Name) { | ||
| 873 | unsigned N = findOption(Name); | ||
| 874 | assert(N != Values.size() && "Option not found!"); | ||
| 875 | Values.erase(Values.begin() + N); | ||
| 876 |   } | ||
| 877 | }; | ||
| 878 | |||
| 879 | //-------------------------------------------------- | ||
| 880 | // Super class of parsers to provide boilerplate code | ||
| 881 | // | ||
| 882 | class basic_parser_impl { // non-template implementation of basic_parser<t> | ||
| 883 | public: | ||
| 884 | basic_parser_impl(Option &) {} | ||
| 885 | |||
| 886 | virtual ~basic_parser_impl() = default; | ||
| 887 | |||
| 888 | enum ValueExpected getValueExpectedFlagDefault() const { | ||
| 889 | return ValueRequired; | ||
| 890 |   } | ||
| 891 | |||
| 892 | void getExtraOptionNames(SmallVectorImpl<StringRef> &) {} | ||
| 893 | |||
| 894 | void initialize() {} | ||
| 895 | |||
| 896 |   // Return the width of the option tag for printing... | ||
| 897 | size_t getOptionWidth(const Option &O) const; | ||
| 898 | |||
| 899 |   // Print out information about this option. The to-be-maintained width is | ||
| 900 |   // specified. | ||
| 901 |   // | ||
| 902 | void printOptionInfo(const Option &O, size_t GlobalWidth) const; | ||
| 903 | |||
| 904 |   // Print a placeholder for options that don't yet support printOptionDiff(). | ||
| 905 | void printOptionNoValue(const Option &O, size_t GlobalWidth) const; | ||
| 906 | |||
| 907 |   // Overload in subclass to provide a better default value. | ||
| 908 | virtual StringRef getValueName() const { return "value"; } | ||
| 909 | |||
| 910 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 911 | virtual void anchor(); | ||
| 912 | |||
| 913 | protected: | ||
| 914 |   // A helper for basic_parser::printOptionDiff. | ||
| 915 | void printOptionName(const Option &O, size_t GlobalWidth) const; | ||
| 916 | }; | ||
| 917 | |||
| 918 | // The real basic parser is just a template wrapper that provides a typedef for | ||
| 919 | // the provided data type. | ||
| 920 | // | ||
| 921 | template <class DataType> class basic_parser : public basic_parser_impl { | ||
| 922 | public: | ||
| 923 | using parser_data_type = DataType; | ||
| 924 | using OptVal = OptionValue<DataType>; | ||
| 925 | |||
| 926 | basic_parser(Option &O) : basic_parser_impl(O) {} | ||
| 927 | }; | ||
| 928 | |||
| 929 | //-------------------------------------------------- | ||
| 930 | |||
| 931 | extern template class basic_parser<bool>; | ||
| 932 | |||
| 933 | template <> class parser<bool> : public basic_parser<bool> { | ||
| 934 | public: | ||
| 935 | parser(Option &O) : basic_parser(O) {} | ||
| 936 | |||
| 937 |   // Return true on error. | ||
| 938 | bool parse(Option &O, StringRef ArgName, StringRef Arg, bool &Val); | ||
| 939 | |||
| 940 | void initialize() {} | ||
| 941 | |||
| 942 | enum ValueExpected getValueExpectedFlagDefault() const { | ||
| 943 | return ValueOptional; | ||
| 944 |   } | ||
| 945 | |||
| 946 |   // Do not print =<value> at all. | ||
| 947 | StringRef getValueName() const override { return StringRef(); } | ||
| 948 | |||
| 949 | void printOptionDiff(const Option &O, bool V, OptVal Default, | ||
| 950 | size_t GlobalWidth) const; | ||
| 951 | |||
| 952 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 953 | void anchor() override; | ||
| 954 | }; | ||
| 955 | |||
| 956 | //-------------------------------------------------- | ||
| 957 | |||
| 958 | extern template class basic_parser<boolOrDefault>; | ||
| 959 | |||
| 960 | template <> class parser<boolOrDefault> : public basic_parser<boolOrDefault> { | ||
| 961 | public: | ||
| 962 | parser(Option &O) : basic_parser(O) {} | ||
| 963 | |||
| 964 |   // Return true on error. | ||
| 965 | bool parse(Option &O, StringRef ArgName, StringRef Arg, boolOrDefault &Val); | ||
| 966 | |||
| 967 | enum ValueExpected getValueExpectedFlagDefault() const { | ||
| 968 | return ValueOptional; | ||
| 969 |   } | ||
| 970 | |||
| 971 |   // Do not print =<value> at all. | ||
| 972 | StringRef getValueName() const override { return StringRef(); } | ||
| 973 | |||
| 974 | void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default, | ||
| 975 | size_t GlobalWidth) const; | ||
| 976 | |||
| 977 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 978 | void anchor() override; | ||
| 979 | }; | ||
| 980 | |||
| 981 | //-------------------------------------------------- | ||
| 982 | |||
| 983 | extern template class basic_parser<int>; | ||
| 984 | |||
| 985 | template <> class parser<int> : public basic_parser<int> { | ||
| 986 | public: | ||
| 987 | parser(Option &O) : basic_parser(O) {} | ||
| 988 | |||
| 989 |   // Return true on error. | ||
| 990 | bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val); | ||
| 991 | |||
| 992 |   // Overload in subclass to provide a better default value. | ||
| 993 | StringRef getValueName() const override { return "int"; } | ||
| 994 | |||
| 995 | void printOptionDiff(const Option &O, int V, OptVal Default, | ||
| 996 | size_t GlobalWidth) const; | ||
| 997 | |||
| 998 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 999 | void anchor() override; | ||
| 1000 | }; | ||
| 1001 | |||
| 1002 | //-------------------------------------------------- | ||
| 1003 | |||
| 1004 | extern template class basic_parser<long>; | ||
| 1005 | |||
| 1006 | template <> class parser<long> final : public basic_parser<long> { | ||
| 1007 | public: | ||
| 1008 | parser(Option &O) : basic_parser(O) {} | ||
| 1009 | |||
| 1010 |   // Return true on error. | ||
| 1011 | bool parse(Option &O, StringRef ArgName, StringRef Arg, long &Val); | ||
| 1012 | |||
| 1013 |   // Overload in subclass to provide a better default value. | ||
| 1014 | StringRef getValueName() const override { return "long"; } | ||
| 1015 | |||
| 1016 | void printOptionDiff(const Option &O, long V, OptVal Default, | ||
| 1017 | size_t GlobalWidth) const; | ||
| 1018 | |||
| 1019 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1020 | void anchor() override; | ||
| 1021 | }; | ||
| 1022 | |||
| 1023 | //-------------------------------------------------- | ||
| 1024 | |||
| 1025 | extern template class basic_parser<long long>; | ||
| 1026 | |||
| 1027 | template <> class parser<long long> : public basic_parser<long long> { | ||
| 1028 | public: | ||
| 1029 | parser(Option &O) : basic_parser(O) {} | ||
| 1030 | |||
| 1031 |   // Return true on error. | ||
| 1032 | bool parse(Option &O, StringRef ArgName, StringRef Arg, long long &Val); | ||
| 1033 | |||
| 1034 |   // Overload in subclass to provide a better default value. | ||
| 1035 | StringRef getValueName() const override { return "long"; } | ||
| 1036 | |||
| 1037 | void printOptionDiff(const Option &O, long long V, OptVal Default, | ||
| 1038 | size_t GlobalWidth) const; | ||
| 1039 | |||
| 1040 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1041 | void anchor() override; | ||
| 1042 | }; | ||
| 1043 | |||
| 1044 | //-------------------------------------------------- | ||
| 1045 | |||
| 1046 | extern template class basic_parser<unsigned>; | ||
| 1047 | |||
| 1048 | template <> class parser<unsigned> : public basic_parser<unsigned> { | ||
| 1049 | public: | ||
| 1050 | parser(Option &O) : basic_parser(O) {} | ||
| 1051 | |||
| 1052 |   // Return true on error. | ||
| 1053 | bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val); | ||
| 1054 | |||
| 1055 |   // Overload in subclass to provide a better default value. | ||
| 1056 | StringRef getValueName() const override { return "uint"; } | ||
| 1057 | |||
| 1058 | void printOptionDiff(const Option &O, unsigned V, OptVal Default, | ||
| 1059 | size_t GlobalWidth) const; | ||
| 1060 | |||
| 1061 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1062 | void anchor() override; | ||
| 1063 | }; | ||
| 1064 | |||
| 1065 | //-------------------------------------------------- | ||
| 1066 | |||
| 1067 | extern template class basic_parser<unsigned long>; | ||
| 1068 | |||
| 1069 | template <> | ||
| 1070 | class parser<unsigned long> final : public basic_parser<unsigned long> { | ||
| 1071 | public: | ||
| 1072 | parser(Option &O) : basic_parser(O) {} | ||
| 1073 | |||
| 1074 |   // Return true on error. | ||
| 1075 | bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned long &Val); | ||
| 1076 | |||
| 1077 |   // Overload in subclass to provide a better default value. | ||
| 1078 | StringRef getValueName() const override { return "ulong"; } | ||
| 1079 | |||
| 1080 | void printOptionDiff(const Option &O, unsigned long V, OptVal Default, | ||
| 1081 | size_t GlobalWidth) const; | ||
| 1082 | |||
| 1083 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1084 | void anchor() override; | ||
| 1085 | }; | ||
| 1086 | |||
| 1087 | //-------------------------------------------------- | ||
| 1088 | |||
| 1089 | extern template class basic_parser<unsigned long long>; | ||
| 1090 | |||
| 1091 | template <> | ||
| 1092 | class parser<unsigned long long> : public basic_parser<unsigned long long> { | ||
| 1093 | public: | ||
| 1094 | parser(Option &O) : basic_parser(O) {} | ||
| 1095 | |||
| 1096 |   // Return true on error. | ||
| 1097 | bool parse(Option &O, StringRef ArgName, StringRef Arg, | ||
| 1098 | unsigned long long &Val); | ||
| 1099 | |||
| 1100 |   // Overload in subclass to provide a better default value. | ||
| 1101 | StringRef getValueName() const override { return "ulong"; } | ||
| 1102 | |||
| 1103 | void printOptionDiff(const Option &O, unsigned long long V, OptVal Default, | ||
| 1104 | size_t GlobalWidth) const; | ||
| 1105 | |||
| 1106 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1107 | void anchor() override; | ||
| 1108 | }; | ||
| 1109 | |||
| 1110 | //-------------------------------------------------- | ||
| 1111 | |||
| 1112 | extern template class basic_parser<double>; | ||
| 1113 | |||
| 1114 | template <> class parser<double> : public basic_parser<double> { | ||
| 1115 | public: | ||
| 1116 | parser(Option &O) : basic_parser(O) {} | ||
| 1117 | |||
| 1118 |   // Return true on error. | ||
| 1119 | bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val); | ||
| 1120 | |||
| 1121 |   // Overload in subclass to provide a better default value. | ||
| 1122 | StringRef getValueName() const override { return "number"; } | ||
| 1123 | |||
| 1124 | void printOptionDiff(const Option &O, double V, OptVal Default, | ||
| 1125 | size_t GlobalWidth) const; | ||
| 1126 | |||
| 1127 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1128 | void anchor() override; | ||
| 1129 | }; | ||
| 1130 | |||
| 1131 | //-------------------------------------------------- | ||
| 1132 | |||
| 1133 | extern template class basic_parser<float>; | ||
| 1134 | |||
| 1135 | template <> class parser<float> : public basic_parser<float> { | ||
| 1136 | public: | ||
| 1137 | parser(Option &O) : basic_parser(O) {} | ||
| 1138 | |||
| 1139 |   // Return true on error. | ||
| 1140 | bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val); | ||
| 1141 | |||
| 1142 |   // Overload in subclass to provide a better default value. | ||
| 1143 | StringRef getValueName() const override { return "number"; } | ||
| 1144 | |||
| 1145 | void printOptionDiff(const Option &O, float V, OptVal Default, | ||
| 1146 | size_t GlobalWidth) const; | ||
| 1147 | |||
| 1148 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1149 | void anchor() override; | ||
| 1150 | }; | ||
| 1151 | |||
| 1152 | //-------------------------------------------------- | ||
| 1153 | |||
| 1154 | extern template class basic_parser<std::string>; | ||
| 1155 | |||
| 1156 | template <> class parser<std::string> : public basic_parser<std::string> { | ||
| 1157 | public: | ||
| 1158 | parser(Option &O) : basic_parser(O) {} | ||
| 1159 | |||
| 1160 |   // Return true on error. | ||
| 1161 | bool parse(Option &, StringRef, StringRef Arg, std::string &Value) { | ||
| 1162 | Value = Arg.str(); | ||
| 1163 | return false; | ||
| 1164 |   } | ||
| 1165 | |||
| 1166 |   // Overload in subclass to provide a better default value. | ||
| 1167 | StringRef getValueName() const override { return "string"; } | ||
| 1168 | |||
| 1169 | void printOptionDiff(const Option &O, StringRef V, const OptVal &Default, | ||
| 1170 | size_t GlobalWidth) const; | ||
| 1171 | |||
| 1172 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1173 | void anchor() override; | ||
| 1174 | }; | ||
| 1175 | |||
| 1176 | //-------------------------------------------------- | ||
| 1177 | |||
| 1178 | extern template class basic_parser<char>; | ||
| 1179 | |||
| 1180 | template <> class parser<char> : public basic_parser<char> { | ||
| 1181 | public: | ||
| 1182 | parser(Option &O) : basic_parser(O) {} | ||
| 1183 | |||
| 1184 |   // Return true on error. | ||
| 1185 | bool parse(Option &, StringRef, StringRef Arg, char &Value) { | ||
| 1186 | Value = Arg[0]; | ||
| 1187 | return false; | ||
| 1188 |   } | ||
| 1189 | |||
| 1190 |   // Overload in subclass to provide a better default value. | ||
| 1191 | StringRef getValueName() const override { return "char"; } | ||
| 1192 | |||
| 1193 | void printOptionDiff(const Option &O, char V, OptVal Default, | ||
| 1194 | size_t GlobalWidth) const; | ||
| 1195 | |||
| 1196 |   // An out-of-line virtual method to provide a 'home' for this class. | ||
| 1197 | void anchor() override; | ||
| 1198 | }; | ||
| 1199 | |||
| 1200 | //-------------------------------------------------- | ||
| 1201 | // This collection of wrappers is the intermediary between class opt and class | ||
| 1202 | // parser to handle all the template nastiness. | ||
| 1203 | |||
| 1204 | // This overloaded function is selected by the generic parser. | ||
| 1205 | template <class ParserClass, class DT> | ||
| 1206 | void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V, | ||
| 1207 | const OptionValue<DT> &Default, size_t GlobalWidth) { | ||
| 1208 | OptionValue<DT> OV = V; | ||
| 1209 | P.printOptionDiff(O, OV, Default, GlobalWidth); | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | // This is instantiated for basic parsers when the parsed value has a different | ||
| 1213 | // type than the option value. e.g. HelpPrinter. | ||
| 1214 | template <class ParserDT, class ValDT> struct OptionDiffPrinter { | ||
| 1215 | void print(const Option &O, const parser<ParserDT> &P, const ValDT & /*V*/, | ||
| 1216 | const OptionValue<ValDT> & /*Default*/, size_t GlobalWidth) { | ||
| 1217 | P.printOptionNoValue(O, GlobalWidth); | ||
| 1218 |   } | ||
| 1219 | }; | ||
| 1220 | |||
| 1221 | // This is instantiated for basic parsers when the parsed value has the same | ||
| 1222 | // type as the option value. | ||
| 1223 | template <class DT> struct OptionDiffPrinter<DT, DT> { | ||
| 1224 | void print(const Option &O, const parser<DT> &P, const DT &V, | ||
| 1225 | const OptionValue<DT> &Default, size_t GlobalWidth) { | ||
| 1226 | P.printOptionDiff(O, V, Default, GlobalWidth); | ||
| 1227 |   } | ||
| 1228 | }; | ||
| 1229 | |||
| 1230 | // This overloaded function is selected by the basic parser, which may parse a | ||
| 1231 | // different type than the option type. | ||
| 1232 | template <class ParserClass, class ValDT> | ||
| 1233 | void printOptionDiff( | ||
| 1234 | const Option &O, | ||
| 1235 | const basic_parser<typename ParserClass::parser_data_type> &P, | ||
| 1236 | const ValDT &V, const OptionValue<ValDT> &Default, size_t GlobalWidth) { | ||
| 1237 | |||
| 1238 | OptionDiffPrinter<typename ParserClass::parser_data_type, ValDT> printer; | ||
| 1239 | printer.print(O, static_cast<const ParserClass &>(P), V, Default, | ||
| 1240 | GlobalWidth); | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | //===----------------------------------------------------------------------===// | ||
| 1244 | // This class is used because we must use partial specialization to handle | ||
| 1245 | // literal string arguments specially (const char* does not correctly respond to | ||
| 1246 | // the apply method). Because the syntax to use this is a pain, we have the | ||
| 1247 | // 'apply' method below to handle the nastiness... | ||
| 1248 | // | ||
| 1249 | template <class Mod> struct applicator { | ||
| 1250 | template <class Opt> static void opt(const Mod &M, Opt &O) { M.apply(O); } | ||
| 1251 | }; | ||
| 1252 | |||
| 1253 | // Handle const char* as a special case... | ||
| 1254 | template <unsigned n> struct applicator<char[n]> { | ||
| 1255 | template <class Opt> static void opt(StringRef Str, Opt &O) { | ||
| 1256 | O.setArgStr(Str); | ||
| 1257 |   } | ||
| 1258 | }; | ||
| 1259 | template <unsigned n> struct applicator<const char[n]> { | ||
| 1260 | template <class Opt> static void opt(StringRef Str, Opt &O) { | ||
| 1261 | O.setArgStr(Str); | ||
| 1262 |   } | ||
| 1263 | }; | ||
| 1264 | template <> struct applicator<StringRef > { | ||
| 1265 | template <class Opt> static void opt(StringRef Str, Opt &O) { | ||
| 1266 | O.setArgStr(Str); | ||
| 1267 |   } | ||
| 1268 | }; | ||
| 1269 | |||
| 1270 | template <> struct applicator<NumOccurrencesFlag> { | ||
| 1271 | static void opt(NumOccurrencesFlag N, Option &O) { | ||
| 1272 | O.setNumOccurrencesFlag(N); | ||
| 1273 |   } | ||
| 1274 | }; | ||
| 1275 | |||
| 1276 | template <> struct applicator<ValueExpected> { | ||
| 1277 | static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); } | ||
| 1278 | }; | ||
| 1279 | |||
| 1280 | template <> struct applicator<OptionHidden> { | ||
| 1281 | static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); } | ||
| 1282 | }; | ||
| 1283 | |||
| 1284 | template <> struct applicator<FormattingFlags> { | ||
| 1285 | static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); } | ||
| 1286 | }; | ||
| 1287 | |||
| 1288 | template <> struct applicator<MiscFlags> { | ||
| 1289 | static void opt(MiscFlags MF, Option &O) { | ||
| 1290 | assert((MF != Grouping || O.ArgStr.size() == 1) && | ||
| 1291 | "cl::Grouping can only apply to single character Options."); | ||
| 1292 | O.setMiscFlag(MF); | ||
| 1293 |   } | ||
| 1294 | }; | ||
| 1295 | |||
| 1296 | // Apply modifiers to an option in a type safe way. | ||
| 1297 | template <class Opt, class Mod, class... Mods> | ||
| 1298 | void apply(Opt *O, const Mod &M, const Mods &... Ms) { | ||
| 1299 | applicator<Mod>::opt(M, *O); | ||
| 1300 | apply(O, Ms...); | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | template <class Opt, class Mod> void apply(Opt *O, const Mod &M) { | ||
| 1304 | applicator<Mod>::opt(M, *O); | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | //===----------------------------------------------------------------------===// | ||
| 1308 | // Default storage class definition: external storage.  This implementation | ||
| 1309 | // assumes the user will specify a variable to store the data into with the | ||
| 1310 | // cl::location(x) modifier. | ||
| 1311 | // | ||
| 1312 | template <class DataType, bool ExternalStorage, bool isClass> | ||
| 1313 | class opt_storage { | ||
| 1314 | DataType *Location = nullptr; // Where to store the object... | ||
| 1315 | OptionValue<DataType> Default; | ||
| 1316 | |||
| 1317 | void check_location() const { | ||
| 1318 | assert(Location && "cl::location(...) not specified for a command " | ||
| 1319 |                        "line option with external storage, " | ||
| 1320 | "or cl::init specified before cl::location()!!"); | ||
| 1321 |   } | ||
| 1322 | |||
| 1323 | public: | ||
| 1324 | opt_storage() = default; | ||
| 1325 | |||
| 1326 | bool setLocation(Option &O, DataType &L) { | ||
| 1327 | if (Location) | ||
| 1328 | return O.error("cl::location(x) specified more than once!"); | ||
| 1329 | Location = &L; | ||
| 1330 | Default = L; | ||
| 1331 | return false; | ||
| 1332 |   } | ||
| 1333 | |||
| 1334 | template <class T> void setValue(const T &V, bool initial = false) { | ||
| 1335 | check_location(); | ||
| 1336 | *Location = V; | ||
| 1337 | if (initial) | ||
| 1338 | Default = V; | ||
| 1339 |   } | ||
| 1340 | |||
| 1341 | DataType &getValue() { | ||
| 1342 | check_location(); | ||
| 1343 | return *Location; | ||
| 1344 |   } | ||
| 1345 | const DataType &getValue() const { | ||
| 1346 | check_location(); | ||
| 1347 | return *Location; | ||
| 1348 |   } | ||
| 1349 | |||
| 1350 | operator DataType() const { return this->getValue(); } | ||
| 1351 | |||
| 1352 | const OptionValue<DataType> &getDefault() const { return Default; } | ||
| 1353 | }; | ||
| 1354 | |||
| 1355 | // Define how to hold a class type object, such as a string.  Since we can | ||
| 1356 | // inherit from a class, we do so.  This makes us exactly compatible with the | ||
| 1357 | // object in all cases that it is used. | ||
| 1358 | // | ||
| 1359 | template <class DataType> | ||
| 1360 | class opt_storage<DataType, false, true> : public DataType { | ||
| 1361 | public: | ||
| 1362 | OptionValue<DataType> Default; | ||
| 1363 | |||
| 1364 | template <class T> void setValue(const T &V, bool initial = false) { | ||
| 1365 | DataType::operator=(V); | ||
| 1366 | if (initial) | ||
| 1367 | Default = V; | ||
| 1368 |   } | ||
| 1369 | |||
| 1370 | DataType &getValue() { return *this; } | ||
| 1371 | const DataType &getValue() const { return *this; } | ||
| 1372 | |||
| 1373 | const OptionValue<DataType> &getDefault() const { return Default; } | ||
| 1374 | }; | ||
| 1375 | |||
| 1376 | // Define a partial specialization to handle things we cannot inherit from.  In | ||
| 1377 | // this case, we store an instance through containment, and overload operators | ||
| 1378 | // to get at the value. | ||
| 1379 | // | ||
| 1380 | template <class DataType> class opt_storage<DataType, false, false> { | ||
| 1381 | public: | ||
| 1382 |   DataType Value; | ||
| 1383 | OptionValue<DataType> Default; | ||
| 1384 | |||
| 1385 |   // Make sure we initialize the value with the default constructor for the | ||
| 1386 |   // type. | ||
| 1387 | opt_storage() : Value(DataType()), Default() {} | ||
| 1388 | |||
| 1389 | template <class T> void setValue(const T &V, bool initial = false) { | ||
| 1390 | Value = V; | ||
| 1391 | if (initial) | ||
| 1392 | Default = V; | ||
| 1393 |   } | ||
| 1394 | DataType &getValue() { return Value; } | ||
| 1395 | DataType getValue() const { return Value; } | ||
| 1396 | |||
| 1397 | const OptionValue<DataType> &getDefault() const { return Default; } | ||
| 1398 | |||
| 1399 | operator DataType() const { return getValue(); } | ||
| 1400 | |||
| 1401 |   // If the datatype is a pointer, support -> on it. | ||
| 1402 | DataType operator->() const { return Value; } | ||
| 1403 | }; | ||
| 1404 | |||
| 1405 | //===----------------------------------------------------------------------===// | ||
| 1406 | // A scalar command line option. | ||
| 1407 | // | ||
| 1408 | template <class DataType, bool ExternalStorage = false, | ||
| 1409 | class ParserClass = parser<DataType>> | ||
| 1410 | class opt : public Option, | ||
| 1411 | public opt_storage<DataType, ExternalStorage, | ||
| 1412 | std::is_class<DataType>::value> { | ||
| 1413 |   ParserClass Parser; | ||
| 1414 | |||
| 1415 | bool handleOccurrence(unsigned pos, StringRef ArgName, | ||
| 1416 | StringRef Arg) override { | ||
| 1417 | typename ParserClass::parser_data_type Val = | ||
| 1418 | typename ParserClass::parser_data_type(); | ||
| 1419 | if (Parser.parse(*this, ArgName, Arg, Val)) | ||
| 1420 | return true; // Parse error! | ||
| 1421 | this->setValue(Val); | ||
| 1422 | this->setPosition(pos); | ||
| 1423 | Callback(Val); | ||
| 1424 | return false; | ||
| 1425 |   } | ||
| 1426 | |||
| 1427 | enum ValueExpected getValueExpectedFlagDefault() const override { | ||
| 1428 | return Parser.getValueExpectedFlagDefault(); | ||
| 1429 |   } | ||
| 1430 | |||
| 1431 | void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { | ||
| 1432 | return Parser.getExtraOptionNames(OptionNames); | ||
| 1433 |   } | ||
| 1434 | |||
| 1435 |   // Forward printing stuff to the parser... | ||
| 1436 | size_t getOptionWidth() const override { | ||
| 1437 | return Parser.getOptionWidth(*this); | ||
| 1438 |   } | ||
| 1439 | |||
| 1440 | void printOptionInfo(size_t GlobalWidth) const override { | ||
| 1441 | Parser.printOptionInfo(*this, GlobalWidth); | ||
| 1442 |   } | ||
| 1443 | |||
| 1444 | void printOptionValue(size_t GlobalWidth, bool Force) const override { | ||
| 1445 | if (Force || this->getDefault().compare(this->getValue())) { | ||
| 1446 | cl::printOptionDiff<ParserClass>(*this, Parser, this->getValue(), | ||
| 1447 | this->getDefault(), GlobalWidth); | ||
| 1448 |     } | ||
| 1449 |   } | ||
| 1450 | |||
| 1451 | template <class T, | ||
| 1452 | class = std::enable_if_t<std::is_assignable<T &, T>::value>> | ||
| 1453 | void setDefaultImpl() { | ||
| 1454 | const OptionValue<DataType> &V = this->getDefault(); | ||
| 1455 | if (V.hasValue()) | ||
| 1456 | this->setValue(V.getValue()); | ||
| 1457 |     else | ||
| 1458 | this->setValue(T()); | ||
| 1459 |   } | ||
| 1460 | |||
| 1461 | template <class T, | ||
| 1462 | class = std::enable_if_t<!std::is_assignable<T &, T>::value>> | ||
| 1463 | void setDefaultImpl(...) {} | ||
| 1464 | |||
| 1465 | void setDefault() override { setDefaultImpl<DataType>(); } | ||
| 1466 | |||
| 1467 | void done() { | ||
| 1468 | addArgument(); | ||
| 1469 | Parser.initialize(); | ||
| 1470 |   } | ||
| 1471 | |||
| 1472 | public: | ||
| 1473 |   // Command line options should not be copyable | ||
| 1474 | opt(const opt &) = delete; | ||
| 1475 | opt &operator=(const opt &) = delete; | ||
| 1476 | |||
| 1477 |   // setInitialValue - Used by the cl::init modifier... | ||
| 1478 | void setInitialValue(const DataType &V) { this->setValue(V, true); } | ||
| 1479 | |||
| 1480 | ParserClass &getParser() { return Parser; } | ||
| 1481 | |||
| 1482 | template <class T> DataType &operator=(const T &Val) { | ||
| 1483 | this->setValue(Val); | ||
| 1484 | Callback(Val); | ||
| 1485 | return this->getValue(); | ||
| 1486 |   } | ||
| 1487 | |||
| 1488 | template <class... Mods> | ||
| 1489 | explicit opt(const Mods &... Ms) | ||
| 1490 | : Option(llvm::cl::Optional, NotHidden), Parser(*this) { | ||
| 1491 | apply(this, Ms...); | ||
| 1492 | done(); | ||
| 1493 |   } | ||
| 1494 | |||
| 1495 | void setCallback( | ||
| 1496 | std::function<void(const typename ParserClass::parser_data_type &)> CB) { | ||
| 1497 | Callback = CB; | ||
| 1498 |   } | ||
| 1499 | |||
| 1500 | std::function<void(const typename ParserClass::parser_data_type &)> Callback = | ||
| 1501 | [](const typename ParserClass::parser_data_type &) {}; | ||
| 1502 | }; | ||
| 1503 | |||
| 1504 | extern template class opt<unsigned>; | ||
| 1505 | extern template class opt<int>; | ||
| 1506 | extern template class opt<std::string>; | ||
| 1507 | extern template class opt<char>; | ||
| 1508 | extern template class opt<bool>; | ||
| 1509 | |||
| 1510 | //===----------------------------------------------------------------------===// | ||
| 1511 | // Default storage class definition: external storage.  This implementation | ||
| 1512 | // assumes the user will specify a variable to store the data into with the | ||
| 1513 | // cl::location(x) modifier. | ||
| 1514 | // | ||
| 1515 | template <class DataType, class StorageClass> class list_storage { | ||
| 1516 | StorageClass *Location = nullptr; // Where to store the object... | ||
| 1517 | std::vector<OptionValue<DataType>> Default = | ||
| 1518 | std::vector<OptionValue<DataType>>(); | ||
| 1519 | bool DefaultAssigned = false; | ||
| 1520 | |||
| 1521 | public: | ||
| 1522 | list_storage() = default; | ||
| 1523 | |||
| 1524 | void clear() {} | ||
| 1525 | |||
| 1526 | bool setLocation(Option &O, StorageClass &L) { | ||
| 1527 | if (Location) | ||
| 1528 | return O.error("cl::location(x) specified more than once!"); | ||
| 1529 | Location = &L; | ||
| 1530 | return false; | ||
| 1531 |   } | ||
| 1532 | |||
| 1533 | template <class T> void addValue(const T &V, bool initial = false) { | ||
| 1534 | assert(Location != nullptr && | ||
| 1535 |            "cl::location(...) not specified for a command " | ||
| 1536 | "line option with external storage!"); | ||
| 1537 | Location->push_back(V); | ||
| 1538 | if (initial) | ||
| 1539 | Default.push_back(V); | ||
| 1540 |   } | ||
| 1541 | |||
| 1542 | const std::vector<OptionValue<DataType>> &getDefault() const { | ||
| 1543 | return Default; | ||
| 1544 |   } | ||
| 1545 | |||
| 1546 | void assignDefault() { DefaultAssigned = true; } | ||
| 1547 | void overwriteDefault() { DefaultAssigned = false; } | ||
| 1548 | bool isDefaultAssigned() { return DefaultAssigned; } | ||
| 1549 | }; | ||
| 1550 | |||
| 1551 | // Define how to hold a class type object, such as a string. | ||
| 1552 | // Originally this code inherited from std::vector. In transitioning to a new | ||
| 1553 | // API for command line options we should change this. The new implementation | ||
| 1554 | // of this list_storage specialization implements the minimum subset of the | ||
| 1555 | // std::vector API required for all the current clients. | ||
| 1556 | // | ||
| 1557 | // FIXME: Reduce this API to a more narrow subset of std::vector | ||
| 1558 | // | ||
| 1559 | template <class DataType> class list_storage<DataType, bool> { | ||
| 1560 | std::vector<DataType> Storage; | ||
| 1561 | std::vector<OptionValue<DataType>> Default; | ||
| 1562 | bool DefaultAssigned = false; | ||
| 1563 | |||
| 1564 | public: | ||
| 1565 | using iterator = typename std::vector<DataType>::iterator; | ||
| 1566 | |||
| 1567 | iterator begin() { return Storage.begin(); } | ||
| 1568 | iterator end() { return Storage.end(); } | ||
| 1569 | |||
| 1570 | using const_iterator = typename std::vector<DataType>::const_iterator; | ||
| 1571 | |||
| 1572 | const_iterator begin() const { return Storage.begin(); } | ||
| 1573 | const_iterator end() const { return Storage.end(); } | ||
| 1574 | |||
| 1575 | using size_type = typename std::vector<DataType>::size_type; | ||
| 1576 | |||
| 1577 | size_type size() const { return Storage.size(); } | ||
| 1578 | |||
| 1579 | bool empty() const { return Storage.empty(); } | ||
| 1580 | |||
| 1581 | void push_back(const DataType &value) { Storage.push_back(value); } | ||
| 1582 | void push_back(DataType &&value) { Storage.push_back(value); } | ||
| 1583 | |||
| 1584 | using reference = typename std::vector<DataType>::reference; | ||
| 1585 | using const_reference = typename std::vector<DataType>::const_reference; | ||
| 1586 | |||
| 1587 | reference operator[](size_type pos) { return Storage[pos]; } | ||
| 1588 | const_reference operator[](size_type pos) const { return Storage[pos]; } | ||
| 1589 | |||
| 1590 | void clear() { | ||
| 1591 | Storage.clear(); | ||
| 1592 |   } | ||
| 1593 | |||
| 1594 | iterator erase(const_iterator pos) { return Storage.erase(pos); } | ||
| 1595 | iterator erase(const_iterator first, const_iterator last) { | ||
| 1596 | return Storage.erase(first, last); | ||
| 1597 |   } | ||
| 1598 | |||
| 1599 | iterator erase(iterator pos) { return Storage.erase(pos); } | ||
| 1600 | iterator erase(iterator first, iterator last) { | ||
| 1601 | return Storage.erase(first, last); | ||
| 1602 |   } | ||
| 1603 | |||
| 1604 | iterator insert(const_iterator pos, const DataType &value) { | ||
| 1605 | return Storage.insert(pos, value); | ||
| 1606 |   } | ||
| 1607 | iterator insert(const_iterator pos, DataType &&value) { | ||
| 1608 | return Storage.insert(pos, value); | ||
| 1609 |   } | ||
| 1610 | |||
| 1611 | iterator insert(iterator pos, const DataType &value) { | ||
| 1612 | return Storage.insert(pos, value); | ||
| 1613 |   } | ||
| 1614 | iterator insert(iterator pos, DataType &&value) { | ||
| 1615 | return Storage.insert(pos, value); | ||
| 1616 |   } | ||
| 1617 | |||
| 1618 | reference front() { return Storage.front(); } | ||
| 1619 | const_reference front() const { return Storage.front(); } | ||
| 1620 | |||
| 1621 | operator std::vector<DataType> &() { return Storage; } | ||
| 1622 | operator ArrayRef<DataType>() const { return Storage; } | ||
| 1623 | std::vector<DataType> *operator&() { return &Storage; } | ||
| 1624 | const std::vector<DataType> *operator&() const { return &Storage; } | ||
| 1625 | |||
| 1626 | template <class T> void addValue(const T &V, bool initial = false) { | ||
| 1627 | Storage.push_back(V); | ||
| 1628 | if (initial) | ||
| 1629 | Default.push_back(OptionValue<DataType>(V)); | ||
| 1630 |   } | ||
| 1631 | |||
| 1632 | const std::vector<OptionValue<DataType>> &getDefault() const { | ||
| 1633 | return Default; | ||
| 1634 |   } | ||
| 1635 | |||
| 1636 | void assignDefault() { DefaultAssigned = true; } | ||
| 1637 | void overwriteDefault() { DefaultAssigned = false; } | ||
| 1638 | bool isDefaultAssigned() { return DefaultAssigned; } | ||
| 1639 | }; | ||
| 1640 | |||
| 1641 | //===----------------------------------------------------------------------===// | ||
| 1642 | // A list of command line options. | ||
| 1643 | // | ||
| 1644 | template <class DataType, class StorageClass = bool, | ||
| 1645 | class ParserClass = parser<DataType>> | ||
| 1646 | class list : public Option, public list_storage<DataType, StorageClass> { | ||
| 1647 | std::vector<unsigned> Positions; | ||
| 1648 |   ParserClass Parser; | ||
| 1649 | |||
| 1650 | enum ValueExpected getValueExpectedFlagDefault() const override { | ||
| 1651 | return Parser.getValueExpectedFlagDefault(); | ||
| 1652 |   } | ||
| 1653 | |||
| 1654 | void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { | ||
| 1655 | return Parser.getExtraOptionNames(OptionNames); | ||
| 1656 |   } | ||
| 1657 | |||
| 1658 | bool handleOccurrence(unsigned pos, StringRef ArgName, | ||
| 1659 | StringRef Arg) override { | ||
| 1660 | typename ParserClass::parser_data_type Val = | ||
| 1661 | typename ParserClass::parser_data_type(); | ||
| 1662 | if (list_storage<DataType, StorageClass>::isDefaultAssigned()) { | ||
| 1663 | clear(); | ||
| 1664 | list_storage<DataType, StorageClass>::overwriteDefault(); | ||
| 1665 |     } | ||
| 1666 | if (Parser.parse(*this, ArgName, Arg, Val)) | ||
| 1667 | return true; // Parse Error! | ||
| 1668 | list_storage<DataType, StorageClass>::addValue(Val); | ||
| 1669 | setPosition(pos); | ||
| 1670 | Positions.push_back(pos); | ||
| 1671 | Callback(Val); | ||
| 1672 | return false; | ||
| 1673 |   } | ||
| 1674 | |||
| 1675 |   // Forward printing stuff to the parser... | ||
| 1676 | size_t getOptionWidth() const override { | ||
| 1677 | return Parser.getOptionWidth(*this); | ||
| 1678 |   } | ||
| 1679 | |||
| 1680 | void printOptionInfo(size_t GlobalWidth) const override { | ||
| 1681 | Parser.printOptionInfo(*this, GlobalWidth); | ||
| 1682 |   } | ||
| 1683 | |||
| 1684 |   // Unimplemented: list options don't currently store their default value. | ||
| 1685 | void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { | ||
| 1686 |   } | ||
| 1687 | |||
| 1688 | void setDefault() override { | ||
| 1689 | Positions.clear(); | ||
| 1690 | list_storage<DataType, StorageClass>::clear(); | ||
| 1691 | for (auto &Val : list_storage<DataType, StorageClass>::getDefault()) | ||
| 1692 | list_storage<DataType, StorageClass>::addValue(Val.getValue()); | ||
| 1693 |   } | ||
| 1694 | |||
| 1695 | void done() { | ||
| 1696 | addArgument(); | ||
| 1697 | Parser.initialize(); | ||
| 1698 |   } | ||
| 1699 | |||
| 1700 | public: | ||
| 1701 |   // Command line options should not be copyable | ||
| 1702 | list(const list &) = delete; | ||
| 1703 | list &operator=(const list &) = delete; | ||
| 1704 | |||
| 1705 | ParserClass &getParser() { return Parser; } | ||
| 1706 | |||
| 1707 | unsigned getPosition(unsigned optnum) const { | ||
| 1708 | assert(optnum < this->size() && "Invalid option index"); | ||
| 1709 | return Positions[optnum]; | ||
| 1710 |   } | ||
| 1711 | |||
| 1712 | void clear() { | ||
| 1713 | Positions.clear(); | ||
| 1714 | list_storage<DataType, StorageClass>::clear(); | ||
| 1715 |   } | ||
| 1716 | |||
| 1717 |   // setInitialValues - Used by the cl::list_init modifier... | ||
| 1718 | void setInitialValues(ArrayRef<DataType> Vs) { | ||
| 1719 | assert(!(list_storage<DataType, StorageClass>::isDefaultAssigned()) && | ||
| 1720 | "Cannot have two default values"); | ||
| 1721 | list_storage<DataType, StorageClass>::assignDefault(); | ||
| 1722 | for (auto &Val : Vs) | ||
| 1723 | list_storage<DataType, StorageClass>::addValue(Val, true); | ||
| 1724 |   } | ||
| 1725 | |||
| 1726 | void setNumAdditionalVals(unsigned n) { Option::setNumAdditionalVals(n); } | ||
| 1727 | |||
| 1728 | template <class... Mods> | ||
| 1729 | explicit list(const Mods &... Ms) | ||
| 1730 | : Option(ZeroOrMore, NotHidden), Parser(*this) { | ||
| 1731 | apply(this, Ms...); | ||
| 1732 | done(); | ||
| 1733 |   } | ||
| 1734 | |||
| 1735 | void setCallback( | ||
| 1736 | std::function<void(const typename ParserClass::parser_data_type &)> CB) { | ||
| 1737 | Callback = CB; | ||
| 1738 |   } | ||
| 1739 | |||
| 1740 | std::function<void(const typename ParserClass::parser_data_type &)> Callback = | ||
| 1741 | [](const typename ParserClass::parser_data_type &) {}; | ||
| 1742 | }; | ||
| 1743 | |||
| 1744 | // Modifier to set the number of additional values. | ||
| 1745 | struct multi_val { | ||
| 1746 | unsigned AdditionalVals; | ||
| 1747 | explicit multi_val(unsigned N) : AdditionalVals(N) {} | ||
| 1748 | |||
| 1749 | template <typename D, typename S, typename P> | ||
| 1750 | void apply(list<D, S, P> &L) const { | ||
| 1751 | L.setNumAdditionalVals(AdditionalVals); | ||
| 1752 |   } | ||
| 1753 | }; | ||
| 1754 | |||
| 1755 | //===----------------------------------------------------------------------===// | ||
| 1756 | // Default storage class definition: external storage.  This implementation | ||
| 1757 | // assumes the user will specify a variable to store the data into with the | ||
| 1758 | // cl::location(x) modifier. | ||
| 1759 | // | ||
| 1760 | template <class DataType, class StorageClass> class bits_storage { | ||
| 1761 | unsigned *Location = nullptr; // Where to store the bits... | ||
| 1762 | |||
| 1763 | template <class T> static unsigned Bit(const T &V) { | ||
| 1764 | unsigned BitPos = static_cast<unsigned>(V); | ||
| 1765 | assert(BitPos < sizeof(unsigned) * CHAR_BIT && | ||
| 1766 | "enum exceeds width of bit vector!"); | ||
| 1767 | return 1 << BitPos; | ||
| 1768 |   } | ||
| 1769 | |||
| 1770 | public: | ||
| 1771 | bits_storage() = default; | ||
| 1772 | |||
| 1773 | bool setLocation(Option &O, unsigned &L) { | ||
| 1774 | if (Location) | ||
| 1775 | return O.error("cl::location(x) specified more than once!"); | ||
| 1776 | Location = &L; | ||
| 1777 | return false; | ||
| 1778 |   } | ||
| 1779 | |||
| 1780 | template <class T> void addValue(const T &V) { | ||
| 1781 | assert(Location != nullptr && | ||
| 1782 |            "cl::location(...) not specified for a command " | ||
| 1783 | "line option with external storage!"); | ||
| 1784 | *Location |= Bit(V); | ||
| 1785 |   } | ||
| 1786 | |||
| 1787 | unsigned getBits() { return *Location; } | ||
| 1788 | |||
| 1789 | void clear() { | ||
| 1790 | if (Location) | ||
| 1791 | *Location = 0; | ||
| 1792 |   } | ||
| 1793 | |||
| 1794 | template <class T> bool isSet(const T &V) { | ||
| 1795 | return (*Location & Bit(V)) != 0; | ||
| 1796 |   } | ||
| 1797 | }; | ||
| 1798 | |||
| 1799 | // Define how to hold bits.  Since we can inherit from a class, we do so. | ||
| 1800 | // This makes us exactly compatible with the bits in all cases that it is used. | ||
| 1801 | // | ||
| 1802 | template <class DataType> class bits_storage<DataType, bool> { | ||
| 1803 | unsigned Bits{0}; // Where to store the bits... | ||
| 1804 | |||
| 1805 | template <class T> static unsigned Bit(const T &V) { | ||
| 1806 | unsigned BitPos = static_cast<unsigned>(V); | ||
| 1807 | assert(BitPos < sizeof(unsigned) * CHAR_BIT && | ||
| 1808 | "enum exceeds width of bit vector!"); | ||
| 1809 | return 1 << BitPos; | ||
| 1810 |   } | ||
| 1811 | |||
| 1812 | public: | ||
| 1813 | template <class T> void addValue(const T &V) { Bits |= Bit(V); } | ||
| 1814 | |||
| 1815 | unsigned getBits() { return Bits; } | ||
| 1816 | |||
| 1817 | void clear() { Bits = 0; } | ||
| 1818 | |||
| 1819 | template <class T> bool isSet(const T &V) { return (Bits & Bit(V)) != 0; } | ||
| 1820 | }; | ||
| 1821 | |||
| 1822 | //===----------------------------------------------------------------------===// | ||
| 1823 | // A bit vector of command options. | ||
| 1824 | // | ||
| 1825 | template <class DataType, class Storage = bool, | ||
| 1826 | class ParserClass = parser<DataType>> | ||
| 1827 | class bits : public Option, public bits_storage<DataType, Storage> { | ||
| 1828 | std::vector<unsigned> Positions; | ||
| 1829 |   ParserClass Parser; | ||
| 1830 | |||
| 1831 | enum ValueExpected getValueExpectedFlagDefault() const override { | ||
| 1832 | return Parser.getValueExpectedFlagDefault(); | ||
| 1833 |   } | ||
| 1834 | |||
| 1835 | void getExtraOptionNames(SmallVectorImpl<StringRef> &OptionNames) override { | ||
| 1836 | return Parser.getExtraOptionNames(OptionNames); | ||
| 1837 |   } | ||
| 1838 | |||
| 1839 | bool handleOccurrence(unsigned pos, StringRef ArgName, | ||
| 1840 | StringRef Arg) override { | ||
| 1841 | typename ParserClass::parser_data_type Val = | ||
| 1842 | typename ParserClass::parser_data_type(); | ||
| 1843 | if (Parser.parse(*this, ArgName, Arg, Val)) | ||
| 1844 | return true; // Parse Error! | ||
| 1845 | this->addValue(Val); | ||
| 1846 | setPosition(pos); | ||
| 1847 | Positions.push_back(pos); | ||
| 1848 | Callback(Val); | ||
| 1849 | return false; | ||
| 1850 |   } | ||
| 1851 | |||
| 1852 |   // Forward printing stuff to the parser... | ||
| 1853 | size_t getOptionWidth() const override { | ||
| 1854 | return Parser.getOptionWidth(*this); | ||
| 1855 |   } | ||
| 1856 | |||
| 1857 | void printOptionInfo(size_t GlobalWidth) const override { | ||
| 1858 | Parser.printOptionInfo(*this, GlobalWidth); | ||
| 1859 |   } | ||
| 1860 | |||
| 1861 |   // Unimplemented: bits options don't currently store their default values. | ||
| 1862 | void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { | ||
| 1863 |   } | ||
| 1864 | |||
| 1865 | void setDefault() override { bits_storage<DataType, Storage>::clear(); } | ||
| 1866 | |||
| 1867 | void done() { | ||
| 1868 | addArgument(); | ||
| 1869 | Parser.initialize(); | ||
| 1870 |   } | ||
| 1871 | |||
| 1872 | public: | ||
| 1873 |   // Command line options should not be copyable | ||
| 1874 | bits(const bits &) = delete; | ||
| 1875 | bits &operator=(const bits &) = delete; | ||
| 1876 | |||
| 1877 | ParserClass &getParser() { return Parser; } | ||
| 1878 | |||
| 1879 | unsigned getPosition(unsigned optnum) const { | ||
| 1880 | assert(optnum < this->size() && "Invalid option index"); | ||
| 1881 | return Positions[optnum]; | ||
| 1882 |   } | ||
| 1883 | |||
| 1884 | template <class... Mods> | ||
| 1885 | explicit bits(const Mods &... Ms) | ||
| 1886 | : Option(ZeroOrMore, NotHidden), Parser(*this) { | ||
| 1887 | apply(this, Ms...); | ||
| 1888 | done(); | ||
| 1889 |   } | ||
| 1890 | |||
| 1891 | void setCallback( | ||
| 1892 | std::function<void(const typename ParserClass::parser_data_type &)> CB) { | ||
| 1893 | Callback = CB; | ||
| 1894 |   } | ||
| 1895 | |||
| 1896 | std::function<void(const typename ParserClass::parser_data_type &)> Callback = | ||
| 1897 | [](const typename ParserClass::parser_data_type &) {}; | ||
| 1898 | }; | ||
| 1899 | |||
| 1900 | //===----------------------------------------------------------------------===// | ||
| 1901 | // Aliased command line option (alias this name to a preexisting name) | ||
| 1902 | // | ||
| 1903 | |||
| 1904 | class alias : public Option { | ||
| 1905 | Option *AliasFor; | ||
| 1906 | |||
| 1907 | bool handleOccurrence(unsigned pos, StringRef /*ArgName*/, | ||
| 1908 | StringRef Arg) override { | ||
| 1909 | return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg); | ||
| 1910 |   } | ||
| 1911 | |||
| 1912 | bool addOccurrence(unsigned pos, StringRef /*ArgName*/, StringRef Value, | ||
| 1913 | bool MultiArg = false) override { | ||
| 1914 | return AliasFor->addOccurrence(pos, AliasFor->ArgStr, Value, MultiArg); | ||
| 1915 |   } | ||
| 1916 | |||
| 1917 |   // Handle printing stuff... | ||
| 1918 | size_t getOptionWidth() const override; | ||
| 1919 | void printOptionInfo(size_t GlobalWidth) const override; | ||
| 1920 | |||
| 1921 |   // Aliases do not need to print their values. | ||
| 1922 | void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override { | ||
| 1923 |   } | ||
| 1924 | |||
| 1925 | void setDefault() override { AliasFor->setDefault(); } | ||
| 1926 | |||
| 1927 | ValueExpected getValueExpectedFlagDefault() const override { | ||
| 1928 | return AliasFor->getValueExpectedFlag(); | ||
| 1929 |   } | ||
| 1930 | |||
| 1931 | void done() { | ||
| 1932 | if (!hasArgStr()) | ||
| 1933 | error("cl::alias must have argument name specified!"); | ||
| 1934 | if (!AliasFor) | ||
| 1935 | error("cl::alias must have an cl::aliasopt(option) specified!"); | ||
| 1936 | if (!Subs.empty()) | ||
| 1937 | error("cl::alias must not have cl::sub(), aliased option's cl::sub() will be used!"); | ||
| 1938 | Subs = AliasFor->Subs; | ||
| 1939 | Categories = AliasFor->Categories; | ||
| 1940 | addArgument(); | ||
| 1941 |   } | ||
| 1942 | |||
| 1943 | public: | ||
| 1944 |   // Command line options should not be copyable | ||
| 1945 | alias(const alias &) = delete; | ||
| 1946 | alias &operator=(const alias &) = delete; | ||
| 1947 | |||
| 1948 | void setAliasFor(Option &O) { | ||
| 1949 | if (AliasFor) | ||
| 1950 | error("cl::alias must only have one cl::aliasopt(...) specified!"); | ||
| 1951 | AliasFor = &O; | ||
| 1952 |   } | ||
| 1953 | |||
| 1954 | template <class... Mods> | ||
| 1955 | explicit alias(const Mods &... Ms) | ||
| 1956 | : Option(Optional, Hidden), AliasFor(nullptr) { | ||
| 1957 | apply(this, Ms...); | ||
| 1958 | done(); | ||
| 1959 |   } | ||
| 1960 | }; | ||
| 1961 | |||
| 1962 | // Modifier to set the option an alias aliases. | ||
| 1963 | struct aliasopt { | ||
| 1964 | Option &Opt; | ||
| 1965 | |||
| 1966 | explicit aliasopt(Option &O) : Opt(O) {} | ||
| 1967 | |||
| 1968 | void apply(alias &A) const { A.setAliasFor(Opt); } | ||
| 1969 | }; | ||
| 1970 | |||
| 1971 | // Provide additional help at the end of the normal help output. All occurrences | ||
| 1972 | // of cl::extrahelp will be accumulated and printed to stderr at the end of the | ||
| 1973 | // regular help, just before exit is called. | ||
| 1974 | struct extrahelp { | ||
| 1975 |   StringRef morehelp; | ||
| 1976 | |||
| 1977 | explicit extrahelp(StringRef help); | ||
| 1978 | }; | ||
| 1979 | |||
| 1980 | void PrintVersionMessage(); | ||
| 1981 | |||
| 1982 | /// This function just prints the help message, exactly the same way as if the | ||
| 1983 | /// -help or -help-hidden option had been given on the command line. | ||
| 1984 | /// | ||
| 1985 | /// \param Hidden if true will print hidden options | ||
| 1986 | /// \param Categorized if true print options in categories | ||
| 1987 | void PrintHelpMessage(bool Hidden = false, bool Categorized = false); | ||
| 1988 | |||
| 1989 | //===----------------------------------------------------------------------===// | ||
| 1990 | // Public interface for accessing registered options. | ||
| 1991 | // | ||
| 1992 | |||
| 1993 | /// Use this to get a StringMap to all registered named options | ||
| 1994 | /// (e.g. -help). | ||
| 1995 | /// | ||
| 1996 | /// \return A reference to the StringMap used by the cl APIs to parse options. | ||
| 1997 | /// | ||
| 1998 | /// Access to unnamed arguments (i.e. positional) are not provided because | ||
| 1999 | /// it is expected that the client already has access to these. | ||
| 2000 | /// | ||
| 2001 | /// Typical usage: | ||
| 2002 | /// \code | ||
| 2003 | /// main(int argc,char* argv[]) { | ||
| 2004 | /// StringMap<llvm::cl::Option*> &opts = llvm::cl::getRegisteredOptions(); | ||
| 2005 | /// assert(opts.count("help") == 1) | ||
| 2006 | /// opts["help"]->setDescription("Show alphabetical help information") | ||
| 2007 | /// // More code | ||
| 2008 | /// llvm::cl::ParseCommandLineOptions(argc,argv); | ||
| 2009 | /// //More code | ||
| 2010 | /// } | ||
| 2011 | /// \endcode | ||
| 2012 | /// | ||
| 2013 | /// This interface is useful for modifying options in libraries that are out of | ||
| 2014 | /// the control of the client. The options should be modified before calling | ||
| 2015 | /// llvm::cl::ParseCommandLineOptions(). | ||
| 2016 | /// | ||
| 2017 | /// Hopefully this API can be deprecated soon. Any situation where options need | ||
| 2018 | /// to be modified by tools or libraries should be handled by sane APIs rather | ||
| 2019 | /// than just handing around a global list. | ||
| 2020 | StringMap<Option *> & | ||
| 2021 | getRegisteredOptions(SubCommand &Sub = SubCommand::getTopLevel()); | ||
| 2022 | |||
| 2023 | /// Use this to get all registered SubCommands from the provided parser. | ||
| 2024 | /// | ||
| 2025 | /// \return A range of all SubCommand pointers registered with the parser. | ||
| 2026 | /// | ||
| 2027 | /// Typical usage: | ||
| 2028 | /// \code | ||
| 2029 | /// main(int argc, char* argv[]) { | ||
| 2030 | ///   llvm::cl::ParseCommandLineOptions(argc, argv); | ||
| 2031 | ///   for (auto* S : llvm::cl::getRegisteredSubcommands()) { | ||
| 2032 | ///     if (*S) { | ||
| 2033 | ///       std::cout << "Executing subcommand: " << S->getName() << std::endl; | ||
| 2034 | ///       // Execute some function based on the name... | ||
| 2035 | ///     } | ||
| 2036 | ///   } | ||
| 2037 | /// } | ||
| 2038 | /// \endcode | ||
| 2039 | /// | ||
| 2040 | /// This interface is useful for defining subcommands in libraries and | ||
| 2041 | /// the dispatch from a single point (like in the main function). | ||
| 2042 | iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator> | ||
| 2043 | getRegisteredSubcommands(); | ||
| 2044 | |||
| 2045 | //===----------------------------------------------------------------------===// | ||
| 2046 | // Standalone command line processing utilities. | ||
| 2047 | // | ||
| 2048 | |||
| 2049 | /// Tokenizes a command line that can contain escapes and quotes. | ||
| 2050 | // | ||
| 2051 | /// The quoting rules match those used by GCC and other tools that use | ||
| 2052 | /// libiberty's buildargv() or expandargv() utilities, and do not match bash. | ||
| 2053 | /// They differ from buildargv() on treatment of backslashes that do not escape | ||
| 2054 | /// a special character to make it possible to accept most Windows file paths. | ||
| 2055 | /// | ||
| 2056 | /// \param [in] Source The string to be split on whitespace with quotes. | ||
| 2057 | /// \param [in] Saver Delegates back to the caller for saving parsed strings. | ||
| 2058 | /// \param [in] MarkEOLs true if tokenizing a response file and you want end of | ||
| 2059 | /// lines and end of the response file to be marked with a nullptr string. | ||
| 2060 | /// \param [out] NewArgv All parsed strings are appended to NewArgv. | ||
| 2061 | void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, | ||
| 2062 | SmallVectorImpl<const char *> &NewArgv, | ||
| 2063 | bool MarkEOLs = false); | ||
| 2064 | |||
| 2065 | /// Tokenizes a string of Windows command line arguments, which may contain | ||
| 2066 | /// quotes and escaped quotes. | ||
| 2067 | /// | ||
| 2068 | /// See MSDN docs for CommandLineToArgvW for information on the quoting rules. | ||
| 2069 | /// http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx | ||
| 2070 | /// | ||
| 2071 | /// For handling a full Windows command line including the executable name at | ||
| 2072 | /// the start, see TokenizeWindowsCommandLineFull below. | ||
| 2073 | /// | ||
| 2074 | /// \param [in] Source The string to be split on whitespace with quotes. | ||
| 2075 | /// \param [in] Saver Delegates back to the caller for saving parsed strings. | ||
| 2076 | /// \param [in] MarkEOLs true if tokenizing a response file and you want end of | ||
| 2077 | /// lines and end of the response file to be marked with a nullptr string. | ||
| 2078 | /// \param [out] NewArgv All parsed strings are appended to NewArgv. | ||
| 2079 | void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, | ||
| 2080 | SmallVectorImpl<const char *> &NewArgv, | ||
| 2081 | bool MarkEOLs = false); | ||
| 2082 | |||
| 2083 | /// Tokenizes a Windows command line while attempting to avoid copies. If no | ||
| 2084 | /// quoting or escaping was used, this produces substrings of the original | ||
| 2085 | /// string. If a token requires unquoting, it will be allocated with the | ||
| 2086 | /// StringSaver. | ||
| 2087 | void TokenizeWindowsCommandLineNoCopy(StringRef Source, StringSaver &Saver, | ||
| 2088 | SmallVectorImpl<StringRef> &NewArgv); | ||
| 2089 | |||
| 2090 | /// Tokenizes a Windows full command line, including command name at the start. | ||
| 2091 | /// | ||
| 2092 | /// This uses the same syntax rules as TokenizeWindowsCommandLine for all but | ||
| 2093 | /// the first token. But the first token is expected to be parsed as the | ||
| 2094 | /// executable file name in the way CreateProcess would do it, rather than the | ||
| 2095 | /// way the C library startup code would do it: CreateProcess does not consider | ||
| 2096 | /// that \ is ever an escape character (because " is not a valid filename char, | ||
| 2097 | /// hence there's never a need to escape it to be used literally). | ||
| 2098 | /// | ||
| 2099 | /// Parameters are the same as for TokenizeWindowsCommandLine. In particular, | ||
| 2100 | /// if you set MarkEOLs = true, then the first word of every line will be | ||
| 2101 | /// parsed using the special rules for command names, making this function | ||
| 2102 | /// suitable for parsing a file full of commands to execute. | ||
| 2103 | void TokenizeWindowsCommandLineFull(StringRef Source, StringSaver &Saver, | ||
| 2104 | SmallVectorImpl<const char *> &NewArgv, | ||
| 2105 | bool MarkEOLs = false); | ||
| 2106 | |||
| 2107 | /// String tokenization function type.  Should be compatible with either | ||
| 2108 | /// Windows or Unix command line tokenizers. | ||
| 2109 | using TokenizerCallback = void (*)(StringRef Source, StringSaver &Saver, | ||
| 2110 | SmallVectorImpl<const char *> &NewArgv, | ||
| 2111 | bool MarkEOLs); | ||
| 2112 | |||
| 2113 | /// Tokenizes content of configuration file. | ||
| 2114 | /// | ||
| 2115 | /// \param [in] Source The string representing content of config file. | ||
| 2116 | /// \param [in] Saver Delegates back to the caller for saving parsed strings. | ||
| 2117 | /// \param [out] NewArgv All parsed strings are appended to NewArgv. | ||
| 2118 | /// \param [in] MarkEOLs Added for compatibility with TokenizerCallback. | ||
| 2119 | /// | ||
| 2120 | /// It works like TokenizeGNUCommandLine with ability to skip comment lines. | ||
| 2121 | /// | ||
| 2122 | void tokenizeConfigFile(StringRef Source, StringSaver &Saver, | ||
| 2123 | SmallVectorImpl<const char *> &NewArgv, | ||
| 2124 | bool MarkEOLs = false); | ||
| 2125 | |||
| 2126 | /// Contains options that control response file expansion. | ||
| 2127 | class ExpansionContext { | ||
| 2128 |   /// Provides persistent storage for parsed strings. | ||
| 2129 |   StringSaver Saver; | ||
| 2130 | |||
| 2131 |   /// Tokenization strategy. Typically Unix or Windows. | ||
| 2132 |   TokenizerCallback Tokenizer; | ||
| 2133 | |||
| 2134 |   /// File system used for all file access when running the expansion. | ||
| 2135 | vfs::FileSystem *FS; | ||
| 2136 | |||
| 2137 |   /// Path used to resolve relative rsp files. If empty, the file system | ||
| 2138 |   /// current directory is used instead. | ||
| 2139 |   StringRef CurrentDir; | ||
| 2140 | |||
| 2141 |   /// Directories used for search of config files. | ||
| 2142 | ArrayRef<StringRef> SearchDirs; | ||
| 2143 | |||
| 2144 |   /// True if names of nested response files must be resolved relative to | ||
| 2145 |   /// including file. | ||
| 2146 | bool RelativeNames = false; | ||
| 2147 | |||
| 2148 |   /// If true, mark end of lines and the end of the response file with nullptrs | ||
| 2149 |   /// in the Argv vector. | ||
| 2150 | bool MarkEOLs = false; | ||
| 2151 | |||
| 2152 |   /// If true, body of config file is expanded. | ||
| 2153 | bool InConfigFile = false; | ||
| 2154 | |||
| 2155 | llvm::Error expandResponseFile(StringRef FName, | ||
| 2156 | SmallVectorImpl<const char *> &NewArgv); | ||
| 2157 | |||
| 2158 | public: | ||
| 2159 | ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T); | ||
| 2160 | |||
| 2161 | ExpansionContext &setMarkEOLs(bool X) { | ||
| 2162 | MarkEOLs = X; | ||
| 2163 | return *this; | ||
| 2164 |   } | ||
| 2165 | |||
| 2166 | ExpansionContext &setRelativeNames(bool X) { | ||
| 2167 | RelativeNames = X; | ||
| 2168 | return *this; | ||
| 2169 |   } | ||
| 2170 | |||
| 2171 | ExpansionContext &setCurrentDir(StringRef X) { | ||
| 2172 | CurrentDir = X; | ||
| 2173 | return *this; | ||
| 2174 |   } | ||
| 2175 | |||
| 2176 | ExpansionContext &setSearchDirs(ArrayRef<StringRef> X) { | ||
| 2177 | SearchDirs = X; | ||
| 2178 | return *this; | ||
| 2179 |   } | ||
| 2180 | |||
| 2181 | ExpansionContext &setVFS(vfs::FileSystem *X) { | ||
| 2182 | FS = X; | ||
| 2183 | return *this; | ||
| 2184 |   } | ||
| 2185 | |||
| 2186 |   /// Looks for the specified configuration file. | ||
| 2187 |   /// | ||
| 2188 |   /// \param[in]  FileName Name of the file to search for. | ||
| 2189 |   /// \param[out] FilePath File absolute path, if it was found. | ||
| 2190 |   /// \return True if file was found. | ||
| 2191 |   /// | ||
| 2192 |   /// If the specified file name contains a directory separator, it is searched | ||
| 2193 |   /// for by its absolute path. Otherwise looks for file sequentially in | ||
| 2194 |   /// directories specified by SearchDirs field. | ||
| 2195 | bool findConfigFile(StringRef FileName, SmallVectorImpl<char> &FilePath); | ||
| 2196 | |||
| 2197 |   /// Reads command line options from the given configuration file. | ||
| 2198 |   /// | ||
| 2199 |   /// \param [in] CfgFile Path to configuration file. | ||
| 2200 |   /// \param [out] Argv Array to which the read options are added. | ||
| 2201 |   /// \return true if the file was successfully read. | ||
| 2202 |   /// | ||
| 2203 |   /// It reads content of the specified file, tokenizes it and expands "@file" | ||
| 2204 |   /// commands resolving file names in them relative to the directory where | ||
| 2205 |   /// CfgFilename resides. It also expands "<CFGDIR>" to the base path of the | ||
| 2206 |   /// current config file. | ||
| 2207 | Error readConfigFile(StringRef CfgFile, SmallVectorImpl<const char *> &Argv); | ||
| 2208 | |||
| 2209 |   /// Expands constructs "@file" in the provided array of arguments recursively. | ||
| 2210 | Error expandResponseFiles(SmallVectorImpl<const char *> &Argv); | ||
| 2211 | }; | ||
| 2212 | |||
| 2213 | /// A convenience helper which concatenates the options specified by the | ||
| 2214 | /// environment variable EnvVar and command line options, then expands | ||
| 2215 | /// response files recursively. | ||
| 2216 | /// \return true if all @files were expanded successfully or there were none. | ||
| 2217 | bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar, | ||
| 2218 | SmallVectorImpl<const char *> &NewArgv); | ||
| 2219 | |||
| 2220 | /// A convenience helper which supports the typical use case of expansion | ||
| 2221 | /// function call. | ||
| 2222 | bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, | ||
| 2223 | SmallVectorImpl<const char *> &Argv); | ||
| 2224 | |||
| 2225 | /// A convenience helper which concatenates the options specified by the | ||
| 2226 | /// environment variable EnvVar and command line options, then expands response | ||
| 2227 | /// files recursively. The tokenizer is a predefined GNU or Windows one. | ||
| 2228 | /// \return true if all @files were expanded successfully or there were none. | ||
| 2229 | bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar, | ||
| 2230 |                          StringSaver &Saver, | ||
| 2231 | SmallVectorImpl<const char *> &NewArgv); | ||
| 2232 | |||
| 2233 | /// Mark all options not part of this category as cl::ReallyHidden. | ||
| 2234 | /// | ||
| 2235 | /// \param Category the category of options to keep displaying | ||
| 2236 | /// | ||
| 2237 | /// Some tools (like clang-format) like to be able to hide all options that are | ||
| 2238 | /// not specific to the tool. This function allows a tool to specify a single | ||
| 2239 | /// option category to display in the -help output. | ||
| 2240 | void HideUnrelatedOptions(cl::OptionCategory &Category, | ||
| 2241 | SubCommand &Sub = SubCommand::getTopLevel()); | ||
| 2242 | |||
| 2243 | /// Mark all options not part of the categories as cl::ReallyHidden. | ||
| 2244 | /// | ||
| 2245 | /// \param Categories the categories of options to keep displaying. | ||
| 2246 | /// | ||
| 2247 | /// Some tools (like clang-format) like to be able to hide all options that are | ||
| 2248 | /// not specific to the tool. This function allows a tool to specify a single | ||
| 2249 | /// option category to display in the -help output. | ||
| 2250 | void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories, | ||
| 2251 | SubCommand &Sub = SubCommand::getTopLevel()); | ||
| 2252 | |||
| 2253 | /// Reset all command line options to a state that looks as if they have | ||
| 2254 | /// never appeared on the command line.  This is useful for being able to parse | ||
| 2255 | /// a command line multiple times (especially useful for writing tests). | ||
| 2256 | void ResetAllOptionOccurrences(); | ||
| 2257 | |||
| 2258 | /// Reset the command line parser back to its initial state.  This | ||
| 2259 | /// removes | ||
| 2260 | /// all options, categories, and subcommands and returns the parser to a state | ||
| 2261 | /// where no options are supported. | ||
| 2262 | void ResetCommandLineParser(); | ||
| 2263 | |||
| 2264 | /// Parses `Arg` into the option handler `Handler`. | ||
| 2265 | bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i); | ||
| 2266 | |||
| 2267 | } // end namespace cl | ||
| 2268 | |||
| 2269 | } // end namespace llvm | ||
| 2270 | |||
| 2271 | #endif // LLVM_SUPPORT_COMMANDLINE_H |