1 //===- Option.cpp - Abstract Driver Options -------------------------------===//
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/StringRef.h"
11 #include "llvm/ADT/Twine.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
);
63 for (const char *const *Pre
= Info
->Prefixes
; *Pre
!= nullptr; ++Pre
) {
64 O
<< '"' << *Pre
<< (*(Pre
+ 1) == nullptr ? "\"" : "\", ");
69 O
<< " Name:\"" << getName() << '"';
71 const Option Group
= getGroup();
72 if (Group
.isValid()) {
77 const Option Alias
= getAlias();
78 if (Alias
.isValid()) {
83 if (getKind() == MultiArgClass
)
84 O
<< " NumArgs:" << getNumArgs();
89 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
90 LLVM_DUMP_METHOD
void Option::dump() const { print(dbgs()); }
93 bool Option::matches(OptSpecifier Opt
) const {
94 // Aliases are never considered in matching, look through them.
95 const Option Alias
= getAlias();
97 return Alias
.matches(Opt
);
100 if (getID() == Opt
.getID())
103 const Option Group
= getGroup();
105 return Group
.matches(Opt
);
109 Arg
*Option::accept(const ArgList
&Args
,
111 unsigned ArgSize
) const {
112 const Option
&UnaliasedOption
= getUnaliasedOption();
114 // If the option was an alias, get the spelling from the unaliased one.
115 if (getID() == UnaliasedOption
.getID()) {
116 Spelling
= StringRef(Args
.getArgString(Index
), ArgSize
);
118 Spelling
= Args
.MakeArgString(Twine(UnaliasedOption
.getPrefix()) +
119 Twine(UnaliasedOption
.getName()));
124 if (ArgSize
!= strlen(Args
.getArgString(Index
)))
127 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
++);
128 if (getAliasArgs()) {
129 const char *Val
= getAliasArgs();
130 while (*Val
!= '\0') {
131 A
->getValues().push_back(Val
);
133 // Move past the '\0' to the next argument.
134 Val
+= strlen(Val
) + 1;
138 if (UnaliasedOption
.getKind() == JoinedClass
&& !getAliasArgs())
139 // A Flag alias for a Joined option must provide an argument.
140 A
->getValues().push_back("");
145 const char *Value
= Args
.getArgString(Index
) + ArgSize
;
146 return new Arg(UnaliasedOption
, Spelling
, Index
++, Value
);
148 case CommaJoinedClass
: {
150 const char *Str
= Args
.getArgString(Index
) + ArgSize
;
151 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
++);
153 // Parse out the comma separated values.
154 const char *Prev
= Str
;
158 if (!c
|| c
== ',') {
160 char *Value
= new char[Str
- Prev
+ 1];
161 memcpy(Value
, Prev
, Str
- Prev
);
162 Value
[Str
- Prev
] = '\0';
163 A
->getValues().push_back(Value
);
172 A
->setOwnsValues(true);
177 // Matches iff this is an exact match.
178 // FIXME: Avoid strlen.
179 if (ArgSize
!= strlen(Args
.getArgString(Index
)))
183 if (Index
> Args
.getNumInputArgStrings() ||
184 Args
.getArgString(Index
- 1) == nullptr)
187 return new Arg(UnaliasedOption
, Spelling
,
188 Index
- 2, Args
.getArgString(Index
- 1));
189 case MultiArgClass
: {
190 // Matches iff this is an exact match.
191 // FIXME: Avoid strlen.
192 if (ArgSize
!= strlen(Args
.getArgString(Index
)))
195 Index
+= 1 + getNumArgs();
196 if (Index
> Args
.getNumInputArgStrings())
199 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
- 1 - getNumArgs(),
200 Args
.getArgString(Index
- getNumArgs()));
201 for (unsigned i
= 1; i
!= getNumArgs(); ++i
)
202 A
->getValues().push_back(Args
.getArgString(Index
- getNumArgs() + i
));
205 case JoinedOrSeparateClass
: {
206 // If this is not an exact match, it is a joined arg.
207 // FIXME: Avoid strlen.
208 if (ArgSize
!= strlen(Args
.getArgString(Index
))) {
209 const char *Value
= Args
.getArgString(Index
) + ArgSize
;
210 return new Arg(*this, Spelling
, Index
++, Value
);
213 // Otherwise it must be separate.
215 if (Index
> Args
.getNumInputArgStrings() ||
216 Args
.getArgString(Index
- 1) == nullptr)
219 return new Arg(UnaliasedOption
, Spelling
,
220 Index
- 2, Args
.getArgString(Index
- 1));
222 case JoinedAndSeparateClass
:
225 if (Index
> Args
.getNumInputArgStrings() ||
226 Args
.getArgString(Index
- 1) == nullptr)
229 return new Arg(UnaliasedOption
, Spelling
, Index
- 2,
230 Args
.getArgString(Index
- 2) + ArgSize
,
231 Args
.getArgString(Index
- 1));
232 case RemainingArgsClass
: {
233 // Matches iff this is an exact match.
234 // FIXME: Avoid strlen.
235 if (ArgSize
!= strlen(Args
.getArgString(Index
)))
237 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
++);
238 while (Index
< Args
.getNumInputArgStrings() &&
239 Args
.getArgString(Index
) != nullptr)
240 A
->getValues().push_back(Args
.getArgString(Index
++));
243 case RemainingArgsJoinedClass
: {
244 Arg
*A
= new Arg(UnaliasedOption
, Spelling
, Index
);
245 if (ArgSize
!= strlen(Args
.getArgString(Index
))) {
246 // An inexact match means there is a joined arg.
247 A
->getValues().push_back(Args
.getArgString(Index
) + ArgSize
);
250 while (Index
< Args
.getNumInputArgStrings() &&
251 Args
.getArgString(Index
) != nullptr)
252 A
->getValues().push_back(Args
.getArgString(Index
++));
257 llvm_unreachable("Invalid option kind!");