40 size_t MinSize = std::min(
A.size(),
B.size());
41 if (
int Res =
A.substr(0, MinSize).compare_insensitive(
B.substr(0, MinSize)))
44 if (
A.size() ==
B.size())
47 return (
A.size() == MinSize) ? 1
65 for (
size_t I = 0, K = std::min(
A.Prefixes.size(),
B.Prefixes.size());
I != K;
73 "Unexpected classes for options with same name.");
89 : OptionInfos(OptionInfos), IgnoreCase(IgnoreCase) {
95 unsigned Kind = getInfo(i + 1).
Kind;
97 assert(!InputOptionID &&
"Cannot have multiple input options!");
98 InputOptionID = getInfo(i + 1).
ID;
100 assert(!UnknownOptionID &&
"Cannot have multiple unknown options!");
101 UnknownOptionID = getInfo(i + 1).
ID;
116 "Special options should be defined first!");
121 if (!(getInfo(i) < getInfo(i + 1))) {
135 for (
char C : Prefix)
144 unsigned id = Opt.
getID();
146 return Option(
nullptr,
nullptr);
148 return Option(&getInfo(
id),
this);
155 if (
Arg.starts_with(Prefix))
163 for (
auto Prefix :
I->Prefixes) {
164 if (Str.starts_with(Prefix)) {
165 StringRef Rest = Str.substr(Prefix.size());
177 for (
auto Prefix : In.Prefixes)
178 if (
Option.ends_with(In.getName()))
179 if (
Option.slice(0,
Option.size() - In.getName().size()) == Prefix)
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.Prefixes.empty() || (!In.HelpText && !In.GroupID))
215 if (!(In.Visibility & VisibilityMask))
217 if (In.Flags & DisableFlags)
220 for (
auto Prefix : In.Prefixes) {
221 std::string S = (Prefix + In.getName() +
"\t").str();
233 unsigned MinimumLength,
234 unsigned MaximumDistance)
const {
235 return internalFindNearest(
236 Option, NearestString, MinimumLength, MaximumDistance,
237 [VisibilityMask](
const Info &CandidateInfo) {
238 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
243 unsigned FlagsToInclude,
unsigned FlagsToExclude,
244 unsigned MinimumLength,
245 unsigned MaximumDistance)
const {
246 return internalFindNearest(
247 Option, NearestString, MinimumLength, MaximumDistance,
248 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
249 if (FlagsToInclude && !(CandidateInfo.
Flags & FlagsToInclude))
251 if (CandidateInfo.
Flags & FlagsToExclude)
257unsigned OptTable::internalFindNearest(
259 unsigned MaximumDistance,
260 std::function<
bool(
const Info &)> ExcludeOption)
const {
265 unsigned BestDistance =
266 MaximumDistance == UINT_MAX ? UINT_MAX : MaximumDistance + 1;
270 for (
const Info &CandidateInfo :
272 StringRef CandidateName = CandidateInfo.getName();
277 if (CandidateName.
size() < MinimumLength)
281 if (ExcludeOption(CandidateInfo))
286 if (CandidateInfo.Prefixes.empty())
293 bool CandidateHasDelimiter =
Last ==
'=' ||
Last ==
':';
295 if (CandidateHasDelimiter) {
296 std::tie(NormalizedName, RHS) =
Option.split(
Last);
298 NormalizedName +=
Last;
305 for (
auto CandidatePrefix : CandidateInfo.Prefixes) {
310 size_t CandidateSize = CandidatePrefix.size() + CandidateName.
size(),
311 NormalizedSize = NormalizedName.
size();
312 size_t AbsDiff = CandidateSize > NormalizedSize
313 ? CandidateSize - NormalizedSize
314 : NormalizedSize - CandidateSize;
315 if (AbsDiff > BestDistance) {
318 Candidate = CandidatePrefix;
319 Candidate += CandidateName;
321 NormalizedName,
true,
323 if (
RHS.empty() && CandidateHasDelimiter) {
332 if (Distance < BestDistance) {
333 BestDistance = Distance;
334 NearestString = (Candidate +
RHS).str();
345std::unique_ptr<Arg> OptTable::parseOneArgGrouped(
InputArgList &Args,
346 unsigned &
Index)
const {
349 const char *CStr =
Args.getArgString(
Index);
352 return std::make_unique<Arg>(
getOption(InputOptionID), Str,
Index++, CStr);
354 const Info *
End = OptionInfos.data() + OptionInfos.size();
359 unsigned Prev =
Index;
362 for (; Start !=
End; ++Start) {
363 unsigned ArgSize =
matchOption(Start, Str, IgnoreCase);
368 if (std::unique_ptr<Arg>
A =
384 Option Opt(Fallback,
this);
387 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str,
Index++,
390 if (std::unique_ptr<Arg>
A = Opt.accept(
391 Args, Str.substr(0, 2),
true,
Index)) {
400 CStr =
Args.MakeArgString(Str.substr(0, 2));
402 return std::make_unique<Arg>(
getOption(UnknownOptionID), CStr,
Index, CStr);
405 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str,
Index++, CStr);
410 return internalParseOneArg(Args,
Index, [VisibilityMask](
const Option &Opt) {
416 unsigned FlagsToInclude,
417 unsigned FlagsToExclude)
const {
418 return internalParseOneArg(
419 Args,
Index, [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
420 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
428std::unique_ptr<Arg> OptTable::internalParseOneArg(
430 std::function<
bool(
const Option &)> ExcludeOption)
const {
431 unsigned Prev =
Index;
437 return std::make_unique<Arg>(
getOption(InputOptionID), Str,
Index++,
441 const Info *
End = OptionInfos.data() + OptionInfos.size();
445 Start = std::lower_bound(Start,
End,
Name);
455 for (; Start !=
End; ++Start) {
456 unsigned ArgSize = 0;
458 for (; Start !=
End; ++Start)
459 if ((ArgSize =
matchOption(Start, Str, IgnoreCase)))
466 if (ExcludeOption(Opt))
470 if (std::unique_ptr<Arg>
A =
483 return std::make_unique<Arg>(
getOption(InputOptionID), Str,
Index++,
486 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str,
Index++,
491 unsigned &MissingArgIndex,
492 unsigned &MissingArgCount,
494 return internalParseArgs(
495 Args, MissingArgIndex, MissingArgCount,
496 [VisibilityMask](
const Option &Opt) {
502 unsigned &MissingArgIndex,
503 unsigned &MissingArgCount,
504 unsigned FlagsToInclude,
505 unsigned FlagsToExclude)
const {
506 return internalParseArgs(
507 Args, MissingArgIndex, MissingArgCount,
508 [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
509 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
519 unsigned &MissingArgCount,
520 std::function<
bool(
const Option &)> ExcludeOption)
const {
525 MissingArgIndex = MissingArgCount = 0;
529 if (Args.getArgString(
Index) ==
nullptr) {
542 if (DashDashParsing && Str ==
"--") {
545 Args.getArgString(
Index)));
550 unsigned Prev =
Index;
551 std::unique_ptr<Arg>
A = GroupedShortOptions
552 ? parseOneArgGrouped(Args,
Index)
553 : internalParseOneArg(
Args,
Index, ExcludeOption);
555 "Parser failed to consume argument.");
560 assert(
Index - Prev - 1 &&
"No missing arguments!");
561 MissingArgIndex = Prev;
562 MissingArgCount =
Index - Prev - 1;
566 Args.append(
A.release());
574 std::function<
void(
StringRef)> ErrorFn)
const {
583 ErrorFn((
Twine(Args.getArgString(MAI)) +
": missing argument").str());
589 std::string Spelling =
A->getAsString(Args);
591 ErrorFn(
"unknown argument '" + Spelling +
"'");
593 ErrorFn(
"unknown argument '" + Spelling +
"', did you mean '" + Nearest +
601 std::string
Name = O.getPrefixedName().str();
604 switch (O.getKind()) {
616 for (
unsigned i=0, e=O.getNumArgs(); i< e; ++i) {
652 std::vector<OptionInfo> &OptionHelp) {
653 OS << Title <<
":\n";
656 unsigned OptionFieldWidth = 0;
657 for (
const OptionInfo &Opt : OptionHelp) {
659 unsigned Length = Opt.Name.size();
661 OptionFieldWidth = std::max(OptionFieldWidth,
Length);
664 const unsigned InitialPad = 2;
665 for (
const OptionInfo &Opt : OptionHelp) {
666 const std::string &
Option = Opt.Name;
667 int Pad = OptionFieldWidth + InitialPad;
668 int FirstLinePad = OptionFieldWidth - int(
Option.size());
672 if (FirstLinePad < 0) {
674 FirstLinePad = OptionFieldWidth + InitialPad;
679 Opt.HelpText.split(Lines,
'\n');
680 assert(Lines.size() &&
"Expected at least the first line in the help text");
681 auto *LinesIt = Lines.begin();
682 OS.
indent(FirstLinePad + 1) << *LinesIt <<
'\n';
683 while (Lines.end() != ++LinesIt)
684 OS.
indent(Pad + 1) << *LinesIt <<
'\n';
707 bool ShowHidden,
bool ShowAllAliases,
709 return internalPrintHelp(
710 OS, Usage, Title, ShowHidden, ShowAllAliases,
711 [VisibilityMask](
const Info &CandidateInfo) ->
bool {
712 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
718 unsigned FlagsToInclude,
unsigned FlagsToExclude,
719 bool ShowAllAliases)
const {
720 bool ShowHidden = !(FlagsToExclude &
HelpHidden);
721 FlagsToExclude &= ~HelpHidden;
722 return internalPrintHelp(
723 OS, Usage, Title, ShowHidden, ShowAllAliases,
724 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
725 if (FlagsToInclude && !(CandidateInfo.
Flags & FlagsToInclude))
727 if (CandidateInfo.
Flags & FlagsToExclude)
734void OptTable::internalPrintHelp(
735 raw_ostream &
OS,
const char *Usage,
const char *Title,
bool ShowHidden,
736 bool ShowAllAliases, std::function<
bool(
const Info &)> ExcludeOption,
738 OS <<
"OVERVIEW: " << Title <<
"\n\n";
739 OS <<
"USAGE: " << Usage <<
"\n\n";
743 std::map<std::string, std::vector<OptionInfo>> GroupedOptionHelp;
745 for (
unsigned Id = 1, e =
getNumOptions() + 1; Id != e; ++Id) {
750 const Info &CandidateInfo = getInfo(Id);
754 if (ExcludeOption(CandidateInfo))
760 if (!HelpText && ShowAllAliases) {
766 if (HelpText && (strlen(HelpText) != 0)) {
769 GroupedOptionHelp[HelpGroup].push_back({OptName, HelpText});
773 for (
auto& OptionGroup : GroupedOptionHelp) {
774 if (OptionGroup.first != GroupedOptionHelp.begin()->first)
783 :
OptTable(OptionInfos, IgnoreCase) {
785 std::set<StringLiteral> TmpPrefixesUnion;
788 PrefixesUnionBuffer.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 unsigned matchOption(const OptTable::Info *I, StringRef Str, bool IgnoreCase)
static bool optionMatches(const OptTable::Info &In, StringRef Option)
static const char * getOptionHelpGroup(const OptTable &Opts, OptSpecifier Id)
static bool isInput(const ArrayRef< StringLiteral > &Prefixes, StringRef Arg)
static std::string getOptionHelpName(const OptTable &Opts, OptSpecifier Id)
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.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
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(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.
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(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.
virtual ArrayRef< StringLiteral > getPrefixesUnion() const =0
The union 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 ...
static int StrCmpOptionName(StringRef A, StringRef B)
static bool operator<(const OptTable::Info &A, const OptTable::Info &B)
static int StrCmpOptionNameIgnoreCase(StringRef A, StringRef B)
This is an optimization pass for GlobalISel generic memory operations.
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< StringLiteral > Prefixes
A null terminated array of prefix strings to apply to name while matching.