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/Option/Option.h"
10 #include "llvm/ADT/StringRef.h"
11 #include "llvm/ADT/Twine.h"
12 #include "llvm/Config/llvm-config.h"
13 #include "llvm/Option/Arg.h"
14 #include "llvm/Option/ArgList.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"
23 using namespace llvm::opt
;
25 Option::Option(const OptTable::Info
*info
, const OptTable
*owner
)
26 : Info(info
), Owner(owner
) {
27 // Multi-level aliases are not supported. This just simplifies option
28 // tracking, it is not an inherent limitation.
29 assert((!Info
|| !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
30 "Multi-level aliases are not supported.");
32 if (Info
&& getAliasArgs()) {
33 assert(getAlias().isValid() && "Only alias options can have alias args.");
34 assert(getKind() == FlagClass
&& "Only Flag aliases can have alias args.");
35 assert(getAlias().getKind() != FlagClass
&&
36 "Cannot provide alias args to a flag option.");
40 void Option::print(raw_ostream
&O
, bool AddNewLine
) const {
43 #define P(N) case N: O << #N; break
53 P(JoinedOrSeparateClass
);
54 P(JoinedAndSeparateClass
);
55 P(RemainingArgsClass
);
56 P(RemainingArgsJoinedClass
);
60 if (!Info
->hasNoPrefix()) {
62 for (size_t I
= 0, N
= Info
->getNumPrefixes(Owner
->getPrefixesTable());
65 << Info
->getPrefix(Owner
->getStrTable(), Owner
->getPrefixesTable(), I
)
66 << (I
== N
- 1 ? "\"" : "\", ");
70 O
<< " Name:\"" << getName() << '"';
72 const Option Group
= getGroup();
73 if (Group
.isValid()) {
75 Group
.print(O
, /*AddNewLine=*/false);
78 const Option Alias
= getAlias();
79 if (Alias
.isValid()) {
81 Alias
.print(O
, /*AddNewLine=*/false);
84 if (getKind() == MultiArgClass
)
85 O
<< " NumArgs:" << getNumArgs();
92 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
93 LLVM_DUMP_METHOD
void Option::dump() const { print(dbgs()); }
96 bool Option::matches(OptSpecifier Opt
) const {
97 // Aliases are never considered in matching, look through them.
98 const Option Alias
= getAlias();
100 return Alias
.matches(Opt
);
102 // Check exact match.
103 if (getID() == Opt
.getID())
106 const Option Group
= getGroup();
108 return Group
.matches(Opt
);
112 std::unique_ptr
<Arg
> Option::acceptInternal(const ArgList
&Args
,
114 unsigned &Index
) const {
115 const size_t SpellingSize
= Spelling
.size();
116 const size_t ArgStringSize
= StringRef(Args
.getArgString(Index
)).size();
119 if (SpellingSize
!= ArgStringSize
)
121 return std::make_unique
<Arg
>(*this, Spelling
, Index
++);
124 const char *Value
= Args
.getArgString(Index
) + SpellingSize
;
125 return std::make_unique
<Arg
>(*this, Spelling
, Index
++, Value
);
127 case CommaJoinedClass
: {
129 const char *Str
= Args
.getArgString(Index
) + SpellingSize
;
130 auto A
= std::make_unique
<Arg
>(*this, Spelling
, Index
++);
132 // Parse out the comma separated values.
133 const char *Prev
= Str
;
137 if (!c
|| c
== ',') {
139 char *Value
= new char[Str
- Prev
+ 1];
140 memcpy(Value
, Prev
, Str
- Prev
);
141 Value
[Str
- Prev
] = '\0';
142 A
->getValues().push_back(Value
);
151 A
->setOwnsValues(true);
156 // Matches iff this is an exact match.
157 if (SpellingSize
!= ArgStringSize
)
161 if (Index
> Args
.getNumInputArgStrings() ||
162 Args
.getArgString(Index
- 1) == nullptr)
165 return std::make_unique
<Arg
>(*this, Spelling
, Index
- 2,
166 Args
.getArgString(Index
- 1));
167 case MultiArgClass
: {
168 // Matches iff this is an exact match.
169 if (SpellingSize
!= ArgStringSize
)
172 Index
+= 1 + getNumArgs();
173 if (Index
> Args
.getNumInputArgStrings())
176 auto A
= std::make_unique
<Arg
>(*this, Spelling
, Index
- 1 - getNumArgs(),
177 Args
.getArgString(Index
- getNumArgs()));
178 for (unsigned i
= 1; i
!= getNumArgs(); ++i
)
179 A
->getValues().push_back(Args
.getArgString(Index
- getNumArgs() + i
));
182 case JoinedOrSeparateClass
: {
183 // If this is not an exact match, it is a joined arg.
184 if (SpellingSize
!= ArgStringSize
) {
185 const char *Value
= Args
.getArgString(Index
) + SpellingSize
;
186 return std::make_unique
<Arg
>(*this, Spelling
, Index
++, Value
);
189 // Otherwise it must be separate.
191 if (Index
> Args
.getNumInputArgStrings() ||
192 Args
.getArgString(Index
- 1) == nullptr)
195 return std::make_unique
<Arg
>(*this, Spelling
, Index
- 2,
196 Args
.getArgString(Index
- 1));
198 case JoinedAndSeparateClass
:
201 if (Index
> Args
.getNumInputArgStrings() ||
202 Args
.getArgString(Index
- 1) == nullptr)
205 return std::make_unique
<Arg
>(*this, Spelling
, Index
- 2,
206 Args
.getArgString(Index
- 2) + SpellingSize
,
207 Args
.getArgString(Index
- 1));
208 case RemainingArgsClass
: {
209 // Matches iff this is an exact match.
210 if (SpellingSize
!= ArgStringSize
)
212 auto A
= std::make_unique
<Arg
>(*this, Spelling
, Index
++);
213 while (Index
< Args
.getNumInputArgStrings() &&
214 Args
.getArgString(Index
) != nullptr)
215 A
->getValues().push_back(Args
.getArgString(Index
++));
218 case RemainingArgsJoinedClass
: {
219 auto A
= std::make_unique
<Arg
>(*this, Spelling
, Index
);
220 if (SpellingSize
!= ArgStringSize
) {
221 // An inexact match means there is a joined arg.
222 A
->getValues().push_back(Args
.getArgString(Index
) + SpellingSize
);
225 while (Index
< Args
.getNumInputArgStrings() &&
226 Args
.getArgString(Index
) != nullptr)
227 A
->getValues().push_back(Args
.getArgString(Index
++));
232 llvm_unreachable("Invalid option kind!");
236 std::unique_ptr
<Arg
> Option::accept(const ArgList
&Args
, StringRef CurArg
,
237 bool GroupedShortOption
,
238 unsigned &Index
) const {
239 auto A(GroupedShortOption
&& getKind() == FlagClass
240 ? std::make_unique
<Arg
>(*this, CurArg
, Index
)
241 : acceptInternal(Args
, CurArg
, Index
));
245 const Option
&UnaliasedOption
= getUnaliasedOption();
246 if (getID() == UnaliasedOption
.getID())
249 // "A" is an alias for a different flag. For most clients it's more convenient
250 // if this function returns unaliased Args, so create an unaliased arg for
253 // This creates a completely new Arg object for the unaliased Arg because
254 // the alias and the unaliased arg can have different Kinds and different
255 // Values (due to AliasArgs<>).
257 // Get the spelling from the unaliased option.
258 StringRef UnaliasedSpelling
= Args
.MakeArgString(
259 Twine(UnaliasedOption
.getPrefix()) + Twine(UnaliasedOption
.getName()));
261 // It's a bit weird that aliased and unaliased arg share one index, but
262 // the index is mostly use as a memory optimization in render().
263 // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling
264 // of the aliased arg always, while A->getSpelling() returns either the
265 // unaliased or the aliased arg, depending on which Arg object it's called on.
267 std::make_unique
<Arg
>(UnaliasedOption
, UnaliasedSpelling
, A
->getIndex());
269 UnaliasedA
->setAlias(std::move(A
));
271 if (getKind() != FlagClass
) {
272 // Values are usually owned by the ArgList. The exception are
273 // CommaJoined flags, where the Arg owns the values. For aliased flags,
274 // make the unaliased Arg the owner of the values.
275 // FIXME: There aren't many uses of CommaJoined -- try removing
276 // CommaJoined in favor of just calling StringRef::split(',') instead.
277 UnaliasedA
->getValues() = RawA
->getValues();
278 UnaliasedA
->setOwnsValues(RawA
->getOwnsValues());
279 RawA
->setOwnsValues(false);
283 // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg.
284 if (const char *Val
= getAliasArgs()) {
285 while (*Val
!= '\0') {
286 UnaliasedA
->getValues().push_back(Val
);
288 // Move past the '\0' to the next argument.
289 Val
+= strlen(Val
) + 1;
292 if (UnaliasedOption
.getKind() == JoinedClass
&& !getAliasArgs())
293 // A Flag alias for a Joined option must provide an argument.
294 UnaliasedA
->getValues().push_back("");