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
23namespace clang {
24  class DiagnosticsEngine;
25
26namespace 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)
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
123    arglist_type &getArgs() { return Args; }
124    const arglist_type &getArgs() const { return Args; }
125
126    unsigned size() const { return Args.size(); }
127
128    /// @}
129    /// @name Arg Iteration
130    /// @{
131
132    iterator begin() { return Args.begin(); }
133    iterator end() { return Args.end(); }
134
135    reverse_iterator rbegin() { return Args.rbegin(); }
136    reverse_iterator rend() { return Args.rend(); }
137
138    const_iterator begin() const { return Args.begin(); }
139    const_iterator end() const { return Args.end(); }
140
141    const_reverse_iterator rbegin() const { return Args.rbegin(); }
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    }
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.
166    bool hasArgNoClaim(OptSpecifier Id) const {
167      return getLastArgNoClaim(Id) != 0;
168    }
169    bool hasArg(OptSpecifier Id) const {
170      return getLastArg(Id) != 0;
171    }
172    bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
173      return getLastArg(Id0, Id1) != 0;
174    }
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.
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;
281    const char *MakeArgString(const char *Str) const {
282      return MakeArgString(StringRef(Str));
283    }
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
320    virtual const char *getArgString(unsigned Index) const {
321      return ArgStrings[Index];
322    }
323
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
354    virtual const char *getArgString(unsigned Index) const {
355      return BaseArgs.getArgString(Index);
356    }
357
358    virtual unsigned getNumInputArgStrings() const {
359      return BaseArgs.getNumInputArgStrings();
360    }
361
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).
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.
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.
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.
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.
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