]>
Commit | Line | Data |
---|---|---|
970d7e83 LB |
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 LLVM_OPTION_ARGLIST_H | |
11 | #define LLVM_OPTION_ARGLIST_H | |
12 | ||
13 | #include "llvm/ADT/SmallVector.h" | |
14 | #include "llvm/ADT/StringRef.h" | |
15 | #include "llvm/Option/OptSpecifier.h" | |
16 | #include "llvm/Option/Option.h" | |
17 | #include <list> | |
1a4d82fc | 18 | #include <memory> |
970d7e83 LB |
19 | #include <string> |
20 | #include <vector> | |
21 | ||
22 | namespace llvm { | |
23 | namespace opt { | |
24 | class Arg; | |
25 | class ArgList; | |
26 | class Option; | |
27 | ||
28 | /// arg_iterator - Iterates through arguments stored inside an ArgList. | |
29 | class arg_iterator { | |
30 | /// The current argument. | |
31 | SmallVectorImpl<Arg*>::const_iterator Current; | |
32 | ||
33 | /// The argument list we are iterating over. | |
34 | const ArgList &Args; | |
35 | ||
36 | /// Optional filters on the arguments which will be match. Most clients | |
37 | /// should never want to iterate over arguments without filters, so we won't | |
38 | /// bother to factor this into two separate iterator implementations. | |
39 | // | |
40 | // FIXME: Make efficient; the idea is to provide efficient iteration over | |
41 | // all arguments which match a particular id and then just provide an | |
42 | // iterator combinator which takes multiple iterators which can be | |
43 | // efficiently compared and returns them in order. | |
44 | OptSpecifier Id0, Id1, Id2; | |
45 | ||
46 | void SkipToNextArg(); | |
47 | ||
48 | public: | |
49 | typedef Arg * const * value_type; | |
50 | typedef Arg * const & reference; | |
51 | typedef Arg * const * pointer; | |
52 | typedef std::forward_iterator_tag iterator_category; | |
53 | typedef std::ptrdiff_t difference_type; | |
54 | ||
55 | arg_iterator(SmallVectorImpl<Arg*>::const_iterator it, | |
56 | const ArgList &_Args, OptSpecifier _Id0 = 0U, | |
57 | OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U) | |
58 | : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) { | |
59 | SkipToNextArg(); | |
60 | } | |
61 | ||
62 | operator const Arg*() { return *Current; } | |
63 | reference operator*() const { return *Current; } | |
64 | pointer operator->() const { return Current; } | |
65 | ||
66 | arg_iterator &operator++() { | |
67 | ++Current; | |
68 | SkipToNextArg(); | |
69 | return *this; | |
70 | } | |
71 | ||
72 | arg_iterator operator++(int) { | |
73 | arg_iterator tmp(*this); | |
74 | ++(*this); | |
75 | return tmp; | |
76 | } | |
77 | ||
78 | friend bool operator==(arg_iterator LHS, arg_iterator RHS) { | |
79 | return LHS.Current == RHS.Current; | |
80 | } | |
81 | friend bool operator!=(arg_iterator LHS, arg_iterator RHS) { | |
82 | return !(LHS == RHS); | |
83 | } | |
84 | }; | |
85 | ||
86 | /// ArgList - Ordered collection of driver arguments. | |
87 | /// | |
88 | /// The ArgList class manages a list of Arg instances as well as | |
89 | /// auxiliary data and convenience methods to allow Tools to quickly | |
90 | /// check for the presence of Arg instances for a particular Option | |
91 | /// and to iterate over groups of arguments. | |
92 | class ArgList { | |
93 | private: | |
94 | ArgList(const ArgList &) LLVM_DELETED_FUNCTION; | |
95 | void operator=(const ArgList &) LLVM_DELETED_FUNCTION; | |
96 | ||
97 | public: | |
98 | typedef SmallVector<Arg*, 16> arglist_type; | |
99 | typedef arglist_type::iterator iterator; | |
100 | typedef arglist_type::const_iterator const_iterator; | |
101 | typedef arglist_type::reverse_iterator reverse_iterator; | |
102 | typedef arglist_type::const_reverse_iterator const_reverse_iterator; | |
103 | ||
104 | private: | |
105 | /// The internal list of arguments. | |
106 | arglist_type Args; | |
107 | ||
108 | protected: | |
1a4d82fc JJ |
109 | // Default ctor provided explicitly as it is not provided implicitly due to |
110 | // the presence of the (deleted) copy ctor above. | |
111 | ArgList() { } | |
112 | // Virtual to provide a vtable anchor and because -Wnon-virtua-dtor warns, not | |
113 | // because this type is ever actually destroyed polymorphically. | |
114 | virtual ~ArgList(); | |
970d7e83 LB |
115 | |
116 | public: | |
970d7e83 LB |
117 | |
118 | /// @name Arg Access | |
119 | /// @{ | |
120 | ||
121 | /// append - Append \p A to the arg list. | |
122 | void append(Arg *A); | |
123 | ||
124 | arglist_type &getArgs() { return Args; } | |
125 | const arglist_type &getArgs() const { return Args; } | |
126 | ||
127 | unsigned size() const { return Args.size(); } | |
128 | ||
129 | /// @} | |
130 | /// @name Arg Iteration | |
131 | /// @{ | |
132 | ||
133 | iterator begin() { return Args.begin(); } | |
134 | iterator end() { return Args.end(); } | |
135 | ||
136 | reverse_iterator rbegin() { return Args.rbegin(); } | |
137 | reverse_iterator rend() { return Args.rend(); } | |
138 | ||
139 | const_iterator begin() const { return Args.begin(); } | |
140 | const_iterator end() const { return Args.end(); } | |
141 | ||
142 | const_reverse_iterator rbegin() const { return Args.rbegin(); } | |
143 | const_reverse_iterator rend() const { return Args.rend(); } | |
144 | ||
145 | arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U, | |
146 | OptSpecifier Id2 = 0U) const { | |
147 | return arg_iterator(Args.begin(), *this, Id0, Id1, Id2); | |
148 | } | |
149 | arg_iterator filtered_end() const { | |
150 | return arg_iterator(Args.end(), *this); | |
151 | } | |
152 | ||
1a4d82fc JJ |
153 | iterator_range<arg_iterator> filtered(OptSpecifier Id0 = 0U, |
154 | OptSpecifier Id1 = 0U, | |
155 | OptSpecifier Id2 = 0U) const { | |
156 | return make_range(filtered_begin(Id0, Id1, Id2), filtered_end()); | |
157 | } | |
158 | ||
970d7e83 LB |
159 | /// @} |
160 | /// @name Arg Removal | |
161 | /// @{ | |
162 | ||
163 | /// eraseArg - Remove any option matching \p Id. | |
164 | void eraseArg(OptSpecifier Id); | |
165 | ||
166 | /// @} | |
167 | /// @name Arg Access | |
168 | /// @{ | |
169 | ||
170 | /// hasArg - Does the arg list contain any option matching \p Id. | |
171 | /// | |
172 | /// \p Claim Whether the argument should be claimed, if it exists. | |
173 | bool hasArgNoClaim(OptSpecifier Id) const { | |
1a4d82fc | 174 | return getLastArgNoClaim(Id) != nullptr; |
970d7e83 LB |
175 | } |
176 | bool hasArg(OptSpecifier Id) const { | |
1a4d82fc | 177 | return getLastArg(Id) != nullptr; |
970d7e83 LB |
178 | } |
179 | bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const { | |
1a4d82fc | 180 | return getLastArg(Id0, Id1) != nullptr; |
970d7e83 LB |
181 | } |
182 | bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { | |
1a4d82fc | 183 | return getLastArg(Id0, Id1, Id2) != nullptr; |
970d7e83 LB |
184 | } |
185 | ||
186 | /// getLastArg - Return the last argument matching \p Id, or null. | |
187 | /// | |
188 | /// \p Claim Whether the argument should be claimed, if it exists. | |
189 | Arg *getLastArgNoClaim(OptSpecifier Id) const; | |
1a4d82fc | 190 | Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1) const; |
970d7e83 LB |
191 | Arg *getLastArg(OptSpecifier Id) const; |
192 | Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const; | |
193 | Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const; | |
194 | Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, | |
195 | OptSpecifier Id3) const; | |
196 | Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, | |
197 | OptSpecifier Id3, OptSpecifier Id4) const; | |
198 | Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, | |
199 | OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const; | |
200 | Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, | |
201 | OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, | |
202 | OptSpecifier Id6) const; | |
203 | Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2, | |
204 | OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5, | |
205 | OptSpecifier Id6, OptSpecifier Id7) const; | |
206 | ||
207 | /// getArgString - Return the input argument string at \p Index. | |
208 | virtual const char *getArgString(unsigned Index) const = 0; | |
209 | ||
210 | /// getNumInputArgStrings - Return the number of original argument strings, | |
211 | /// which are guaranteed to be the first strings in the argument string | |
212 | /// list. | |
213 | virtual unsigned getNumInputArgStrings() const = 0; | |
214 | ||
215 | /// @} | |
216 | /// @name Argument Lookup Utilities | |
217 | /// @{ | |
218 | ||
219 | /// getLastArgValue - Return the value of the last argument, or a default. | |
220 | StringRef getLastArgValue(OptSpecifier Id, | |
221 | StringRef Default = "") const; | |
222 | ||
223 | /// getAllArgValues - Get the values of all instances of the given argument | |
224 | /// as strings. | |
225 | std::vector<std::string> getAllArgValues(OptSpecifier Id) const; | |
226 | ||
227 | /// @} | |
228 | /// @name Translation Utilities | |
229 | /// @{ | |
230 | ||
231 | /// hasFlag - Given an option \p Pos and its negative form \p Neg, return | |
232 | /// true if the option is present, false if the negation is present, and | |
233 | /// \p Default if neither option is given. If both the option and its | |
234 | /// negation are present, the last one wins. | |
235 | bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const; | |
236 | ||
1a4d82fc JJ |
237 | /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative |
238 | /// form \p Neg, return true if the option or its alias is present, false if | |
239 | /// the negation is present, and \p Default if none of the options are | |
240 | /// given. If multiple options are present, the last one wins. | |
241 | bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, | |
242 | bool Default = true) const; | |
243 | ||
970d7e83 LB |
244 | /// AddLastArg - Render only the last argument match \p Id0, if present. |
245 | void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; | |
1a4d82fc JJ |
246 | void AddLastArg(ArgStringList &Output, OptSpecifier Id0, |
247 | OptSpecifier Id1) const; | |
970d7e83 LB |
248 | |
249 | /// AddAllArgs - Render all arguments matching the given ids. | |
250 | void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, | |
251 | OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; | |
252 | ||
253 | /// AddAllArgValues - Render the argument values of all arguments | |
254 | /// matching the given ids. | |
255 | void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, | |
256 | OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const; | |
257 | ||
258 | /// AddAllArgsTranslated - Render all the arguments matching the | |
259 | /// given ids, but forced to separate args and using the provided | |
260 | /// name instead of the first option value. | |
261 | /// | |
262 | /// \param Joined - If true, render the argument as joined with | |
263 | /// the option specifier. | |
264 | void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, | |
265 | const char *Translation, | |
266 | bool Joined = false) const; | |
267 | ||
268 | /// ClaimAllArgs - Claim all arguments which match the given | |
269 | /// option id. | |
270 | void ClaimAllArgs(OptSpecifier Id0) const; | |
271 | ||
272 | /// ClaimAllArgs - Claim all arguments. | |
273 | /// | |
274 | void ClaimAllArgs() const; | |
275 | ||
276 | /// @} | |
277 | /// @name Arg Synthesis | |
278 | /// @{ | |
279 | ||
280 | /// MakeArgString - Construct a constant string pointer whose | |
281 | /// lifetime will match that of the ArgList. | |
282 | virtual const char *MakeArgString(StringRef Str) const = 0; | |
283 | const char *MakeArgString(const char *Str) const { | |
284 | return MakeArgString(StringRef(Str)); | |
285 | } | |
286 | const char *MakeArgString(std::string Str) const { | |
287 | return MakeArgString(StringRef(Str)); | |
288 | } | |
289 | const char *MakeArgString(const Twine &Str) const; | |
290 | ||
291 | /// \brief Create an arg string for (\p LHS + \p RHS), reusing the | |
292 | /// string at \p Index if possible. | |
293 | const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS, | |
294 | StringRef RHS) const; | |
295 | ||
296 | /// @} | |
297 | }; | |
298 | ||
299 | class InputArgList : public ArgList { | |
300 | private: | |
301 | /// List of argument strings used by the contained Args. | |
302 | /// | |
303 | /// This is mutable since we treat the ArgList as being the list | |
304 | /// of Args, and allow routines to add new strings (to have a | |
305 | /// convenient place to store the memory) via MakeIndex. | |
306 | mutable ArgStringList ArgStrings; | |
307 | ||
308 | /// Strings for synthesized arguments. | |
309 | /// | |
310 | /// This is mutable since we treat the ArgList as being the list | |
311 | /// of Args, and allow routines to add new strings (to have a | |
312 | /// convenient place to store the memory) via MakeIndex. | |
313 | mutable std::list<std::string> SynthesizedStrings; | |
314 | ||
315 | /// The number of original input argument strings. | |
316 | unsigned NumInputArgStrings; | |
317 | ||
318 | public: | |
319 | InputArgList(const char* const *ArgBegin, const char* const *ArgEnd); | |
320 | ~InputArgList(); | |
321 | ||
1a4d82fc | 322 | const char *getArgString(unsigned Index) const override { |
970d7e83 LB |
323 | return ArgStrings[Index]; |
324 | } | |
325 | ||
1a4d82fc | 326 | unsigned getNumInputArgStrings() const override { |
970d7e83 LB |
327 | return NumInputArgStrings; |
328 | } | |
329 | ||
330 | /// @name Arg Synthesis | |
331 | /// @{ | |
332 | ||
333 | public: | |
334 | /// MakeIndex - Get an index for the given string(s). | |
335 | unsigned MakeIndex(StringRef String0) const; | |
336 | unsigned MakeIndex(StringRef String0, StringRef String1) const; | |
337 | ||
1a4d82fc JJ |
338 | using ArgList::MakeArgString; |
339 | const char *MakeArgString(StringRef Str) const override; | |
970d7e83 LB |
340 | |
341 | /// @} | |
342 | }; | |
343 | ||
344 | /// DerivedArgList - An ordered collection of driver arguments, | |
345 | /// whose storage may be in another argument list. | |
346 | class DerivedArgList : public ArgList { | |
347 | const InputArgList &BaseArgs; | |
348 | ||
349 | /// The list of arguments we synthesized. | |
1a4d82fc | 350 | mutable SmallVector<std::unique_ptr<Arg>, 16> SynthesizedArgs; |
970d7e83 LB |
351 | |
352 | public: | |
353 | /// Construct a new derived arg list from \p BaseArgs. | |
354 | DerivedArgList(const InputArgList &BaseArgs); | |
355 | ~DerivedArgList(); | |
356 | ||
1a4d82fc | 357 | const char *getArgString(unsigned Index) const override { |
970d7e83 LB |
358 | return BaseArgs.getArgString(Index); |
359 | } | |
360 | ||
1a4d82fc | 361 | unsigned getNumInputArgStrings() const override { |
970d7e83 LB |
362 | return BaseArgs.getNumInputArgStrings(); |
363 | } | |
364 | ||
365 | const InputArgList &getBaseArgs() const { | |
366 | return BaseArgs; | |
367 | } | |
368 | ||
369 | /// @name Arg Synthesis | |
370 | /// @{ | |
371 | ||
372 | /// AddSynthesizedArg - Add a argument to the list of synthesized arguments | |
373 | /// (to be freed). | |
1a4d82fc | 374 | void AddSynthesizedArg(Arg *A); |
970d7e83 | 375 | |
1a4d82fc JJ |
376 | using ArgList::MakeArgString; |
377 | const char *MakeArgString(StringRef Str) const override; | |
970d7e83 LB |
378 | |
379 | /// AddFlagArg - Construct a new FlagArg for the given option \p Id and | |
380 | /// append it to the argument list. | |
381 | void AddFlagArg(const Arg *BaseArg, const Option Opt) { | |
382 | append(MakeFlagArg(BaseArg, Opt)); | |
383 | } | |
384 | ||
385 | /// AddPositionalArg - Construct a new Positional arg for the given option | |
386 | /// \p Id, with the provided \p Value and append it to the argument | |
387 | /// list. | |
388 | void AddPositionalArg(const Arg *BaseArg, const Option Opt, | |
389 | StringRef Value) { | |
390 | append(MakePositionalArg(BaseArg, Opt, Value)); | |
391 | } | |
392 | ||
393 | ||
394 | /// AddSeparateArg - Construct a new Positional arg for the given option | |
395 | /// \p Id, with the provided \p Value and append it to the argument | |
396 | /// list. | |
397 | void AddSeparateArg(const Arg *BaseArg, const Option Opt, | |
398 | StringRef Value) { | |
399 | append(MakeSeparateArg(BaseArg, Opt, Value)); | |
400 | } | |
401 | ||
402 | ||
403 | /// AddJoinedArg - Construct a new Positional arg for the given option | |
404 | /// \p Id, with the provided \p Value and append it to the argument list. | |
405 | void AddJoinedArg(const Arg *BaseArg, const Option Opt, | |
406 | StringRef Value) { | |
407 | append(MakeJoinedArg(BaseArg, Opt, Value)); | |
408 | } | |
409 | ||
410 | ||
411 | /// MakeFlagArg - Construct a new FlagArg for the given option \p Id. | |
412 | Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const; | |
413 | ||
414 | /// MakePositionalArg - Construct a new Positional arg for the | |
415 | /// given option \p Id, with the provided \p Value. | |
416 | Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt, | |
417 | StringRef Value) const; | |
418 | ||
419 | /// MakeSeparateArg - Construct a new Positional arg for the | |
420 | /// given option \p Id, with the provided \p Value. | |
421 | Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt, | |
422 | StringRef Value) const; | |
423 | ||
424 | /// MakeJoinedArg - Construct a new Positional arg for the | |
425 | /// given option \p Id, with the provided \p Value. | |
426 | Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt, | |
427 | StringRef Value) const; | |
428 | ||
429 | /// @} | |
430 | }; | |
431 | ||
432 | } // end namespace opt | |
433 | } // end namespace llvm | |
434 | ||
435 | #endif |