40 : StrTable(StrTable), PrefixesTable(PrefixesTable) {}
49 B.getName(StrTable, PrefixesTable)))
53 A.appendPrefixes(StrTable, PrefixesTable, APrefixes);
54 B.appendPrefixes(StrTable, PrefixesTable, BPrefixes);
63 "Unexpected classes for options with same name.");
81 : StrTable(StrTable), PrefixesTable(PrefixesTable),
82 OptionInfos(OptionInfos), IgnoreCase(IgnoreCase) {
88 unsigned Kind = getInfo(i + 1).
Kind;
90 assert(!InputOptionID &&
"Cannot have multiple input options!");
91 InputOptionID = getInfo(i + 1).
ID;
93 assert(!UnknownOptionID &&
"Cannot have multiple unknown options!");
94 UnknownOptionID = getInfo(i + 1).
ID;
109 "Special options should be defined first!");
114 if (!(OptNameLess(StrTable, PrefixesTable)(getInfo(i), getInfo(i + 1)))) {
128 for (
char C : Prefix)
137 unsigned id = Opt.
getID();
139 return Option(
nullptr,
nullptr);
141 return Option(&getInfo(
id),
this);
148 if (
Arg.starts_with(Prefix))
159 for (
unsigned PrefixOffset :
I->getPrefixOffsets(PrefixesTable)) {
160 StringRef Prefix = &StrTable[PrefixOffset];
161 if (Str.starts_with(Prefix)) {
162 StringRef Rest = Str.substr(Prefix.size());
166 return Prefix.size() +
Name.size();
178 for (
unsigned PrefixOffset : In.getPrefixOffsets(PrefixesTable))
179 if (
Option == &StrTable[PrefixOffset])
187std::vector<std::string>
191 const Info &In = OptionInfos[
I];
198 std::vector<std::string> Result;
200 if (Val.starts_with(
Arg) &&
Arg != Val)
201 Result.push_back(std::string(Val));
207std::vector<std::string>
209 unsigned int DisableFlags)
const {
210 std::vector<std::string> Ret;
212 const Info &In = OptionInfos[
I];
213 if (In.hasNoPrefix() || (!In.HelpText && !In.GroupID))
215 if (!(In.Visibility & VisibilityMask))
217 if (In.Flags & DisableFlags)
221 for (
unsigned PrefixOffset : In.getPrefixOffsets(PrefixesTable)) {
222 StringRef Prefix = &StrTable[PrefixOffset];
223 std::string S = (
Twine(Prefix) +
Name +
"\t").str();
235 unsigned MinimumLength,
236 unsigned MaximumDistance)
const {
237 return internalFindNearest(
238 Option, NearestString, MinimumLength, MaximumDistance,
239 [VisibilityMask](
const Info &CandidateInfo) {
240 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
245 unsigned FlagsToInclude,
unsigned FlagsToExclude,
246 unsigned MinimumLength,
247 unsigned MaximumDistance)
const {
248 return internalFindNearest(
249 Option, NearestString, MinimumLength, MaximumDistance,
250 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
251 if (FlagsToInclude && !(CandidateInfo.
Flags & FlagsToInclude))
253 if (CandidateInfo.
Flags & FlagsToExclude)
259unsigned OptTable::internalFindNearest(
261 unsigned MaximumDistance,
262 std::function<
bool(
const Info &)> ExcludeOption)
const {
267 unsigned BestDistance =
268 MaximumDistance == UINT_MAX ? UINT_MAX : MaximumDistance + 1;
272 for (
const Info &CandidateInfo :
274 StringRef CandidateName = CandidateInfo.getName(StrTable, PrefixesTable);
279 if (CandidateName.
size() < MinimumLength)
283 if (ExcludeOption(CandidateInfo))
288 if (CandidateInfo.hasNoPrefix())
295 bool CandidateHasDelimiter =
Last ==
'=' ||
Last ==
':';
297 if (CandidateHasDelimiter) {
298 std::tie(NormalizedName, RHS) =
Option.split(
Last);
300 NormalizedName +=
Last;
307 for (
unsigned CandidatePrefixOffset :
308 CandidateInfo.getPrefixOffsets(PrefixesTable)) {
309 StringRef CandidatePrefix = &StrTable[CandidatePrefixOffset];
314 size_t CandidateSize = CandidatePrefix.
size() + CandidateName.
size(),
315 NormalizedSize = NormalizedName.
size();
316 size_t AbsDiff = CandidateSize > NormalizedSize
317 ? CandidateSize - NormalizedSize
318 : NormalizedSize - CandidateSize;
319 if (AbsDiff > BestDistance) {
322 Candidate = CandidatePrefix;
323 Candidate += CandidateName;
325 NormalizedName,
true,
327 if (
RHS.empty() && CandidateHasDelimiter) {
336 if (Distance < BestDistance) {
337 BestDistance = Distance;
338 NearestString = (Candidate +
RHS).str();
349std::unique_ptr<Arg> OptTable::parseOneArgGrouped(
InputArgList &Args,
350 unsigned &Index)
const {
353 const char *CStr =
Args.getArgString(Index);
356 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++, CStr);
358 const Info *
End = OptionInfos.data() + OptionInfos.size();
362 OptNameLess(StrTable, PrefixesTable));
364 unsigned Prev =
Index;
367 for (; Start !=
End; ++Start) {
369 matchOption(StrTable, PrefixesTable, Start, Str, IgnoreCase);
374 if (std::unique_ptr<Arg>
A =
375 Opt.accept(Args,
StringRef(
Args.getArgString(Index), ArgSize),
390 Option Opt(Fallback,
this);
393 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
396 if (std::unique_ptr<Arg>
A = Opt.accept(
397 Args, Str.substr(0, 2),
true, Index)) {
398 Args.replaceArgString(Index,
Twine(
'-') + Str.substr(2));
406 CStr =
Args.MakeArgString(Str.substr(0, 2));
407 Args.replaceArgString(Index,
Twine(
'-') + Str.substr(2));
408 return std::make_unique<Arg>(
getOption(UnknownOptionID), CStr, Index, CStr);
411 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++, CStr);
416 return internalParseOneArg(Args, Index, [VisibilityMask](
const Option &Opt) {
422 unsigned FlagsToInclude,
423 unsigned FlagsToExclude)
const {
424 return internalParseOneArg(
425 Args, Index, [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
426 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
434std::unique_ptr<Arg> OptTable::internalParseOneArg(
435 const ArgList &Args,
unsigned &Index,
436 std::function<
bool(
const Option &)> ExcludeOption)
const {
437 unsigned Prev = Index;
438 StringRef Str = Args.getArgString(Index);
443 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
447 const Info *
End = OptionInfos.data() + OptionInfos.size();
452 std::lower_bound(Start,
End,
Name, OptNameLess(StrTable, PrefixesTable));
462 for (; Start !=
End; ++Start) {
463 unsigned ArgSize = 0;
465 for (; Start !=
End; ++Start)
467 matchOption(StrTable, PrefixesTable, Start, Str, IgnoreCase)))
474 if (ExcludeOption(Opt))
478 if (std::unique_ptr<Arg>
A =
479 Opt.accept(Args,
StringRef(Args.getArgString(Index), ArgSize),
491 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
494 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
499 unsigned &MissingArgIndex,
500 unsigned &MissingArgCount,
502 return internalParseArgs(
503 Args, MissingArgIndex, MissingArgCount,
504 [VisibilityMask](
const Option &Opt) {
510 unsigned &MissingArgIndex,
511 unsigned &MissingArgCount,
512 unsigned FlagsToInclude,
513 unsigned FlagsToExclude)
const {
514 return internalParseArgs(
515 Args, MissingArgIndex, MissingArgCount,
516 [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
517 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
527 unsigned &MissingArgCount,
528 std::function<
bool(
const Option &)> ExcludeOption)
const {
533 MissingArgIndex = MissingArgCount = 0;
534 unsigned Index = 0,
End = ArgArr.
size();
535 while (Index <
End) {
537 if (Args.getArgString(Index) ==
nullptr) {
542 StringRef Str = Args.getArgString(Index);
550 if (DashDashParsing && Str ==
"--") {
551 while (++Index <
End) {
552 Args.append(
new Arg(
getOption(InputOptionID), Str, Index,
553 Args.getArgString(Index)));
558 unsigned Prev =
Index;
559 std::unique_ptr<Arg>
A = GroupedShortOptions
560 ? parseOneArgGrouped(Args, Index)
561 : internalParseOneArg(
Args,
Index, ExcludeOption);
562 assert((Index > Prev || GroupedShortOptions) &&
563 "Parser failed to consume argument.");
567 assert(Index >=
End &&
"Unexpected parser error.");
568 assert(Index - Prev - 1 &&
"No missing arguments!");
569 MissingArgIndex = Prev;
570 MissingArgCount =
Index - Prev - 1;
574 Args.append(
A.release());
582 std::function<
void(
StringRef)> ErrorFn)
const {
591 ErrorFn((
Twine(Args.getArgString(MAI)) +
": missing argument").str());
597 std::string Spelling =
A->getAsString(Args);
599 ErrorFn(
"unknown argument '" + Spelling +
"'");
601 ErrorFn(
"unknown argument '" + Spelling +
"', did you mean '" + Nearest +
609 std::string
Name = O.getPrefixedName().str();
612 switch (O.getKind()) {
624 for (
unsigned i=0, e=O.getNumArgs(); i< e; ++i) {
660 std::vector<OptionInfo> &OptionHelp) {
661 OS << Title <<
":\n";
664 unsigned OptionFieldWidth = 0;
665 for (
const OptionInfo &Opt : OptionHelp) {
667 unsigned Length = Opt.Name.size();
669 OptionFieldWidth = std::max(OptionFieldWidth,
Length);
672 const unsigned InitialPad = 2;
673 for (
const OptionInfo &Opt : OptionHelp) {
674 const std::string &
Option = Opt.Name;
675 int Pad = OptionFieldWidth + InitialPad;
676 int FirstLinePad = OptionFieldWidth - int(
Option.size());
680 if (FirstLinePad < 0) {
682 FirstLinePad = OptionFieldWidth + InitialPad;
687 Opt.HelpText.split(Lines,
'\n');
688 assert(Lines.size() &&
"Expected at least the first line in the help text");
689 auto *LinesIt = Lines.begin();
690 OS.
indent(FirstLinePad + 1) << *LinesIt <<
'\n';
691 while (Lines.end() != ++LinesIt)
692 OS.
indent(Pad + 1) << *LinesIt <<
'\n';
715 bool ShowHidden,
bool ShowAllAliases,
717 return internalPrintHelp(
718 OS, Usage, Title, 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);
729 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(
743 raw_ostream &
OS,
const char *Usage,
const char *Title,
bool ShowHidden,
744 bool ShowAllAliases, std::function<
bool(
const Info &)> ExcludeOption,
746 OS <<
"OVERVIEW: " << Title <<
"\n\n";
747 OS <<
"USAGE: " << Usage <<
"\n\n";
751 std::map<std::string, std::vector<OptionInfo>> GroupedOptionHelp;
753 for (
unsigned Id = 1, e =
getNumOptions() + 1; Id != e; ++Id) {
758 const Info &CandidateInfo = getInfo(Id);
762 if (ExcludeOption(CandidateInfo))
768 if (!HelpText && ShowAllAliases) {
774 if (HelpText && (strlen(HelpText) != 0)) {
777 GroupedOptionHelp[HelpGroup].push_back({OptName, HelpText});
781 for (
auto& OptionGroup : GroupedOptionHelp) {
782 if (OptionGroup.first != GroupedOptionHelp.begin()->first)
793 :
OptTable(StrTable, PrefixesTable, OptionInfos, IgnoreCase) {
795 std::set<StringRef> TmpPrefixesUnion;
798 TmpPrefixesUnion.insert(
StringRef(&StrTable[PrefixOffset]));
799 PrefixesUnion.append(TmpPrefixesUnion.begin(), TmpPrefixesUnion.end());
Defines the llvm::Arg class for parsed arguments.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
static const char * getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id)
static bool optionMatches(const char *StrTable, ArrayRef< unsigned > PrefixesTable, const OptTable::Info &In, StringRef Option)
static unsigned matchOption(const char *StrTable, ArrayRef< unsigned > PrefixesTable, const OptTable::Info *I, StringRef Str, bool IgnoreCase)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
size_t size() const
size - Get the array size.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - 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.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool starts_with_insensitive(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
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
back - Get the last character in the string.
constexpr size_t size() const
size - Get the string size.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
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.
GenericOptTable(const char *StrTable, ArrayRef< unsigned > PrefixesTable, ArrayRef< Info > OptionInfos, bool IgnoreCase=false)
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...
void printHelp(raw_ostream &OS, const char *Usage, const char *Title, bool ShowHidden=false, bool ShowAllAliases=false, Visibility VisibilityMask=Visibility()) const
Render the help text for an option table.
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 char *StrTable, ArrayRef< unsigned > PrefixesTable, ArrayRef< Info > OptionInfos, bool IgnoreCase=false)
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.
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
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.
@ C
The default llvm calling convention, compatible with C.
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.
int StrCmpOptionName(StringRef A, StringRef B, bool FallbackCaseSensitive=true)
int StrCmpOptionPrefixes(ArrayRef< StringRef > APrefixes, ArrayRef< StringRef > BPrefixes)
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< unsigned > getPrefixOffsets(ArrayRef< unsigned > PrefixesTable) const