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"
15 #include "llvm/Support/ErrorHandling.h"
18 using namespace clang::driver;
20 Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
21 const OptionGroup *_Group, const Option *_Alias)
22 : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
23 Unsupported(false), LinkerInput(false), NoOptAsInput(false),
24 DriverOption(false), NoArgumentUnused(false), NoForward(false) {
26 // Multi-level aliases are not supported, and alias options cannot
27 // have groups. This just simplifies option tracking, it is not an
28 // inherent limitation.
29 assert((!Alias || (!Alias->Alias && !Group)) &&
30 "Multi-level aliases and aliases with groups are unsupported.");
32 // Initialize rendering options based on the class.
37 RenderStyle = RenderValuesStyle;
41 case JoinedAndSeparateClass:
42 RenderStyle = RenderJoinedStyle;
45 case CommaJoinedClass:
46 RenderStyle = RenderCommaJoinedStyle;
52 case JoinedOrSeparateClass:
53 RenderStyle = RenderSeparateStyle;
61 void Option::dump() const {
65 llvm_unreachable("Invalid kind");
66 #define P(N) case N: llvm::errs() << #N; break
75 P(JoinedOrSeparateClass);
76 P(JoinedAndSeparateClass);
80 llvm::errs() << " Name:\"" << Name << '"';
83 llvm::errs() << " Group:";
88 llvm::errs() << " Alias:";
92 if (const MultiArgOption *MOA = dyn_cast<MultiArgOption>(this))
93 llvm::errs() << " NumArgs:" << MOA->getNumArgs();
95 llvm::errs() << ">\n";
98 bool Option::matches(OptSpecifier Opt) const {
99 // Aliases are never considered in matching, look through them.
101 return Alias->matches(Opt);
103 // Check exact match.
108 return Group->matches(Opt);
112 OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
113 const OptionGroup *Group)
114 : Option(Option::GroupClass, ID, Name, Group, 0) {
117 Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const {
118 llvm_unreachable("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 llvm_unreachable("accept() should never be called on an InputOption");
129 UnknownOption::UnknownOption(OptSpecifier ID)
130 : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
133 Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const {
134 llvm_unreachable("accept() should never be called on an UnknownOption");
137 FlagOption::FlagOption(OptSpecifier ID, const char *Name,
138 const OptionGroup *Group, const Option *Alias)
139 : Option(Option::FlagClass, ID, Name, Group, Alias) {
142 Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const {
143 // Matches iff this is an exact match.
144 // FIXME: Avoid strlen.
145 if (getName().size() != strlen(Args.getArgString(Index)))
148 return new Arg(getUnaliasedOption(), Index++);
151 JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
152 const OptionGroup *Group, const Option *Alias)
153 : Option(Option::JoinedClass, ID, Name, Group, Alias) {
156 Arg *JoinedOption::accept(const ArgList &Args, unsigned &Index) const {
158 const char *Value = Args.getArgString(Index) + getName().size();
159 return new Arg(getUnaliasedOption(), Index++, Value);
162 CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
163 const OptionGroup *Group,
165 : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
168 Arg *CommaJoinedOption::accept(const ArgList &Args,
169 unsigned &Index) const {
171 const char *Str = Args.getArgString(Index) + getName().size();
172 Arg *A = new Arg(getUnaliasedOption(), Index++);
174 // Parse out the comma separated values.
175 const char *Prev = Str;
179 if (!c || c == ',') {
181 char *Value = new char[Str - Prev + 1];
182 memcpy(Value, Prev, Str - Prev);
183 Value[Str - Prev] = '\0';
184 A->getValues().push_back(Value);
193 A->setOwnsValues(true);
198 SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
199 const OptionGroup *Group, const Option *Alias)
200 : Option(Option::SeparateClass, ID, Name, Group, Alias) {
203 Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const {
204 // Matches iff this is an exact match.
205 // FIXME: Avoid strlen.
206 if (getName().size() != strlen(Args.getArgString(Index)))
210 if (Index > Args.getNumInputArgStrings())
213 return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
216 MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
217 const OptionGroup *Group, const Option *Alias,
219 : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
220 assert(NumArgs > 1 && "Invalid MultiArgOption!");
223 Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const {
224 // Matches iff this is an exact match.
225 // FIXME: Avoid strlen.
226 if (getName().size() != strlen(Args.getArgString(Index)))
229 Index += 1 + NumArgs;
230 if (Index > Args.getNumInputArgStrings())
233 Arg *A = new Arg(getUnaliasedOption(), Index - 1 - NumArgs,
234 Args.getArgString(Index - NumArgs));
235 for (unsigned i = 1; i != NumArgs; ++i)
236 A->getValues().push_back(Args.getArgString(Index - NumArgs + i));
240 JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID,
242 const OptionGroup *Group,
244 : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
247 Arg *JoinedOrSeparateOption::accept(const ArgList &Args,
248 unsigned &Index) const {
249 // If this is not an exact match, it is a joined arg.
250 // FIXME: Avoid strlen.
251 if (getName().size() != strlen(Args.getArgString(Index))) {
252 const char *Value = Args.getArgString(Index) + getName().size();
253 return new Arg(this, Index++, Value);
256 // Otherwise it must be separate.
258 if (Index > Args.getNumInputArgStrings())
261 return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
264 JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
266 const OptionGroup *Group,
268 : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
271 Arg *JoinedAndSeparateOption::accept(const ArgList &Args,
272 unsigned &Index) const {
276 if (Index > Args.getNumInputArgStrings())
279 return new Arg(getUnaliasedOption(), Index - 2,
280 Args.getArgString(Index-2)+getName().size(),
281 Args.getArgString(Index-1));