Use unique_ptr to handle ownership of synthesized args in DerivedArgList
[oota-llvm.git] / lib / Option / ArgList.cpp
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/SmallString.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/Option/Arg.h"
15 #include "llvm/Option/Option.h"
16 #include "llvm/Support/raw_ostream.h"
17
18 using namespace llvm;
19 using namespace llvm::opt;
20
21 void arg_iterator::SkipToNextArg() {
22   for (; Current != Args.end(); ++Current) {
23     // Done if there are no filters.
24     if (!Id0.isValid())
25       break;
26
27     // Otherwise require a match.
28     const Option &O = (*Current)->getOption();
29     if (O.matches(Id0) ||
30         (Id1.isValid() && O.matches(Id1)) ||
31         (Id2.isValid() && O.matches(Id2)))
32       break;
33   }
34 }
35
36 //
37
38 ArgList::ArgList() {
39 }
40
41 ArgList::~ArgList() {
42 }
43
44 void ArgList::append(Arg *A) {
45   Args.push_back(A);
46 }
47
48 void ArgList::eraseArg(OptSpecifier Id) {
49   for (iterator it = begin(), ie = end(); it != ie; ) {
50     if ((*it)->getOption().matches(Id)) {
51       it = Args.erase(it);
52       ie = end();
53     } else {
54       ++it;
55     }
56   }
57 }
58
59 Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
60   // FIXME: Make search efficient?
61   for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
62     if ((*it)->getOption().matches(Id))
63       return *it;
64   return nullptr;
65 }
66
67 Arg *ArgList::getLastArg(OptSpecifier Id) const {
68   Arg *Res = nullptr;
69   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
70     if ((*it)->getOption().matches(Id)) {
71       Res = *it;
72       Res->claim();
73     }
74   }
75
76   return Res;
77 }
78
79 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
80   Arg *Res = nullptr;
81   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
82     if ((*it)->getOption().matches(Id0) ||
83         (*it)->getOption().matches(Id1)) {
84       Res = *it;
85       Res->claim();
86
87     }
88   }
89
90   return Res;
91 }
92
93 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
94                          OptSpecifier Id2) const {
95   Arg *Res = nullptr;
96   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
97     if ((*it)->getOption().matches(Id0) ||
98         (*it)->getOption().matches(Id1) ||
99         (*it)->getOption().matches(Id2)) {
100       Res = *it;
101       Res->claim();
102     }
103   }
104
105   return Res;
106 }
107
108 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
109                          OptSpecifier Id2, OptSpecifier Id3) const {
110   Arg *Res = nullptr;
111   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
112     if ((*it)->getOption().matches(Id0) ||
113         (*it)->getOption().matches(Id1) ||
114         (*it)->getOption().matches(Id2) ||
115         (*it)->getOption().matches(Id3)) {
116       Res = *it;
117       Res->claim();
118     }
119   }
120
121   return Res;
122 }
123
124 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
125                          OptSpecifier Id2, OptSpecifier Id3,
126                          OptSpecifier Id4) 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         (*it)->getOption().matches(Id4)) {
134       Res = *it;
135       Res->claim();
136     }
137   }
138
139   return Res;
140 }
141
142 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
143                          OptSpecifier Id2, OptSpecifier Id3,
144                          OptSpecifier Id4, OptSpecifier Id5) const {
145   Arg *Res = nullptr;
146   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
147     if ((*it)->getOption().matches(Id0) ||
148         (*it)->getOption().matches(Id1) ||
149         (*it)->getOption().matches(Id2) ||
150         (*it)->getOption().matches(Id3) ||
151         (*it)->getOption().matches(Id4) ||
152         (*it)->getOption().matches(Id5)) {
153       Res = *it;
154       Res->claim();
155     }
156   }
157
158   return Res;
159 }
160
161 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
162                          OptSpecifier Id2, OptSpecifier Id3,
163                          OptSpecifier Id4, OptSpecifier Id5,
164                          OptSpecifier Id6) const {
165   Arg *Res = nullptr;
166   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
167     if ((*it)->getOption().matches(Id0) ||
168         (*it)->getOption().matches(Id1) ||
169         (*it)->getOption().matches(Id2) ||
170         (*it)->getOption().matches(Id3) ||
171         (*it)->getOption().matches(Id4) ||
172         (*it)->getOption().matches(Id5) ||
173         (*it)->getOption().matches(Id6)) {
174       Res = *it;
175       Res->claim();
176     }
177   }
178
179   return Res;
180 }
181
182 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
183                          OptSpecifier Id2, OptSpecifier Id3,
184                          OptSpecifier Id4, OptSpecifier Id5,
185                          OptSpecifier Id6, OptSpecifier Id7) const {
186   Arg *Res = nullptr;
187   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
188     if ((*it)->getOption().matches(Id0) ||
189         (*it)->getOption().matches(Id1) ||
190         (*it)->getOption().matches(Id2) ||
191         (*it)->getOption().matches(Id3) ||
192         (*it)->getOption().matches(Id4) ||
193         (*it)->getOption().matches(Id5) ||
194         (*it)->getOption().matches(Id6) ||
195         (*it)->getOption().matches(Id7)) {
196       Res = *it;
197       Res->claim();
198     }
199   }
200
201   return Res;
202 }
203
204 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
205   if (Arg *A = getLastArg(Pos, Neg))
206     return A->getOption().matches(Pos);
207   return Default;
208 }
209
210 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
211                       bool Default) const {
212   if (Arg *A = getLastArg(Pos, PosAlias, Neg))
213     return A->getOption().matches(Pos) || A->getOption().matches(PosAlias);
214   return Default;
215 }
216
217 StringRef ArgList::getLastArgValue(OptSpecifier Id,
218                                          StringRef Default) const {
219   if (Arg *A = getLastArg(Id))
220     return A->getValue();
221   return Default;
222 }
223
224 std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
225   SmallVector<const char *, 16> Values;
226   AddAllArgValues(Values, Id);
227   return std::vector<std::string>(Values.begin(), Values.end());
228 }
229
230 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
231   if (Arg *A = getLastArg(Id)) {
232     A->claim();
233     A->render(*this, Output);
234   }
235 }
236
237 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0,
238                          OptSpecifier Id1) const {
239   if (Arg *A = getLastArg(Id0, Id1)) {
240     A->claim();
241     A->render(*this, Output);
242   }
243 }
244
245 void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
246                          OptSpecifier Id1, OptSpecifier Id2) const {
247   for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
248          ie = filtered_end(); it != ie; ++it) {
249     (*it)->claim();
250     (*it)->render(*this, Output);
251   }
252 }
253
254 void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
255                               OptSpecifier Id1, OptSpecifier Id2) const {
256   for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
257          ie = filtered_end(); it != ie; ++it) {
258     (*it)->claim();
259     for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
260       Output.push_back((*it)->getValue(i));
261   }
262 }
263
264 void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
265                                    const char *Translation,
266                                    bool Joined) const {
267   for (arg_iterator it = filtered_begin(Id0),
268          ie = filtered_end(); it != ie; ++it) {
269     (*it)->claim();
270
271     if (Joined) {
272       Output.push_back(MakeArgString(StringRef(Translation) +
273                                      (*it)->getValue(0)));
274     } else {
275       Output.push_back(Translation);
276       Output.push_back((*it)->getValue(0));
277     }
278   }
279 }
280
281 void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
282   for (arg_iterator it = filtered_begin(Id0),
283          ie = filtered_end(); it != ie; ++it)
284     (*it)->claim();
285 }
286
287 void ArgList::ClaimAllArgs() const {
288   for (const_iterator it = begin(), ie = end(); it != ie; ++it)
289     if (!(*it)->isClaimed())
290       (*it)->claim();
291 }
292
293 const char *ArgList::MakeArgString(const Twine &T) const {
294   SmallString<256> Str;
295   return MakeArgString(T.toStringRef(Str));
296 }
297
298 const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
299                                               StringRef LHS,
300                                               StringRef RHS) const {
301   StringRef Cur = getArgString(Index);
302   if (Cur.size() == LHS.size() + RHS.size() &&
303       Cur.startswith(LHS) && Cur.endswith(RHS))
304     return Cur.data();
305
306   return MakeArgString(LHS + RHS);
307 }
308
309 //
310
311 InputArgList::InputArgList(const char* const *ArgBegin,
312                            const char* const *ArgEnd)
313   : NumInputArgStrings(ArgEnd - ArgBegin) {
314   ArgStrings.append(ArgBegin, ArgEnd);
315 }
316
317 InputArgList::~InputArgList() {
318   // An InputArgList always owns its arguments.
319   for (iterator it = begin(), ie = end(); it != ie; ++it)
320     delete *it;
321 }
322
323 unsigned InputArgList::MakeIndex(StringRef String0) const {
324   unsigned Index = ArgStrings.size();
325
326   // Tuck away so we have a reliable const char *.
327   SynthesizedStrings.push_back(String0);
328   ArgStrings.push_back(SynthesizedStrings.back().c_str());
329
330   return Index;
331 }
332
333 unsigned InputArgList::MakeIndex(StringRef String0,
334                                  StringRef String1) const {
335   unsigned Index0 = MakeIndex(String0);
336   unsigned Index1 = MakeIndex(String1);
337   assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
338   (void) Index1;
339   return Index0;
340 }
341
342 const char *InputArgList::MakeArgString(StringRef Str) const {
343   return getArgString(MakeIndex(Str));
344 }
345
346 //
347
348 DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs)
349   : BaseArgs(_BaseArgs) {
350 }
351
352 DerivedArgList::~DerivedArgList() {}
353
354 const char *DerivedArgList::MakeArgString(StringRef Str) const {
355   return BaseArgs.MakeArgString(Str);
356 }
357
358 void DerivedArgList::AddSynthesizedArg(Arg *A) {
359   SynthesizedArgs.push_back(std::unique_ptr<Arg>(A));
360 }
361
362 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
363   SynthesizedArgs.push_back(make_unique<Arg>(
364       Opt,
365       ArgList::MakeArgString(Twine(Opt.getPrefix()) + Twine(Opt.getName())),
366       BaseArgs.MakeIndex(Opt.getName()), BaseArg));
367   return SynthesizedArgs.back().get();
368 }
369
370 Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
371                                        StringRef Value) const {
372   unsigned Index = BaseArgs.MakeIndex(Value);
373   SynthesizedArgs.push_back(make_unique<Arg>(
374       Opt,
375       ArgList::MakeArgString(Twine(Opt.getPrefix()) + Twine(Opt.getName())),
376       Index, BaseArgs.getArgString(Index), BaseArg));
377   return SynthesizedArgs.back().get();
378 }
379
380 Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
381                                      StringRef Value) const {
382   unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
383   SynthesizedArgs.push_back(make_unique<Arg>(
384       Opt,
385       ArgList::MakeArgString(Twine(Opt.getPrefix()) + Twine(Opt.getName())),
386       Index, BaseArgs.getArgString(Index + 1), BaseArg));
387   return SynthesizedArgs.back().get();
388 }
389
390 Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
391                                    StringRef Value) const {
392   unsigned Index = BaseArgs.MakeIndex(Opt.getName().str() + Value.str());
393   SynthesizedArgs.push_back(make_unique<Arg>(
394       Opt,
395       ArgList::MakeArgString(Twine(Opt.getPrefix()) + Twine(Opt.getName())),
396       Index, BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg));
397   return SynthesizedArgs.back().get();
398 }