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
, options::ID _ID
, const char *_Name
,
20 const OptionGroup
*_Group
, const Option
*_Alias
)
21 : Kind(_Kind
), ID(_ID
), Name(_Name
), Group(_Group
), Alias(_Alias
),
22 Unsupported(false), LinkerInput(false), NoOptAsInput(false),
23 ForceSeparateRender(false), ForceJoinedRender(false),
24 DriverOption(false), NoArgumentUnused(false)
27 // Multi-level aliases are not supported, and alias options cannot
28 // have groups. This just simplifies option tracking, it is not an
29 // inherent limitation.
30 assert((!Alias
|| (!Alias
->Alias
&& !Group
)) &&
31 "Multi-level aliases and aliases with groups are unsupported.");
37 void Option::dump() const {
41 assert(0 && "Invalid kind");
42 #define P(N) case N: llvm::errs() << #N; break
51 P(JoinedOrSeparateClass
);
52 P(JoinedAndSeparateClass
);
56 llvm::errs() << " Name:\"" << Name
<< '"';
59 llvm::errs() << " Group:";
64 llvm::errs() << " Alias:";
68 if (const MultiArgOption
*MOA
= dyn_cast
<MultiArgOption
>(this))
69 llvm::errs() << " NumArgs:" << MOA
->getNumArgs();
71 llvm::errs() << ">\n";
74 bool Option::matches(const Option
*Opt
) const {
75 // Aliases are never considered in matching.
77 return matches(Opt
->getAlias());
79 return Alias
->matches(Opt
);
85 return Group
->matches(Opt
);
89 bool Option::matches(options::ID Id
) const {
90 // FIXME: Decide what to do here; we should either pull out the
91 // handling of alias on the option for Id from the other matches, or
92 // find some other solution (which hopefully doesn't require using
95 return Alias
->matches(Id
);
101 return Group
->matches(Id
);
105 OptionGroup::OptionGroup(options::ID ID
, const char *Name
,
106 const OptionGroup
*Group
)
107 : Option(Option::GroupClass
, ID
, Name
, Group
, 0) {
110 Arg
*OptionGroup::accept(const InputArgList
&Args
, unsigned &Index
) const {
111 assert(0 && "accept() should never be called on an OptionGroup");
115 InputOption::InputOption()
116 : Option(Option::InputClass
, options::OPT_INPUT
, "<input>", 0, 0) {
119 Arg
*InputOption::accept(const InputArgList
&Args
, unsigned &Index
) const {
120 assert(0 && "accept() should never be called on an InputOption");
124 UnknownOption::UnknownOption()
125 : Option(Option::UnknownClass
, options::OPT_UNKNOWN
, "<unknown>", 0, 0) {
128 Arg
*UnknownOption::accept(const InputArgList
&Args
, unsigned &Index
) const {
129 assert(0 && "accept() should never be called on an UnknownOption");
133 FlagOption::FlagOption(options::ID ID
, const char *Name
,
134 const OptionGroup
*Group
, const Option
*Alias
)
135 : Option(Option::FlagClass
, ID
, Name
, Group
, Alias
) {
138 Arg
*FlagOption::accept(const InputArgList
&Args
, unsigned &Index
) const {
139 // Matches iff this is an exact match.
140 // FIXME: Avoid strlen.
141 if (strlen(getName()) != strlen(Args
.getArgString(Index
)))
144 return new FlagArg(this, Index
++);
147 JoinedOption::JoinedOption(options::ID ID
, const char *Name
,
148 const OptionGroup
*Group
, const Option
*Alias
)
149 : Option(Option::JoinedClass
, ID
, Name
, Group
, Alias
) {
152 Arg
*JoinedOption::accept(const InputArgList
&Args
, unsigned &Index
) const {
154 return new JoinedArg(this, Index
++);
157 CommaJoinedOption::CommaJoinedOption(options::ID ID
, const char *Name
,
158 const OptionGroup
*Group
,
160 : Option(Option::CommaJoinedClass
, ID
, Name
, Group
, Alias
) {
163 Arg
*CommaJoinedOption::accept(const InputArgList
&Args
,
164 unsigned &Index
) const {
165 // Always matches. We count the commas now so we can answer
166 // getNumValues easily.
168 // Get the suffix string.
169 // FIXME: Avoid strlen, and move to helper method?
170 const char *Suffix
= Args
.getArgString(Index
) + strlen(getName());
171 return new CommaJoinedArg(this, Index
++, Suffix
);
174 SeparateOption::SeparateOption(options::ID ID
, const char *Name
,
175 const OptionGroup
*Group
, const Option
*Alias
)
176 : Option(Option::SeparateClass
, ID
, Name
, Group
, Alias
) {
179 Arg
*SeparateOption::accept(const InputArgList
&Args
, unsigned &Index
) const {
180 // Matches iff this is an exact match.
181 // FIXME: Avoid strlen.
182 if (strlen(getName()) != strlen(Args
.getArgString(Index
)))
186 if (Index
> Args
.getNumInputArgStrings())
189 return new SeparateArg(this, Index
- 2, 1);
192 MultiArgOption::MultiArgOption(options::ID ID
, const char *Name
,
193 const OptionGroup
*Group
, const Option
*Alias
,
195 : Option(Option::MultiArgClass
, ID
, Name
, Group
, Alias
), NumArgs(_NumArgs
) {
196 assert(NumArgs
> 1 && "Invalid MultiArgOption!");
199 Arg
*MultiArgOption::accept(const InputArgList
&Args
, unsigned &Index
) const {
200 // Matches iff this is an exact match.
201 // FIXME: Avoid strlen.
202 if (strlen(getName()) != strlen(Args
.getArgString(Index
)))
205 Index
+= 1 + NumArgs
;
206 if (Index
> Args
.getNumInputArgStrings())
209 return new SeparateArg(this, Index
- 1 - NumArgs
, NumArgs
);
212 JoinedOrSeparateOption::JoinedOrSeparateOption(options::ID ID
, const char *Name
,
213 const OptionGroup
*Group
,
215 : Option(Option::JoinedOrSeparateClass
, ID
, Name
, Group
, Alias
) {
218 Arg
*JoinedOrSeparateOption::accept(const InputArgList
&Args
,
219 unsigned &Index
) const {
220 // If this is not an exact match, it is a joined arg.
221 // FIXME: Avoid strlen.
222 if (strlen(getName()) != strlen(Args
.getArgString(Index
)))
223 return new JoinedArg(this, Index
++);
225 // Otherwise it must be separate.
227 if (Index
> Args
.getNumInputArgStrings())
230 return new SeparateArg(this, Index
- 2, 1);
233 JoinedAndSeparateOption::JoinedAndSeparateOption(options::ID ID
,
235 const OptionGroup
*Group
,
237 : Option(Option::JoinedAndSeparateClass
, ID
, Name
, Group
, Alias
) {
240 Arg
*JoinedAndSeparateOption::accept(const InputArgList
&Args
,
241 unsigned &Index
) const {
245 if (Index
> Args
.getNumInputArgStrings())
248 return new JoinedAndSeparateArg(this, Index
- 2);