35 explicit OptNameLess(
const StringTable &StrTable,
37 : StrTable(&StrTable), PrefixesTable(PrefixesTable) {}
40 inline bool operator()(
const OptTable::Info &
A,
41 const OptTable::Info &
B)
const {
46 B.getName(*StrTable, PrefixesTable)))
50 A.appendPrefixes(*StrTable, PrefixesTable, APrefixes);
51 B.appendPrefixes(*StrTable, PrefixesTable, BPrefixes);
60 "Unexpected classes for options with same name.");
66 inline bool operator()(
const OptTable::Info &
I, StringRef Name)
const {
77 : StrTable(
T.StrTable), PrefixesTable(
T.PrefixesTable),
78 OptionInfos(
T.Infos), InfoExtrasTable(
T.InfoExtras),
79 IgnoreCase(IgnoreCase), SubCommands(
T.SubCommands),
80 SubCommandIDsTable(
T.SubCommandIDs),
81 HelpTextVariantsTable(
T.HelpTextVariants) {
83 for (
unsigned I = 0, E = PrefixesTable.size();
I != E;) {
84 unsigned Size = PrefixesTable[I++].value();
85 for (unsigned J = 0; J != Size; ++J) {
86 StringRef Prefix = StrTable[PrefixesTable[I++]];
87 if (is_contained(PrefixesUnion, Prefix))
89 PrefixesUnion.push_back(Prefix);
91 if (!is_contained(PrefixChars, C))
92 PrefixChars.push_back(C);
97 for (
unsigned i = 0, e = getNumOptions(); i != e; ++i) {
98 unsigned Kind = getInfo(i + 1).Kind;
100 assert(!InputOptionID &&
"Cannot have multiple input options!");
101 InputOptionID = i + 1;
103 assert(!UnknownOptionID &&
"Cannot have multiple unknown options!");
104 UnknownOptionID = i + 1;
106 FirstSearchableIndex = i;
110 assert(FirstSearchableIndex != 0 &&
"No searchable options?");
115 for (
unsigned i = FirstSearchableIndex, e = getNumOptions(); i !=
e; ++i) {
119 "Special options should be defined first!");
123 for (
unsigned i = FirstSearchableIndex + 1, e = getNumOptions(); i !=
e; ++i){
124 if (!(OptNameLess(StrTable, PrefixesTable)(getInfo(i), getInfo(i + 1)))) {
126 getOption(i + 1).dump();
136 unsigned id = Opt.
getID();
138 return Option(
nullptr,
nullptr);
140 return Option(&getInfo(
id),
this);
147 if (
Arg.starts_with(Prefix))
157 StringRef Name =
I->getName(StrTable, PrefixesTable);
158 for (
auto PrefixOffset :
I->getPrefixOffsets(PrefixesTable)) {
159 StringRef Prefix = StrTable[PrefixOffset];
160 if (Str.starts_with(Prefix)) {
165 return Prefix.size() + Name.size();
175 StringRef Name = In.getName(StrTable, PrefixesTable);
176 if (
Option.consume_back(Name))
177 for (
auto PrefixOffset : In.getPrefixOffsets(PrefixesTable))
178 if (
Option == StrTable[PrefixOffset])
186std::vector<std::string>
189 for (
size_t I = FirstSearchableIndex, E = OptionInfos.size();
I < E;
I++) {
190 const Info &In = OptionInfos[
I];
198 Values.split(Candidates,
",", -1,
false);
200 std::vector<std::string> Result;
202 if (Val.starts_with(
Arg) &&
Arg != Val)
203 Result.push_back(std::string(Val));
209std::vector<std::string>
211 unsigned int DisableFlags)
const {
212 std::vector<std::string> Ret;
213 for (
size_t I = FirstSearchableIndex, E = OptionInfos.size();
I < E;
I++) {
214 const Info &In = OptionInfos[
I];
215 if (In.hasNoPrefix() || (!In.hasHelpText() && !In.GroupID))
217 if (!(In.Visibility & VisibilityMask))
219 if (In.Flags & DisableFlags)
222 StringRef Name = In.getName(StrTable, PrefixesTable);
223 for (
auto PrefixOffset : In.getPrefixOffsets(PrefixesTable)) {
224 StringRef Prefix = StrTable[PrefixOffset];
225 std::string S = (
Twine(Prefix) + Name +
"\t").str();
226 S += StrTable[In.HelpTextOffset];
236 unsigned MinimumLength,
237 unsigned MaximumDistance)
const {
238 return internalFindNearest(
239 Option, NearestString, MinimumLength, MaximumDistance,
240 [VisibilityMask](
const Info &CandidateInfo) {
241 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
246 unsigned FlagsToInclude,
unsigned FlagsToExclude,
247 unsigned MinimumLength,
248 unsigned MaximumDistance)
const {
249 return internalFindNearest(
250 Option, NearestString, MinimumLength, MaximumDistance,
251 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
252 if (FlagsToInclude && !(CandidateInfo.
Flags & FlagsToInclude))
254 if (CandidateInfo.
Flags & FlagsToExclude)
260unsigned OptTable::internalFindNearest(
262 unsigned MaximumDistance,
263 std::function<
bool(
const Info &)> ExcludeOption)
const {
266 unsigned BestDistance =
267 MaximumDistance == UINT_MAX ? UINT_MAX : MaximumDistance + 1;
271 for (
const Info &CandidateInfo :
273 StringRef CandidateName = CandidateInfo.getName(StrTable, PrefixesTable);
278 if (CandidateName.
size() < MinimumLength)
282 if (ExcludeOption(CandidateInfo))
287 if (CandidateInfo.hasNoPrefix())
294 bool CandidateHasDelimiter =
Last ==
'=' ||
Last ==
':';
296 if (CandidateHasDelimiter) {
297 std::tie(NormalizedName, RHS) =
Option.split(
Last);
299 NormalizedName +=
Last;
306 for (
auto CandidatePrefixOffset :
307 CandidateInfo.getPrefixOffsets(PrefixesTable)) {
308 StringRef CandidatePrefix = StrTable[CandidatePrefixOffset];
313 size_t CandidateSize = CandidatePrefix.
size() + CandidateName.
size(),
314 NormalizedSize = NormalizedName.
size();
315 size_t AbsDiff = CandidateSize > NormalizedSize
316 ? CandidateSize - NormalizedSize
317 : NormalizedSize - CandidateSize;
318 if (AbsDiff > BestDistance) {
321 Candidate = CandidatePrefix;
322 Candidate += CandidateName;
324 NormalizedName,
true,
326 if (
RHS.empty() && CandidateHasDelimiter) {
335 if (Distance < BestDistance) {
336 BestDistance = Distance;
337 NearestString = (Candidate +
RHS).str();
348std::unique_ptr<Arg> OptTable::parseOneArgGrouped(
InputArgList &Args,
349 unsigned &Index)
const {
352 const char *CStr =
Args.getArgString(Index);
354 if (
isInput(PrefixesUnion, Str))
355 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++, CStr);
357 const Info *End = OptionInfos.data() + OptionInfos.size();
358 StringRef
Name = Str.ltrim(PrefixChars);
360 std::lower_bound(OptionInfos.data() + FirstSearchableIndex, End, Name,
361 OptNameLess(StrTable, PrefixesTable));
363 unsigned Prev =
Index;
368 matchOption(StrTable, PrefixesTable, Start, Str, IgnoreCase);
372 Option Opt(Start,
this);
373 if (std::unique_ptr<Arg>
A =
374 Opt.accept(Args, StringRef(
Args.getArgString(Index), ArgSize),
392 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
395 if (std::unique_ptr<Arg>
A = Opt.accept(
396 Args, Str.substr(0, 2),
true, Index)) {
397 Args.replaceArgString(Index, Twine(
'-') + Str.substr(2));
405 CStr =
Args.MakeArgString(Str.substr(0, 2));
406 Args.replaceArgString(Index, Twine(
'-') + Str.substr(2));
407 return std::make_unique<Arg>(
getOption(UnknownOptionID), CStr, Index, CStr);
410 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++, CStr);
415 return internalParseOneArg(Args, Index, [VisibilityMask](
const Option &Opt) {
421 unsigned FlagsToInclude,
422 unsigned FlagsToExclude)
const {
423 return internalParseOneArg(
424 Args, Index, [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
425 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
427 if (Opt.
hasFlag(FlagsToExclude))
433std::unique_ptr<Arg> OptTable::internalParseOneArg(
434 const ArgList &Args,
unsigned &Index,
435 std::function<
bool(
const Option &)> ExcludeOption)
const {
436 unsigned Prev = Index;
437 StringRef Str = Args.getArgString(Index);
441 if (
isInput(PrefixesUnion, Str))
442 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
445 const Info *Start = OptionInfos.data() + FirstSearchableIndex;
446 const Info *End = OptionInfos.data() + OptionInfos.size();
451 std::lower_bound(Start, End, Name, OptNameLess(StrTable, PrefixesTable));
461 for (; Start != End; ++Start) {
462 unsigned ArgSize = 0;
464 for (; Start != End; ++Start)
466 matchOption(StrTable, PrefixesTable, Start, Str, IgnoreCase)))
473 if (ExcludeOption(Opt))
477 if (std::unique_ptr<Arg>
A =
478 Opt.accept(Args,
StringRef(Args.getArgString(Index), ArgSize),
490 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
493 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
498 unsigned &MissingArgIndex,
499 unsigned &MissingArgCount,
501 return internalParseArgs(
502 Args, MissingArgIndex, MissingArgCount,
503 [VisibilityMask](
const Option &Opt) {
509 unsigned &MissingArgIndex,
510 unsigned &MissingArgCount,
511 unsigned FlagsToInclude,
512 unsigned FlagsToExclude)
const {
513 return internalParseArgs(
514 Args, MissingArgIndex, MissingArgCount,
515 [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
516 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
518 if (Opt.
hasFlag(FlagsToExclude))
526 unsigned &MissingArgCount,
527 std::function<
bool(
const Option &)> ExcludeOption)
const {
532 MissingArgIndex = MissingArgCount = 0;
533 unsigned Index = 0, End = ArgArr.
size();
534 while (Index < End) {
536 if (Args.getArgString(Index) ==
nullptr) {
541 StringRef Str = Args.getArgString(Index);
549 if (DashDashParsing && Str ==
"--") {
550 while (++Index < End) {
551 Args.append(
new Arg(
getOption(InputOptionID), Str, Index,
552 Args.getArgString(Index)));
557 unsigned Prev =
Index;
558 std::unique_ptr<Arg>
A = GroupedShortOptions
559 ? parseOneArgGrouped(Args, Index)
560 : internalParseOneArg(
Args,
Index, ExcludeOption);
561 assert((Index > Prev || GroupedShortOptions) &&
562 "Parser failed to consume argument.");
566 assert(Index >= End &&
"Unexpected parser error.");
567 assert(Index - Prev - 1 &&
"No missing arguments!");
568 MissingArgIndex = Prev;
569 MissingArgCount =
Index - Prev - 1;
573 Args.append(
A.release());
581 std::function<
void(
StringRef)> ErrorFn)
const {
590 ErrorFn((
Twine(Args.getArgString(MAI)) +
": missing argument").str());
596 std::string
Spelling =
A->getAsString(Args);
598 ErrorFn(
"unknown argument '" +
Spelling +
"'");
600 ErrorFn(
"unknown argument '" +
Spelling +
"', did you mean '" + Nearest +
608 std::string Name = O.getPrefixedName().str();
611 switch (O.getKind()) {
617 !MetaVarName.
empty()) {
623 for (
unsigned i=0, e=O.getNumArgs(); i< e; ++i) {
659 std::vector<OptionInfo> &OptionHelp) {
660 OS << Title <<
":\n";
663 unsigned OptionFieldWidth = 0;
664 for (
const OptionInfo &Opt : OptionHelp) {
666 unsigned Length = Opt.Name.size();
668 OptionFieldWidth = std::max(OptionFieldWidth,
Length);
671 const unsigned InitialPad = 2;
672 for (
const OptionInfo &Opt : OptionHelp) {
673 const std::string &
Option = Opt.Name;
674 int Pad = OptionFieldWidth + InitialPad;
675 int FirstLinePad = OptionFieldWidth - int(
Option.size());
679 if (FirstLinePad < 0) {
681 FirstLinePad = OptionFieldWidth + InitialPad;
686 Opt.HelpText.split(Lines,
'\n');
687 assert(Lines.size() &&
"Expected at least the first line in the help text");
688 auto *LinesIt = Lines.begin();
689 OS.
indent(FirstLinePad + 1) << *LinesIt <<
'\n';
690 while (Lines.end() != ++LinesIt)
691 OS.
indent(Pad + 1) << *LinesIt <<
'\n';
714 bool ShowHidden,
bool ShowAllAliases,
717 return internalPrintHelp(
718 OS, Usage, Title,
SubCommand, ShowHidden, ShowAllAliases,
719 [VisibilityMask](
const Info &CandidateInfo) ->
bool {
720 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
726 unsigned FlagsToInclude,
unsigned FlagsToExclude,
727 bool ShowAllAliases)
const {
728 bool ShowHidden = !(FlagsToExclude &
HelpHidden);
730 return internalPrintHelp(
731 OS, Usage, Title, {}, ShowHidden, ShowAllAliases,
732 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
733 if (FlagsToInclude && !(CandidateInfo.Flags & FlagsToInclude))
735 if (CandidateInfo.Flags & FlagsToExclude)
742void OptTable::internalPrintHelp(
744 bool ShowHidden,
bool ShowAllAliases,
745 std::function<
bool(
const Info &)> ExcludeOption,
747 OS <<
"OVERVIEW: " << Title <<
"\n\n";
751 std::map<StringRef, std::vector<OptionInfo>> GroupedOptionHelp;
754 SubCommands, [&](
const auto &
C) {
return SubCommand ==
C.Name; });
755 if (!SubCommand.
empty()) {
756 assert(ActiveSubCommand != SubCommands.end() &&
757 "Not a valid registered subcommand.");
758 OS << ActiveSubCommand->HelpText <<
"\n\n";
760 OS <<
"USAGE: " << ActiveSubCommand->Usage <<
"\n\n";
762 OS <<
"USAGE: " << Usage <<
"\n\n";
763 if (SubCommands.size() > 1) {
764 OS <<
"SUBCOMMANDS:\n\n";
765 for (
const auto &
C : SubCommands)
766 OS <<
C.Name <<
" - " <<
C.HelpText <<
"\n";
771 auto DoesOptionBelongToSubcommand = [&](
const Info &CandidateInfo) {
774 ArrayRef<unsigned> SubCommandIDs = getSubCommandIDs(CandidateInfo);
779 if (SubCommandIDs.
empty())
790 unsigned ActiveSubCommandID = ActiveSubCommand - &SubCommands[0];
801 const Info &CandidateInfo = getInfo(Id);
805 if (ExcludeOption(CandidateInfo))
808 if (!DoesOptionBelongToSubcommand(CandidateInfo))
813 StringTable::Offset HelpTextOffset =
814 getHelpTextOffset(CandidateInfo, VisibilityMask);
815 if (!HelpTextOffset.
value() && ShowAllAliases) {
819 getHelpTextOffset(getInfo(Alias.
getID()), VisibilityMask);
822 if (StringRef HelpText = StrTable[HelpTextOffset]; !HelpText.empty()) {
825 GroupedOptionHelp[HelpGroup].push_back({OptName, HelpText});
829 for (
auto& OptionGroup : GroupedOptionHelp) {
830 if (OptionGroup.first != GroupedOptionHelp.begin()->first)
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 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 StringRef getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id)
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.
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.
constexpr unsigned value() const
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.
OptSpecifier - Wrapper class for abstracting references to option IDs.
Provide access to the Option info table.
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.
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.
const Option getOption(OptSpecifier Opt) const
Get the given Opt's Option instance, lazily creating it if necessary.
unsigned getOptionGroupID(OptSpecifier id) const
Get the group id for the given option.
StringRef getOptionMetaVar(OptSpecifier id) const
Get the meta-variable name to use when describing this options values in the help text.
OptTable(const Tables &Tables, bool IgnoreCase=false)
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.
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.
StringRef getOptionHelpText(OptSpecifier id) const
Get the help text to use to describe this option.
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
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.
RelativeUniformCounterPtr Values
@ 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.
unsigned short Visibility
Represents a subcommand and its options in the option table.
The tables TableGen emits for an option set under OPTTABLE_CODE.