38 explicit OptNameLess(
const StringTable &StrTable,
40 : StrTable(&StrTable), PrefixesTable(PrefixesTable) {}
43 inline bool operator()(
const OptTable::Info &
A,
44 const OptTable::Info &
B)
const {
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.");
69 inline bool operator()(
const OptTable::Info &
I, StringRef Name)
const {
84 : StrTable(&StrTable), PrefixesTable(PrefixesTable),
85 OptionInfos(OptionInfos), IgnoreCase(IgnoreCase),
86 SubCommands(SubCommands), SubCommandIDsTable(SubCommandIDsTable) {
92 unsigned Kind = getInfo(i + 1).Kind;
94 assert(!InputOptionID &&
"Cannot have multiple input options!");
95 InputOptionID = getInfo(i + 1).ID;
97 assert(!UnknownOptionID &&
"Cannot have multiple unknown options!");
98 UnknownOptionID = getInfo(i + 1).ID;
113 "Special options should be defined first!");
118 if (!(OptNameLess(StrTable, PrefixesTable)(getInfo(i), getInfo(i + 1)))) {
132 for (
char C : Prefix)
141 unsigned id = Opt.
getID();
143 return Option(
nullptr,
nullptr);
145 return Option(&getInfo(
id),
this);
152 if (
Arg.starts_with(Prefix))
162 StringRef Name =
I->getName(StrTable, PrefixesTable);
163 for (
auto PrefixOffset :
I->getPrefixOffsets(PrefixesTable)) {
164 StringRef Prefix = StrTable[PrefixOffset];
165 if (Str.starts_with(Prefix)) {
170 return Prefix.size() + Name.size();
180 StringRef Name = In.getName(StrTable, PrefixesTable);
181 if (
Option.consume_back(Name))
182 for (
auto PrefixOffset : In.getPrefixOffsets(PrefixesTable))
183 if (
Option == StrTable[PrefixOffset])
191std::vector<std::string>
195 const Info &In = OptionInfos[
I];
202 std::vector<std::string> Result;
204 if (Val.starts_with(
Arg) &&
Arg != Val)
205 Result.push_back(std::string(Val));
211std::vector<std::string>
213 unsigned int DisableFlags)
const {
214 std::vector<std::string> Ret;
216 const Info &In = OptionInfos[
I];
217 if (In.hasNoPrefix() || (!In.HelpText && !In.GroupID))
219 if (!(In.Visibility & VisibilityMask))
221 if (In.Flags & DisableFlags)
224 StringRef Name = In.getName(*StrTable, PrefixesTable);
225 for (
auto PrefixOffset : In.getPrefixOffsets(PrefixesTable)) {
226 StringRef Prefix = (*StrTable)[PrefixOffset];
227 std::string S = (
Twine(Prefix) + Name +
"\t").str();
239 unsigned MinimumLength,
240 unsigned MaximumDistance)
const {
241 return internalFindNearest(
242 Option, NearestString, MinimumLength, MaximumDistance,
243 [VisibilityMask](
const Info &CandidateInfo) {
244 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
249 unsigned FlagsToInclude,
unsigned FlagsToExclude,
250 unsigned MinimumLength,
251 unsigned MaximumDistance)
const {
252 return internalFindNearest(
253 Option, NearestString, MinimumLength, MaximumDistance,
254 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
255 if (FlagsToInclude && !(CandidateInfo.
Flags & FlagsToInclude))
257 if (CandidateInfo.
Flags & FlagsToExclude)
263unsigned OptTable::internalFindNearest(
265 unsigned MaximumDistance,
266 std::function<
bool(
const Info &)> ExcludeOption)
const {
271 unsigned BestDistance =
272 MaximumDistance == UINT_MAX ? UINT_MAX : MaximumDistance + 1;
276 for (
const Info &CandidateInfo :
278 StringRef CandidateName = CandidateInfo.getName(*StrTable, PrefixesTable);
283 if (CandidateName.
size() < MinimumLength)
287 if (ExcludeOption(CandidateInfo))
292 if (CandidateInfo.hasNoPrefix())
299 bool CandidateHasDelimiter =
Last ==
'=' ||
Last ==
':';
301 if (CandidateHasDelimiter) {
302 std::tie(NormalizedName, RHS) =
Option.split(
Last);
304 NormalizedName +=
Last;
311 for (
auto CandidatePrefixOffset :
312 CandidateInfo.getPrefixOffsets(PrefixesTable)) {
313 StringRef CandidatePrefix = (*StrTable)[CandidatePrefixOffset];
318 size_t CandidateSize = CandidatePrefix.
size() + CandidateName.
size(),
319 NormalizedSize = NormalizedName.
size();
320 size_t AbsDiff = CandidateSize > NormalizedSize
321 ? CandidateSize - NormalizedSize
322 : NormalizedSize - CandidateSize;
323 if (AbsDiff > BestDistance) {
326 Candidate = CandidatePrefix;
327 Candidate += CandidateName;
329 NormalizedName,
true,
331 if (
RHS.empty() && CandidateHasDelimiter) {
340 if (Distance < BestDistance) {
341 BestDistance = Distance;
342 NearestString = (Candidate +
RHS).str();
353std::unique_ptr<Arg> OptTable::parseOneArgGrouped(
InputArgList &Args,
354 unsigned &Index)
const {
357 const char *CStr =
Args.getArgString(Index);
360 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++, CStr);
362 const Info *End = OptionInfos.data() + OptionInfos.size();
366 OptNameLess(*StrTable, PrefixesTable));
368 unsigned Prev =
Index;
373 matchOption(*StrTable, PrefixesTable, Start, Str, IgnoreCase);
378 if (std::unique_ptr<Arg>
A =
379 Opt.accept(Args, StringRef(
Args.getArgString(Index), ArgSize),
397 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
400 if (std::unique_ptr<Arg>
A = Opt.accept(
401 Args, Str.substr(0, 2),
true, Index)) {
402 Args.replaceArgString(Index, Twine(
'-') + Str.substr(2));
410 CStr =
Args.MakeArgString(Str.substr(0, 2));
411 Args.replaceArgString(Index, Twine(
'-') + Str.substr(2));
412 return std::make_unique<Arg>(
getOption(UnknownOptionID), CStr, Index, CStr);
415 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++, CStr);
420 return internalParseOneArg(Args, Index, [VisibilityMask](
const Option &Opt) {
426 unsigned FlagsToInclude,
427 unsigned FlagsToExclude)
const {
428 return internalParseOneArg(
429 Args, Index, [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
430 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
432 if (Opt.
hasFlag(FlagsToExclude))
438std::unique_ptr<Arg> OptTable::internalParseOneArg(
439 const ArgList &Args,
unsigned &Index,
440 std::function<
bool(
const Option &)> ExcludeOption)
const {
441 unsigned Prev = Index;
442 StringRef Str = Args.getArgString(Index);
447 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
451 const Info *End = OptionInfos.data() + OptionInfos.size();
456 std::lower_bound(Start, End, Name, OptNameLess(*StrTable, PrefixesTable));
466 for (; Start != End; ++Start) {
467 unsigned ArgSize = 0;
469 for (; Start != End; ++Start)
471 matchOption(*StrTable, PrefixesTable, Start, Str, IgnoreCase)))
478 if (ExcludeOption(Opt))
482 if (std::unique_ptr<Arg>
A =
483 Opt.accept(Args,
StringRef(Args.getArgString(Index), ArgSize),
495 return std::make_unique<Arg>(
getOption(InputOptionID), Str, Index++,
498 return std::make_unique<Arg>(
getOption(UnknownOptionID), Str, Index++,
503 unsigned &MissingArgIndex,
504 unsigned &MissingArgCount,
506 return internalParseArgs(
507 Args, MissingArgIndex, MissingArgCount,
508 [VisibilityMask](
const Option &Opt) {
514 unsigned &MissingArgIndex,
515 unsigned &MissingArgCount,
516 unsigned FlagsToInclude,
517 unsigned FlagsToExclude)
const {
518 return internalParseArgs(
519 Args, MissingArgIndex, MissingArgCount,
520 [FlagsToInclude, FlagsToExclude](
const Option &Opt) {
521 if (FlagsToInclude && !Opt.
hasFlag(FlagsToInclude))
523 if (Opt.
hasFlag(FlagsToExclude))
531 unsigned &MissingArgCount,
532 std::function<
bool(
const Option &)> ExcludeOption)
const {
537 MissingArgIndex = MissingArgCount = 0;
538 unsigned Index = 0, End = ArgArr.
size();
539 while (Index < End) {
541 if (Args.getArgString(Index) ==
nullptr) {
546 StringRef Str = Args.getArgString(Index);
554 if (DashDashParsing && Str ==
"--") {
555 while (++Index < End) {
556 Args.append(
new Arg(
getOption(InputOptionID), Str, Index,
557 Args.getArgString(Index)));
562 unsigned Prev =
Index;
563 std::unique_ptr<Arg>
A = GroupedShortOptions
564 ? parseOneArgGrouped(Args, Index)
565 : internalParseOneArg(
Args,
Index, ExcludeOption);
566 assert((Index > Prev || GroupedShortOptions) &&
567 "Parser failed to consume argument.");
571 assert(Index >= End &&
"Unexpected parser error.");
572 assert(Index - Prev - 1 &&
"No missing arguments!");
573 MissingArgIndex = Prev;
574 MissingArgCount =
Index - Prev - 1;
578 Args.append(
A.release());
586 std::function<
void(
StringRef)> ErrorFn)
const {
595 ErrorFn((
Twine(Args.getArgString(MAI)) +
": missing argument").str());
601 std::string
Spelling =
A->getAsString(Args);
603 ErrorFn(
"unknown argument '" +
Spelling +
"'");
605 ErrorFn(
"unknown argument '" +
Spelling +
"', did you mean '" + Nearest +
613 std::string Name = O.getPrefixedName().str();
616 switch (O.getKind()) {
628 for (
unsigned i=0, e=O.getNumArgs(); i< e; ++i) {
664 std::vector<OptionInfo> &OptionHelp) {
665 OS << Title <<
":\n";
668 unsigned OptionFieldWidth = 0;
669 for (
const OptionInfo &Opt : OptionHelp) {
671 unsigned Length = Opt.Name.size();
673 OptionFieldWidth = std::max(OptionFieldWidth,
Length);
676 const unsigned InitialPad = 2;
677 for (
const OptionInfo &Opt : OptionHelp) {
678 const std::string &
Option = Opt.Name;
679 int Pad = OptionFieldWidth + InitialPad;
680 int FirstLinePad = OptionFieldWidth - int(
Option.size());
684 if (FirstLinePad < 0) {
686 FirstLinePad = OptionFieldWidth + InitialPad;
691 Opt.HelpText.split(Lines,
'\n');
692 assert(Lines.size() &&
"Expected at least the first line in the help text");
693 auto *LinesIt = Lines.begin();
694 OS.
indent(FirstLinePad + 1) << *LinesIt <<
'\n';
695 while (Lines.end() != ++LinesIt)
696 OS.
indent(Pad + 1) << *LinesIt <<
'\n';
719 bool ShowHidden,
bool ShowAllAliases,
722 return internalPrintHelp(
723 OS, Usage, Title,
SubCommand, ShowHidden, ShowAllAliases,
724 [VisibilityMask](
const Info &CandidateInfo) ->
bool {
725 return (CandidateInfo.
Visibility & VisibilityMask) == 0;
731 unsigned FlagsToInclude,
unsigned FlagsToExclude,
732 bool ShowAllAliases)
const {
733 bool ShowHidden = !(FlagsToExclude &
HelpHidden);
735 return internalPrintHelp(
736 OS, Usage, Title, {}, ShowHidden, ShowAllAliases,
737 [FlagsToInclude, FlagsToExclude](
const Info &CandidateInfo) {
738 if (FlagsToInclude && !(CandidateInfo.Flags & FlagsToInclude))
740 if (CandidateInfo.Flags & FlagsToExclude)
747void OptTable::internalPrintHelp(
749 bool ShowHidden,
bool ShowAllAliases,
750 std::function<
bool(
const Info &)> ExcludeOption,
752 OS <<
"OVERVIEW: " << Title <<
"\n\n";
756 std::map<std::string, std::vector<OptionInfo>> GroupedOptionHelp;
759 SubCommands, [&](
const auto &
C) {
return SubCommand ==
C.Name; });
760 if (!SubCommand.
empty()) {
761 assert(ActiveSubCommand != SubCommands.end() &&
762 "Not a valid registered subcommand.");
763 OS << ActiveSubCommand->HelpText <<
"\n\n";
765 OS <<
"USAGE: " << ActiveSubCommand->Usage <<
"\n\n";
767 OS <<
"USAGE: " << Usage <<
"\n\n";
768 if (SubCommands.size() > 1) {
769 OS <<
"SUBCOMMANDS:\n\n";
770 for (
const auto &
C : SubCommands)
771 OS <<
C.Name <<
" - " <<
C.HelpText <<
"\n";
776 auto DoesOptionBelongToSubcommand = [&](
const Info &CandidateInfo) {
779 ArrayRef<unsigned> SubCommandIDs =
780 CandidateInfo.getSubCommandIDs(SubCommandIDsTable);
785 if (SubCommandIDs.
empty())
796 unsigned ActiveSubCommandID = ActiveSubCommand - &SubCommands[0];
807 const Info &CandidateInfo = getInfo(Id);
811 if (ExcludeOption(CandidateInfo))
814 if (!DoesOptionBelongToSubcommand(CandidateInfo))
820 if (!HelpText && ShowAllAliases) {
826 if (HelpText && (strlen(HelpText) != 0)) {
829 GroupedOptionHelp[HelpGroup].push_back({OptName, HelpText});
833 for (
auto& OptionGroup : GroupedOptionHelp) {
834 if (OptionGroup.first != GroupedOptionHelp.begin()->first)
847 :
OptTable(StrTable, PrefixesTable, OptionInfos, IgnoreCase, SubCommands,
848 SubCommandIDsTable) {
850 std::set<StringRef> TmpPrefixesUnion;
853 TmpPrefixesUnion.insert(StrTable[PrefixOffset]);
854 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< 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)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - 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.
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.
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
empty - 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
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.
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.
@ C
The default llvm calling convention, compatible with C.
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.
int StrCmpOptionName(StringRef A, StringRef B, bool FallbackCaseSensitive=true)
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.