37 explicit OptNameLess(
const StringTable &StrTable,
39 : StrTable(&StrTable), PrefixesTable(PrefixesTable) {}
42 inline bool operator()(
const OptTable::Info &
A,
43 const OptTable::Info &
B)
const {
48 B.getName(*StrTable, PrefixesTable)))
52 A.appendPrefixes(*StrTable, PrefixesTable, APrefixes);
53 B.appendPrefixes(*StrTable, PrefixesTable, BPrefixes);
62 "Unexpected classes for options with same name.");
68 inline bool operator()(
const OptTable::Info &
I, StringRef Name)
const {
83 : StrTable(&StrTable), PrefixesTable(PrefixesTable),
84 OptionInfos(OptionInfos), IgnoreCase(IgnoreCase),
85 SubCommands(SubCommands), SubCommandIDsTable(SubCommandIDsTable) {
91 unsigned Kind = getInfo(i + 1).Kind;
93 assert(!InputOptionID &&
"Cannot have multiple input options!");
94 InputOptionID = getInfo(i + 1).ID;
96 assert(!UnknownOptionID &&
"Cannot have multiple unknown options!");
97 UnknownOptionID = getInfo(i + 1).ID;
112 "Special options should be defined first!");
117 if (!(OptNameLess(StrTable, PrefixesTable)(getInfo(i), getInfo(i + 1)))) {
131 for (
char C : Prefix)
140 unsigned id = Opt.
getID();
142 return Option(
nullptr,
nullptr);
144 return Option(&getInfo(
id),
this);
151 if (
Arg.starts_with(Prefix))
161 StringRef Name =
I->getName(StrTable, PrefixesTable);
162 for (
auto PrefixOffset :
I->getPrefixOffsets(PrefixesTable)) {
163 StringRef Prefix = StrTable[PrefixOffset];
164 if (Str.starts_with(Prefix)) {
169 return Prefix.size() + Name.size();
179 StringRef Name = In.getName(StrTable, PrefixesTable);
180 if (
Option.consume_back(Name))
181 for (
auto PrefixOffset : In.getPrefixOffsets(PrefixesTable))
182 if (
Option == StrTable[PrefixOffset])
190std::vector<std::string>
194 const Info &In = OptionInfos[
I];
201 std::vector<std::string> Result;
203 if (Val.starts_with(
Arg) &&
Arg != Val)
204 Result.push_back(std::string(Val));
210std::vector<std::string>
212 unsigned int DisableFlags)
const {
213 std::vector<std::string> Ret;
215 const Info &In = OptionInfos[
I];
216 if (In.hasNoPrefix() || (!In.HelpText && !In.GroupID))
218 if (!(In.Visibility & VisibilityMask))
220 if (In.Flags & DisableFlags)
223 StringRef Name = In.getName(*StrTable, PrefixesTable);
224 for (
auto PrefixOffset : In.getPrefixOffsets(PrefixesTable)) {
225 StringRef Prefix = (*StrTable)[PrefixOffset];
226 std::string S = (
Twine(Prefix) + Name +
"\t").str();
238 unsigned MinimumLength,
239 unsigned MaximumDistance)
const {
240 return internalFindNearest(
241 Option, NearestString, MinimumLength, MaximumDistance,
242 [VisibilityMask](
const Info &CandidateInfo) {
243 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
248 unsigned FlagsToInclude,
unsigned FlagsToExclude,
249 unsigned MinimumLength,
250 unsigned MaximumDistance)
const {
251 return internalFindNearest(
252 Option, NearestString, MinimumLength, MaximumDistance,
253 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
254 if (FlagsToInclude && !(CandidateInfo.
Flags & FlagsToInclude))
256 if (CandidateInfo.
Flags & FlagsToExclude)
262unsigned OptTable::internalFindNearest(
264 unsigned MaximumDistance,
265 std::function<
bool(
const Info &)> ExcludeOption)
const {
268 unsigned BestDistance =
269 MaximumDistance == UINT_MAX ? UINT_MAX : MaximumDistance + 1;
273 for (
const Info &CandidateInfo :
275 StringRef CandidateName = CandidateInfo.getName(*StrTable, PrefixesTable);
280 if (CandidateName.
size() < MinimumLength)
284 if (ExcludeOption(CandidateInfo))
289 if (CandidateInfo.hasNoPrefix())
296 bool CandidateHasDelimiter =
Last ==
'=' ||
Last ==
':';
298 if (CandidateHasDelimiter) {
299 std::tie(NormalizedName, RHS) =
Option.split(
Last);
301 NormalizedName +=
Last;
308 for (
auto CandidatePrefixOffset :
309 CandidateInfo.getPrefixOffsets(PrefixesTable)) {
310 StringRef CandidatePrefix = (*StrTable)[CandidatePrefixOffset];
315 size_t CandidateSize = CandidatePrefix.
size() + CandidateName.
size(),
316 NormalizedSize = NormalizedName.
size();
317 size_t AbsDiff = CandidateSize > NormalizedSize
318 ? CandidateSize - NormalizedSize
319 : NormalizedSize - CandidateSize;
320 if (AbsDiff > BestDistance) {
323 Candidate = CandidatePrefix;
324 Candidate += CandidateName;
326 NormalizedName,
true,
328 if (
RHS.empty() && CandidateHasDelimiter) {
337 if (Distance < BestDistance) {
338 BestDistance = Distance;
339 NearestString = (Candidate +
RHS).str();
350std::unique_ptr<Arg> OptTable::parseOneArgGrouped(
InputArgList &Args,
351 unsigned &Index)
const {
354 const char *CStr =
Args.getArgString(Index);
357 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++, CStr);
359 const Info *End = OptionInfos.data() + OptionInfos.size();
363 OptNameLess(*StrTable, PrefixesTable));
365 unsigned Prev =
Index;
370 matchOption(*StrTable, PrefixesTable, Start, Str, IgnoreCase);
374 Option Opt(Start,
this);
375 if (std::unique_ptr<Arg>
A =
376 Opt.accept(Args, StringRef(
Args.getArgString(Index), ArgSize),
394 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
397 if (std::unique_ptr<Arg>
A = Opt.accept(
398 Args, Str.substr(0, 2),
true, Index)) {
399 Args.replaceArgString(Index, Twine(
'-') + Str.substr(2));
407 CStr =
Args.MakeArgString(Str.substr(0, 2));
408 Args.replaceArgString(Index, Twine(
'-') + Str.substr(2));
409 return std::make_unique<Arg>(
getOption(UnknownOptionID), CStr, Index, CStr);
412 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++, CStr);
417 return internalParseOneArg(Args, Index, [VisibilityMask](
const Option &Opt) {
423 unsigned FlagsToInclude,
424 unsigned FlagsToExclude)
const {
425 return internalParseOneArg(
426 Args, Index, [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
427 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
429 if (Opt.
hasFlag(FlagsToExclude))
435std::unique_ptr<Arg> OptTable::internalParseOneArg(
436 const ArgList &Args,
unsigned &Index,
437 std::function<
bool(
const Option &)> ExcludeOption)
const {
438 unsigned Prev = Index;
439 StringRef Str = Args.getArgString(Index);
444 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
448 const Info *End = OptionInfos.data() + OptionInfos.size();
453 std::lower_bound(Start, End, Name, OptNameLess(*StrTable, PrefixesTable));
463 for (; Start != End; ++Start) {
464 unsigned ArgSize = 0;
466 for (; Start != End; ++Start)
468 matchOption(*StrTable, PrefixesTable, Start, Str, IgnoreCase)))
475 if (ExcludeOption(Opt))
479 if (std::unique_ptr<Arg>
A =
480 Opt.accept(Args,
StringRef(Args.getArgString(Index), ArgSize),
492 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
495 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
500 unsigned &MissingArgIndex,
501 unsigned &MissingArgCount,
503 return internalParseArgs(
504 Args, MissingArgIndex, MissingArgCount,
505 [VisibilityMask](
const Option &Opt) {
511 unsigned &MissingArgIndex,
512 unsigned &MissingArgCount,
513 unsigned FlagsToInclude,
514 unsigned FlagsToExclude)
const {
515 return internalParseArgs(
516 Args, MissingArgIndex, MissingArgCount,
517 [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
518 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
520 if (Opt.
hasFlag(FlagsToExclude))
528 unsigned &MissingArgCount,
529 std::function<
bool(
const Option &)> ExcludeOption)
const {
534 MissingArgIndex = MissingArgCount = 0;
535 unsigned Index = 0, End = ArgArr.
size();
536 while (Index < End) {
538 if (Args.getArgString(Index) ==
nullptr) {
543 StringRef Str = Args.getArgString(Index);
551 if (DashDashParsing && Str ==
"--") {
552 while (++Index < End) {
553 Args.append(
new Arg(
getOption(InputOptionID), Str, Index,
554 Args.getArgString(Index)));
559 unsigned Prev =
Index;
560 std::unique_ptr<Arg>
A = GroupedShortOptions
561 ? parseOneArgGrouped(Args, Index)
562 : internalParseOneArg(
Args,
Index, ExcludeOption);
563 assert((Index > Prev || GroupedShortOptions) &&
564 "Parser failed to consume argument.");
568 assert(Index >= End &&
"Unexpected parser error.");
569 assert(Index - Prev - 1 &&
"No missing arguments!");
570 MissingArgIndex = Prev;
571 MissingArgCount =
Index - Prev - 1;
575 Args.append(
A.release());
583 std::function<
void(
StringRef)> ErrorFn)
const {
592 ErrorFn((
Twine(Args.getArgString(MAI)) +
": missing argument").str());
598 std::string
Spelling =
A->getAsString(Args);
600 ErrorFn(
"unknown argument '" +
Spelling +
"'");
602 ErrorFn(
"unknown argument '" +
Spelling +
"', did you mean '" + Nearest +
610 std::string Name = O.getPrefixedName().str();
613 switch (O.getKind()) {
625 for (
unsigned i=0, e=O.getNumArgs(); i< e; ++i) {
661 std::vector<OptionInfo> &OptionHelp) {
662 OS << Title <<
":\n";
665 unsigned OptionFieldWidth = 0;
666 for (
const OptionInfo &Opt : OptionHelp) {
668 unsigned Length = Opt.Name.size();
670 OptionFieldWidth = std::max(OptionFieldWidth,
Length);
673 const unsigned InitialPad = 2;
674 for (
const OptionInfo &Opt : OptionHelp) {
675 const std::string &
Option = Opt.Name;
676 int Pad = OptionFieldWidth + InitialPad;
677 int FirstLinePad = OptionFieldWidth - int(
Option.size());
681 if (FirstLinePad < 0) {
683 FirstLinePad = OptionFieldWidth + InitialPad;
688 Opt.HelpText.split(Lines,
'\n');
689 assert(Lines.size() &&
"Expected at least the first line in the help text");
690 auto *LinesIt = Lines.begin();
691 OS.
indent(FirstLinePad + 1) << *LinesIt <<
'\n';
692 while (Lines.end() != ++LinesIt)
693 OS.
indent(Pad + 1) << *LinesIt <<
'\n';
716 bool ShowHidden,
bool ShowAllAliases,
719 return internalPrintHelp(
720 OS, Usage, Title,
SubCommand, ShowHidden, ShowAllAliases,
721 [VisibilityMask](
const Info &CandidateInfo) ->
bool {
722 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
728 unsigned FlagsToInclude,
unsigned FlagsToExclude,
729 bool ShowAllAliases)
const {
730 bool ShowHidden = !(FlagsToExclude &
HelpHidden);
732 return internalPrintHelp(
733 OS, Usage, Title, {}, ShowHidden, ShowAllAliases,
734 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
735 if (FlagsToInclude && !(CandidateInfo.Flags & FlagsToInclude))
737 if (CandidateInfo.Flags & FlagsToExclude)
744void OptTable::internalPrintHelp(
746 bool ShowHidden,
bool ShowAllAliases,
747 std::function<
bool(
const Info &)> ExcludeOption,
749 OS <<
"OVERVIEW: " << Title <<
"\n\n";
753 std::map<std::string, std::vector<OptionInfo>> GroupedOptionHelp;
756 SubCommands, [&](
const auto &
C) {
return SubCommand ==
C.Name; });
757 if (!SubCommand.
empty()) {
758 assert(ActiveSubCommand != SubCommands.end() &&
759 "Not a valid registered subcommand.");
760 OS << ActiveSubCommand->HelpText <<
"\n\n";
762 OS <<
"USAGE: " << ActiveSubCommand->Usage <<
"\n\n";
764 OS <<
"USAGE: " << Usage <<
"\n\n";
765 if (SubCommands.size() > 1) {
766 OS <<
"SUBCOMMANDS:\n\n";
767 for (
const auto &
C : SubCommands)
768 OS <<
C.Name <<
" - " <<
C.HelpText <<
"\n";
773 auto DoesOptionBelongToSubcommand = [&](
const Info &CandidateInfo) {
776 ArrayRef<unsigned> SubCommandIDs =
777 CandidateInfo.getSubCommandIDs(SubCommandIDsTable);
782 if (SubCommandIDs.
empty())
793 unsigned ActiveSubCommandID = ActiveSubCommand - &SubCommands[0];
804 const Info &CandidateInfo = getInfo(Id);
808 if (ExcludeOption(CandidateInfo))
811 if (!DoesOptionBelongToSubcommand(CandidateInfo))
817 if (!HelpText && ShowAllAliases) {
823 if (HelpText && (strlen(HelpText) != 0)) {
826 GroupedOptionHelp[HelpGroup].push_back({OptName, HelpText});
830 for (
auto& OptionGroup : GroupedOptionHelp) {
831 if (OptionGroup.first != GroupedOptionHelp.begin()->first)
844 :
OptTable(StrTable, PrefixesTable, OptionInfos, IgnoreCase, SubCommands,
845 SubCommandIDsTable) {
847 std::set<StringRef> TmpPrefixesUnion;
850 TmpPrefixesUnion.insert(StrTable[PrefixOffset]);
851 PrefixesUnion.append(TmpPrefixesUnion.begin(), TmpPrefixesUnion.end());
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Defines the llvm::Arg class for parsed arguments.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static const char * getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id)
static unsigned matchOption(const StringTable &StrTable, ArrayRef< StringTable::Offset > PrefixesTable, const OptTable::Info *I, StringRef Str, bool IgnoreCase)
static bool optionMatches(const StringTable &StrTable, ArrayRef< StringTable::Offset > PrefixesTable, const OptTable::Info &In, StringRef Option)
static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id)
static bool isInput(const ArrayRef< StringRef > &Prefixes, StringRef Arg)
static void PrintHelpOptionList(raw_ostream &OS, StringRef Title, std::vector< OptionInfo > &OptionHelp)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
LLVM_ABI bool starts_with_insensitive(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
LLVM_ABI unsigned edit_distance(StringRef Other, bool AllowReplacements=true, unsigned MaxEditDistance=0) const
Determine the edit distance between this string and another string.
char back() const
Get the last character in the string.
constexpr size_t size() const
Get the string size.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
A table of densely packed, null-terminated strings indexed by offset.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
ArgList - Ordered collection of driver arguments.
A concrete instance of a particular driver option.
LLVM_ABI GenericOptTable(const StringTable &StrTable, ArrayRef< StringTable::Offset > PrefixesTable, ArrayRef< Info > OptionInfos, bool IgnoreCase=false, ArrayRef< SubCommand > SubCommands={}, ArrayRef< unsigned > SubCommandIDsTable={})
OptSpecifier - Wrapper class for abstracting references to option IDs.
Provide access to the Option info table.
void buildPrefixChars()
Build (or rebuild) the PrefixChars member.
InputArgList parseArgs(int Argc, char *const *Argv, OptSpecifier Unknown, StringSaver &Saver, std::function< void(StringRef)> ErrorFn) const
A convenience helper which handles optional initial options populated from an environment variable,...
unsigned getOptionKind(OptSpecifier id) const
Get the kind of the given option.
unsigned FirstSearchableIndex
The index of the first option which can be parsed (i.e., is not a special option like 'input' or 'unk...
const char * getOptionMetaVar(OptSpecifier id) const
Get the meta-variable name to use when describing this options values in the help text.
std::unique_ptr< Arg > ParseOneArg(const ArgList &Args, unsigned &Index, Visibility VisibilityMask=Visibility()) const
Parse a single argument; returning the new argument and updating Index.
unsigned findNearest(StringRef Option, std::string &NearestString, Visibility VisibilityMask=Visibility(), unsigned MinimumLength=4, unsigned MaximumDistance=UINT_MAX) const
Find the OptTable option that most closely matches the given string.
SmallVector< StringRef > PrefixesUnion
The union of all option prefixes.
const Option getOption(OptSpecifier Opt) const
Get the given Opt's Option instance, lazily creating it if necessary.
const char * getOptionHelpText(OptSpecifier id) const
Get the help text to use to describe this option.
OptTable(const StringTable &StrTable, ArrayRef< StringTable::Offset > PrefixesTable, ArrayRef< Info > OptionInfos, bool IgnoreCase=false, ArrayRef< SubCommand > SubCommands={}, ArrayRef< unsigned > SubCommandIDsTable={})
Initialize OptTable using Tablegen'ed OptionInfos.
unsigned getOptionGroupID(OptSpecifier id) const
Get the group id for the given option.
std::vector< std::string > suggestValueCompletions(StringRef Option, StringRef Arg) const
Find possible value for given flags.
InputArgList ParseArgs(ArrayRef< const char * > Args, unsigned &MissingArgIndex, unsigned &MissingArgCount, Visibility VisibilityMask=Visibility()) const
Parse an list of arguments into an InputArgList.
SmallString< 8 > PrefixChars
The union of the first element of all option prefixes.
void printHelp(raw_ostream &OS, const char *Usage, const char *Title, bool ShowHidden=false, bool ShowAllAliases=false, Visibility VisibilityMask=Visibility(), StringRef SubCommand={}) const
Render the help text for an option table.
unsigned getNumOptions() const
Return the total number of option classes.
std::vector< std::string > findByPrefix(StringRef Cur, Visibility VisibilityMask, unsigned int DisableFlags) const
Find flags from OptTable which starts with Cur.
Option - Abstract representation for a single form of driver argument.
const Option getAlias() const
LLVM_ABI void dump() const
bool hasFlag(unsigned Val) const
Test if this option has the flag Val.
@ RemainingArgsJoinedClass
bool hasVisibilityFlag(unsigned Val) const
Test if this option has the visibility flag Val.
Helper for overload resolution while transitioning from FlagsToInclude/FlagsToExclude APIs to Visibil...
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
LLVM_ABI bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar, SmallVectorImpl< const char * > &NewArgv)
A convenience helper which concatenates the options specified by the environment variable EnvVar and ...
This is an optimization pass for GlobalISel generic memory operations.
@ Unknown
Not known to have no common set bits.
LLVM_ABI int StrCmpOptionName(StringRef A, StringRef B, bool FallbackCaseSensitive=true)
LLVM_ABI int StrCmpOptionPrefixes(ArrayRef< StringRef > APrefixes, ArrayRef< StringRef > BPrefixes)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
ArrayRef(const T &OneElt) -> ArrayRef< T >
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Entry for a single option instance in the option data table.
ArrayRef< StringTable::Offset > getPrefixOffsets(ArrayRef< StringTable::Offset > PrefixesTable) const
Represents a subcommand and its options in the option table.