blob: d26da25b3e300007272dc11b6b7363dd28b8c9e8 [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
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000143bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
Daniel Dunbar9af66682009-04-07 21:08:57 +0000144 if (Arg *A = getLastArg(Pos, Neg))
145 return A->getOption().matches(Pos);
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000146 return Default;
147}
148
Chris Lattner5f9e2722011-07-23 10:55:15 +0000149StringRef ArgList::getLastArgValue(OptSpecifier Id,
150 StringRef Default) const {
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000151 if (Arg *A = getLastArg(Id))
152 return A->getValue(*this);
153 return Default;
154}
155
156int ArgList::getLastArgIntValue(OptSpecifier Id, int Default,
David Blaikied6471f72011-09-25 23:23:43 +0000157 clang::DiagnosticsEngine &Diags) const {
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000158 int Res = Default;
159
160 if (Arg *A = getLastArg(Id)) {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000161 if (StringRef(A->getValue(*this)).getAsInteger(10, Res))
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000162 Diags.Report(diag::err_drv_invalid_int_value)
163 << A->getAsString(*this) << A->getValue(*this);
164 }
165
166 return Res;
167}
168
169std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000170 SmallVector<const char *, 16> Values;
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000171 AddAllArgValues(Values, Id);
172 return std::vector<std::string>(Values.begin(), Values.end());
173}
174
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000175void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000176 if (Arg *A = getLastArg(Id)) {
177 A->claim();
178 A->render(*this, Output);
179 }
180}
181
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000182void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
183 OptSpecifier Id1, OptSpecifier Id2) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000184 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
185 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000186 (*it)->claim();
187 (*it)->render(*this, Output);
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000188 }
189}
Daniel Dunbaree510312009-03-20 15:59:01 +0000190
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000191void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000192 OptSpecifier Id1, OptSpecifier Id2) const {
193 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
194 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000195 (*it)->claim();
196 for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
197 Output.push_back((*it)->getValue(*this, i));
Daniel Dunbaree510312009-03-20 15:59:01 +0000198 }
199}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000200
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000201void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000202 const char *Translation,
203 bool Joined) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000204 for (arg_iterator it = filtered_begin(Id0),
205 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000206 (*it)->claim();
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000207
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000208 if (Joined) {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000209 Output.push_back(MakeArgString(StringRef(Translation) +
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000210 (*it)->getValue(*this, 0)));
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000211 } else {
212 Output.push_back(Translation);
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000213 Output.push_back((*it)->getValue(*this, 0));
Daniel Dunbar524b9fb2009-03-26 15:39:22 +0000214 }
215 }
216}
217
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000218void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000219 for (arg_iterator it = filtered_begin(Id0),
220 ie = filtered_end(); it != ie; ++it)
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000221 (*it)->claim();
Daniel Dunbar68fb4692009-04-03 20:51:31 +0000222}
223
Chad Rosier2b819102011-08-02 17:58:04 +0000224void ArgList::ClaimAllArgs() const {
225 for (const_iterator it = begin(), ie = end(); it != ie; ++it)
226 if (!(*it)->isClaimed())
227 (*it)->claim();
228}
229
Chris Lattner5f9e2722011-07-23 10:55:15 +0000230const char *ArgList::MakeArgString(const Twine &T) const {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000231 SmallString<256> Str;
Daniel Dunbar16484af2009-09-09 22:32:26 +0000232 T.toVector(Str);
233 return MakeArgString(Str.str());
234}
235
Daniel Dunbar312a8b72010-06-09 18:49:38 +0000236const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000237 StringRef LHS,
238 StringRef RHS) const {
239 StringRef Cur = getArgString(Index);
Daniel Dunbar312a8b72010-06-09 18:49:38 +0000240 if (Cur.size() == LHS.size() + RHS.size() &&
241 Cur.startswith(LHS) && Cur.endswith(RHS))
242 return Cur.data();
243
244 return MakeArgString(LHS + RHS);
245}
246
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000247//
248
Axel Naumann9d520c52010-10-11 09:18:43 +0000249InputArgList::InputArgList(const char* const *ArgBegin,
250 const char* const *ArgEnd)
Daniel Dunbar3612bc82010-06-11 22:00:22 +0000251 : NumInputArgStrings(ArgEnd - ArgBegin) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000252 ArgStrings.append(ArgBegin, ArgEnd);
253}
254
255InputArgList::~InputArgList() {
256 // An InputArgList always owns its arguments.
257 for (iterator it = begin(), ie = end(); it != ie; ++it)
258 delete *it;
259}
260
Chris Lattner5f9e2722011-07-23 10:55:15 +0000261unsigned InputArgList::MakeIndex(StringRef String0) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000262 unsigned Index = ArgStrings.size();
263
264 // Tuck away so we have a reliable const char *.
265 SynthesizedStrings.push_back(String0);
266 ArgStrings.push_back(SynthesizedStrings.back().c_str());
267
268 return Index;
269}
270
Chris Lattner5f9e2722011-07-23 10:55:15 +0000271unsigned InputArgList::MakeIndex(StringRef String0,
272 StringRef String1) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000273 unsigned Index0 = MakeIndex(String0);
274 unsigned Index1 = MakeIndex(String1);
275 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
276 (void) Index1;
277 return Index0;
278}
279
Chris Lattner5f9e2722011-07-23 10:55:15 +0000280const char *InputArgList::MakeArgString(StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000281 return getArgString(MakeIndex(Str));
282}
283
284//
285
Daniel Dunbar279c1db2010-06-11 22:00:26 +0000286DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs)
Daniel Dunbar3612bc82010-06-11 22:00:22 +0000287 : BaseArgs(_BaseArgs) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000288}
289
290DerivedArgList::~DerivedArgList() {
291 // We only own the arguments we explicitly synthesized.
Mike Stump1eb44332009-09-09 15:08:12 +0000292 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000293 it != ie; ++it)
294 delete *it;
295}
296
Chris Lattner5f9e2722011-07-23 10:55:15 +0000297const char *DerivedArgList::MakeArgString(StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000298 return BaseArgs.MakeArgString(Str);
299}
300
Daniel Dunbar478edc22009-03-29 22:29:05 +0000301Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000302 Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000303 SynthesizedArgs.push_back(A);
304 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000305}
306
Mike Stump1eb44332009-09-09 15:08:12 +0000307Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000308 StringRef Value) const {
Daniel Dunbar4465a772010-06-09 22:31:00 +0000309 unsigned Index = BaseArgs.MakeIndex(Value);
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000310 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000311 SynthesizedArgs.push_back(A);
312 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000313}
314
Mike Stump1eb44332009-09-09 15:08:12 +0000315Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000316 StringRef Value) const {
Daniel Dunbar4465a772010-06-09 22:31:00 +0000317 unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value);
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +0000318 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000319 SynthesizedArgs.push_back(A);
320 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000321}
322
Mike Stump1eb44332009-09-09 15:08:12 +0000323Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000324 StringRef Value) const {
Douglas Gregorbcf6a802011-07-05 16:56:25 +0000325 unsigned Index = BaseArgs.MakeIndex(Opt->getName().str() + Value.str());
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000326 Arg *A = new Arg(Opt, Index,
Douglas Gregorbcf6a802011-07-05 16:56:25 +0000327 BaseArgs.getArgString(Index) + Opt->getName().size(),
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000328 BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000329 SynthesizedArgs.push_back(A);
330 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000331}