blob: 7fd439e630828de4c3c53441b3d2a6f7ab15cd74 [file] [log] [blame]
Nick Lewycky3fdcc6f2010-12-31 17:31:54 +00001//===--- ArgList.cpp - Argument List Management ---------------------------===//
Daniel Dunbar6ac1e222009-03-04 17:10:42 +00002//
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 "clang/Driver/ArgList.h"
11#include "clang/Driver/Arg.h"
Daniel Dunbar03e8ab22010-05-20 16:54:55 +000012#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbar9358dc82009-03-04 22:40:08 +000013#include "clang/Driver/Option.h"
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000014
Daniel Dunbar16484af2009-09-09 22:32:26 +000015#include "llvm/ADT/SmallString.h"
16#include "llvm/ADT/Twine.h"
17#include "llvm/Support/raw_ostream.h"
18
Benjamin Kramera5ddbca2010-05-21 19:58:44 +000019using namespace clang;
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000020using namespace clang::driver;
21
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +000022void 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
37//
38
Daniel Dunbar3612bc82010-06-11 22:00:22 +000039ArgList::ArgList() {
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000040}
41
42ArgList::~ArgList() {
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000043}
Daniel Dunbar9358dc82009-03-04 22:40:08 +000044
45void ArgList::append(Arg *A) {
Daniel Dunbar9358dc82009-03-04 22:40:08 +000046 Args.push_back(A);
47}
Daniel Dunbard8cadd42009-03-12 01:36:44 +000048
Chad Rosier2b819102011-08-02 17:58:04 +000049void ArgList::eraseArg(OptSpecifier Id) {
Chad Rosieraec8f452011-08-08 17:17:15 +000050 for (iterator it = begin(), ie = end(); it != ie; ) {
Chad Rosier2b819102011-08-02 17:58:04 +000051 if ((*it)->getOption().matches(Id)) {
Chad Rosieraec8f452011-08-08 17:17:15 +000052 it = Args.erase(it);
Chad Rosierb18d5032011-08-12 23:38:19 +000053 ie = end();
Chad Rosier30601782011-08-17 23:08:45 +000054 } else {
Chad Rosieraec8f452011-08-08 17:17:15 +000055 ++it;
Chad Rosier30601782011-08-17 23:08:45 +000056 }
Chad Rosier2b819102011-08-02 17:58:04 +000057 }
58}
59
Daniel Dunbar9e1f9822009-11-19 04:14:53 +000060Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
Daniel Dunbard8cadd42009-03-12 01:36:44 +000061 // FIXME: Make search efficient?
Daniel Dunbare4bdae72009-11-19 04:00:53 +000062 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
63 if ((*it)->getOption().matches(Id))
Daniel Dunbar0c562a22009-03-12 16:03:38 +000064 return *it;
Daniel Dunbar0c562a22009-03-12 16:03:38 +000065 return 0;
Daniel Dunbard8cadd42009-03-12 01:36:44 +000066}
Daniel Dunbarbca58cb2009-03-12 18:20:18 +000067
Daniel Dunbar9e1f9822009-11-19 04:14:53 +000068Arg *ArgList::getLastArg(OptSpecifier Id) const {
Rafael Espindola592f2412010-12-20 22:45:09 +000069 Arg *Res = 0;
70 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
71 if ((*it)->getOption().matches(Id)) {
72 Res = *it;
73 Res->claim();
74 }
75 }
76
77 return Res;
Daniel Dunbare4bdae72009-11-19 04:00:53 +000078}
79
Daniel Dunbar9e1f9822009-11-19 04:14:53 +000080Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +000081 Arg *Res = 0;
Rafael Espindola592f2412010-12-20 22:45:09 +000082 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +000083 if ((*it)->getOption().matches(Id0) ||
84 (*it)->getOption().matches(Id1)) {
85 Res = *it;
Rafael Espindola592f2412010-12-20 22:45:09 +000086 Res->claim();
87
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +000088 }
89 }
Daniel Dunbarcd4e1862009-03-17 18:51:42 +000090
Daniel Dunbarcd4e1862009-03-17 18:51:42 +000091 return Res;
92}
93
Daniel Dunbar9e1f9822009-11-19 04:14:53 +000094Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
95 OptSpecifier Id2) const {
Bill Wendling45483f72009-06-28 07:36:13 +000096 Arg *Res = 0;
Rafael Espindola592f2412010-12-20 22:45:09 +000097 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +000098 if ((*it)->getOption().matches(Id0) ||
99 (*it)->getOption().matches(Id1) ||
100 (*it)->getOption().matches(Id2)) {
101 Res = *it;
Rafael Espindola592f2412010-12-20 22:45:09 +0000102 Res->claim();
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +0000103 }
Bill Wendling45483f72009-06-28 07:36:13 +0000104 }
105
Bill Wendling45483f72009-06-28 07:36:13 +0000106 return Res;
107}
108
Daniel Dunbar47e879d2010-07-13 23:31:40 +0000109Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
110 OptSpecifier Id2, OptSpecifier Id3) const {
111 Arg *Res = 0;
Rafael Espindola592f2412010-12-20 22:45:09 +0000112 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
Daniel Dunbar47e879d2010-07-13 23:31:40 +0000113 if ((*it)->getOption().matches(Id0) ||
114 (*it)->getOption().matches(Id1) ||
115 (*it)->getOption().matches(Id2) ||
116 (*it)->getOption().matches(Id3)) {
117 Res = *it;
Rafael Espindola592f2412010-12-20 22:45:09 +0000118 Res->claim();
Daniel Dunbar47e879d2010-07-13 23:31:40 +0000119 }
120 }
121
Daniel Dunbar47e879d2010-07-13 23:31:40 +0000122 return Res;
123}
124
Chandler Carruthabf07a72012-01-02 14:19:45 +0000125Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
126 OptSpecifier Id2, OptSpecifier Id3,
127 OptSpecifier Id4) const {
128 Arg *Res = 0;
129 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
130 if ((*it)->getOption().matches(Id0) ||
131 (*it)->getOption().matches(Id1) ||
132 (*it)->getOption().matches(Id2) ||
133 (*it)->getOption().matches(Id3) ||
134 (*it)->getOption().matches(Id4)) {
135 Res = *it;
136 Res->claim();
137 }
138 }
139
140 return Res;
141}
142
Simon Atanasyan003ab662012-05-29 18:50:33 +0000143Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
144 OptSpecifier Id2, OptSpecifier Id3,
145 OptSpecifier Id4, OptSpecifier Id5) const {
146 Arg *Res = 0;
147 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
148 if ((*it)->getOption().matches(Id0) ||
149 (*it)->getOption().matches(Id1) ||
150 (*it)->getOption().matches(Id2) ||
151 (*it)->getOption().matches(Id3) ||
152 (*it)->getOption().matches(Id4) ||
153 (*it)->getOption().matches(Id5)) {
154 Res = *it;
155 Res->claim();
156 }
157 }
158
159 return Res;
160}
161
162Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
163 OptSpecifier Id2, OptSpecifier Id3,
164 OptSpecifier Id4, OptSpecifier Id5,
165 OptSpecifier Id6) const {
166 Arg *Res = 0;
167 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
168 if ((*it)->getOption().matches(Id0) ||
169 (*it)->getOption().matches(Id1) ||
170 (*it)->getOption().matches(Id2) ||
171 (*it)->getOption().matches(Id3) ||
172 (*it)->getOption().matches(Id4) ||
173 (*it)->getOption().matches(Id5) ||
174 (*it)->getOption().matches(Id6)) {
175 Res = *it;
176 Res->claim();
177 }
178 }
179
180 return Res;
181}
182
183Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
184 OptSpecifier Id2, OptSpecifier Id3,
185 OptSpecifier Id4, OptSpecifier Id5,
186 OptSpecifier Id6, OptSpecifier Id7) const {
187 Arg *Res = 0;
188 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
189 if ((*it)->getOption().matches(Id0) ||
190 (*it)->getOption().matches(Id1) ||
191 (*it)->getOption().matches(Id2) ||
192 (*it)->getOption().matches(Id3) ||
193 (*it)->getOption().matches(Id4) ||
194 (*it)->getOption().matches(Id5) ||
195 (*it)->getOption().matches(Id6) ||
196 (*it)->getOption().matches(Id7)) {
197 Res = *it;
198 Res->claim();
199 }
200 }
201
202 return Res;
203}
204
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000205bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
Daniel Dunbar9af66682009-04-07 21:08:57 +0000206 if (Arg *A = getLastArg(Pos, Neg))
207 return A->getOption().matches(Pos);
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000208 return Default;
209}
210
Chris Lattner5f9e2722011-07-23 10:55:15 +0000211StringRef ArgList::getLastArgValue(OptSpecifier Id,
212 StringRef Default) const {
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000213 if (Arg *A = getLastArg(Id))
214 return A->getValue(*this);
215 return Default;
216}
217
218int ArgList::getLastArgIntValue(OptSpecifier Id, int Default,
Chad Rosier2dec85b2012-03-13 20:09:56 +0000219 clang::DiagnosticsEngine *Diags) const {
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000220 int Res = Default;
221
222 if (Arg *A = getLastArg(Id)) {
Chad Rosier2dec85b2012-03-13 20:09:56 +0000223 if (StringRef(A->getValue(*this)).getAsInteger(10, Res)) {
224 if (Diags)
225 Diags->Report(diag::err_drv_invalid_int_value)
226 << A->getAsString(*this) << A->getValue(*this);
227 }
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000228 }
229
230 return Res;
231}
232
233std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000234 SmallVector<const char *, 16> Values;
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000235 AddAllArgValues(Values, Id);
236 return std::vector<std::string>(Values.begin(), Values.end());
237}
238
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000239void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000240 if (Arg *A = getLastArg(Id)) {
241 A->claim();
242 A->render(*this, Output);
243 }
244}
245
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000246void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
247 OptSpecifier Id1, OptSpecifier Id2) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000248 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
249 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000250 (*it)->claim();
251 (*it)->render(*this, Output);
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000252 }
253}
Daniel Dunbaree510312009-03-20 15:59:01 +0000254
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000255void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000256 OptSpecifier Id1, OptSpecifier Id2) const {
257 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
258 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000259 (*it)->claim();
260 for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
261 Output.push_back((*it)->getValue(*this, i));
Daniel Dunbaree510312009-03-20 15:59:01 +0000262 }
263}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000264
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000265void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000266 const char *Translation,
267 bool Joined) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000268 for (arg_iterator it = filtered_begin(Id0),
269 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000270 (*it)->claim();
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000271
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000272 if (Joined) {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000273 Output.push_back(MakeArgString(StringRef(Translation) +
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000274 (*it)->getValue(*this, 0)));
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000275 } else {
276 Output.push_back(Translation);
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000277 Output.push_back((*it)->getValue(*this, 0));
Daniel Dunbar524b9fb2009-03-26 15:39:22 +0000278 }
279 }
280}
281
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000282void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000283 for (arg_iterator it = filtered_begin(Id0),
284 ie = filtered_end(); it != ie; ++it)
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000285 (*it)->claim();
Daniel Dunbar68fb4692009-04-03 20:51:31 +0000286}
287
Chad Rosier2b819102011-08-02 17:58:04 +0000288void ArgList::ClaimAllArgs() const {
289 for (const_iterator it = begin(), ie = end(); it != ie; ++it)
290 if (!(*it)->isClaimed())
291 (*it)->claim();
292}
293
Chris Lattner5f9e2722011-07-23 10:55:15 +0000294const char *ArgList::MakeArgString(const Twine &T) const {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000295 SmallString<256> Str;
Daniel Dunbar16484af2009-09-09 22:32:26 +0000296 T.toVector(Str);
297 return MakeArgString(Str.str());
298}
299
Daniel Dunbar312a8b72010-06-09 18:49:38 +0000300const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000301 StringRef LHS,
302 StringRef RHS) const {
303 StringRef Cur = getArgString(Index);
Daniel Dunbar312a8b72010-06-09 18:49:38 +0000304 if (Cur.size() == LHS.size() + RHS.size() &&
305 Cur.startswith(LHS) && Cur.endswith(RHS))
306 return Cur.data();
307
308 return MakeArgString(LHS + RHS);
309}
310
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000311//
312
Axel Naumann9d520c52010-10-11 09:18:43 +0000313InputArgList::InputArgList(const char* const *ArgBegin,
314 const char* const *ArgEnd)
Daniel Dunbar3612bc82010-06-11 22:00:22 +0000315 : NumInputArgStrings(ArgEnd - ArgBegin) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000316 ArgStrings.append(ArgBegin, ArgEnd);
317}
318
319InputArgList::~InputArgList() {
320 // An InputArgList always owns its arguments.
321 for (iterator it = begin(), ie = end(); it != ie; ++it)
322 delete *it;
323}
324
Chris Lattner5f9e2722011-07-23 10:55:15 +0000325unsigned InputArgList::MakeIndex(StringRef String0) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000326 unsigned Index = ArgStrings.size();
327
328 // Tuck away so we have a reliable const char *.
329 SynthesizedStrings.push_back(String0);
330 ArgStrings.push_back(SynthesizedStrings.back().c_str());
331
332 return Index;
333}
334
Chris Lattner5f9e2722011-07-23 10:55:15 +0000335unsigned InputArgList::MakeIndex(StringRef String0,
336 StringRef String1) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000337 unsigned Index0 = MakeIndex(String0);
338 unsigned Index1 = MakeIndex(String1);
339 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
340 (void) Index1;
341 return Index0;
342}
343
Chris Lattner5f9e2722011-07-23 10:55:15 +0000344const char *InputArgList::MakeArgString(StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000345 return getArgString(MakeIndex(Str));
346}
347
348//
349
Daniel Dunbar279c1db2010-06-11 22:00:26 +0000350DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs)
Daniel Dunbar3612bc82010-06-11 22:00:22 +0000351 : BaseArgs(_BaseArgs) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000352}
353
354DerivedArgList::~DerivedArgList() {
355 // We only own the arguments we explicitly synthesized.
Mike Stump1eb44332009-09-09 15:08:12 +0000356 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000357 it != ie; ++it)
358 delete *it;
359}
360
Chris Lattner5f9e2722011-07-23 10:55:15 +0000361const char *DerivedArgList::MakeArgString(StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000362 return BaseArgs.MakeArgString(Str);
363}
364
Daniel Dunbar478edc22009-03-29 22:29:05 +0000365Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000366 Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000367 SynthesizedArgs.push_back(A);
368 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000369}
370
Mike Stump1eb44332009-09-09 15:08:12 +0000371Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000372 StringRef Value) const {
Daniel Dunbar4465a772010-06-09 22:31:00 +0000373 unsigned Index = BaseArgs.MakeIndex(Value);
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000374 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000375 SynthesizedArgs.push_back(A);
376 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000377}
378
Mike Stump1eb44332009-09-09 15:08:12 +0000379Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000380 StringRef Value) const {
Daniel Dunbar4465a772010-06-09 22:31:00 +0000381 unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value);
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +0000382 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000383 SynthesizedArgs.push_back(A);
384 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000385}
386
Mike Stump1eb44332009-09-09 15:08:12 +0000387Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000388 StringRef Value) const {
Douglas Gregorbcf6a802011-07-05 16:56:25 +0000389 unsigned Index = BaseArgs.MakeIndex(Opt->getName().str() + Value.str());
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000390 Arg *A = new Arg(Opt, Index,
Douglas Gregorbcf6a802011-07-05 16:56:25 +0000391 BaseArgs.getArgString(Index) + Opt->getName().size(),
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000392 BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000393 SynthesizedArgs.push_back(A);
394 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000395}