Line data Source code
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 LLVM_OPTION_ARGLIST_H
11 : #define LLVM_OPTION_ARGLIST_H
12 :
13 : #include "llvm/ADT/ArrayRef.h"
14 : #include "llvm/ADT/DenseMap.h"
15 : #include "llvm/ADT/iterator_range.h"
16 : #include "llvm/ADT/SmallString.h"
17 : #include "llvm/ADT/SmallVector.h"
18 : #include "llvm/ADT/StringRef.h"
19 : #include "llvm/ADT/Twine.h"
20 : #include "llvm/Option/Arg.h"
21 : #include "llvm/Option/OptSpecifier.h"
22 : #include "llvm/Option/Option.h"
23 : #include <algorithm>
24 : #include <cstddef>
25 : #include <initializer_list>
26 : #include <iterator>
27 : #include <list>
28 : #include <memory>
29 : #include <string>
30 : #include <utility>
31 : #include <vector>
32 :
33 : namespace llvm {
34 :
35 : class raw_ostream;
36 :
37 : namespace opt {
38 :
39 : /// arg_iterator - Iterates through arguments stored inside an ArgList.
40 : template<typename BaseIter, unsigned NumOptSpecifiers = 0>
41 11350763 : class arg_iterator {
42 : /// The current argument and the end of the sequence we're iterating.
43 : BaseIter Current, End;
44 :
45 : /// Optional filters on the arguments which will be match. To avoid a
46 : /// zero-sized array, we store one specifier even if we're asked for none.
47 : OptSpecifier Ids[NumOptSpecifiers ? NumOptSpecifiers : 1];
48 :
49 70449672 : void SkipToNextArg() {
50 87963804 : for (; Current != End; ++Current) {
51 : // Skip erased elements.
52 18395920 : if (!*Current)
53 : continue;
54 :
55 : // Done if there are no filters.
56 : if (!NumOptSpecifiers)
57 : return;
58 :
59 : // Otherwise require a match.
60 : const Option &O = (*Current)->getOption();
61 3546094 : for (auto Id : Ids) {
62 2981509 : if (!Id.isValid())
63 : break;
64 2899530 : if (O.matches(Id))
65 : return;
66 : }
67 : }
68 : }
69 8550962 :
70 8551722 : using Traits = std::iterator_traits<BaseIter>;
71 :
72 50353 : public:
73 : using value_type = typename Traits::value_type;
74 : using reference = typename Traits::reference;
75 : using pointer = typename Traits::pointer;
76 : using iterator_category = std::forward_iterator_tag;
77 : using difference_type = std::ptrdiff_t;
78 :
79 63284 : arg_iterator(
80 : BaseIter Current, BaseIter End,
81 59817 : const OptSpecifier (&Ids)[NumOptSpecifiers ? NumOptSpecifiers : 1] = {})
82 122341 : : Current(Current), End(End) {
83 2718 : for (unsigned I = 0; I != NumOptSpecifiers; ++I)
84 123655 : this->Ids[I] = Ids[I];
85 31993 : SkipToNextArg();
86 : }
87 :
88 0 : reference operator*() const { return *Current; }
89 35600417 : pointer operator->() const { return Current; }
90 36094681 :
91 : arg_iterator &operator++() {
92 1138653 : ++Current;
93 11832 : SkipToNextArg();
94 : return *this;
95 : }
96 :
97 : arg_iterator operator++(int) {
98 : arg_iterator tmp(*this);
99 : ++(*this);
100 : return tmp;
101 1674076 : }
102 1261807 :
103 0 : friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
104 1179828 : return LHS.Current == RHS.Current;
105 : }
106 0 : friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
107 0 : return !(LHS == RHS);
108 : }
109 8945668 : };
110 8999928 :
111 : /// ArgList - Ordered collection of driver arguments.
112 613010 : ///
113 : /// The ArgList class manages a list of Arg instances as well as
114 : /// auxiliary data and convenience methods to allow Tools to quickly
115 : /// check for the presence of Arg instances for a particular Option
116 : /// and to iterate over groups of arguments.
117 : class ArgList {
118 : public:
119 30781908 : using arglist_type = SmallVector<Arg *, 16>;
120 : using iterator = arg_iterator<arglist_type::iterator>;
121 698294 : using const_iterator = arg_iterator<arglist_type::const_iterator>;
122 31485570 : using reverse_iterator = arg_iterator<arglist_type::reverse_iterator>;
123 26488 : using const_reverse_iterator =
124 741420 : arg_iterator<arglist_type::const_reverse_iterator>;
125 15429954 :
126 : template<unsigned N> using filtered_iterator =
127 : arg_iterator<arglist_type::const_iterator, N>;
128 0 : template<unsigned N> using filtered_reverse_iterator =
129 10347870 : arg_iterator<arglist_type::const_reverse_iterator, N>;
130 10424994 :
131 : private:
132 442351 : /// The internal list of arguments.
133 450231 : arglist_type Args;
134 :
135 : using OptRange = std::pair<unsigned, unsigned>;
136 : static OptRange emptyRange() { return {-1u, 0u}; }
137 :
138 : /// The first and last index of each different OptSpecifier ID.
139 55292 : DenseMap<unsigned, OptRange> OptRanges;
140 :
141 518953 : /// Get the range of indexes in which options with the specified IDs might
142 514931 : /// reside, or (0, 0) if there are no such options.
143 233212 : OptRange getRange(std::initializer_list<OptSpecifier> Ids) const;
144 623853 :
145 114514 : protected:
146 0 : // Make the default special members protected so they won't be used to slice
147 5302 : // derived objects, but can still be used by derived objects to implement
148 0 : // their own special members.
149 3967820 : ArgList() = default;
150 3987844 :
151 : // Explicit move operations to ensure the container is cleared post-move
152 473808 : // otherwise it could lead to a double-delete in the case of moving of an
153 1715 : // InputArgList which deletes the contents of the container. If we could fix
154 : // up the ownership here (delegate storage/ownership to the derived class so
155 0 : // it can be a container of unique_ptr) this would be simpler.
156 0 : ArgList(ArgList &&RHS)
157 : : Args(std::move(RHS.Args)), OptRanges(std::move(RHS.OptRanges)) {
158 0 : RHS.Args.clear();
159 102602 : RHS.OptRanges.clear();
160 : }
161 540384 :
162 728512 : ArgList &operator=(ArgList &&RHS) {
163 91960 : Args = std::move(RHS.Args);
164 585867 : RHS.Args.clear();
165 64540 : OptRanges = std::move(RHS.OptRanges);
166 34821 : RHS.OptRanges.clear();
167 34821 : return *this;
168 0 : }
169 2979014 :
170 2979141 : // Protect the dtor to ensure this type is never destroyed polymorphically.
171 144740 : ~ArgList() = default;
172 2293115 :
173 25026 : // Implicitly convert a value to an OptSpecifier. Used to work around a bug
174 : // in MSVC's implementation of narrowing conversion checking.
175 0 : static OptSpecifier toOptSpecifier(OptSpecifier S) { return S; }
176 0 :
177 : public:
178 0 : /// @name Arg Access
179 18654968 : /// @{
180 :
181 42574 : /// append - Append \p A to the arg list.
182 18684540 : void append(Arg *A);
183 37534319 :
184 26145363 : const arglist_type &getArgs() const { return Args; }
185 15233658 :
186 2 : unsigned size() const { return Args.size(); }
187 0 :
188 0 : /// @}
189 362 : /// @name Arg Iteration
190 362 : /// @{
191 :
192 3335887 : iterator begin() { return {Args.begin(), Args.end()}; }
193 714109 : iterator end() { return {Args.end(), Args.end()}; }
194 :
195 0 : reverse_iterator rbegin() { return {Args.rbegin(), Args.rend()}; }
196 0 : reverse_iterator rend() { return {Args.rend(), Args.rend()}; }
197 :
198 1540790 : const_iterator begin() const { return {Args.begin(), Args.end()}; }
199 14551996 : const_iterator end() const { return {Args.end(), Args.end()}; }
200 :
201 135 : const_reverse_iterator rbegin() const { return {Args.rbegin(), Args.rend()}; }
202 15595432 : const_reverse_iterator rend() const { return {Args.rend(), Args.rend()}; }
203 6999558 :
204 5160123 : template<typename ...OptSpecifiers>
205 8717444 : iterator_range<filtered_iterator<sizeof...(OptSpecifiers)>>
206 31642 : filtered(OptSpecifiers ...Ids) const {
207 31642 : OptRange Range = getRange({toOptSpecifier(Ids)...});
208 31796 : auto B = Args.begin() + Range.first;
209 31867 : auto E = Args.begin() + Range.second;
210 0 : using Iterator = filtered_iterator<sizeof...(OptSpecifiers)>;
211 63111 : return make_range(Iterator(B, E, {toOptSpecifier(Ids)...}),
212 5605643 : Iterator(E, E, {toOptSpecifier(Ids)...}));
213 2450928 : }
214 1541379 :
215 48 : template<typename ...OptSpecifiers>
216 48 : iterator_range<filtered_reverse_iterator<sizeof...(OptSpecifiers)>>
217 589 : filtered_reverse(OptSpecifiers ...Ids) const {
218 541 : OptRange Range = getRange({toOptSpecifier(Ids)...});
219 251992 : auto B = Args.rend() - Range.second;
220 48 : auto E = Args.rend() - Range.first;
221 0 : using Iterator = filtered_reverse_iterator<sizeof...(OptSpecifiers)>;
222 235067 : return make_range(Iterator(B, E, {toOptSpecifier(Ids)...}),
223 1171934 : Iterator(E, E, {toOptSpecifier(Ids)...}));
224 985321 : }
225 218133 :
226 0 : /// @}
227 27062 : /// @name Arg Removal
228 13531 : /// @{
229 0 :
230 0 : /// eraseArg - Remove any option matching \p Id.
231 0 : void eraseArg(OptSpecifier Id);
232 5471 :
233 1259 : /// @}
234 0 : /// @name Arg Access
235 0 : /// @{
236 0 :
237 0 : /// hasArg - Does the arg list contain any option matching \p Id.
238 246 : ///
239 10 : /// \p Claim Whether the argument should be claimed, if it exists.
240 2577 : template<typename ...OptSpecifiers>
241 9 : bool hasArgNoClaim(OptSpecifiers ...Ids) const {
242 52813 : return getLastArgNoClaim(Ids...) != nullptr;
243 6631407 : }
244 4457278 : template<typename ...OptSpecifiers>
245 2230695 : bool hasArg(OptSpecifiers ...Ids) const {
246 97613 : return getLastArg(Ids...) != nullptr;
247 32385 : }
248 32385 :
249 34962 : /// Return the last argument matching \p Id, or null.
250 0 : template<typename ...OptSpecifiers>
251 82832 : Arg *getLastArg(OptSpecifiers ...Ids) const {
252 3010538 : Arg *Res = nullptr;
253 56901 : for (Arg *A : filtered(Ids...)) {
254 19259 : Res = A;
255 19259 : Res->claim();
256 19259 : }
257 37351 : return Res;
258 15388413 : }
259 15426931 :
260 15407672 : /// Return the last argument matching \p Id, or null. Do not "claim" the
261 15389503 : /// option (don't mark it as having been used).
262 27698 : template<typename ...OptSpecifiers>
263 30785751 : Arg *getLastArgNoClaim(OptSpecifiers ...Ids) const {
264 15401980 : for (Arg *A : filtered_reverse(Ids...))
265 13597 : return A;
266 4134 : return nullptr;
267 44079 : }
268 17501 :
269 42847 : /// getArgString - Return the input argument string at \p Index.
270 154 : virtual const char *getArgString(unsigned Index) const = 0;
271 4269 :
272 3980 : /// getNumInputArgStrings - Return the number of original argument strings,
273 18691 : /// which are guaranteed to be the first strings in the argument string
274 15380604 : /// list.
275 15419307 : virtual unsigned getNumInputArgStrings() const = 0;
276 15415711 :
277 15410698 : /// @}
278 35107 : /// @name Argument Lookup Utilities
279 31001223 : /// @{
280 15445706 :
281 35155 : /// getLastArgValue - Return the value of the last argument, or a default.
282 6975 : StringRef getLastArgValue(OptSpecifier Id, StringRef Default = "") const;
283 20476 :
284 52372 : /// getAllArgValues - Get the values of all instances of the given argument
285 90986 : /// as strings.
286 53853 : std::vector<std::string> getAllArgValues(OptSpecifier Id) const;
287 67713 :
288 41753 : /// @}
289 78301 : /// @name Translation Utilities
290 19015 : /// @{
291 17605 :
292 57418 : /// hasFlag - Given an option \p Pos and its negative form \p Neg, return
293 31653 : /// true if the option is present, false if the negation is present, and
294 49022 : /// \p Default if neither option is given. If both the option and its
295 22620 : /// negation are present, the last one wins.
296 17536 : bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
297 22689 :
298 5959 : /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative
299 17536 : /// form \p Neg, return true if the option or its alias is present, false if
300 45796 : /// the negation is present, and \p Default if none of the options are
301 11017 : /// given. If multiple options are present, the last one wins.
302 27986 : bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
303 29639 : bool Default = true) const;
304 17322 :
305 42037 : /// AddLastArg - Render only the last argument match \p Id0, if present.
306 10729 : void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
307 19259 : void AddLastArg(ArgStringList &Output, OptSpecifier Id0,
308 20469 : OptSpecifier Id1) const;
309 43409 :
310 54301 : /// AddAllArgsExcept - Render all arguments matching any of the given ids
311 54301 : /// and not matching any of the excluded ids.
312 51094 : void AddAllArgsExcept(ArgStringList &Output, ArrayRef<OptSpecifier> Ids,
313 74278 : ArrayRef<OptSpecifier> ExcludeIds) const;
314 29449 : /// AddAllArgs - Render all arguments matching any of the given ids.
315 89386 : void AddAllArgs(ArgStringList &Output, ArrayRef<OptSpecifier> Ids) const;
316 51302 :
317 : /// AddAllArgs - Render all arguments matching the given ids.
318 5250 : void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
319 15383475 : OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
320 7618 :
321 31210459 : /// AddAllArgValues - Render the argument values of all arguments
322 1501 : /// matching the given ids.
323 5192 : void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
324 86734 : OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
325 15378225 :
326 31720 : /// AddAllArgsTranslated - Render all the arguments matching the
327 15457344 : /// given ids, but forced to separate args and using the provided
328 31571 : /// name instead of the first option value.
329 31224734 : ///
330 181518 : /// \param Joined - If true, render the argument as joined with
331 242654 : /// the option specifier.
332 213089 : void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
333 15553924 : const char *Translation,
334 8578 : bool Joined = false) const;
335 362710 :
336 9543543 : /// ClaimAllArgs - Claim all arguments which match the given
337 9334934 : /// option id.
338 9394453 : void ClaimAllArgs(OptSpecifier Id0) const;
339 9340662 :
340 13684 : /// ClaimAllArgs - Claim all arguments.
341 12943037 : ///
342 9359537 : void ClaimAllArgs() const;
343 20038 :
344 4132453 : /// @}
345 4140089 : /// @name Arg Synthesis
346 4128998 : /// @{
347 4145320 :
348 52248 : /// Construct a constant string pointer whose
349 4202371 : /// lifetime will match that of the ArgList.
350 4121387 : virtual const char *MakeArgStringRef(StringRef Str) const = 0;
351 468272 : const char *MakeArgString(const Twine &Str) const {
352 1625613 : SmallString<256> Buf;
353 2070067 : return MakeArgStringRef(Str.toStringRef(Buf));
354 1658113 : }
355 1651452 :
356 22601 : /// Create an arg string for (\p LHS + \p RHS), reusing the
357 1695649 : /// string at \p Index if possible.
358 1714612 : const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS,
359 214542 : StringRef RHS) const;
360 3575661 :
361 3673002 : void print(raw_ostream &O) const;
362 11608634 : void dump() const;
363 11538592 :
364 7963075 : /// @}
365 15062804 : };
366 3578009 :
367 15004806 : class InputArgList final : public ArgList {
368 7970485 : private:
369 13956 : /// List of argument strings used by the contained Args.
370 73123 : ///
371 101671 : /// This is mutable since we treat the ArgList as being the list
372 62014 : /// of Args, and allow routines to add new strings (to have a
373 167977 : /// convenient place to store the memory) via MakeIndex.
374 218196 : mutable ArgStringList ArgStrings;
375 81556 :
376 79381 : /// Strings for synthesized arguments.
377 57058 : ///
378 392805 : /// This is mutable since we treat the ArgList as being the list
379 446762 : /// of Args, and allow routines to add new strings (to have a
380 392805 : /// convenient place to store the memory) via MakeIndex.
381 443925 : mutable std::list<std::string> SynthesizedStrings;
382 713 :
383 649339 : /// The number of original input argument strings.
384 393757 : unsigned NumInputArgStrings;
385 24356 :
386 4554530 : /// Release allocated arguments.
387 4575372 : void releaseMemory();
388 4665440 :
389 4708478 : public:
390 110340 : InputArgList() : NumInputArgStrings(0) {}
391 9018841 :
392 4556699 : InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
393 150304 :
394 625098 : InputArgList(InputArgList &&RHS)
395 513228 : : ArgList(std::move(RHS)), ArgStrings(std::move(RHS.ArgStrings)),
396 537780 : SynthesizedStrings(std::move(RHS.SynthesizedStrings)),
397 536092 : NumInputArgStrings(RHS.NumInputArgStrings) {}
398 21176 :
399 534233 : InputArgList &operator=(InputArgList &&RHS) {
400 513511 : releaseMemory();
401 21277 : ArgList::operator=(std::move(RHS));
402 1657723 : ArgStrings = std::move(RHS.ArgStrings);
403 1573471 : SynthesizedStrings = std::move(RHS.SynthesizedStrings);
404 1573269 : NumInputArgStrings = RHS.NumInputArgStrings;
405 8944029 : return *this;
406 301 : }
407 18190313 :
408 2917132 : ~InputArgList() { releaseMemory(); }
409 1372661 :
410 1815071 : const char *getArgString(unsigned Index) const override {
411 14584201 : return ArgStrings[Index];
412 722966 : }
413 5253317 :
414 1136808 : unsigned getNumInputArgStrings() const override {
415 8034357 : return NumInputArgStrings;
416 700740 : }
417 33950 :
418 23645 : /// @name Arg Synthesis
419 3235847 : /// @{
420 22023 :
421 161162 : public:
422 21777 : /// MakeIndex - Get an index for the given string(s).
423 302194 : unsigned MakeIndex(StringRef String0) const;
424 26466 : unsigned MakeIndex(StringRef String0, StringRef String1) const;
425 63307 :
426 47967 : using ArgList::MakeArgString;
427 161906 : const char *MakeArgStringRef(StringRef Str) const override;
428 21168 :
429 4176454 : /// @}
430 47634 : };
431 8314781 :
432 69 : /// DerivedArgList - An ordered collection of driver arguments,
433 31377 : /// whose storage may be in another argument list.
434 21161 : class DerivedArgList final : public ArgList {
435 4123115 : const InputArgList &BaseArgs;
436 2449 :
437 85508 : /// The list of arguments we synthesized.
438 3979 : mutable SmallVector<std::unique_ptr<Arg>, 16> SynthesizedArgs;
439 270767 :
440 1086825 : public:
441 1255557 : /// Construct a new derived arg list from \p BaseArgs.
442 6506861 : DerivedArgList(const InputArgList &BaseArgs);
443 1113316 :
444 672 : const char *getArgString(unsigned Index) const override {
445 1178347 : return BaseArgs.getArgString(Index);
446 1035319 : }
447 6143520 :
448 53871 : unsigned getNumInputArgStrings() const override {
449 12391539 : return BaseArgs.getNumInputArgStrings();
450 1005130 : }
451 88340 :
452 8561 : const InputArgList &getBaseArgs() const {
453 6186289 : return BaseArgs;
454 63627 : }
455 2048524 :
456 : /// @name Arg Synthesis
457 4136055 : /// @{
458 9681 :
459 26412 : /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
460 44779 : /// (to be freed).
461 2085984 : void AddSynthesizedArg(Arg *A);
462 50945 :
463 90016 : using ArgList::MakeArgString;
464 26402 : const char *MakeArgStringRef(StringRef Str) const override;
465 232674 :
466 46679 : /// AddFlagArg - Construct a new FlagArg for the given option \p Id and
467 265 : /// append it to the argument list.
468 10 : void AddFlagArg(const Arg *BaseArg, const Option Opt) {
469 72166 : append(MakeFlagArg(BaseArg, Opt));
470 10 : }
471 578837 :
472 : /// AddPositionalArg - Construct a new Positional arg for the given option
473 1162900 : /// \p Id, with the provided \p Value and append it to the argument
474 0 : /// list.
475 26402 : void AddPositionalArg(const Arg *BaseArg, const Option Opt,
476 26402 : StringRef Value) {
477 605503 : append(MakePositionalArg(BaseArg, Opt, Value));
478 26556 : }
479 263527 :
480 26411 : /// AddSeparateArg - Construct a new Positional arg for the given option
481 586074 : /// \p Id, with the provided \p Value and append it to the argument
482 1 : /// list.
483 802 : void AddSeparateArg(const Arg *BaseArg, const Option Opt,
484 541 : StringRef Value) {
485 264159 : append(MakeSeparateArg(BaseArg, Opt, Value));
486 : }
487 4295211 :
488 541 : /// AddJoinedArg - Construct a new Positional arg for the given option
489 8741492 : /// \p Id, with the provided \p Value and append it to the argument list.
490 : void AddJoinedArg(const Arg *BaseArg, const Option Opt,
491 0 : StringRef Value) {
492 1420 : append(MakeJoinedArg(BaseArg, Opt, Value));
493 4294681 : }
494 0 :
495 0 : /// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
496 : Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const;
497 0 :
498 0 : /// MakePositionalArg - Construct a new Positional arg for the
499 0 : /// given option \p Id, with the provided \p Value.
500 46569 : Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt,
501 0 : StringRef Value) const;
502 :
503 1153 : /// MakeSeparateArg - Construct a new Positional arg for the
504 970529 : /// given option \p Id, with the provided \p Value.
505 92022 : Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt,
506 1366 : StringRef Value) const;
507 184804 :
508 1290 : /// MakeJoinedArg - Construct a new Positional arg for the
509 868518 : /// given option \p Id, with the provided \p Value.
510 2579 : Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt,
511 1844700 : StringRef Value) const;
512 :
513 23964 : /// @}
514 3621 : };
515 909032 :
516 522 : } // end namespace opt
517 276 :
518 5154 : } // end namespace llvm
519 21501 :
520 0 : #endif // LLVM_OPTION_ARGLIST_H
|