summaryrefslogtreecommitdiffstats
path: root/include/clang/Driver/ArgList.h
blob: 84e0329a375e0d789785ffe668a96a9ed9c0dd36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
//===--- ArgList.h - Argument List Management ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_DRIVER_ARGLIST_H_
#define CLANG_DRIVER_ARGLIST_H_

#include "clang/Driver/Options.h"

#include "clang/Driver/Util.h"
#include "llvm/ADT/SmallVector.h"

#include <list>

namespace clang {
namespace driver {
  class Arg;

  /// ArgList - Ordered collection of driver arguments.
  ///
  /// The ArgList class manages a list of Arg instances as well as
  /// auxiliary data and convenience methods to allow Tools to quickly
  /// check for the presence of Arg instances for a particular Option
  /// and to iterate over groups of arguments.
  class ArgList {
  public:
    typedef llvm::SmallVector<Arg*, 16> arglist_type;
    typedef arglist_type::iterator iterator;
    typedef arglist_type::const_iterator const_iterator;
    typedef arglist_type::reverse_iterator reverse_iterator;
    typedef arglist_type::const_reverse_iterator const_reverse_iterator;

  private:
    /// The full list of arguments.
    arglist_type &Args;

  protected:
    ArgList(arglist_type &Args);

  public:
    virtual ~ArgList();

    /// @name Arg Access
    /// @{

    /// append - Append \arg A to the arg list.
    void append(Arg *A);

    arglist_type &getArgs() { return Args; }
    const arglist_type &getArgs() const { return Args; }

    unsigned size() const { return Args.size(); }

    iterator begin() { return Args.begin(); }
    iterator end() { return Args.end(); }

    reverse_iterator rbegin() { return Args.rbegin(); }
    reverse_iterator rend() { return Args.rend(); }

    const_iterator begin() const { return Args.begin(); }
    const_iterator end() const { return Args.end(); }
    
    const_reverse_iterator rbegin() const { return Args.rbegin(); }
    const_reverse_iterator rend() const { return Args.rend(); }

    /// hasArg - Does the arg list contain any option matching \arg Id.
    ///
    /// \arg Claim Whether the argument should be claimed, if it exists.
    bool hasArg(options::ID Id, bool Claim=true) const { 
      return getLastArg(Id, Claim) != 0;
    }
    bool hasArg(options::ID Id0, options::ID Id1, bool Claim=true) const { 
      return getLastArg(Id0, Id1, Claim) != 0;
    }

    /// getLastArg - Return the last argument matching \arg Id, or null.
    ///
    /// \arg Claim Whether the argument should be claimed, if it exists.
    Arg *getLastArg(options::ID Id, bool Claim=true) const;
    Arg *getLastArg(options::ID Id0, options::ID Id1, bool Claim=true) const;

    /// getArgString - Return the input argument string at \arg Index.
    virtual const char *getArgString(unsigned Index) const = 0;
    /// @name Translation Utilities
    /// @{

    /// hasFlag - Given an option \arg Pos and its negative form \arg
    /// Neg, return true if the option is present, false if the
    /// negation is present, and \arg Default if neither option is
    /// given. If both the option and its negation are present, the
    /// last one wins.
    bool hasFlag(options::ID Pos, options::ID Neg, bool Default=true) const;

    /// AddLastArg - Render only the last argument match \arg Id0, if
    /// present.
    void AddLastArg(ArgStringList &Output, options::ID Id0) const;

    /// AddAllArgs - Render all arguments matching the given ids.
    void AddAllArgs(ArgStringList &Output, options::ID Id0) const;
    void AddAllArgs(ArgStringList &Output, options::ID Id0, 
                    options::ID Id1) const;
    void AddAllArgs(ArgStringList &Output, options::ID Id0, options::ID Id1, 
                    options::ID Id2) const;

    /// AddAllArgValues - Render the argument values of all arguments
    /// matching the given ids.
    void AddAllArgValues(ArgStringList &Output, options::ID Id0) const;
    void AddAllArgValues(ArgStringList &Output, options::ID Id0, 
                         options::ID Id1) const;

    /// AddAllArgsTranslated - Render all the arguments matching the
    /// given ids, but forced to separate args and using the provided
    /// name instead of the first option value.
    ///
    /// \param Joined - If true, render the argument as joined with
    /// the option specifier.
    void AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
                              const char *Translation, 
                              bool Joined = false) const;

    /// ClaimAllArgs - Claim all arguments which match the given
    /// option id.
    void ClaimAllArgs(options::ID Id0) const;

    /// @}
    /// @name Arg Synthesis
    /// @{

    /// MakeArgString - Construct a constant string pointer whose
    /// lifetime will match that of the ArgList.
    virtual const char *MakeArgString(const char *Str) const = 0;

    /// @}
  };

  class InputArgList : public ArgList  {
  private:
    /// The internal list of arguments.
    arglist_type ActualArgs;

    /// List of argument strings used by the contained Args.
    ///
    /// This is mutable since we treat the ArgList as being the list
    /// of Args, and allow routines to add new strings (to have a
    /// convenient place to store the memory) via MakeIndex.
    mutable ArgStringList ArgStrings;

    /// Strings for synthesized arguments.
    ///
    /// This is mutable since we treat the ArgList as being the list
    /// of Args, and allow routines to add new strings (to have a
    /// convenient place to store the memory) via MakeIndex.
    mutable std::list<std::string> SynthesizedStrings;

    /// The number of original input argument strings.
    unsigned NumInputArgStrings;

  public:
    InputArgList(const char **ArgBegin, const char **ArgEnd);
    InputArgList(const ArgList &);
    ~InputArgList();

    virtual const char *getArgString(unsigned Index) const { 
      return ArgStrings[Index]; 
    }

    /// getNumInputArgStrings - Return the number of original input
    /// argument strings.
    unsigned getNumInputArgStrings() const { return NumInputArgStrings; }

    /// @name Arg Synthesis
    /// @{

  public:
    /// MakeIndex - Get an index for the given string(s).
    unsigned MakeIndex(const char *String0) const;
    unsigned MakeIndex(const char *String0, const char *String1) const;

    virtual const char *MakeArgString(const char *Str) const;

    /// @}
  };

  /// DerivedArgList - An ordered collection of driver arguments,
  /// whose storage may be in another argument list.
  class DerivedArgList : public ArgList {
    InputArgList &BaseArgs;

    /// The internal list of arguments.
    arglist_type ActualArgs;

    /// The list of arguments we synthesized.
    arglist_type SynthesizedArgs;

    /// Is this only a proxy for the base ArgList?
    bool OnlyProxy;

  public:
    /// Construct a new derived arg list from \arg BaseArgs.
    ///
    /// \param OnlyProxy - If true, this is only a proxy for the base
    /// list (to adapt the type), and it's Args list is unused.
    DerivedArgList(InputArgList &BaseArgs, bool OnlyProxy);
    ~DerivedArgList();

    virtual const char *getArgString(unsigned Index) const {
      return BaseArgs.getArgString(Index); 
    }

    /// @name Arg Synthesis
    /// @{

    virtual const char *MakeArgString(const char *Str) const;

    /// MakeFlagArg - Construct a new FlagArg for the given option
    /// \arg Id.
    Arg *MakeFlagArg(const Arg *BaseArg, const Option *Opt) const;

    /// MakePositionalArg - Construct a new Positional arg for the
    /// given option \arg Id, with the provided \arg Value.
    Arg *MakePositionalArg(const Arg *BaseArg, const Option *Opt, 
                           const char *Value) const;

    /// MakeSeparateArg - Construct a new Positional arg for the
    /// given option \arg Id, with the provided \arg Value.
    Arg *MakeSeparateArg(const Arg *BaseArg, const Option *Opt, 
                         const char *Value) const;

    /// MakeJoinedArg - Construct a new Positional arg for the
    /// given option \arg Id, with the provided \arg Value.
    Arg *MakeJoinedArg(const Arg *BaseArg, const Option *Opt, 
                       const char *Value) const;

    /// @}
  };

} // end namespace driver
} // end namespace clang

#endif
OpenPOWER on IntegriCloud