blob: ca9b944950e13cd190862a2750d8ad7e241702ab [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
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000125bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
Daniel Dunbar9af66682009-04-07 21:08:57 +0000126 if (Arg *A = getLastArg(Pos, Neg))
127 return A->getOption().matches(Pos);
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000128 return Default;
129}
130
Chris Lattner5f9e2722011-07-23 10:55:15 +0000131StringRef ArgList::getLastArgValue(OptSpecifier Id,
132 StringRef Default) const {
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000133 if (Arg *A = getLastArg(Id))
134 return A->getValue(*this);
135 return Default;
136}
137
138int ArgList::getLastArgIntValue(OptSpecifier Id, int Default,
David Blaikied6471f72011-09-25 23:23:43 +0000139 clang::DiagnosticsEngine &Diags) const {
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000140 int Res = Default;
141
142 if (Arg *A = getLastArg(Id)) {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000143 if (StringRef(A->getValue(*this)).getAsInteger(10, Res))
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000144 Diags.Report(diag::err_drv_invalid_int_value)
145 << A->getAsString(*this) << A->getValue(*this);
146 }
147
148 return Res;
149}
150
151std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000152 SmallVector<const char *, 16> Values;
Daniel Dunbar03e8ab22010-05-20 16:54:55 +0000153 AddAllArgValues(Values, Id);
154 return std::vector<std::string>(Values.begin(), Values.end());
155}
156
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000157void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000158 if (Arg *A = getLastArg(Id)) {
159 A->claim();
160 A->render(*this, Output);
161 }
162}
163
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000164void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
165 OptSpecifier Id1, OptSpecifier Id2) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000166 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
167 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000168 (*it)->claim();
169 (*it)->render(*this, Output);
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000170 }
171}
Daniel Dunbaree510312009-03-20 15:59:01 +0000172
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000173void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000174 OptSpecifier Id1, OptSpecifier Id2) const {
175 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
176 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000177 (*it)->claim();
178 for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
179 Output.push_back((*it)->getValue(*this, i));
Daniel Dunbaree510312009-03-20 15:59:01 +0000180 }
181}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000182
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000183void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000184 const char *Translation,
185 bool Joined) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000186 for (arg_iterator it = filtered_begin(Id0),
187 ie = filtered_end(); it != ie; ++it) {
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000188 (*it)->claim();
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000189
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000190 if (Joined) {
Chris Lattner5f9e2722011-07-23 10:55:15 +0000191 Output.push_back(MakeArgString(StringRef(Translation) +
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000192 (*it)->getValue(*this, 0)));
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000193 } else {
194 Output.push_back(Translation);
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000195 Output.push_back((*it)->getValue(*this, 0));
Daniel Dunbar524b9fb2009-03-26 15:39:22 +0000196 }
197 }
198}
199
Daniel Dunbar9e1f9822009-11-19 04:14:53 +0000200void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
Daniel Dunbar3b84f5b2009-11-25 11:33:30 +0000201 for (arg_iterator it = filtered_begin(Id0),
202 ie = filtered_end(); it != ie; ++it)
Daniel Dunbar7e4953e2010-06-11 22:00:13 +0000203 (*it)->claim();
Daniel Dunbar68fb4692009-04-03 20:51:31 +0000204}
205
Chad Rosier2b819102011-08-02 17:58:04 +0000206void ArgList::ClaimAllArgs() const {
207 for (const_iterator it = begin(), ie = end(); it != ie; ++it)
208 if (!(*it)->isClaimed())
209 (*it)->claim();
210}
211
Chris Lattner5f9e2722011-07-23 10:55:15 +0000212const char *ArgList::MakeArgString(const Twine &T) const {
Daniel Dunbar16484af2009-09-09 22:32:26 +0000213 llvm::SmallString<256> Str;
214 T.toVector(Str);
215 return MakeArgString(Str.str());
216}
217
Daniel Dunbar312a8b72010-06-09 18:49:38 +0000218const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000219 StringRef LHS,
220 StringRef RHS) const {
221 StringRef Cur = getArgString(Index);
Daniel Dunbar312a8b72010-06-09 18:49:38 +0000222 if (Cur.size() == LHS.size() + RHS.size() &&
223 Cur.startswith(LHS) && Cur.endswith(RHS))
224 return Cur.data();
225
226 return MakeArgString(LHS + RHS);
227}
228
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000229//
230
Axel Naumann9d520c52010-10-11 09:18:43 +0000231InputArgList::InputArgList(const char* const *ArgBegin,
232 const char* const *ArgEnd)
Daniel Dunbar3612bc82010-06-11 22:00:22 +0000233 : NumInputArgStrings(ArgEnd - ArgBegin) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000234 ArgStrings.append(ArgBegin, ArgEnd);
235}
236
237InputArgList::~InputArgList() {
238 // An InputArgList always owns its arguments.
239 for (iterator it = begin(), ie = end(); it != ie; ++it)
240 delete *it;
241}
242
Chris Lattner5f9e2722011-07-23 10:55:15 +0000243unsigned InputArgList::MakeIndex(StringRef String0) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000244 unsigned Index = ArgStrings.size();
245
246 // Tuck away so we have a reliable const char *.
247 SynthesizedStrings.push_back(String0);
248 ArgStrings.push_back(SynthesizedStrings.back().c_str());
249
250 return Index;
251}
252
Chris Lattner5f9e2722011-07-23 10:55:15 +0000253unsigned InputArgList::MakeIndex(StringRef String0,
254 StringRef String1) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000255 unsigned Index0 = MakeIndex(String0);
256 unsigned Index1 = MakeIndex(String1);
257 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
258 (void) Index1;
259 return Index0;
260}
261
Chris Lattner5f9e2722011-07-23 10:55:15 +0000262const char *InputArgList::MakeArgString(StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000263 return getArgString(MakeIndex(Str));
264}
265
266//
267
Daniel Dunbar279c1db2010-06-11 22:00:26 +0000268DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs)
Daniel Dunbar3612bc82010-06-11 22:00:22 +0000269 : BaseArgs(_BaseArgs) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000270}
271
272DerivedArgList::~DerivedArgList() {
273 // We only own the arguments we explicitly synthesized.
Mike Stump1eb44332009-09-09 15:08:12 +0000274 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000275 it != ie; ++it)
276 delete *it;
277}
278
Chris Lattner5f9e2722011-07-23 10:55:15 +0000279const char *DerivedArgList::MakeArgString(StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000280 return BaseArgs.MakeArgString(Str);
281}
282
Daniel Dunbar478edc22009-03-29 22:29:05 +0000283Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000284 Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000285 SynthesizedArgs.push_back(A);
286 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000287}
288
Mike Stump1eb44332009-09-09 15:08:12 +0000289Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000290 StringRef Value) const {
Daniel Dunbar4465a772010-06-09 22:31:00 +0000291 unsigned Index = BaseArgs.MakeIndex(Value);
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000292 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000293 SynthesizedArgs.push_back(A);
294 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000295}
296
Mike Stump1eb44332009-09-09 15:08:12 +0000297Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000298 StringRef Value) const {
Daniel Dunbar4465a772010-06-09 22:31:00 +0000299 unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value);
Daniel Dunbarfdbe65e2010-06-14 20:20:44 +0000300 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000301 SynthesizedArgs.push_back(A);
302 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000303}
304
Mike Stump1eb44332009-09-09 15:08:12 +0000305Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000306 StringRef Value) const {
Douglas Gregorbcf6a802011-07-05 16:56:25 +0000307 unsigned Index = BaseArgs.MakeIndex(Opt->getName().str() + Value.str());
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000308 Arg *A = new Arg(Opt, Index,
Douglas Gregorbcf6a802011-07-05 16:56:25 +0000309 BaseArgs.getArgString(Index) + Opt->getName().size(),
Daniel Dunbar532c1ec2010-06-09 22:31:08 +0000310 BaseArg);
Daniel Dunbarfd48cb32010-03-11 18:04:53 +0000311 SynthesizedArgs.push_back(A);
312 return A;
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000313}