1 //===- Option.cpp - Abstract Driver Options -------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/StringRef.h"
10 #include "llvm/ADT/Twine.h"
11 #include "llvm/Config/llvm-config.h"
12 #include "llvm/Option/Arg.h"
13 #include "llvm/Option/ArgList.h"
14 #include "llvm/Option/Option.h"
15 #include "llvm/Option/OptTable.h"
16 #include "llvm/Support/Compiler.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/raw_ostream.h"
24 using namespace llvm::opt
;
26 Option::Option(const OptTable::Info
*info
, const OptTable
*owner
)
27 : Info(info
), Owner(owner
) {
28 // Multi-level aliases are not supported. This just simplifies option
29 // tracking, it is not an inherent limitation.
30 assert((!Info
|| !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
31 "Multi-level aliases are not supported.");
33 if (Info
&& getAliasArgs()) {
34 assert(getAlias().isValid() && "Only alias options can have alias args.");
35 assert(getKind() == FlagClass
&& "Only Flag aliases can have alias args.");
36 assert(getAlias().getKind() != FlagClass
&&
37 "Cannot provide alias args to a flag option.");
41 void Option::print(raw_ostream
&O
) const {
44 #define P(N) case N: O << #N; break
54 P(JoinedOrSeparateClass
);
55 P(JoinedAndSeparateClass
);
56 P(RemainingArgsClass
);
57 P(RemainingArgsJoinedClass
);
61 if (!Info
->Prefixes
.empty()) {
63 for (size_t I
= 0, N
= Info
->Prefixes
.size(); I
!= N
; ++I
)
64 O
<< '"' << Info
->Prefixes
[I
] << (I
== N
- 1 ? "\"" : "\", ");
68 O
<< " Name:\"" << getName() << '"';
70 const Option Group
= getGroup();
71 if (Group
.isValid()) {
76 const Option Alias
= getAlias();
77 if (Alias
.isValid()) {
82 if (getKind() == MultiArgClass
)
83 O
<< " NumArgs:" << getNumArgs();
88 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
89 LLVM_DUMP_METHOD
void Option::dump() const { print(dbgs()); }
92 bool Option::matches(OptSpecifier Opt
) const {
93 // Aliases are never considered in matching, look through them.
94 const Option Alias
= getAlias();
96 return Alias
.matches(Opt
);
99 if (getID() == Opt
.getID())
102 const Option Group
= getGroup();
104 return Group
.matches(Opt
);
108 std::unique_ptr
<Arg
> Option::acceptInternal(const ArgList
&Args
,
110 unsigned &Index
) const {
111 const size_t SpellingSize
= Spelling
.size();
112 const size_t ArgStringSize
= StringRef(Args
.getArgString(Index
)).size();
115 if (SpellingSize
!= ArgStringSize
)
117 return std::make_unique
<Arg
>(*this, Spelling
, Index
++);
120 const char *Value
= Args
.getArgString(Index
) + SpellingSize
;
121 return std::make_unique
<Arg
>(*this, Spelling
, Index
++, Value
);
123 case CommaJoinedClass
: {
125 const char *Str
= Args
.getArgString(Index
) + SpellingSize
;
126 auto A
= std::make_unique
<Arg
>(*this, Spelling
, Index
++);
128 // Parse out the comma separated values.
129 const char *Prev
= Str
;
133 if (!c
|| c
== ',') {
135 char *Value
= new char[Str
- Prev
+ 1];
136 memcpy(Value
, Prev
, Str
- Prev
);
137 Value
[Str
- Prev
] = '\0';
138 A
->getValues().push_back(Value
);
147 A
->setOwnsValues(true);
152 // Matches iff this is an exact match.
153 if (SpellingSize
!= ArgStringSize
)
157 if (Index
> Args
.getNumInputArgStrings() ||
158 Args
.getArgString(Index
- 1) == nullptr)
161 return std::make_unique
<Arg
>(*this, Spelling
, Index
- 2,
162 Args
.getArgString(Index
- 1));
163 case MultiArgClass
: {
164 // Matches iff this is an exact match.
165 if (SpellingSize
!= ArgStringSize
)
168 Index
+= 1 + getNumArgs();
169 if (Index
> Args
.getNumInputArgStrings())
172 auto A
= std::make_unique
<Arg
>(*this, Spelling
, Index
- 1 - getNumArgs(),
173 Args
.getArgString(Index
- getNumArgs()));
174 for (unsigned i
= 1; i
!= getNumArgs(); ++i
)
175 A
->getValues().push_back(Args
.getArgString(Index
- getNumArgs() + i
));
178 case JoinedOrSeparateClass
: {
179 // If this is not an exact match, it is a joined arg.
180 if (SpellingSize
!= ArgStringSize
) {
181 const char *Value
= Args
.getArgString(Index
) + SpellingSize
;
182 return std::make_unique
<Arg
>(*this, Spelling
, Index
++, Value
);
185 // Otherwise it must be separate.
187 if (Index
> Args
.getNumInputArgStrings() ||
188 Args
.getArgString(Index
- 1) == nullptr)
191 return std::make_unique
<Arg
>(*this, Spelling
, Index
- 2,
192 Args
.getArgString(Index
- 1));
194 case JoinedAndSeparateClass
:
197 if (Index
> Args
.getNumInputArgStrings() ||
198 Args
.getArgString(Index
- 1) == nullptr)
201 return std::make_unique
<Arg
>(*this, Spelling
, Index
- 2,
202 Args
.getArgString(Index
- 2) + SpellingSize
,
203 Args
.getArgString(Index
- 1));
204 case RemainingArgsClass
: {
205 // Matches iff this is an exact match.
206 if (SpellingSize
!= ArgStringSize
)
208 auto A
= std::make_unique
<Arg
>(*this, Spelling
, Index
++);
209 while (Index
< Args
.getNumInputArgStrings() &&
210 Args
.getArgString(Index
) != nullptr)
211 A
->getValues().push_back(Args
.getArgString(Index
++));
214 case RemainingArgsJoinedClass
: {
215 auto A
= std::make_unique
<Arg
>(*this, Spelling
, Index
);
216 if (SpellingSize
!= ArgStringSize
) {
217 // An inexact match means there is a joined arg.
218 A
->getValues().push_back(Args
.getArgString(Index
) + SpellingSize
);
221 while (Index
< Args
.getNumInputArgStrings() &&
222 Args
.getArgString(Index
) != nullptr)
223 A
->getValues().push_back(Args
.getArgString(Index
++));
228 llvm_unreachable("Invalid option kind!");
232 std::unique_ptr
<Arg
> Option::accept(const ArgList
&Args
, StringRef CurArg
,
233 bool GroupedShortOption
,
234 unsigned &Index
) const {
235 auto A(GroupedShortOption
&& getKind() == FlagClass
236 ? std::make_unique
<Arg
>(*this, CurArg
, Index
)
237 : acceptInternal(Args
, CurArg
, Index
));
241 const Option
&UnaliasedOption
= getUnaliasedOption();
242 if (getID() == UnaliasedOption
.getID())
245 // "A" is an alias for a different flag. For most clients it's more convenient
246 // if this function returns unaliased Args, so create an unaliased arg for
249 // This creates a completely new Arg object for the unaliased Arg because
250 // the alias and the unaliased arg can have different Kinds and different
251 // Values (due to AliasArgs<>).
253 // Get the spelling from the unaliased option.
254 StringRef UnaliasedSpelling
= Args
.MakeArgString(
255 Twine(UnaliasedOption
.getPrefix()) + Twine(UnaliasedOption
.getName()));
257 // It's a bit weird that aliased and unaliased arg share one index, but
258 // the index is mostly use as a memory optimization in render().
259 // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling
260 // of the aliased arg always, while A->getSpelling() returns either the
261 // unaliased or the aliased arg, depending on which Arg object it's called on.
263 std::make_unique
<Arg
>(UnaliasedOption
, UnaliasedSpelling
, A
->getIndex());
265 UnaliasedA
->setAlias(std::move(A
));
267 if (getKind() != FlagClass
) {
268 // Values are usually owned by the ArgList. The exception are
269 // CommaJoined flags, where the Arg owns the values. For aliased flags,
270 // make the unaliased Arg the owner of the values.
271 // FIXME: There aren't many uses of CommaJoined -- try removing
272 // CommaJoined in favor of just calling StringRef::split(',') instead.
273 UnaliasedA
->getValues() = RawA
->getValues();
274 UnaliasedA
->setOwnsValues(RawA
->getOwnsValues());
275 RawA
->setOwnsValues(false);
279 // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg.
280 if (const char *Val
= getAliasArgs()) {
281 while (*Val
!= '\0') {
282 UnaliasedA
->getValues().push_back(Val
);
284 // Move past the '\0' to the next argument.
285 Val
+= strlen(Val
) + 1;
288 if (UnaliasedOption
.getKind() == JoinedClass
&& !getAliasArgs())
289 // A Flag alias for a Joined option must provide an argument.
290 UnaliasedA
->getValues().push_back("");