]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Driver/Option.cpp
Import Clang, at r72732.
[FreeBSD/FreeBSD.git] / lib / Driver / Option.cpp
1 //===--- Option.cpp - Abstract Driver Options ---------------------------*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "clang/Driver/Option.h"
11
12 #include "clang/Driver/Arg.h"
13 #include "clang/Driver/ArgList.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include <cassert>
16 #include <algorithm>
17 using namespace clang::driver;
18
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)
25 {
26
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.");    
32 }
33
34 Option::~Option() {
35 }
36
37 void Option::dump() const {
38   llvm::errs() << "<";
39   switch (Kind) {
40   default:
41     assert(0 && "Invalid kind");
42 #define P(N) case N: llvm::errs() << #N; break
43     P(GroupClass);
44     P(InputClass);
45     P(UnknownClass);
46     P(FlagClass);
47     P(JoinedClass);
48     P(SeparateClass);
49     P(CommaJoinedClass);
50     P(MultiArgClass);
51     P(JoinedOrSeparateClass);
52     P(JoinedAndSeparateClass);
53 #undef P
54   }
55
56   llvm::errs() << " Name:\"" << Name << '"';
57
58   if (Group) {
59     llvm::errs() << " Group:";
60     Group->dump();
61   }
62   
63   if (Alias) {
64     llvm::errs() << " Alias:";
65     Alias->dump();
66   }
67   
68   if (const MultiArgOption *MOA = dyn_cast<MultiArgOption>(this))
69     llvm::errs() << " NumArgs:" << MOA->getNumArgs();
70
71   llvm::errs() << ">\n";
72 }
73
74 bool Option::matches(const Option *Opt) const {
75   // Aliases are never considered in matching.
76   if (Opt->getAlias())
77     return matches(Opt->getAlias());
78   if (Alias)
79     return Alias->matches(Opt);
80   
81   if (this == Opt)
82     return true;
83   
84   if (Group)
85     return Group->matches(Opt);
86   return false;
87 }
88
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
93   // the option table).
94   if (Alias)
95     return Alias->matches(Id);
96   
97   if (ID == Id)
98     return true;
99   
100   if (Group)
101     return Group->matches(Id);
102   return false;
103 }
104
105 OptionGroup::OptionGroup(options::ID ID, const char *Name, 
106                          const OptionGroup *Group)
107   : Option(Option::GroupClass, ID, Name, Group, 0) {
108 }
109
110 Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const {
111   assert(0 && "accept() should never be called on an OptionGroup");
112   return 0;
113 }
114
115 InputOption::InputOption()
116   : Option(Option::InputClass, options::OPT_INPUT, "<input>", 0, 0) {
117 }
118
119 Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
120   assert(0 && "accept() should never be called on an InputOption");
121   return 0;
122 }
123
124 UnknownOption::UnknownOption()
125   : Option(Option::UnknownClass, options::OPT_UNKNOWN, "<unknown>", 0, 0) {
126 }
127
128 Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
129   assert(0 && "accept() should never be called on an UnknownOption");
130   return 0;
131 }
132
133 FlagOption::FlagOption(options::ID ID, const char *Name, 
134                        const OptionGroup *Group, const Option *Alias)
135   : Option(Option::FlagClass, ID, Name, Group, Alias) {
136 }
137
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)))
142     return 0;
143
144   return new FlagArg(this, Index++);
145 }
146
147 JoinedOption::JoinedOption(options::ID ID, const char *Name, 
148                            const OptionGroup *Group, const Option *Alias)
149   : Option(Option::JoinedClass, ID, Name, Group, Alias) {
150 }
151
152 Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
153   // Always matches.
154   return new JoinedArg(this, Index++);
155 }
156
157 CommaJoinedOption::CommaJoinedOption(options::ID ID, const char *Name, 
158                                      const OptionGroup *Group, 
159                                      const Option *Alias)
160   : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
161 }
162
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.
167   
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);
172 }
173
174 SeparateOption::SeparateOption(options::ID ID, const char *Name, 
175                                const OptionGroup *Group, const Option *Alias)
176   : Option(Option::SeparateClass, ID, Name, Group, Alias) {
177 }
178
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)))
183     return 0;
184
185   Index += 2;
186   if (Index > Args.getNumInputArgStrings())
187     return 0;
188
189   return new SeparateArg(this, Index - 2, 1);
190 }
191
192 MultiArgOption::MultiArgOption(options::ID ID, const char *Name, 
193                                const OptionGroup *Group, const Option *Alias, 
194                                unsigned _NumArgs)
195   : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
196   assert(NumArgs > 1  && "Invalid MultiArgOption!");
197 }
198
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)))
203     return 0;
204
205   Index += 1 + NumArgs;
206   if (Index > Args.getNumInputArgStrings())
207     return 0;
208
209   return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
210 }
211
212 JoinedOrSeparateOption::JoinedOrSeparateOption(options::ID ID, const char *Name,
213                                                const OptionGroup *Group, 
214                                                const Option *Alias)
215   : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
216 }
217
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++);
224
225   // Otherwise it must be separate.
226   Index += 2;
227   if (Index > Args.getNumInputArgStrings())
228     return 0;
229
230   return new SeparateArg(this, Index - 2, 1);  
231 }
232
233 JoinedAndSeparateOption::JoinedAndSeparateOption(options::ID ID,
234                                                  const char *Name, 
235                                                  const OptionGroup *Group, 
236                                                  const Option *Alias)
237   : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
238 }
239
240 Arg *JoinedAndSeparateOption::accept(const InputArgList &Args, 
241                                      unsigned &Index) const {
242   // Always matches.
243
244   Index += 2;
245   if (Index > Args.getNumInputArgStrings())
246     return 0;
247
248   return new JoinedAndSeparateArg(this, Index - 2);
249 }
250