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 "clang/Driver/Option.h"
12 #include "clang/Driver/Arg.h"
13 #include "clang/Driver/ArgList.h"
14 #include "llvm/Support/raw_ostream.h"
17 using namespace clang::driver
;
19 Option::Option(OptionClass _Kind
, OptSpecifier _ID
, const char *_Name
,
20 const OptionGroup
*_Group
, const Option
*_Alias
)
21 : Kind(_Kind
), ID(_ID
.getID()), Name(_Name
), Group(_Group
), Alias(_Alias
),
22 Unsupported(false), LinkerInput(false), NoOptAsInput(false),
23 DriverOption(false), NoArgumentUnused(false), NoForward(false) {
25 // Multi-level aliases are not supported, and alias options cannot
26 // have groups. This just simplifies option tracking, it is not an
27 // inherent limitation.
28 assert((!Alias
|| (!Alias
->Alias
&& !Group
)) &&
29 "Multi-level aliases and aliases with groups are unsupported.");
31 // Initialize rendering options based on the class.
36 RenderStyle
= RenderValuesStyle
;
40 case JoinedAndSeparateClass
:
41 RenderStyle
= RenderJoinedStyle
;
44 case CommaJoinedClass
:
45 RenderStyle
= RenderCommaJoinedStyle
;
51 case JoinedOrSeparateClass
:
52 RenderStyle
= RenderSeparateStyle
;
60 void Option::dump() const {
64 assert(0 && "Invalid kind");
65 #define P(N) case N: llvm::errs() << #N; break
74 P(JoinedOrSeparateClass
);
75 P(JoinedAndSeparateClass
);
79 llvm::errs() << " Name:\"" << Name
<< '"';
82 llvm::errs() << " Group:";
87 llvm::errs() << " Alias:";
91 if (const MultiArgOption
*MOA
= dyn_cast
<MultiArgOption
>(this))
92 llvm::errs() << " NumArgs:" << MOA
->getNumArgs();
94 llvm::errs() << ">\n";
97 bool Option::matches(OptSpecifier Opt
) const {
98 // Aliases are never considered in matching, look through them.
100 return Alias
->matches(Opt
);
102 // Check exact match.
107 return Group
->matches(Opt
);
111 OptionGroup::OptionGroup(OptSpecifier ID
, const char *Name
,
112 const OptionGroup
*Group
)
113 : Option(Option::GroupClass
, ID
, Name
, Group
, 0) {
116 Arg
*OptionGroup::accept(const ArgList
&Args
, unsigned &Index
) const {
117 assert(0 && "accept() should never be called on an OptionGroup");
121 InputOption::InputOption(OptSpecifier ID
)
122 : Option(Option::InputClass
, ID
, "<input>", 0, 0) {
125 Arg
*InputOption::accept(const ArgList
&Args
, unsigned &Index
) const {
126 assert(0 && "accept() should never be called on an InputOption");
130 UnknownOption::UnknownOption(OptSpecifier ID
)
131 : Option(Option::UnknownClass
, ID
, "<unknown>", 0, 0) {
134 Arg
*UnknownOption::accept(const ArgList
&Args
, unsigned &Index
) const {
135 assert(0 && "accept() should never be called on an UnknownOption");
139 FlagOption::FlagOption(OptSpecifier ID
, const char *Name
,
140 const OptionGroup
*Group
, const Option
*Alias
)
141 : Option(Option::FlagClass
, ID
, Name
, Group
, Alias
) {
144 Arg
*FlagOption::accept(const ArgList
&Args
, unsigned &Index
) const {
145 // Matches iff this is an exact match.
146 // FIXME: Avoid strlen.
147 if (strlen(getName()) != strlen(Args
.getArgString(Index
)))
150 return new Arg(getUnaliasedOption(), Index
++);
153 JoinedOption::JoinedOption(OptSpecifier ID
, const char *Name
,
154 const OptionGroup
*Group
, const Option
*Alias
)
155 : Option(Option::JoinedClass
, ID
, Name
, Group
, Alias
) {
158 Arg
*JoinedOption::accept(const ArgList
&Args
, unsigned &Index
) const {
160 const char *Value
= Args
.getArgString(Index
) + strlen(getName());
161 return new Arg(getUnaliasedOption(), Index
++, Value
);
164 CommaJoinedOption::CommaJoinedOption(OptSpecifier ID
, const char *Name
,
165 const OptionGroup
*Group
,
167 : Option(Option::CommaJoinedClass
, ID
, Name
, Group
, Alias
) {
170 Arg
*CommaJoinedOption::accept(const ArgList
&Args
,
171 unsigned &Index
) const {
173 const char *Str
= Args
.getArgString(Index
) + strlen(getName());
174 Arg
*A
= new Arg(getUnaliasedOption(), Index
++);
176 // Parse out the comma separated values.
177 const char *Prev
= Str
;
181 if (!c
|| c
== ',') {
183 char *Value
= new char[Str
- Prev
+ 1];
184 memcpy(Value
, Prev
, Str
- Prev
);
185 Value
[Str
- Prev
] = '\0';
186 A
->getValues().push_back(Value
);
195 A
->setOwnsValues(true);
200 SeparateOption::SeparateOption(OptSpecifier ID
, const char *Name
,
201 const OptionGroup
*Group
, const Option
*Alias
)
202 : Option(Option::SeparateClass
, ID
, Name
, Group
, Alias
) {
205 Arg
*SeparateOption::accept(const ArgList
&Args
, unsigned &Index
) const {
206 // Matches iff this is an exact match.
207 // FIXME: Avoid strlen.
208 if (strlen(getName()) != strlen(Args
.getArgString(Index
)))
212 if (Index
> Args
.getNumInputArgStrings())
215 return new Arg(getUnaliasedOption(), Index
- 2, Args
.getArgString(Index
- 1));
218 MultiArgOption::MultiArgOption(OptSpecifier ID
, const char *Name
,
219 const OptionGroup
*Group
, const Option
*Alias
,
221 : Option(Option::MultiArgClass
, ID
, Name
, Group
, Alias
), NumArgs(_NumArgs
) {
222 assert(NumArgs
> 1 && "Invalid MultiArgOption!");
225 Arg
*MultiArgOption::accept(const ArgList
&Args
, unsigned &Index
) const {
226 // Matches iff this is an exact match.
227 // FIXME: Avoid strlen.
228 if (strlen(getName()) != strlen(Args
.getArgString(Index
)))
231 Index
+= 1 + NumArgs
;
232 if (Index
> Args
.getNumInputArgStrings())
235 Arg
*A
= new Arg(getUnaliasedOption(), Index
- 1 - NumArgs
,
236 Args
.getArgString(Index
- NumArgs
));
237 for (unsigned i
= 1; i
!= NumArgs
; ++i
)
238 A
->getValues().push_back(Args
.getArgString(Index
- NumArgs
+ i
));
242 JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID
,
244 const OptionGroup
*Group
,
246 : Option(Option::JoinedOrSeparateClass
, ID
, Name
, Group
, Alias
) {
249 Arg
*JoinedOrSeparateOption::accept(const ArgList
&Args
,
250 unsigned &Index
) const {
251 // If this is not an exact match, it is a joined arg.
252 // FIXME: Avoid strlen.
253 if (strlen(getName()) != strlen(Args
.getArgString(Index
))) {
254 const char *Value
= Args
.getArgString(Index
) + strlen(getName());
255 return new Arg(this, Index
++, Value
);
258 // Otherwise it must be separate.
260 if (Index
> Args
.getNumInputArgStrings())
263 return new Arg(getUnaliasedOption(), Index
- 2, Args
.getArgString(Index
- 1));
266 JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID
,
268 const OptionGroup
*Group
,
270 : Option(Option::JoinedAndSeparateClass
, ID
, Name
, Group
, Alias
) {
273 Arg
*JoinedAndSeparateOption::accept(const ArgList
&Args
,
274 unsigned &Index
) const {
278 if (Index
> Args
.getNumInputArgStrings())
281 return new Arg(getUnaliasedOption(), Index
- 2,
282 Args
.getArgString(Index
-2)+strlen(getName()),
283 Args
.getArgString(Index
-1));