1 //===- OptTable.cpp - Option Table Implementation -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/ADT/StringSet.h"
13 #include "llvm/Option/Arg.h"
14 #include "llvm/Option/ArgList.h"
15 #include "llvm/Option/Option.h"
16 #include "llvm/Option/OptSpecifier.h"
17 #include "llvm/Option/OptTable.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
31 using namespace llvm::opt
;
36 // Ordering on Info. The ordering is *almost* case-insensitive lexicographic,
37 // with an exception. '\0' comes at the end of the alphabet instead of the
38 // beginning (thus options precede any other options which prefix them).
39 static int StrCmpOptionNameIgnoreCase(const char *A
, const char *B
) {
40 const char *X
= A
, *Y
= B
;
41 char a
= tolower(*A
), b
= tolower(*B
);
50 if (a
== '\0') // A is a prefix of B.
52 if (b
== '\0') // B is a prefix of A.
55 // Otherwise lexicographic.
56 return (a
< b
) ? -1 : 1;
60 static int StrCmpOptionName(const char *A
, const char *B
) {
61 if (int N
= StrCmpOptionNameIgnoreCase(A
, B
))
66 static inline bool operator<(const OptTable::Info
&A
, const OptTable::Info
&B
) {
70 if (int N
= StrCmpOptionName(A
.Name
, B
.Name
))
73 for (const char * const *APre
= A
.Prefixes
,
74 * const *BPre
= B
.Prefixes
;
75 *APre
!= nullptr && *BPre
!= nullptr; ++APre
, ++BPre
){
76 if (int N
= StrCmpOptionName(*APre
, *BPre
))
80 // Names are the same, check that classes are in order; exactly one
81 // should be joined, and it should succeed the other.
82 assert(((A
.Kind
== Option::JoinedClass
) ^ (B
.Kind
== Option::JoinedClass
)) &&
83 "Unexpected classes for options with same name.");
84 return B
.Kind
== Option::JoinedClass
;
88 // Support lower_bound between info and an option name.
89 static inline bool operator<(const OptTable::Info
&I
, const char *Name
) {
90 return StrCmpOptionNameIgnoreCase(I
.Name
, Name
) < 0;
93 } // end namespace opt
94 } // end namespace llvm
96 OptSpecifier::OptSpecifier(const Option
*Opt
) : ID(Opt
->getID()) {}
98 OptTable::OptTable(ArrayRef
<Info
> OptionInfos
, bool IgnoreCase
)
99 : OptionInfos(OptionInfos
), IgnoreCase(IgnoreCase
) {
100 // Explicitly zero initialize the error to work around a bug in array
101 // value-initialization on MinGW with gcc 4.3.5.
103 // Find start of normal options.
104 for (unsigned i
= 0, e
= getNumOptions(); i
!= e
; ++i
) {
105 unsigned Kind
= getInfo(i
+ 1).Kind
;
106 if (Kind
== Option::InputClass
) {
107 assert(!TheInputOptionID
&& "Cannot have multiple input options!");
108 TheInputOptionID
= getInfo(i
+ 1).ID
;
109 } else if (Kind
== Option::UnknownClass
) {
110 assert(!TheUnknownOptionID
&& "Cannot have multiple unknown options!");
111 TheUnknownOptionID
= getInfo(i
+ 1).ID
;
112 } else if (Kind
!= Option::GroupClass
) {
113 FirstSearchableIndex
= i
;
117 assert(FirstSearchableIndex
!= 0 && "No searchable options?");
120 // Check that everything after the first searchable option is a
121 // regular option class.
122 for (unsigned i
= FirstSearchableIndex
, e
= getNumOptions(); i
!= e
; ++i
) {
123 Option::OptionClass Kind
= (Option::OptionClass
) getInfo(i
+ 1).Kind
;
124 assert((Kind
!= Option::InputClass
&& Kind
!= Option::UnknownClass
&&
125 Kind
!= Option::GroupClass
) &&
126 "Special options should be defined first!");
129 // Check that options are in order.
130 for (unsigned i
= FirstSearchableIndex
+ 1, e
= getNumOptions(); i
!= e
; ++i
){
131 if (!(getInfo(i
) < getInfo(i
+ 1))) {
133 getOption(i
+ 1).dump();
134 llvm_unreachable("Options are not in order!");
140 for (unsigned i
= FirstSearchableIndex
+ 1, e
= getNumOptions() + 1;
142 if (const char *const *P
= getInfo(i
).Prefixes
) {
143 for (; *P
!= nullptr; ++P
) {
144 PrefixesUnion
.insert(*P
);
149 // Build prefix chars.
150 for (StringSet
<>::const_iterator I
= PrefixesUnion
.begin(),
151 E
= PrefixesUnion
.end(); I
!= E
; ++I
) {
152 StringRef Prefix
= I
->getKey();
153 for (StringRef::const_iterator C
= Prefix
.begin(), CE
= Prefix
.end();
155 if (!is_contained(PrefixChars
, *C
))
156 PrefixChars
.push_back(*C
);
160 OptTable::~OptTable() = default;
162 const Option
OptTable::getOption(OptSpecifier Opt
) const {
163 unsigned id
= Opt
.getID();
165 return Option(nullptr, nullptr);
166 assert((unsigned) (id
- 1) < getNumOptions() && "Invalid ID.");
167 return Option(&getInfo(id
), this);
170 static bool isInput(const StringSet
<> &Prefixes
, StringRef Arg
) {
173 for (StringSet
<>::const_iterator I
= Prefixes
.begin(),
174 E
= Prefixes
.end(); I
!= E
; ++I
)
175 if (Arg
.startswith(I
->getKey()))
180 /// \returns Matched size. 0 means no match.
181 static unsigned matchOption(const OptTable::Info
*I
, StringRef Str
,
183 for (const char * const *Pre
= I
->Prefixes
; *Pre
!= nullptr; ++Pre
) {
184 StringRef
Prefix(*Pre
);
185 if (Str
.startswith(Prefix
)) {
186 StringRef Rest
= Str
.substr(Prefix
.size());
187 bool Matched
= IgnoreCase
188 ? Rest
.startswith_lower(I
->Name
)
189 : Rest
.startswith(I
->Name
);
191 return Prefix
.size() + StringRef(I
->Name
).size();
197 // Returns true if one of the Prefixes + In.Names matches Option
198 static bool optionMatches(const OptTable::Info
&In
, StringRef Option
) {
200 for (size_t I
= 0; In
.Prefixes
[I
]; I
++)
201 if (Option
== std::string(In
.Prefixes
[I
]) + In
.Name
)
206 // This function is for flag value completion.
207 // Eg. When "-stdlib=" and "l" was passed to this function, it will return
208 // appropiriate values for stdlib, which starts with l.
209 std::vector
<std::string
>
210 OptTable::suggestValueCompletions(StringRef Option
, StringRef Arg
) const {
211 // Search all options and return possible values.
212 for (size_t I
= FirstSearchableIndex
, E
= OptionInfos
.size(); I
< E
; I
++) {
213 const Info
&In
= OptionInfos
[I
];
214 if (!In
.Values
|| !optionMatches(In
, Option
))
217 SmallVector
<StringRef
, 8> Candidates
;
218 StringRef(In
.Values
).split(Candidates
, ",", -1, false);
220 std::vector
<std::string
> Result
;
221 for (StringRef Val
: Candidates
)
222 if (Val
.startswith(Arg
) && Arg
.compare(Val
))
223 Result
.push_back(Val
);
229 std::vector
<std::string
>
230 OptTable::findByPrefix(StringRef Cur
, unsigned short DisableFlags
) const {
231 std::vector
<std::string
> Ret
;
232 for (size_t I
= FirstSearchableIndex
, E
= OptionInfos
.size(); I
< E
; I
++) {
233 const Info
&In
= OptionInfos
[I
];
234 if (!In
.Prefixes
|| (!In
.HelpText
&& !In
.GroupID
))
236 if (In
.Flags
& DisableFlags
)
239 for (int I
= 0; In
.Prefixes
[I
]; I
++) {
240 std::string S
= std::string(In
.Prefixes
[I
]) + std::string(In
.Name
) + "\t";
243 if (StringRef(S
).startswith(Cur
) && S
.compare(std::string(Cur
) + "\t"))
250 unsigned OptTable::findNearest(StringRef Option
, std::string
&NearestString
,
251 unsigned FlagsToInclude
, unsigned FlagsToExclude
,
252 unsigned MinimumLength
) const {
253 assert(!Option
.empty());
255 // Consider each option as a candidate, finding the closest match.
256 unsigned BestDistance
= UINT_MAX
;
257 for (const Info
&CandidateInfo
:
258 ArrayRef
<Info
>(OptionInfos
).drop_front(FirstSearchableIndex
)) {
259 StringRef CandidateName
= CandidateInfo
.Name
;
261 // Ignore option candidates with empty names, such as "--", or names
262 // that do not meet the minimum length.
263 if (CandidateName
.empty() || CandidateName
.size() < MinimumLength
)
266 // If FlagsToInclude were specified, ignore options that don't include
268 if (FlagsToInclude
&& !(CandidateInfo
.Flags
& FlagsToInclude
))
270 // Ignore options that contain the FlagsToExclude.
271 if (CandidateInfo
.Flags
& FlagsToExclude
)
274 // Ignore positional argument option candidates (which do not
276 if (!CandidateInfo
.Prefixes
)
278 // Find the most appropriate prefix. For example, if a user asks for
279 // "--helm", suggest "--help" over "-help".
280 StringRef Prefix
= CandidateInfo
.Prefixes
[0];
281 for (int P
= 1; CandidateInfo
.Prefixes
[P
]; P
++) {
282 if (Option
.startswith(CandidateInfo
.Prefixes
[P
]))
283 Prefix
= CandidateInfo
.Prefixes
[P
];
286 // Check if the candidate ends with a character commonly used when
287 // delimiting an option from its value, such as '=' or ':'. If it does,
288 // attempt to split the given option based on that delimiter.
289 std::string Delimiter
= "";
290 char Last
= CandidateName
.back();
291 if (Last
== '=' || Last
== ':')
292 Delimiter
= std::string(1, Last
);
295 if (Delimiter
.empty())
298 std::tie(LHS
, RHS
) = Option
.split(Last
);
300 std::string NormalizedName
=
301 (LHS
.drop_front(Prefix
.size()) + Delimiter
).str();
303 CandidateName
.edit_distance(NormalizedName
, /*AllowReplacements=*/true,
304 /*MaxEditDistance=*/BestDistance
);
305 if (Distance
< BestDistance
) {
306 BestDistance
= Distance
;
307 NearestString
= (Prefix
+ CandidateName
+ RHS
).str();
313 bool OptTable::addValues(const char *Option
, const char *Values
) {
314 for (size_t I
= FirstSearchableIndex
, E
= OptionInfos
.size(); I
< E
; I
++) {
315 Info
&In
= OptionInfos
[I
];
316 if (optionMatches(In
, Option
)) {
324 Arg
*OptTable::ParseOneArg(const ArgList
&Args
, unsigned &Index
,
325 unsigned FlagsToInclude
,
326 unsigned FlagsToExclude
) const {
327 unsigned Prev
= Index
;
328 const char *Str
= Args
.getArgString(Index
);
330 // Anything that doesn't start with PrefixesUnion is an input, as is '-'
332 if (isInput(PrefixesUnion
, Str
))
333 return new Arg(getOption(TheInputOptionID
), Str
, Index
++, Str
);
335 const Info
*Start
= OptionInfos
.data() + FirstSearchableIndex
;
336 const Info
*End
= OptionInfos
.data() + OptionInfos
.size();
337 StringRef Name
= StringRef(Str
).ltrim(PrefixChars
);
339 // Search for the first next option which could be a prefix.
340 Start
= std::lower_bound(Start
, End
, Name
.data());
342 // Options are stored in sorted order, with '\0' at the end of the
343 // alphabet. Since the only options which can accept a string must
344 // prefix it, we iteratively search for the next option which could
347 // FIXME: This is searching much more than necessary, but I am
348 // blanking on the simplest way to make it fast. We can solve this
349 // problem when we move to TableGen.
350 for (; Start
!= End
; ++Start
) {
351 unsigned ArgSize
= 0;
352 // Scan for first option which is a proper prefix.
353 for (; Start
!= End
; ++Start
)
354 if ((ArgSize
= matchOption(Start
, Str
, IgnoreCase
)))
359 Option
Opt(Start
, this);
361 if (FlagsToInclude
&& !Opt
.hasFlag(FlagsToInclude
))
363 if (Opt
.hasFlag(FlagsToExclude
))
366 // See if this option matches.
367 if (Arg
*A
= Opt
.accept(Args
, Index
, ArgSize
))
370 // Otherwise, see if this argument was missing values.
375 // If we failed to find an option and this arg started with /, then it's
376 // probably an input path.
378 return new Arg(getOption(TheInputOptionID
), Str
, Index
++, Str
);
380 return new Arg(getOption(TheUnknownOptionID
), Str
, Index
++, Str
);
383 InputArgList
OptTable::ParseArgs(ArrayRef
<const char *> ArgArr
,
384 unsigned &MissingArgIndex
,
385 unsigned &MissingArgCount
,
386 unsigned FlagsToInclude
,
387 unsigned FlagsToExclude
) const {
388 InputArgList
Args(ArgArr
.begin(), ArgArr
.end());
390 // FIXME: Handle '@' args (or at least error on them).
392 MissingArgIndex
= MissingArgCount
= 0;
393 unsigned Index
= 0, End
= ArgArr
.size();
394 while (Index
< End
) {
395 // Ingore nullptrs, they are response file's EOL markers
396 if (Args
.getArgString(Index
) == nullptr) {
400 // Ignore empty arguments (other things may still take them as arguments).
401 StringRef Str
= Args
.getArgString(Index
);
407 unsigned Prev
= Index
;
408 Arg
*A
= ParseOneArg(Args
, Index
, FlagsToInclude
, FlagsToExclude
);
409 assert(Index
> Prev
&& "Parser failed to consume argument.");
411 // Check for missing argument error.
413 assert(Index
>= End
&& "Unexpected parser error.");
414 assert(Index
- Prev
- 1 && "No missing arguments!");
415 MissingArgIndex
= Prev
;
416 MissingArgCount
= Index
- Prev
- 1;
426 static std::string
getOptionHelpName(const OptTable
&Opts
, OptSpecifier Id
) {
427 const Option O
= Opts
.getOption(Id
);
428 std::string Name
= O
.getPrefixedName();
430 // Add metavar, if used.
431 switch (O
.getKind()) {
432 case Option::GroupClass
: case Option::InputClass
: case Option::UnknownClass
:
433 llvm_unreachable("Invalid option with help text.");
435 case Option::MultiArgClass
:
436 if (const char *MetaVarName
= Opts
.getOptionMetaVar(Id
)) {
437 // For MultiArgs, metavar is full list of all argument names.
442 // For MultiArgs<N>, if metavar not supplied, print <value> N times.
443 for (unsigned i
=0, e
=O
.getNumArgs(); i
< e
; ++i
) {
449 case Option::FlagClass
:
452 case Option::ValuesClass
:
455 case Option::SeparateClass
: case Option::JoinedOrSeparateClass
:
456 case Option::RemainingArgsClass
: case Option::RemainingArgsJoinedClass
:
459 case Option::JoinedClass
: case Option::CommaJoinedClass
:
460 case Option::JoinedAndSeparateClass
:
461 if (const char *MetaVarName
= Opts
.getOptionMetaVar(Id
))
478 static void PrintHelpOptionList(raw_ostream
&OS
, StringRef Title
,
479 std::vector
<OptionInfo
> &OptionHelp
) {
480 OS
<< Title
<< ":\n";
482 // Find the maximum option length.
483 unsigned OptionFieldWidth
= 0;
484 for (unsigned i
= 0, e
= OptionHelp
.size(); i
!= e
; ++i
) {
485 // Limit the amount of padding we are willing to give up for alignment.
486 unsigned Length
= OptionHelp
[i
].Name
.size();
488 OptionFieldWidth
= std::max(OptionFieldWidth
, Length
);
491 const unsigned InitialPad
= 2;
492 for (unsigned i
= 0, e
= OptionHelp
.size(); i
!= e
; ++i
) {
493 const std::string
&Option
= OptionHelp
[i
].Name
;
494 int Pad
= OptionFieldWidth
- int(Option
.size());
495 OS
.indent(InitialPad
) << Option
;
497 // Break on long option names.
500 Pad
= OptionFieldWidth
+ InitialPad
;
502 OS
.indent(Pad
+ 1) << OptionHelp
[i
].HelpText
<< '\n';
506 static const char *getOptionHelpGroup(const OptTable
&Opts
, OptSpecifier Id
) {
507 unsigned GroupID
= Opts
.getOptionGroupID(Id
);
509 // If not in a group, return the default help group.
513 // Abuse the help text of the option groups to store the "help group"
516 // FIXME: Split out option groups.
517 if (const char *GroupHelp
= Opts
.getOptionHelpText(GroupID
))
520 // Otherwise keep looking.
521 return getOptionHelpGroup(Opts
, GroupID
);
524 void OptTable::PrintHelp(raw_ostream
&OS
, const char *Usage
, const char *Title
,
525 bool ShowHidden
, bool ShowAllAliases
) const {
526 PrintHelp(OS
, Usage
, Title
, /*Include*/ 0, /*Exclude*/
527 (ShowHidden
? 0 : HelpHidden
), ShowAllAliases
);
530 void OptTable::PrintHelp(raw_ostream
&OS
, const char *Usage
, const char *Title
,
531 unsigned FlagsToInclude
, unsigned FlagsToExclude
,
532 bool ShowAllAliases
) const {
533 OS
<< "OVERVIEW: " << Title
<< "\n\n";
534 OS
<< "USAGE: " << Usage
<< "\n\n";
536 // Render help text into a map of group-name to a list of (option, help)
538 std::map
<std::string
, std::vector
<OptionInfo
>> GroupedOptionHelp
;
540 for (unsigned Id
= 1, e
= getNumOptions() + 1; Id
!= e
; ++Id
) {
541 // FIXME: Split out option groups.
542 if (getOptionKind(Id
) == Option::GroupClass
)
545 unsigned Flags
= getInfo(Id
).Flags
;
546 if (FlagsToInclude
&& !(Flags
& FlagsToInclude
))
548 if (Flags
& FlagsToExclude
)
551 // If an alias doesn't have a help text, show a help text for the aliased
553 const char *HelpText
= getOptionHelpText(Id
);
554 if (!HelpText
&& ShowAllAliases
) {
555 const Option Alias
= getOption(Id
).getAlias();
557 HelpText
= getOptionHelpText(Alias
.getID());
561 const char *HelpGroup
= getOptionHelpGroup(*this, Id
);
562 const std::string
&OptName
= getOptionHelpName(*this, Id
);
563 GroupedOptionHelp
[HelpGroup
].push_back({OptName
, HelpText
});
567 for (auto& OptionGroup
: GroupedOptionHelp
) {
568 if (OptionGroup
.first
!= GroupedOptionHelp
.begin()->first
)
570 PrintHelpOptionList(OS
, OptionGroup
.first
, OptionGroup
.second
);