1 //===--- ArgList.h - Argument List Management -------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_OPTION_ARGLIST_H
11 #define LLVM_OPTION_ARGLIST_H
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Option/OptSpecifier.h"
16 #include "llvm/Option/Option.h"
28 /// arg_iterator - Iterates through arguments stored inside an ArgList.
30 /// The current argument.
31 SmallVectorImpl
<Arg
*>::const_iterator Current
;
33 /// The argument list we are iterating over.
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.
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
;
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
;
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
) {
62 operator const Arg
*() { return *Current
; }
63 reference
operator*() const { return *Current
; }
64 pointer
operator->() const { return Current
; }
66 arg_iterator
&operator++() {
72 arg_iterator
operator++(int) {
73 arg_iterator
tmp(*this);
78 friend bool operator==(arg_iterator LHS
, arg_iterator RHS
) {
79 return LHS
.Current
== RHS
.Current
;
81 friend bool operator!=(arg_iterator LHS
, arg_iterator RHS
) {
86 /// ArgList - Ordered collection of driver arguments.
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.
94 ArgList(const ArgList
&) LLVM_DELETED_FUNCTION
;
95 void operator=(const ArgList
&) LLVM_DELETED_FUNCTION
;
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
;
105 /// The internal list of arguments.
109 // Default ctor provided explicitly as it is not provided implicitly due to
110 // the presence of the (deleted) copy ctor above.
112 // Virtual to provide a vtable anchor and because -Wnon-virtua-dtor warns, not
113 // because this type is ever actually destroyed polymorphically.
121 /// append - Append \p A to the arg list.
124 arglist_type
&getArgs() { return Args
; }
125 const arglist_type
&getArgs() const { return Args
; }
127 unsigned size() const { return Args
.size(); }
130 /// @name Arg Iteration
133 iterator
begin() { return Args
.begin(); }
134 iterator
end() { return Args
.end(); }
136 reverse_iterator
rbegin() { return Args
.rbegin(); }
137 reverse_iterator
rend() { return Args
.rend(); }
139 const_iterator
begin() const { return Args
.begin(); }
140 const_iterator
end() const { return Args
.end(); }
142 const_reverse_iterator
rbegin() const { return Args
.rbegin(); }
143 const_reverse_iterator
rend() const { return Args
.rend(); }
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
);
149 arg_iterator
filtered_end() const {
150 return arg_iterator(Args
.end(), *this);
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());
160 /// @name Arg Removal
163 /// eraseArg - Remove any option matching \p Id.
164 void eraseArg(OptSpecifier Id
);
170 /// hasArg - Does the arg list contain any option matching \p Id.
172 /// \p Claim Whether the argument should be claimed, if it exists.
173 bool hasArgNoClaim(OptSpecifier Id
) const {
174 return getLastArgNoClaim(Id
) != nullptr;
176 bool hasArg(OptSpecifier Id
) const {
177 return getLastArg(Id
) != nullptr;
179 bool hasArg(OptSpecifier Id0
, OptSpecifier Id1
) const {
180 return getLastArg(Id0
, Id1
) != nullptr;
182 bool hasArg(OptSpecifier Id0
, OptSpecifier Id1
, OptSpecifier Id2
) const {
183 return getLastArg(Id0
, Id1
, Id2
) != nullptr;
186 /// getLastArg - Return the last argument matching \p Id, or null.
188 /// \p Claim Whether the argument should be claimed, if it exists.
189 Arg
*getLastArgNoClaim(OptSpecifier Id
) const;
190 Arg
*getLastArgNoClaim(OptSpecifier Id0
, OptSpecifier Id1
) const;
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;
207 /// getArgString - Return the input argument string at \p Index.
208 virtual const char *getArgString(unsigned Index
) const = 0;
210 /// getNumInputArgStrings - Return the number of original argument strings,
211 /// which are guaranteed to be the first strings in the argument string
213 virtual unsigned getNumInputArgStrings() const = 0;
216 /// @name Argument Lookup Utilities
219 /// getLastArgValue - Return the value of the last argument, or a default.
220 StringRef
getLastArgValue(OptSpecifier Id
,
221 StringRef Default
= "") const;
223 /// getAllArgValues - Get the values of all instances of the given argument
225 std::vector
<std::string
> getAllArgValues(OptSpecifier Id
) const;
228 /// @name Translation Utilities
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;
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;
244 /// AddLastArg - Render only the last argument match \p Id0, if present.
245 void AddLastArg(ArgStringList
&Output
, OptSpecifier Id0
) const;
246 void AddLastArg(ArgStringList
&Output
, OptSpecifier Id0
,
247 OptSpecifier Id1
) const;
249 /// AddAllArgs - Render all arguments matching the given ids.
250 void AddAllArgs(ArgStringList
&Output
, OptSpecifier Id0
,
251 OptSpecifier Id1
= 0U, OptSpecifier Id2
= 0U) const;
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;
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.
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;
268 /// ClaimAllArgs - Claim all arguments which match the given
270 void ClaimAllArgs(OptSpecifier Id0
) const;
272 /// ClaimAllArgs - Claim all arguments.
274 void ClaimAllArgs() const;
277 /// @name Arg Synthesis
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
));
286 const char *MakeArgString(std::string Str
) const {
287 return MakeArgString(StringRef(Str
));
289 const char *MakeArgString(const Twine
&Str
) const;
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;
299 class InputArgList
: public ArgList
{
301 /// List of argument strings used by the contained Args.
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
;
308 /// Strings for synthesized arguments.
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
;
315 /// The number of original input argument strings.
316 unsigned NumInputArgStrings
;
319 InputArgList(const char* const *ArgBegin
, const char* const *ArgEnd
);
322 const char *getArgString(unsigned Index
) const override
{
323 return ArgStrings
[Index
];
326 unsigned getNumInputArgStrings() const override
{
327 return NumInputArgStrings
;
330 /// @name Arg Synthesis
334 /// MakeIndex - Get an index for the given string(s).
335 unsigned MakeIndex(StringRef String0
) const;
336 unsigned MakeIndex(StringRef String0
, StringRef String1
) const;
338 using ArgList::MakeArgString
;
339 const char *MakeArgString(StringRef Str
) const override
;
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
;
349 /// The list of arguments we synthesized.
350 mutable SmallVector
<std::unique_ptr
<Arg
>, 16> SynthesizedArgs
;
353 /// Construct a new derived arg list from \p BaseArgs.
354 DerivedArgList(const InputArgList
&BaseArgs
);
357 const char *getArgString(unsigned Index
) const override
{
358 return BaseArgs
.getArgString(Index
);
361 unsigned getNumInputArgStrings() const override
{
362 return BaseArgs
.getNumInputArgStrings();
365 const InputArgList
&getBaseArgs() const {
369 /// @name Arg Synthesis
372 /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
374 void AddSynthesizedArg(Arg
*A
);
376 using ArgList::MakeArgString
;
377 const char *MakeArgString(StringRef Str
) const override
;
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
));
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
388 void AddPositionalArg(const Arg
*BaseArg
, const Option Opt
,
390 append(MakePositionalArg(BaseArg
, Opt
, Value
));
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
397 void AddSeparateArg(const Arg
*BaseArg
, const Option Opt
,
399 append(MakeSeparateArg(BaseArg
, Opt
, Value
));
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
,
407 append(MakeJoinedArg(BaseArg
, Opt
, Value
));
411 /// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
412 Arg
*MakeFlagArg(const Arg
*BaseArg
, const Option Opt
) const;
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;
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;
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;
432 } // end namespace opt
433 } // end namespace llvm