summaryrefslogtreecommitdiffstats
path: root/include/clang/Driver/ArgList.h
blob: 5263108d1a6d3eca66f38f18a60ee2c4996a20c2 (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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
//===--- 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/OptSpecifier.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"

#include <list>
#include <string>

namespace llvm {
  class Twine;
}

namespace clang {
namespace driver {
  class Arg;
  class Option;

  /// 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 hasArgNoClaim(OptSpecifier Id) const {
      return getLastArgNoClaim(Id) != 0;
    }
    bool hasArg(OptSpecifier Id) const {
      return getLastArg(Id) != 0;
    }
    bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
      return getLastArg(Id0, Id1) != 0;
    }
    bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
      return getLastArg(Id0, Id1, Id2) != 0;
    }

    /// getLastArg - Return the last argument matching \arg Id, or null.
    ///
    /// \arg Claim Whether the argument should be claimed, if it exists.
    Arg *getLastArgNoClaim(OptSpecifier Id) const;
    Arg *getLastArg(OptSpecifier Id) const;
    Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
    Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) 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(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;

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

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

    /// AddAllArgValues - Render the argument values of all arguments
    /// matching the given ids.
    void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const;
    void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
                         OptSpecifier 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, OptSpecifier Id0,
                              const char *Translation,
                              bool Joined = false) const;

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

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

    /// MakeArgString - Construct a constant string pointer whose
    /// lifetime will match that of the ArgList.
    virtual const char *MakeArgString(llvm::StringRef Str) const = 0;
    const char *MakeArgString(const char *Str) const {
      return MakeArgString(llvm::StringRef(Str));
    }
    const char *MakeArgString(std::string Str) const {
      return MakeArgString(llvm::StringRef(Str));
    }
    const char *MakeArgString(const llvm::Twine &Str) const;

    /// @}
  };

  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(llvm::StringRef String0) const;
    unsigned MakeIndex(llvm::StringRef String0, llvm::StringRef String1) const;

    virtual const char *MakeArgString(llvm::StringRef 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(llvm::StringRef 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,
                           llvm::StringRef 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,
                         llvm::StringRef 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,
                       llvm::StringRef Value) const;

    /// @}
  };

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

#endif
OpenPOWER on IntegriCloud