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
))
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
))
250 bool OptTable::addValues(const char *Option
, const char *Values
) {
251 for (size_t I
= FirstSearchableIndex
, E
= OptionInfos
.size(); I
< E
; I
++) {
252 Info
&In
= OptionInfos
[I
];
253 if (optionMatches(In
, Option
)) {
261 Arg
*OptTable::ParseOneArg(const ArgList
&Args
, unsigned &Index
,
262 unsigned FlagsToInclude
,
263 unsigned FlagsToExclude
) const {
264 unsigned Prev
= Index
;
265 const char *Str
= Args
.getArgString(Index
);
267 // Anything that doesn't start with PrefixesUnion is an input, as is '-'
269 if (isInput(PrefixesUnion
, Str
))
270 return new Arg(getOption(TheInputOptionID
), Str
, Index
++, Str
);
272 const Info
*Start
= OptionInfos
.data() + FirstSearchableIndex
;
273 const Info
*End
= OptionInfos
.data() + OptionInfos
.size();
274 StringRef Name
= StringRef(Str
).ltrim(PrefixChars
);
276 // Search for the first next option which could be a prefix.
277 Start
= std::lower_bound(Start
, End
, Name
.data());
279 // Options are stored in sorted order, with '\0' at the end of the
280 // alphabet. Since the only options which can accept a string must
281 // prefix it, we iteratively search for the next option which could
284 // FIXME: This is searching much more than necessary, but I am
285 // blanking on the simplest way to make it fast. We can solve this
286 // problem when we move to TableGen.
287 for (; Start
!= End
; ++Start
) {
288 unsigned ArgSize
= 0;
289 // Scan for first option which is a proper prefix.
290 for (; Start
!= End
; ++Start
)
291 if ((ArgSize
= matchOption(Start
, Str
, IgnoreCase
)))
296 Option
Opt(Start
, this);
298 if (FlagsToInclude
&& !Opt
.hasFlag(FlagsToInclude
))
300 if (Opt
.hasFlag(FlagsToExclude
))
303 // See if this option matches.
304 if (Arg
*A
= Opt
.accept(Args
, Index
, ArgSize
))
307 // Otherwise, see if this argument was missing values.
312 // If we failed to find an option and this arg started with /, then it's
313 // probably an input path.
315 return new Arg(getOption(TheInputOptionID
), Str
, Index
++, Str
);
317 return new Arg(getOption(TheUnknownOptionID
), Str
, Index
++, Str
);
320 InputArgList
OptTable::ParseArgs(ArrayRef
<const char *> ArgArr
,
321 unsigned &MissingArgIndex
,
322 unsigned &MissingArgCount
,
323 unsigned FlagsToInclude
,
324 unsigned FlagsToExclude
) const {
325 InputArgList
Args(ArgArr
.begin(), ArgArr
.end());
327 // FIXME: Handle '@' args (or at least error on them).
329 MissingArgIndex
= MissingArgCount
= 0;
330 unsigned Index
= 0, End
= ArgArr
.size();
331 while (Index
< End
) {
332 // Ingore nullptrs, they are response file's EOL markers
333 if (Args
.getArgString(Index
) == nullptr) {
337 // Ignore empty arguments (other things may still take them as arguments).
338 StringRef Str
= Args
.getArgString(Index
);
344 unsigned Prev
= Index
;
345 Arg
*A
= ParseOneArg(Args
, Index
, FlagsToInclude
, FlagsToExclude
);
346 assert(Index
> Prev
&& "Parser failed to consume argument.");
348 // Check for missing argument error.
350 assert(Index
>= End
&& "Unexpected parser error.");
351 assert(Index
- Prev
- 1 && "No missing arguments!");
352 MissingArgIndex
= Prev
;
353 MissingArgCount
= Index
- Prev
- 1;
363 static std::string
getOptionHelpName(const OptTable
&Opts
, OptSpecifier Id
) {
364 const Option O
= Opts
.getOption(Id
);
365 std::string Name
= O
.getPrefixedName();
367 // Add metavar, if used.
368 switch (O
.getKind()) {
369 case Option::GroupClass
: case Option::InputClass
: case Option::UnknownClass
:
370 llvm_unreachable("Invalid option with help text.");
372 case Option::MultiArgClass
:
373 if (const char *MetaVarName
= Opts
.getOptionMetaVar(Id
)) {
374 // For MultiArgs, metavar is full list of all argument names.
379 // For MultiArgs<N>, if metavar not supplied, print <value> N times.
380 for (unsigned i
=0, e
=O
.getNumArgs(); i
< e
; ++i
) {
386 case Option::FlagClass
:
389 case Option::ValuesClass
:
392 case Option::SeparateClass
: case Option::JoinedOrSeparateClass
:
393 case Option::RemainingArgsClass
: case Option::RemainingArgsJoinedClass
:
396 case Option::JoinedClass
: case Option::CommaJoinedClass
:
397 case Option::JoinedAndSeparateClass
:
398 if (const char *MetaVarName
= Opts
.getOptionMetaVar(Id
))
415 static void PrintHelpOptionList(raw_ostream
&OS
, StringRef Title
,
416 std::vector
<OptionInfo
> &OptionHelp
) {
417 OS
<< Title
<< ":\n";
419 // Find the maximum option length.
420 unsigned OptionFieldWidth
= 0;
421 for (unsigned i
= 0, e
= OptionHelp
.size(); i
!= e
; ++i
) {
422 // Limit the amount of padding we are willing to give up for alignment.
423 unsigned Length
= OptionHelp
[i
].Name
.size();
425 OptionFieldWidth
= std::max(OptionFieldWidth
, Length
);
428 const unsigned InitialPad
= 2;
429 for (unsigned i
= 0, e
= OptionHelp
.size(); i
!= e
; ++i
) {
430 const std::string
&Option
= OptionHelp
[i
].Name
;
431 int Pad
= OptionFieldWidth
- int(Option
.size());
432 OS
.indent(InitialPad
) << Option
;
434 // Break on long option names.
437 Pad
= OptionFieldWidth
+ InitialPad
;
439 OS
.indent(Pad
+ 1) << OptionHelp
[i
].HelpText
<< '\n';
443 static const char *getOptionHelpGroup(const OptTable
&Opts
, OptSpecifier Id
) {
444 unsigned GroupID
= Opts
.getOptionGroupID(Id
);
446 // If not in a group, return the default help group.
450 // Abuse the help text of the option groups to store the "help group"
453 // FIXME: Split out option groups.
454 if (const char *GroupHelp
= Opts
.getOptionHelpText(GroupID
))
457 // Otherwise keep looking.
458 return getOptionHelpGroup(Opts
, GroupID
);
461 void OptTable::PrintHelp(raw_ostream
&OS
, const char *Name
, const char *Title
,
462 bool ShowHidden
, bool ShowAllAliases
) const {
463 PrintHelp(OS
, Name
, Title
, /*Include*/ 0, /*Exclude*/
464 (ShowHidden
? 0 : HelpHidden
), ShowAllAliases
);
467 void OptTable::PrintHelp(raw_ostream
&OS
, const char *Name
, const char *Title
,
468 unsigned FlagsToInclude
, unsigned FlagsToExclude
,
469 bool ShowAllAliases
) const {
470 OS
<< "OVERVIEW: " << Title
<< "\n";
472 OS
<< "USAGE: " << Name
<< " [options] <inputs>\n";
475 // Render help text into a map of group-name to a list of (option, help)
477 using helpmap_ty
= std::map
<std::string
, std::vector
<OptionInfo
>>;
478 helpmap_ty GroupedOptionHelp
;
480 for (unsigned i
= 0, e
= getNumOptions(); i
!= e
; ++i
) {
483 // FIXME: Split out option groups.
484 if (getOptionKind(Id
) == Option::GroupClass
)
487 unsigned Flags
= getInfo(Id
).Flags
;
488 if (FlagsToInclude
&& !(Flags
& FlagsToInclude
))
490 if (Flags
& FlagsToExclude
)
493 // If an alias doesn't have a help text, show a help text for the aliased
495 const char *HelpText
= getOptionHelpText(Id
);
496 if (!HelpText
&& ShowAllAliases
) {
497 const Option Alias
= getOption(Id
).getAlias();
499 HelpText
= getOptionHelpText(Alias
.getID());
503 const char *HelpGroup
= getOptionHelpGroup(*this, Id
);
504 const std::string
&OptName
= getOptionHelpName(*this, Id
);
505 GroupedOptionHelp
[HelpGroup
].push_back({OptName
, HelpText
});
509 for (helpmap_ty::iterator it
= GroupedOptionHelp
.begin(),
510 ie
= GroupedOptionHelp
.end(); it
!= ie
; ++it
) {
511 if (it
!= GroupedOptionHelp
.begin())
513 PrintHelpOptionList(OS
, it
->first
, it
->second
);