41 : StrTable(&StrTable), PrefixesTable(PrefixesTable) {}
50 B.getName(*StrTable, PrefixesTable)))
54 A.appendPrefixes(*StrTable, PrefixesTable, APrefixes);
55 B.appendPrefixes(*StrTable, PrefixesTable, BPrefixes);
64 "Unexpected classes for options with same name.");
83 : StrTable(&StrTable), PrefixesTable(PrefixesTable),
84 OptionInfos(OptionInfos), IgnoreCase(IgnoreCase) {
90 unsigned Kind = getInfo(i + 1).
Kind;
92 assert(!InputOptionID &&
"Cannot have multiple input options!");
93 InputOptionID = getInfo(i + 1).
ID;
95 assert(!UnknownOptionID &&
"Cannot have multiple unknown options!");
96 UnknownOptionID = getInfo(i + 1).
ID;
111 "Special options should be defined first!");
116 if (!(OptNameLess(StrTable, PrefixesTable)(getInfo(i), getInfo(i + 1)))) {
130 for (
char C : Prefix)
139 unsigned id = Opt.
getID();
141 return Option(
nullptr,
nullptr);
143 return Option(&getInfo(
id),
this);
150 if (
Arg.starts_with(Prefix))
161 for (
auto PrefixOffset :
I->getPrefixOffsets(PrefixesTable)) {
162 StringRef Prefix = StrTable[PrefixOffset];
163 if (Str.starts_with(Prefix)) {
164 StringRef Rest = Str.substr(Prefix.size());
168 return Prefix.size() +
Name.size();
180 for (
auto PrefixOffset : In.getPrefixOffsets(PrefixesTable))
181 if (
Option == StrTable[PrefixOffset])
189std::vector<std::string>
193 const Info &In = OptionInfos[
I];
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;
214 const Info &In = OptionInfos[
I];
215 if (In.hasNoPrefix() || (!In.HelpText && !In.GroupID))
217 if (!(In.Visibility & VisibilityMask))
219 if (In.Flags & DisableFlags)
223 for (
auto PrefixOffset : In.getPrefixOffsets(PrefixesTable)) {
224 StringRef Prefix = (*StrTable)[PrefixOffset];
225 std::string S = (
Twine(Prefix) +
Name +
"\t").str();
237 unsigned MinimumLength,
238 unsigned MaximumDistance)
const {
239 return internalFindNearest(
240 Option, NearestString, MinimumLength, MaximumDistance,
241 [VisibilityMask](
const Info &CandidateInfo) {
242 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
247 unsigned FlagsToInclude,
unsigned FlagsToExclude,
248 unsigned MinimumLength,
249 unsigned MaximumDistance)
const {
250 return internalFindNearest(
251 Option, NearestString, MinimumLength, MaximumDistance,
252 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
253 if (FlagsToInclude && !(CandidateInfo.
Flags & FlagsToInclude))
255 if (CandidateInfo.
Flags & FlagsToExclude)
261unsigned OptTable::internalFindNearest(
263 unsigned MaximumDistance,
264 std::function<
bool(
const Info &)> ExcludeOption)
const {
269 unsigned BestDistance =
270 MaximumDistance == UINT_MAX ? UINT_MAX : MaximumDistance + 1;
274 for (
const Info &CandidateInfo :
276 StringRef CandidateName = CandidateInfo.getName(*StrTable, PrefixesTable);
281 if (CandidateName.
size() < MinimumLength)
285 if (ExcludeOption(CandidateInfo))
290 if (CandidateInfo.hasNoPrefix())
297 bool CandidateHasDelimiter =
Last ==
'=' ||
Last ==
':';
299 if (CandidateHasDelimiter) {
300 std::tie(NormalizedName, RHS) =
Option.split(
Last);
302 NormalizedName +=
Last;
309 for (
auto CandidatePrefixOffset :
310 CandidateInfo.getPrefixOffsets(PrefixesTable)) {
311 StringRef CandidatePrefix = (*StrTable)[CandidatePrefixOffset];
316 size_t CandidateSize = CandidatePrefix.
size() + CandidateName.
size(),
317 NormalizedSize = NormalizedName.
size();
318 size_t AbsDiff = CandidateSize > NormalizedSize
319 ? CandidateSize - NormalizedSize
320 : NormalizedSize - CandidateSize;
321 if (AbsDiff > BestDistance) {
324 Candidate = CandidatePrefix;
325 Candidate += CandidateName;
327 NormalizedName,
true,
329 if (
RHS.empty() && CandidateHasDelimiter) {
338 if (Distance < BestDistance) {
339 BestDistance = Distance;
340 NearestString = (Candidate +
RHS).str();
351std::unique_ptr<Arg> OptTable::parseOneArgGrouped(
InputArgList &Args,
352 unsigned &Index)
const {
355 const char *CStr =
Args.getArgString(Index);
358 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++, CStr);
360 const Info *
End = OptionInfos.data() + OptionInfos.size();
364 OptNameLess(*StrTable, PrefixesTable));
366 unsigned Prev =
Index;
369 for (; Start !=
End; ++Start) {
371 matchOption(*StrTable, PrefixesTable, Start, Str, IgnoreCase);
376 if (std::unique_ptr<Arg>
A =
377 Opt.accept(Args,
StringRef(
Args.getArgString(Index), ArgSize),
392 Option Opt(Fallback,
this);
395 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
398 if (std::unique_ptr<Arg>
A = Opt.accept(
399 Args, Str.substr(0, 2),
true, Index)) {
400 Args.replaceArgString(Index,
Twine(
'-') + Str.substr(2));
408 CStr =
Args.MakeArgString(Str.substr(0, 2));
409 Args.replaceArgString(Index,
Twine(
'-') + Str.substr(2));
410 return std::make_unique<Arg>(
getOption(UnknownOptionID), CStr, Index, CStr);
413 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++, CStr);
418 return internalParseOneArg(Args, Index, [VisibilityMask](
const Option &Opt) {
424 unsigned FlagsToInclude,
425 unsigned FlagsToExclude)
const {
426 return internalParseOneArg(
427 Args, Index, [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
428 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
436std::unique_ptr<Arg> OptTable::internalParseOneArg(
437 const ArgList &Args,
unsigned &Index,
438 std::function<
bool(
const Option &)> ExcludeOption)
const {
439 unsigned Prev = Index;
440 StringRef Str = Args.getArgString(Index);
445 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
449 const Info *
End = OptionInfos.data() + OptionInfos.size();
454 std::lower_bound(Start,
End,
Name, OptNameLess(*StrTable, PrefixesTable));
464 for (; Start !=
End; ++Start) {
465 unsigned ArgSize = 0;
467 for (; Start !=
End; ++Start)
469 matchOption(*StrTable, PrefixesTable, Start, Str, IgnoreCase)))
476 if (ExcludeOption(Opt))
480 if (std::unique_ptr<Arg>
A =
481 Opt.accept(Args,
StringRef(Args.getArgString(Index), ArgSize),
493 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
496 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
501 unsigned &MissingArgIndex,
502 unsigned &MissingArgCount,
504 return internalParseArgs(
505 Args, MissingArgIndex, MissingArgCount,
506 [VisibilityMask](
const Option &Opt) {
512 unsigned &MissingArgIndex,
513 unsigned &MissingArgCount,
514 unsigned FlagsToInclude,
515 unsigned FlagsToExclude)
const {
516 return internalParseArgs(
517 Args, MissingArgIndex, MissingArgCount,
518 [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
519 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
529 unsigned &MissingArgCount,
530 std::function<
bool(
const Option &)> ExcludeOption)
const {
535 MissingArgIndex = MissingArgCount = 0;
536 unsigned Index = 0,
End = ArgArr.
size();
537 while (Index <
End) {
539 if (Args.getArgString(Index) ==
nullptr) {
544 StringRef Str = Args.getArgString(Index);
552 if (DashDashParsing && Str ==
"--") {
553 while (++Index <
End) {
554 Args.append(
new Arg(
getOption(InputOptionID), Str, Index,
555 Args.getArgString(Index)));
560 unsigned Prev =
Index;
561 std::unique_ptr<Arg>
A = GroupedShortOptions
562 ? parseOneArgGrouped(Args, Index)
563 : internalParseOneArg(
Args,
Index, ExcludeOption);
564 assert((Index > Prev || GroupedShortOptions) &&
565 "Parser failed to consume argument.");
569 assert(Index >=
End &&
"Unexpected parser error.");
570 assert(Index - Prev - 1 &&
"No missing arguments!");
571 MissingArgIndex = Prev;
572 MissingArgCount =
Index - Prev - 1;
576 Args.append(
A.release());
584 std::function<
void(
StringRef)> ErrorFn)
const {
593 ErrorFn((
Twine(Args.getArgString(MAI)) +
": missing argument").str());
599 std::string Spelling =
A->getAsString(Args);
601 ErrorFn(
"unknown argument '" + Spelling +
"'");
603 ErrorFn(
"unknown argument '" + Spelling +
"', did you mean '" + Nearest +
611 std::string
Name = O.getPrefixedName().str();
614 switch (O.getKind()) {
626 for (
unsigned i=0, e=O.getNumArgs(); i< e; ++i) {
662 std::vector<OptionInfo> &OptionHelp) {
663 OS << Title <<
":\n";
666 unsigned OptionFieldWidth = 0;
667 for (
const OptionInfo &Opt : OptionHelp) {
669 unsigned Length = Opt.Name.size();
671 OptionFieldWidth = std::max(OptionFieldWidth,
Length);
674 const unsigned InitialPad = 2;
675 for (
const OptionInfo &Opt : OptionHelp) {
676 const std::string &
Option = Opt.Name;
677 int Pad = OptionFieldWidth + InitialPad;
678 int FirstLinePad = OptionFieldWidth - int(
Option.size());
682 if (FirstLinePad < 0) {
684 FirstLinePad = OptionFieldWidth + InitialPad;
689 Opt.HelpText.split(Lines,
'\n');
690 assert(Lines.size() &&
"Expected at least the first line in the help text");
691 auto *LinesIt = Lines.begin();
692 OS.
indent(FirstLinePad + 1) << *LinesIt <<
'\n';
693 while (Lines.end() != ++LinesIt)
694 OS.
indent(Pad + 1) << *LinesIt <<
'\n';
717 bool ShowHidden,
bool ShowAllAliases,
719 return internalPrintHelp(
720 OS, Usage, Title, 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);
731 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(
745 raw_ostream &
OS,
const char *Usage,
const char *Title,
bool ShowHidden,
746 bool ShowAllAliases, std::function<
bool(
const Info &)> ExcludeOption,
748 OS <<
"OVERVIEW: " << Title <<
"\n\n";
749 OS <<
"USAGE: " << Usage <<
"\n\n";
753 std::map<std::string, std::vector<OptionInfo>> GroupedOptionHelp;
755 for (
unsigned Id = 1, e =
getNumOptions() + 1; Id != e; ++Id) {
760 const Info &CandidateInfo = getInfo(Id);
764 if (ExcludeOption(CandidateInfo))
770 if (!HelpText && ShowAllAliases) {
776 if (HelpText && (strlen(HelpText) != 0)) {
779 GroupedOptionHelp[HelpGroup].push_back({OptName, HelpText});
783 for (
auto& OptionGroup : GroupedOptionHelp) {
784 if (OptionGroup.first != GroupedOptionHelp.begin()->first)
795 :
OptTable(StrTable, PrefixesTable, OptionInfos, IgnoreCase) {
797 std::set<StringRef> TmpPrefixesUnion;
800 TmpPrefixesUnion.insert(StrTable[PrefixOffset]);
801 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 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)
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.
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.
GenericOptTable(const StringTable &StrTable, ArrayRef< StringTable::Offset > 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.
OptTable(const StringTable &StrTable, ArrayRef< StringTable::Offset > PrefixesTable, ArrayRef< Info > OptionInfos, bool IgnoreCase=false)
Initialize OptTable using Tablegen'ed OptionInfos.
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.
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< StringTable::Offset > getPrefixOffsets(ArrayRef< StringTable::Offset > PrefixesTable) const