blob: 84fae6ad693a8b50d867f87f4308ae6d5225e8de [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 Dunbar16484af2009-09-09 22:32:26 +000014#include "llvm/ADT/SmallString.h"
15#include "llvm/ADT/Twine.h"
16#include "llvm/Support/raw_ostream.h"
17
Benjamin Kramera5ddbca2010-05-21 19:58:44 +000018using namespace clang;
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000019using namespace clang::driver;
20
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +000021void 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
Daniel Dunbar3612bc82010-06-11 22:00:22 +000038ArgList::ArgList() {
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000039}
40
41ArgList::~ArgList() {
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000042}
Daniel Dunbar9358dc82009-03-04 22:40:08 +000043
44void ArgList::append(Arg *A) {
Daniel Dunbar9358dc82009-03-04 22:40:08 +000045 Args.push_back(A);
46}
Daniel Dunbard8cadd42009-03-12 01:36:44 +000047
Chad Rosier2b819102011-08-02 17:58:04 +000048void ArgList::eraseArg(OptSpecifier Id) {
Chad Rosieraec8f452011-08-08 17:17:15 +000049 for (iterator it = begin(), ie = end(); it != ie; ) {
Chad Rosier2b819102011-08-02 17:58:04 +000050 if ((*it)->getOption().matches(Id)) {
Chad Rosieraec8f452011-08-08 17:17:15 +000051 it = Args.erase(it);
Chad Rosierb18d5032011-08-12 23:38:19 +000052 ie = end();
Chad Rosier30601782011-08-17 23:08:45 +000053 } else {
Chad Rosieraec8f452011-08-08 17:17:15 +000054 ++it;
Chad Rosier30601782011-08-17 23:08:45 +000055 }
Chad Rosier2b819102011-08-02 17:58:04 +000056 }
57}
58
Daniel Dunbar9e1f9822009-11-19 04:14:53 +000059Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
Daniel Dunbard8cadd42009-03-12 01:36:44 +000060 // FIXME: Make search efficient?
Daniel Dunbare4bdae72009-11-19 04:00:53 +000061 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
62 if ((*it)->getOption().matches(Id))
Daniel Dunbar0c562a22009-03-12 16:03:38 +000063 return *it;
Daniel Dunbar0c562a22009-03-12 16:03:38 +000064 return 0;
Daniel Dunbard8cadd42009-03-12 01:36:44 +000065}
Daniel Dunbarbca58cb2009-03-12 18:20:18 +000066
Daniel Dunbar9e1f9822009-11-19 04:14:53 +000067Arg *ArgList::getLastArg(OptSpecifier Id) const {
Rafael Espindola592f2412010-12-20 22:45:09 +000068 Arg *Res = 0;
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;
Daniel Dunbare4bdae72009-11-19 04:00:53 +000077}
78
Daniel Dunbar9e1f9822009-11-19 04:14:53 +000079Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +000080 Arg *Res = 0;
Rafael Espindola592f2412010-12-20 22:45:09 +000081 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +000082 if ((*it)->getOption().matches(Id0) ||
83 (*it)->getOption().matches(Id1)) {
84 Res = *it;
Rafael Espindola592f2412010-12-20 22:45:09 +000085 Res->claim();
86
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +000087 }
88 }
Daniel Dunbarcd4e1862009-03-17 18:51:42 +000089
Daniel Dunbarcd4e1862009-03-17 18:51:42 +000090 return Res;
91}
92
Daniel Dunbar9e1f9822009-11-19 04:14:53 +000093Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
94 OptSpecifier Id2) const {
Bill Wendling45483f72009-06-28 07:36:13 +000095 Arg *Res = 0;
Rafael Espindola592f2412010-12-20 22:45:09 +000096 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +000097 if ((*it)->getOption().matches(Id0) ||
98 (*it)->getOption().matches(Id1) ||
99 (*it)->getOption().matches(Id2)) {
100 Res = *it;
Rafael Espindola592f2412010-12-20 22:45:09 +0000101 Res->claim();
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +0000102 }
Bill Wendling45483f72009-06-28 07:36:13 +0000103 }
104
Bill Wendling45483f72009-06-28 07:36:13 +0000105 return Res;
106}
107
Daniel Dunbar47e879d2010-07-13 23:31:40 +0000108Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
109 OptSpecifier Id2, OptSpecifier Id3) const {
110 Arg *Res = 0;
Rafael Espindola592f2412010-12-20 22:45:09 +0000111 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
Daniel Dunbar47e879d2010-07-13 23:31:40 +0000112 if ((*it)->getOption().matches(Id0) ||
113 (*it)->getOption().matches(Id1) ||
114 (*it)->getOption().matches(Id2) ||
115 (*it)->getOption().matches(Id3)) {
116 Res = *it;
Rafael Espindola592f2412010-12-20 22:45:09 +0000117 Res->claim();
Daniel Dunbar47e879d2010-07-13 23:31:40 +0000118 }
119 }
120
Daniel Dunbar47e879d2010-07-13 23:31:40 +0000121 return Res;
122}
123
Chandler Carruthabf07a72012-01-02 14:19:45 +0000124Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
125 OptSpecifier Id2, OptSpecifier Id3,
126 OptSpecifier Id4) const {
127 Arg *Res = 0;
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
Simon Atanasyan003ab662012-05-29 18:50:33 +0000142Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
143 OptSpecifier Id2, OptSpecifier Id3,
144 OptSpecifier Id4, OptSpecifier Id5) const {
145 Arg *Res = 0;
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
161Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
162 OptSpecifier Id2, OptSpecifier Id3,
163 OptSpecifier Id4, OptSpecifier Id5,
164 OptSpecifier Id6) const {
165 Arg *Res = 0;
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
182Arg *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 = 0;
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
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000204bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
Daniel Dunbar9af66682009-04-07 21:08:57 +0000205 if (Arg *A = getLastArg(Pos, Neg))
206 return A->getOption().matches(Pos);
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000207 return Default;
208}
209
Chris Lattner5f9e2722011-07-23 10:55:15 +0000210StringRef ArgList::getLastArgValue(OptSpecifier Id,
211 StringRef Default) const {
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000212 if (Arg *A = getLastArg(Id))
Richard Smith1d489cf2012-11-01 04:30:05 +0000213 return A->getValue();
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000214 return Default;
215}
216
217int ArgList::getLastArgIntValue(OptSpecifier Id, int Default,
Chad Rosier2dec85b2012-03-13 20:09:56 +0000218 clang::DiagnosticsEngine *Diags) const {
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000219 int Res = Default;
220
221 if (Arg *A = getLastArg(Id)) {
Richard Smith1d489cf2012-11-01 04:30:05 +0000222 if (StringRef(A->getValue()).getAsInteger(10, Res)) {
Chad Rosier2dec85b2012-03-13 20:09:56 +0000223 if (Diags)
224 Diags->Report(diag::err_drv_invalid_int_value)
Richard Smith1d489cf2012-11-01 04:30:05 +0000225 << A->getAsString(*this) << A->getValue();
Chad Rosier2dec85b2012-03-13 20:09:56 +0000226 }
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000227 }
228
229 return Res;
230}
231
232std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000233 SmallVector<const char *, 16> Values;
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000234 AddAllArgValues(Values, Id);
235 return std::vector<std::string>(Values.begin(), Values.end());
236}
237
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000238void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000239 if (Arg *A = getLastArg(Id)) {
240 A->claim();
241 A->render(*this, Output);
242 }
243}
244
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000245void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
246 OptSpecifier Id1, OptSpecifier Id2) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000247 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
248 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000249 (*it)->claim();
250 (*it)->render(*this, Output);
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000251 }
252}
Daniel Dunbaree510312009-03-20 15:59:01 +0000253
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000254void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000255 OptSpecifier Id1, OptSpecifier Id2) const {
256 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
257 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000258 (*it)->claim();
259 for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
Richard Smith1d489cf2012-11-01 04:30:05 +0000260 Output.push_back((*it)->getValue(i));
Daniel Dunbaree510312009-03-20 15:59:01 +0000261 }
262}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000263
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000264void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000265 const char *Translation,
266 bool Joined) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000267 for (arg_iterator it = filtered_begin(Id0),
268 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000269 (*it)->claim();
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000270
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000271 if (Joined) {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000272 Output.push_back(MakeArgString(StringRef(Translation) +
Richard Smith1d489cf2012-11-01 04:30:05 +0000273 (*it)->getValue(0)));
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000274 } else {
275 Output.push_back(Translation);
Richard Smith1d489cf2012-11-01 04:30:05 +0000276 Output.push_back((*it)->getValue(0));
Daniel Dunbar524b9fb2009-03-26 15:39:22 +0000277 }
278 }
279}
280
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000281void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000282 for (arg_iterator it = filtered_begin(Id0),
283 ie = filtered_end(); it != ie; ++it)
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000284 (*it)->claim();
Daniel Dunbar68fb4692009-04-03 20:51:31 +0000285}
286
Chad Rosier2b819102011-08-02 17:58:04 +0000287void ArgList::ClaimAllArgs() const {
288 for (const_iterator it = begin(), ie = end(); it != ie; ++it)
289 if (!(*it)->isClaimed())
290 (*it)->claim();
291}
292
Chris Lattner5f9e2722011-07-23 10:55:15 +0000293const char *ArgList::MakeArgString(const Twine &T) const {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000294 SmallString<256> Str;
Daniel Dunbar16484af2009-09-09 22:32:26 +0000295 T.toVector(Str);
296 return MakeArgString(Str.str());
297}
298
Daniel Dunbar312a8b72010-06-09 18:49:38 +0000299const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000300 StringRef LHS,
301 StringRef RHS) const {
302 StringRef Cur = getArgString(Index);
Daniel Dunbar312a8b72010-06-09 18:49:38 +0000303 if (Cur.size() == LHS.size() + RHS.size() &&
304 Cur.startswith(LHS) && Cur.endswith(RHS))
305 return Cur.data();
306
307 return MakeArgString(LHS + RHS);
308}
309
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000310//
311
Axel Naumann9d520c52010-10-11 09:18:43 +0000312InputArgList::InputArgList(const char* const *ArgBegin,
313 const char* const *ArgEnd)
Daniel Dunbar3612bc82010-06-11 22:00:22 +0000314 : NumInputArgStrings(ArgEnd - ArgBegin) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000315 ArgStrings.append(ArgBegin, ArgEnd);
316}
317
318InputArgList::~InputArgList() {
319 // An InputArgList always owns its arguments.
320 for (iterator it = begin(), ie = end(); it != ie; ++it)
321 delete *it;
322}
323
Chris Lattner5f9e2722011-07-23 10:55:15 +0000324unsigned InputArgList::MakeIndex(StringRef String0) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000325 unsigned Index = ArgStrings.size();
326
327 // Tuck away so we have a reliable const char *.
328 SynthesizedStrings.push_back(String0);
329 ArgStrings.push_back(SynthesizedStrings.back().c_str());
330
331 return Index;
332}
333
Chris Lattner5f9e2722011-07-23 10:55:15 +0000334unsigned InputArgList::MakeIndex(StringRef String0,
335 StringRef String1) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000336 unsigned Index0 = MakeIndex(String0);
337 unsigned Index1 = MakeIndex(String1);
338 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
339 (void) Index1;
340 return Index0;
341}
342
Chris Lattner5f9e2722011-07-23 10:55:15 +0000343const char *InputArgList::MakeArgString(StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000344 return getArgString(MakeIndex(Str));
345}
346
347//
348
Daniel Dunbar279c1db2010-06-11 22:00:26 +0000349DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs)
Daniel Dunbar3612bc82010-06-11 22:00:22 +0000350 : BaseArgs(_BaseArgs) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000351}
352
353DerivedArgList::~DerivedArgList() {
354 // We only own the arguments we explicitly synthesized.
Mike Stump1eb44332009-09-09 15:08:12 +0000355 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000356 it != ie; ++it)
357 delete *it;
358}
359
Chris Lattner5f9e2722011-07-23 10:55:15 +0000360const char *DerivedArgList::MakeArgString(StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000361 return BaseArgs.MakeArgString(Str);
362}
363
Michael J. Spencere4151c52012-10-19 22:36:40 +0000364Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
Michael J. Spencerc6357102012-10-22 22:13:48 +0000365 Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
366 Twine(Opt.getName())),
367 BaseArgs.MakeIndex(Opt.getName()), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000368 SynthesizedArgs.push_back(A);
369 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000370}
371
Michael J. Spencere4151c52012-10-19 22:36:40 +0000372Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000373 StringRef Value) const {
Daniel Dunbar4465a772010-06-09 22:31:00 +0000374 unsigned Index = BaseArgs.MakeIndex(Value);
Michael J. Spencerc6357102012-10-22 22:13:48 +0000375 Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
376 Twine(Opt.getName())),
377 Index, BaseArgs.getArgString(Index), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000378 SynthesizedArgs.push_back(A);
379 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000380}
381
Michael J. Spencere4151c52012-10-19 22:36:40 +0000382Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000383 StringRef Value) const {
Michael J. Spencere4151c52012-10-19 22:36:40 +0000384 unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
Michael J. Spencerc6357102012-10-22 22:13:48 +0000385 Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
386 Twine(Opt.getName())),
387 Index, BaseArgs.getArgString(Index + 1), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000388 SynthesizedArgs.push_back(A);
389 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000390}
391
Michael J. Spencere4151c52012-10-19 22:36:40 +0000392Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000393 StringRef Value) const {
Michael J. Spencere4151c52012-10-19 22:36:40 +0000394 unsigned Index = BaseArgs.MakeIndex(Opt.getName().str() + Value.str());
Michael J. Spencerc6357102012-10-22 22:13:48 +0000395 Arg *A = new Arg(Opt, ArgList::MakeArgString(Twine(Opt.getPrefix()) +
396 Twine(Opt.getName())), Index,
Michael J. Spencere4151c52012-10-19 22:36:40 +0000397 BaseArgs.getArgString(Index) + Opt.getName().size(),
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000398 BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000399 SynthesizedArgs.push_back(A);
400 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000401}