LLVM  4.0.0
ArgList.cpp
Go to the documentation of this file.
1 //===--- ArgList.cpp - Argument List Management ---------------------------===//
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 #include "llvm/Option/ArgList.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/Option/Arg.h"
15 #include "llvm/Option/Option.h"
16 #include "llvm/Support/Debug.h"
18 
19 using namespace llvm;
20 using namespace llvm::opt;
21 
22 void arg_iterator::SkipToNextArg() {
23  for (; Current != Args.end(); ++Current) {
24  // Done if there are no filters.
25  if (!Id0.isValid())
26  break;
27 
28  // Otherwise require a match.
29  const Option &O = (*Current)->getOption();
30  if (O.matches(Id0) ||
31  (Id1.isValid() && O.matches(Id1)) ||
32  (Id2.isValid() && O.matches(Id2)))
33  break;
34  }
35 }
36 
38  Args.push_back(A);
39 }
40 
42  Args.erase(
43  remove_if(*this, [=](Arg *A) { return A->getOption().matches(Id); }),
44  end());
45 }
46 
48  // FIXME: Make search efficient?
49  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
50  if ((*it)->getOption().matches(Id))
51  return *it;
52  return nullptr;
53 }
54 
56  // FIXME: Make search efficient?
57  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
58  if ((*it)->getOption().matches(Id0) ||
59  (*it)->getOption().matches(Id1))
60  return *it;
61  return nullptr;
62 }
63 
65  OptSpecifier Id2) const {
66  // FIXME: Make search efficient?
67  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
68  if ((*it)->getOption().matches(Id0) || (*it)->getOption().matches(Id1) ||
69  (*it)->getOption().matches(Id2))
70  return *it;
71  return nullptr;
72 }
73 
75  OptSpecifier Id2, OptSpecifier Id3) const {
76  // FIXME: Make search efficient?
77  for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
78  if ((*it)->getOption().matches(Id0) || (*it)->getOption().matches(Id1) ||
79  (*it)->getOption().matches(Id2) || (*it)->getOption().matches(Id3))
80  return *it;
81  return nullptr;
82 }
83 
85  Arg *Res = nullptr;
86  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
87  if ((*it)->getOption().matches(Id)) {
88  Res = *it;
89  Res->claim();
90  }
91  }
92 
93  return Res;
94 }
95 
97  Arg *Res = nullptr;
98  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
99  if ((*it)->getOption().matches(Id0) ||
100  (*it)->getOption().matches(Id1)) {
101  Res = *it;
102  Res->claim();
103 
104  }
105  }
106 
107  return Res;
108 }
109 
111  OptSpecifier Id2) const {
112  Arg *Res = nullptr;
113  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
114  if ((*it)->getOption().matches(Id0) ||
115  (*it)->getOption().matches(Id1) ||
116  (*it)->getOption().matches(Id2)) {
117  Res = *it;
118  Res->claim();
119  }
120  }
121 
122  return Res;
123 }
124 
126  OptSpecifier Id2, OptSpecifier Id3) const {
127  Arg *Res = nullptr;
128  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
129  if ((*it)->getOption().matches(Id0) ||
130  (*it)->getOption().matches(Id1) ||
131  (*it)->getOption().matches(Id2) ||
132  (*it)->getOption().matches(Id3)) {
133  Res = *it;
134  Res->claim();
135  }
136  }
137 
138  return Res;
139 }
140 
142  OptSpecifier Id2, OptSpecifier Id3,
143  OptSpecifier Id4) const {
144  Arg *Res = nullptr;
145  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
146  if ((*it)->getOption().matches(Id0) ||
147  (*it)->getOption().matches(Id1) ||
148  (*it)->getOption().matches(Id2) ||
149  (*it)->getOption().matches(Id3) ||
150  (*it)->getOption().matches(Id4)) {
151  Res = *it;
152  Res->claim();
153  }
154  }
155 
156  return Res;
157 }
158 
160  OptSpecifier Id2, OptSpecifier Id3,
161  OptSpecifier Id4, OptSpecifier Id5) const {
162  Arg *Res = nullptr;
163  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
164  if ((*it)->getOption().matches(Id0) ||
165  (*it)->getOption().matches(Id1) ||
166  (*it)->getOption().matches(Id2) ||
167  (*it)->getOption().matches(Id3) ||
168  (*it)->getOption().matches(Id4) ||
169  (*it)->getOption().matches(Id5)) {
170  Res = *it;
171  Res->claim();
172  }
173  }
174 
175  return Res;
176 }
177 
179  OptSpecifier Id2, OptSpecifier Id3,
180  OptSpecifier Id4, OptSpecifier Id5,
181  OptSpecifier Id6) const {
182  Arg *Res = nullptr;
183  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
184  if ((*it)->getOption().matches(Id0) ||
185  (*it)->getOption().matches(Id1) ||
186  (*it)->getOption().matches(Id2) ||
187  (*it)->getOption().matches(Id3) ||
188  (*it)->getOption().matches(Id4) ||
189  (*it)->getOption().matches(Id5) ||
190  (*it)->getOption().matches(Id6)) {
191  Res = *it;
192  Res->claim();
193  }
194  }
195 
196  return Res;
197 }
198 
200  OptSpecifier Id2, OptSpecifier Id3,
201  OptSpecifier Id4, OptSpecifier Id5,
202  OptSpecifier Id6, OptSpecifier Id7) const {
203  Arg *Res = nullptr;
204  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
205  if ((*it)->getOption().matches(Id0) ||
206  (*it)->getOption().matches(Id1) ||
207  (*it)->getOption().matches(Id2) ||
208  (*it)->getOption().matches(Id3) ||
209  (*it)->getOption().matches(Id4) ||
210  (*it)->getOption().matches(Id5) ||
211  (*it)->getOption().matches(Id6) ||
212  (*it)->getOption().matches(Id7)) {
213  Res = *it;
214  Res->claim();
215  }
216  }
217 
218  return Res;
219 }
220 
221 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
222  if (Arg *A = getLastArg(Pos, Neg))
223  return A->getOption().matches(Pos);
224  return Default;
225 }
226 
228  bool Default) const {
229  if (Arg *A = getLastArg(Pos, PosAlias, Neg))
230  return A->getOption().matches(Pos) || A->getOption().matches(PosAlias);
231  return Default;
232 }
233 
235  StringRef Default) const {
236  if (Arg *A = getLastArg(Id))
237  return A->getValue();
238  return Default;
239 }
240 
241 std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
243  AddAllArgValues(Values, Id);
244  return std::vector<std::string>(Values.begin(), Values.end());
245 }
246 
248  if (Arg *A = getLastArg(Id)) {
249  A->claim();
250  A->render(*this, Output);
251  }
252 }
253 
255  OptSpecifier Id1) const {
256  if (Arg *A = getLastArg(Id0, Id1)) {
257  A->claim();
258  A->render(*this, Output);
259  }
260 }
261 
264  ArrayRef<OptSpecifier> ExcludeIds) const {
265  for (const Arg *Arg : Args) {
266  bool Excluded = false;
267  for (OptSpecifier Id : ExcludeIds) {
268  if (Arg->getOption().matches(Id)) {
269  Excluded = true;
270  break;
271  }
272  }
273  if (!Excluded) {
274  for (OptSpecifier Id : Ids) {
275  if (Arg->getOption().matches(Id)) {
276  Arg->claim();
277  Arg->render(*this, Output);
278  break;
279  }
280  }
281  }
282  }
283 }
284 
285 /// This is a nicer interface when you don't have a list of Ids to exclude.
287  ArrayRef<OptSpecifier> Ids) const {
288  ArrayRef<OptSpecifier> Exclude = None;
289  AddAllArgsExcept(Output, Ids, Exclude);
290 }
291 
292 /// This 3-opt variant of AddAllArgs could be eliminated in favor of one
293 /// that accepts a single specifier, given the above which accepts any number.
295  OptSpecifier Id1, OptSpecifier Id2) const {
296  for (auto Arg: filtered(Id0, Id1, Id2)) {
297  Arg->claim();
298  Arg->render(*this, Output);
299  }
300 }
301 
303  OptSpecifier Id1, OptSpecifier Id2) const {
304  for (auto Arg : filtered(Id0, Id1, Id2)) {
305  Arg->claim();
306  const auto &Values = Arg->getValues();
307  Output.append(Values.begin(), Values.end());
308  }
309 }
310 
312  const char *Translation,
313  bool Joined) const {
314  for (auto Arg: filtered(Id0)) {
315  Arg->claim();
316 
317  if (Joined) {
318  Output.push_back(MakeArgString(StringRef(Translation) +
319  Arg->getValue(0)));
320  } else {
321  Output.push_back(Translation);
322  Output.push_back(Arg->getValue(0));
323  }
324  }
325 }
326 
328  for (auto Arg : filtered(Id0))
329  Arg->claim();
330 }
331 
332 void ArgList::ClaimAllArgs() const {
333  for (const_iterator it = begin(), ie = end(); it != ie; ++it)
334  if (!(*it)->isClaimed())
335  (*it)->claim();
336 }
337 
338 const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
339  StringRef LHS,
340  StringRef RHS) const {
341  StringRef Cur = getArgString(Index);
342  if (Cur.size() == LHS.size() + RHS.size() &&
343  Cur.startswith(LHS) && Cur.endswith(RHS))
344  return Cur.data();
345 
346  return MakeArgString(LHS + RHS);
347 }
348 
349 void ArgList::print(raw_ostream &O) const {
350  for (Arg *A : *this) {
351  O << "* ";
352  A->print(O);
353  }
354 }
355 
357 
358 //
359 
360 void InputArgList::releaseMemory() {
361  // An InputArgList always owns its arguments.
362  for (Arg *A : *this)
363  delete A;
364 }
365 
366 InputArgList::InputArgList(const char* const *ArgBegin,
367  const char* const *ArgEnd)
368  : NumInputArgStrings(ArgEnd - ArgBegin) {
369  ArgStrings.append(ArgBegin, ArgEnd);
370 }
371 
372 unsigned InputArgList::MakeIndex(StringRef String0) const {
373  unsigned Index = ArgStrings.size();
374 
375  // Tuck away so we have a reliable const char *.
376  SynthesizedStrings.push_back(String0);
377  ArgStrings.push_back(SynthesizedStrings.back().c_str());
378 
379  return Index;
380 }
381 
383  StringRef String1) const {
384  unsigned Index0 = MakeIndex(String0);
385  unsigned Index1 = MakeIndex(String1);
386  assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
387  (void) Index1;
388  return Index0;
389 }
390 
392  return getArgString(MakeIndex(Str));
393 }
394 
395 //
396 
398  : BaseArgs(BaseArgs) {}
399 
401  return BaseArgs.MakeArgString(Str);
402 }
403 
405  SynthesizedArgs.push_back(std::unique_ptr<Arg>(A));
406 }
407 
408 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
409  SynthesizedArgs.push_back(
410  make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
411  BaseArgs.MakeIndex(Opt.getName()), BaseArg));
412  return SynthesizedArgs.back().get();
413 }
414 
415 Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
416  StringRef Value) const {
417  unsigned Index = BaseArgs.MakeIndex(Value);
418  SynthesizedArgs.push_back(
419  make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
420  Index, BaseArgs.getArgString(Index), BaseArg));
421  return SynthesizedArgs.back().get();
422 }
423 
424 Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
425  StringRef Value) const {
426  unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
427  SynthesizedArgs.push_back(
428  make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
429  Index, BaseArgs.getArgString(Index + 1), BaseArg));
430  return SynthesizedArgs.back().get();
431 }
432 
433 Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
434  StringRef Value) const {
435  unsigned Index = BaseArgs.MakeIndex((Opt.getName() + Value).str());
436  SynthesizedArgs.push_back(make_unique<Arg>(
437  Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index,
438  BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg));
439  return SynthesizedArgs.back().get();
440 }
const NoneType None
Definition: None.h:23
void push_back(const T &Elt)
Definition: SmallVector.h:211
bool matches(OptSpecifier ID) const
matches - Predicate for whether this option is part of the given option (which may be a group)...
Definition: Option.cpp:88
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:276
const Option & getOption() const
Definition: Arg.h:70
iterator begin()
Definition: ArgList.h:142
StringRef getName() const
Get the name of this option without any prefix.
Definition: Option.h:90
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:450
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:776
void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, const char *Translation, bool Joined=false) const
AddAllArgsTranslated - Render all the arguments matching the given ids, but forced to separate args a...
Definition: ArgList.cpp:311
Arg * MakeFlagArg(const Arg *BaseArg, const Option Opt) const
MakeFlagArg - Construct a new FlagArg for the given option Id.
Definition: ArgList.cpp:408
arglist_type::const_reverse_iterator const_reverse_iterator
Definition: ArgList.h:100
void eraseArg(OptSpecifier Id)
eraseArg - Remove any option matching Id.
Definition: ArgList.cpp:41
const char * getValue(unsigned N=0) const
Definition: Arg.h:92
reverse_iterator rbegin()
Definition: ArgList.h:145
const char * getArgString(unsigned Index) const override
getArgString - Return the input argument string at Index.
Definition: ArgList.h:357
unsigned MakeIndex(StringRef String0) const
MakeIndex - Get an index for the given string(s).
Definition: ArgList.cpp:372
SmallVectorImpl< const char * > & getValues()
Definition: Arg.h:96
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
void print(raw_ostream &O) const
Definition: Arg.cpp:47
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
void AddAllArgs(ArgStringList &Output, ArrayRef< OptSpecifier > Ids) const
AddAllArgs - Render all arguments matching any of the given ids.
Definition: ArgList.cpp:286
void AddSynthesizedArg(Arg *A)
AddSynthesizedArg - Add a argument to the list of synthesized arguments (to be freed).
Definition: ArgList.cpp:404
Arg * getLastArgNoClaim(OptSpecifier Id) const
getLastArg - Return the last argument matching Id, or null.
Definition: ArgList.cpp:47
void print(raw_ostream &O) const
Definition: ArgList.cpp:349
const char * MakeArgStringRef(StringRef Str) const override
Construct a constant string pointer whose lifetime will match that of the ArgList.
Definition: ArgList.cpp:400
Option - Abstract representation for a single form of driver argument.
Definition: Option.h:44
iterator end()
Definition: ArgList.h:143
A concrete instance of a particular driver option.
Definition: Arg.h:31
DerivedArgList(const InputArgList &BaseArgs)
Construct a new derived arg list from BaseArgs.
Definition: ArgList.cpp:397
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:115
void claim() const
Set the Arg claimed bit.
Definition: Arg.h:89
const char * GetOrMakeJoinedArgString(unsigned Index, StringRef LHS, StringRef RHS) const
Create an arg string for (LHS + RHS), reusing the string at Index if possible.
Definition: ArgList.cpp:338
bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const
hasFlag - Given an option Pos and its negative form Neg, return true if the option is present...
Definition: ArgList.cpp:221
const char * MakeArgString(const Twine &Str) const
Definition: ArgList.h:303
StringRef getPrefix() const
Get the default prefix for this option.
Definition: Option.h:118
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
iterator erase(const_iterator CI)
Definition: SmallVector.h:431
reverse_iterator rend()
Definition: ArgList.h:146
iterator_range< arg_iterator > filtered(OptSpecifier Id0=0U, OptSpecifier Id1=0U, OptSpecifier Id2=0U) const
Definition: ArgList.h:162
void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const
AddLastArg - Render only the last argument match Id0, if present.
Definition: ArgList.cpp:247
void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1=0U, OptSpecifier Id2=0U) const
AddAllArgValues - Render the argument values of all arguments matching the given ids.
Definition: ArgList.cpp:302
void render(const ArgList &Args, ArgStringList &Output) const
Append the argument onto the given array as strings.
Definition: Arg.cpp:91
void AddAllArgsExcept(ArgStringList &Output, ArrayRef< OptSpecifier > Ids, ArrayRef< OptSpecifier > ExcludeIds) const
AddAllArgsExcept - Render all arguments matching any of the given ids and not matching any of the exc...
Definition: ArgList.cpp:262
virtual const char * getArgString(unsigned Index) const =0
getArgString - Return the input argument string at Index.
Arg * MakeJoinedArg(const Arg *BaseArg, const Option Opt, StringRef Value) const
MakeJoinedArg - Construct a new Positional arg for the given option Id, with the provided Value...
Definition: ArgList.cpp:433
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Defines the llvm::Arg class for parsed arguments.
Arg * MakeSeparateArg(const Arg *BaseArg, const Option Opt, StringRef Value) const
MakeSeparateArg - Construct a new Positional arg for the given option Id, with the provided Value...
Definition: ArgList.cpp:424
Arg * MakePositionalArg(const Arg *BaseArg, const Option Opt, StringRef Value) const
MakePositionalArg - Construct a new Positional arg for the given option Id, with the provided Value...
Definition: ArgList.cpp:415
void ClaimAllArgs() const
ClaimAllArgs - Claim all arguments.
Definition: ArgList.cpp:332
void append(Arg *A)
append - Append A to the arg list.
Definition: ArgList.cpp:37
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
OptSpecifier - Wrapper class for abstracting references to option IDs.
Definition: OptSpecifier.h:20
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
Arg * getLastArg(OptSpecifier Id) const
Definition: ArgList.cpp:84
InputArgList(const char *const *ArgBegin, const char *const *ArgEnd)
Definition: ArgList.cpp:366
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::vector< std::string > getAllArgValues(OptSpecifier Id) const
getAllArgValues - Get the values of all instances of the given argument as strings.
Definition: ArgList.cpp:241
LLVM Value Representation.
Definition: Value.h:71
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:125
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
bool isValid() const
Definition: OptSpecifier.h:31
const char * MakeArgStringRef(StringRef Str) const override
Construct a constant string pointer whose lifetime will match that of the ArgList.
Definition: ArgList.cpp:391
StringRef getLastArgValue(OptSpecifier Id, StringRef Default="") const
getLastArgValue - Return the value of the last argument, or a default.
Definition: ArgList.cpp:234
void dump() const
Definition: ArgList.cpp:356
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")