 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
0.0% |
0 / 0 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
0.0% |
0 / 0 |
| |
|
Line Coverage: |
95.3% |
41 / 43 |
| |
 |
|
 |
1 : //===--- ArgList.h - Argument List Management ----------*- C++ -*-===//
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 : #ifndef CLANG_DRIVER_ARGLIST_H_
11 : #define CLANG_DRIVER_ARGLIST_H_
12 :
13 : #include "clang/Driver/OptSpecifier.h"
14 : #include "clang/Driver/Util.h"
15 : #include "llvm/ADT/SmallVector.h"
16 : #include "llvm/ADT/StringRef.h"
17 :
18 : #include <list>
19 : #include <string>
20 :
21 : namespace llvm {
22 : class Twine;
23 : }
24 :
25 : namespace clang {
26 : namespace driver {
27 : class Arg;
28 : class ArgList;
29 : class Option;
30 :
31 : /// arg_iterator - Iterates through arguments stored inside an ArgList.
32 : class arg_iterator {
33 : /// The current argument.
34 : llvm::SmallVectorImpl<Arg*>::const_iterator Current;
35 :
36 : /// The argument list we are iterating over.
37 : const ArgList &Args;
38 :
39 : /// Optional filters on the arguments which will be match. Most clients
40 : /// should never want to iterate over arguments without filters, so we won't
41 : /// bother to factor this into two separate iterator implementations.
42 : //
43 : // FIXME: Make efficient; the idea is to provide efficient iteration over
44 : // all arguments which match a particular id and then just provide an
45 : // iterator combinator which takes multiple iterators which can be
46 : // efficiently compared and returns them in order.
47 : OptSpecifier Id0, Id1, Id2;
48 :
49 : void SkipToNextArg();
50 :
51 : public:
52 : typedef const Arg* value_type;
53 : typedef const Arg* reference;
54 : typedef const Arg* pointer;
55 : typedef std::forward_iterator_tag iterator_category;
56 : typedef std::ptrdiff_t difference_type;
57 :
58 : arg_iterator(llvm::SmallVectorImpl<Arg*>::const_iterator it,
59 : const ArgList &_Args, OptSpecifier _Id0 = 0U,
60 94126: OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
61 94126: : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
62 94126: SkipToNextArg();
63 94126: }
64 :
65 6: operator const Arg*() { return *Current; }
66 23: reference operator*() const { return *Current; }
67 9059: pointer operator->() const { return *Current; }
68 :
69 3160: arg_iterator &operator++() {
70 3160: ++Current;
71 3160: SkipToNextArg();
72 3160: return *this;
73 : }
74 :
75 : arg_iterator operator++(int) {
76 : arg_iterator tmp(*this);
77 : ++(*this);
78 : return tmp;
79 : }
80 :
81 50223: friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
82 50223: return LHS.Current == RHS.Current;
83 : }
84 50223: friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
85 50223: return !(LHS == RHS);
86 : }
87 : };
88 :
89 : /// ArgList - Ordered collection of driver arguments.
90 : ///
91 : /// The ArgList class manages a list of Arg instances as well as
92 : /// auxiliary data and convenience methods to allow Tools to quickly
93 : /// check for the presence of Arg instances for a particular Option
94 : /// and to iterate over groups of arguments.
95 : class ArgList {
96 : public:
97 : typedef llvm::SmallVector<Arg*, 16> arglist_type;
98 : typedef arglist_type::iterator iterator;
99 : typedef arglist_type::const_iterator const_iterator;
100 : typedef arglist_type::reverse_iterator reverse_iterator;
101 : typedef arglist_type::const_reverse_iterator const_reverse_iterator;
102 :
103 : private:
104 : /// The full list of arguments.
105 : arglist_type &Args;
106 :
107 : protected:
108 : ArgList(arglist_type &Args);
109 :
110 : public:
111 : virtual ~ArgList();
112 :
113 : /// @name Arg Access
114 : /// @{
115 :
116 : /// append - Append \arg A to the arg list.
117 : void append(Arg *A);
118 :
119 155: arglist_type &getArgs() { return Args; }
120 : const arglist_type &getArgs() const { return Args; }
121 :
122 : unsigned size() const { return Args.size(); }
123 :
124 : /// @}
125 : /// @name Arg Iteration
126 : /// @{
127 :
128 3071: iterator begin() { return Args.begin(); }
129 3071: iterator end() { return Args.end(); }
130 :
131 : reverse_iterator rbegin() { return Args.rbegin(); }
132 : reverse_iterator rend() { return Args.rend(); }
133 :
134 530: const_iterator begin() const { return Args.begin(); }
135 314369: const_iterator end() const { return Args.end(); }
136 :
137 394499: const_reverse_iterator rbegin() const { return Args.rbegin(); }
138 394499: const_reverse_iterator rend() const { return Args.rend(); }
139 :
140 : arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
141 47063: OptSpecifier Id2 = 0U) const {
142 47063: return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
143 : }
144 47063: arg_iterator filtered_end() const {
145 47063: return arg_iterator(Args.end(), *this);
146 : }
147 :
148 : /// @}
149 : /// @name Arg Access
150 : /// @{
151 :
152 : /// hasArg - Does the arg list contain any option matching \arg Id.
153 : ///
154 : /// \arg Claim Whether the argument should be claimed, if it exists.
155 38: bool hasArgNoClaim(OptSpecifier Id) const {
156 38: return getLastArgNoClaim(Id) != 0;
157 : }
158 267686: bool hasArg(OptSpecifier Id) const {
159 267686: return getLastArg(Id) != 0;
160 : }
161 81: bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
162 81: return getLastArg(Id0, Id1) != 0;
163 : }
164 263: bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
165 263: return getLastArg(Id0, Id1, Id2) != 0;
166 : }
167 :
168 : /// getLastArg - Return the last argument matching \arg Id, or null.
169 : ///
170 : /// \arg Claim Whether the argument should be claimed, if it exists.
171 : Arg *getLastArgNoClaim(OptSpecifier Id) const;
172 : Arg *getLastArg(OptSpecifier Id) const;
173 : Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
174 : Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
175 :
176 : /// getArgString - Return the input argument string at \arg Index.
177 : virtual const char *getArgString(unsigned Index) const = 0;
178 : /// @name Translation Utilities
179 : /// @{
180 :
181 : /// hasFlag - Given an option \arg Pos and its negative form \arg
182 : /// Neg, return true if the option is present, false if the
183 : /// negation is present, and \arg Default if neither option is
184 : /// given. If both the option and its negation are present, the
185 : /// last one wins.
186 : bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
187 :
188 : /// AddLastArg - Render only the last argument match \arg Id0, if
189 : /// present.
190 : void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
191 :
192 : /// AddAllArgs - Render all arguments matching the given ids.
193 : void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
194 : OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
195 :
196 : /// AddAllArgValues - Render the argument values of all arguments
197 : /// matching the given ids.
198 : void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
199 : OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
200 :
201 : /// AddAllArgsTranslated - Render all the arguments matching the
202 : /// given ids, but forced to separate args and using the provided
203 : /// name instead of the first option value.
204 : ///
205 : /// \param Joined - If true, render the argument as joined with
206 : /// the option specifier.
207 : void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
208 : const char *Translation,
209 : bool Joined = false) const;
210 :
211 : /// ClaimAllArgs - Claim all arguments which match the given
212 : /// option id.
213 : void ClaimAllArgs(OptSpecifier Id0) const;
214 :
215 : /// @}
216 : /// @name Arg Synthesis
217 : /// @{
218 :
219 : /// MakeArgString - Construct a constant string pointer whose
220 : /// lifetime will match that of the ArgList.
221 : virtual const char *MakeArgString(llvm::StringRef Str) const = 0;
222 0: const char *MakeArgString(const char *Str) const {
223 0: return MakeArgString(llvm::StringRef(Str));
224 : }
225 509: const char *MakeArgString(std::string Str) const {
226 509: return MakeArgString(llvm::StringRef(Str));
227 : }
228 : const char *MakeArgString(const llvm::Twine &Str) const;
229 :
230 : /// @}
231 : };
232 :
233 : class InputArgList : public ArgList {
234 : private:
235 : /// The internal list of arguments.
236 : arglist_type ActualArgs;
237 :
238 : /// List of argument strings used by the contained Args.
239 : ///
240 : /// This is mutable since we treat the ArgList as being the list
241 : /// of Args, and allow routines to add new strings (to have a
242 : /// convenient place to store the memory) via MakeIndex.
243 : mutable ArgStringList ArgStrings;
244 :
245 : /// Strings for synthesized arguments.
246 : ///
247 : /// This is mutable since we treat the ArgList as being the list
248 : /// of Args, and allow routines to add new strings (to have a
249 : /// convenient place to store the memory) via MakeIndex.
250 : mutable std::list<std::string> SynthesizedStrings;
251 :
252 : /// The number of original input argument strings.
253 : unsigned NumInputArgStrings;
254 :
255 : public:
256 : InputArgList(const char **ArgBegin, const char **ArgEnd);
257 : InputArgList(const ArgList &);
258 : ~InputArgList();
259 :
260 42456: virtual const char *getArgString(unsigned Index) const {
261 42456: return ArgStrings[Index];
262 : }
263 :
264 : /// getNumInputArgStrings - Return the number of original input
265 : /// argument strings.
266 2936: unsigned getNumInputArgStrings() const { return NumInputArgStrings; }
267 :
268 : /// @name Arg Synthesis
269 : /// @{
270 :
271 : public:
272 : /// MakeIndex - Get an index for the given string(s).
273 : unsigned MakeIndex(llvm::StringRef String0) const;
274 : unsigned MakeIndex(llvm::StringRef String0, llvm::StringRef String1) const;
275 :
276 : virtual const char *MakeArgString(llvm::StringRef Str) const;
277 :
278 : /// @}
279 : };
280 :
281 : /// DerivedArgList - An ordered collection of driver arguments,
282 : /// whose storage may be in another argument list.
283 : class DerivedArgList : public ArgList {
284 : InputArgList &BaseArgs;
285 :
286 : /// The internal list of arguments.
287 : arglist_type ActualArgs;
288 :
289 : /// The list of arguments we synthesized.
290 : arglist_type SynthesizedArgs;
291 :
292 : /// Is this only a proxy for the base ArgList?
293 : bool OnlyProxy;
294 :
295 : public:
296 : /// Construct a new derived arg list from \arg BaseArgs.
297 : ///
298 : /// \param OnlyProxy - If true, this is only a proxy for the base
299 : /// list (to adapt the type), and it's Args list is unused.
300 : DerivedArgList(InputArgList &BaseArgs, bool OnlyProxy);
301 : ~DerivedArgList();
302 :
303 613: virtual const char *getArgString(unsigned Index) const {
304 613: return BaseArgs.getArgString(Index);
305 : }
306 :
307 : /// @name Arg Synthesis
308 : /// @{
309 :
310 : virtual const char *MakeArgString(llvm::StringRef Str) const;
311 :
312 : /// MakeFlagArg - Construct a new FlagArg for the given option
313 : /// \arg Id.
314 : Arg *MakeFlagArg(const Arg *BaseArg, const Option *Opt) const;
315 :
316 : /// MakePositionalArg - Construct a new Positional arg for the
317 : /// given option \arg Id, with the provided \arg Value.
318 : Arg *MakePositionalArg(const Arg *BaseArg, const Option *Opt,
319 : llvm::StringRef Value) const;
320 :
321 : /// MakeSeparateArg - Construct a new Positional arg for the
322 : /// given option \arg Id, with the provided \arg Value.
323 : Arg *MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
324 : llvm::StringRef Value) const;
325 :
326 : /// MakeJoinedArg - Construct a new Positional arg for the
327 : /// given option \arg Id, with the provided \arg Value.
328 : Arg *MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
329 : llvm::StringRef Value) const;
330 :
331 : /// @}
332 : };
333 :
334 : } // end namespace driver
335 : } // end namespace clang
336 :
337 : #endif
Generated: 2010-02-10 01:31 by zcov