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 ForceSeparateRender(false), ForceJoinedRender(false),
24 DriverOption(false), NoArgumentUnused(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.");
36 void Option::dump() const {
40 assert(0 && "Invalid kind");
41 #define P(N) case N: llvm::errs() << #N; break
50 P(JoinedOrSeparateClass);
51 P(JoinedAndSeparateClass);
55 llvm::errs() << " Name:\"" << Name << '"';
58 llvm::errs() << " Group:";
63 llvm::errs() << " Alias:";
67 if (const MultiArgOption *MOA = dyn_cast<MultiArgOption>(this))
68 llvm::errs() << " NumArgs:" << MOA->getNumArgs();
70 llvm::errs() << ">\n";
73 bool Option::matches(OptSpecifier Opt) const {
74 // Aliases are never considered in matching, look through them.
76 return Alias->matches(Opt);
83 return Group->matches(Opt);
87 OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
88 const OptionGroup *Group)
89 : Option(Option::GroupClass, ID, Name, Group, 0) {
92 Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const {
93 assert(0 && "accept() should never be called on an OptionGroup");
97 InputOption::InputOption(OptSpecifier ID)
98 : Option(Option::InputClass, ID, "<input>", 0, 0) {
101 Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
102 assert(0 && "accept() should never be called on an InputOption");
106 UnknownOption::UnknownOption(OptSpecifier ID)
107 : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
110 Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
111 assert(0 && "accept() should never be called on an UnknownOption");
115 FlagOption::FlagOption(OptSpecifier ID, const char *Name,
116 const OptionGroup *Group, const Option *Alias)
117 : Option(Option::FlagClass, ID, Name, Group, Alias) {
120 Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const {
121 // Matches iff this is an exact match.
122 // FIXME: Avoid strlen.
123 if (strlen(getName()) != strlen(Args.getArgString(Index)))
126 return new FlagArg(this, Index++);
129 JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
130 const OptionGroup *Group, const Option *Alias)
131 : Option(Option::JoinedClass, ID, Name, Group, Alias) {
134 Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
136 return new JoinedArg(this, Index++);
139 CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
140 const OptionGroup *Group,
142 : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
145 Arg *CommaJoinedOption::accept(const InputArgList &Args,
146 unsigned &Index) const {
147 // Always matches. We count the commas now so we can answer
148 // getNumValues easily.
150 // Get the suffix string.
151 // FIXME: Avoid strlen, and move to helper method?
152 const char *Suffix = Args.getArgString(Index) + strlen(getName());
153 return new CommaJoinedArg(this, Index++, Suffix);
156 SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
157 const OptionGroup *Group, const Option *Alias)
158 : Option(Option::SeparateClass, ID, Name, Group, Alias) {
161 Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const {
162 // Matches iff this is an exact match.
163 // FIXME: Avoid strlen.
164 if (strlen(getName()) != strlen(Args.getArgString(Index)))
168 if (Index > Args.getNumInputArgStrings())
171 return new SeparateArg(this, Index - 2, 1);
174 MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
175 const OptionGroup *Group, const Option *Alias,
177 : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
178 assert(NumArgs > 1 && "Invalid MultiArgOption!");
181 Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const {
182 // Matches iff this is an exact match.
183 // FIXME: Avoid strlen.
184 if (strlen(getName()) != strlen(Args.getArgString(Index)))
187 Index += 1 + NumArgs;
188 if (Index > Args.getNumInputArgStrings())
191 return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
194 JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
195 const OptionGroup *Group,
197 : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
200 Arg *JoinedOrSeparateOption::accept(const InputArgList &Args,
201 unsigned &Index) const {
202 // If this is not an exact match, it is a joined arg.
203 // FIXME: Avoid strlen.
204 if (strlen(getName()) != strlen(Args.getArgString(Index)))
205 return new JoinedArg(this, Index++);
207 // Otherwise it must be separate.
209 if (Index > Args.getNumInputArgStrings())
212 return new SeparateArg(this, Index - 2, 1);
215 JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
217 const OptionGroup *Group,
219 : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
222 Arg *JoinedAndSeparateOption::accept(const InputArgList &Args,
223 unsigned &Index) const {
227 if (Index > Args.getNumInputArgStrings())
230 return new JoinedAndSeparateArg(this, Index - 2);