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