blob: 9ca710f50956882e6f63c19f16a40af47aa2aaf9 [file] [log] [blame]
Daniel Dunbar3e2cbc32009-03-04 17:10:42 +00001//===--- 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 "clang/Driver/ArgList.h"
11#include "clang/Driver/Arg.h"
Daniel Dunbar37300482010-05-20 16:54:55 +000012#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbar16b9fd42009-03-04 22:40:08 +000013#include "clang/Driver/Option.h"
Daniel Dunbar3e2cbc32009-03-04 17:10:42 +000014
Daniel Dunbar5f620c12009-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
Daniel Dunbar3e2cbc32009-03-04 17:10:42 +000019using namespace clang::driver;
20
Daniel Dunbarb8c2f7d2009-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 Dunbardac54a82009-03-25 04:13:45 +000038ArgList::ArgList(arglist_type &_Args) : Args(_Args) {
Daniel Dunbar3e2cbc32009-03-04 17:10:42 +000039}
40
41ArgList::~ArgList() {
Daniel Dunbar3e2cbc32009-03-04 17:10:42 +000042}
Daniel Dunbar16b9fd42009-03-04 22:40:08 +000043
44void ArgList::append(Arg *A) {
Daniel Dunbar16b9fd42009-03-04 22:40:08 +000045 Args.push_back(A);
46}
Daniel Dunbar2c3939c2009-03-12 01:36:44 +000047
Daniel Dunbar8c009572009-11-19 04:14:53 +000048Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
Daniel Dunbar2c3939c2009-03-12 01:36:44 +000049 // FIXME: Make search efficient?
Daniel Dunbarfffd1812009-11-19 04:00:53 +000050 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
51 if ((*it)->getOption().matches(Id))
Daniel Dunbar7586bb92009-03-12 16:03:38 +000052 return *it;
Daniel Dunbar7586bb92009-03-12 16:03:38 +000053 return 0;
Daniel Dunbar2c3939c2009-03-12 01:36:44 +000054}
Daniel Dunbar7c8d6532009-03-12 18:20:18 +000055
Daniel Dunbar8c009572009-11-19 04:14:53 +000056Arg *ArgList::getLastArg(OptSpecifier Id) const {
Daniel Dunbarfffd1812009-11-19 04:00:53 +000057 Arg *A = getLastArgNoClaim(Id);
58 if (A)
59 A->claim();
60 return A;
61}
62
Daniel Dunbar8c009572009-11-19 04:14:53 +000063Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
Daniel Dunbarfffd1812009-11-19 04:00:53 +000064 Arg *Res, *A0 = getLastArgNoClaim(Id0), *A1 = getLastArgNoClaim(Id1);
Mike Stump11289f42009-09-09 15:08:12 +000065
Daniel Dunbarc1b70b22009-03-17 18:51:42 +000066 if (A0 && A1)
67 Res = A0->getIndex() > A1->getIndex() ? A0 : A1;
68 else
69 Res = A0 ? A0 : A1;
70
Daniel Dunbarfffd1812009-11-19 04:00:53 +000071 if (Res)
Daniel Dunbarc1b70b22009-03-17 18:51:42 +000072 Res->claim();
73
74 return Res;
75}
76
Daniel Dunbar8c009572009-11-19 04:14:53 +000077Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
78 OptSpecifier Id2) const {
Bill Wendlingd63bbad2009-06-28 07:36:13 +000079 Arg *Res = 0;
Daniel Dunbarfffd1812009-11-19 04:00:53 +000080 Arg *A0 = getLastArgNoClaim(Id0);
81 Arg *A1 = getLastArgNoClaim(Id1);
82 Arg *A2 = getLastArgNoClaim(Id2);
Bill Wendlingd63bbad2009-06-28 07:36:13 +000083
Ted Kremenek1a0c4d52010-03-10 19:09:31 +000084 int A0Idx = A0 ? (int) A0->getIndex() : -1;
85 int A1Idx = A1 ? (int) A1->getIndex() : -1;
86 int A2Idx = A2 ? (int) A2->getIndex() : -1;
Bill Wendlingd63bbad2009-06-28 07:36:13 +000087
88 if (A0Idx > A1Idx) {
89 if (A0Idx > A2Idx)
90 Res = A0;
91 else if (A2Idx != -1)
92 Res = A2;
93 } else {
94 if (A1Idx > A2Idx)
95 Res = A1;
96 else if (A2Idx != -1)
97 Res = A2;
98 }
99
Daniel Dunbarfffd1812009-11-19 04:00:53 +0000100 if (Res)
Bill Wendlingd63bbad2009-06-28 07:36:13 +0000101 Res->claim();
102
103 return Res;
104}
105
Daniel Dunbar8c009572009-11-19 04:14:53 +0000106bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
Daniel Dunbar30bf11e2009-04-07 21:08:57 +0000107 if (Arg *A = getLastArg(Pos, Neg))
108 return A->getOption().matches(Pos);
Daniel Dunbar7591f292009-03-18 09:29:36 +0000109 return Default;
110}
111
Daniel Dunbar37300482010-05-20 16:54:55 +0000112llvm::StringRef ArgList::getLastArgValue(OptSpecifier Id,
113 llvm::StringRef Default) const {
114 if (Arg *A = getLastArg(Id))
115 return A->getValue(*this);
116 return Default;
117}
118
119int ArgList::getLastArgIntValue(OptSpecifier Id, int Default,
120 Diagnostic &Diags) const {
121 int Res = Default;
122
123 if (Arg *A = getLastArg(Id)) {
124 if (llvm::StringRef(A->getValue(*this)).getAsInteger(10, Res))
125 Diags.Report(diag::err_drv_invalid_int_value)
126 << A->getAsString(*this) << A->getValue(*this);
127 }
128
129 return Res;
130}
131
132std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
133 llvm::SmallVector<const char *, 16> Values;
134 AddAllArgValues(Values, Id);
135 return std::vector<std::string>(Values.begin(), Values.end());
136}
137
Daniel Dunbar8c009572009-11-19 04:14:53 +0000138void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
Daniel Dunbar7591f292009-03-18 09:29:36 +0000139 if (Arg *A = getLastArg(Id)) {
140 A->claim();
141 A->render(*this, Output);
142 }
143}
144
Daniel Dunbar8c009572009-11-19 04:14:53 +0000145void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
146 OptSpecifier Id1, OptSpecifier Id2) const {
Daniel Dunbarb8c2f7d2009-11-25 11:33:30 +0000147 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
148 ie = filtered_end(); it != ie; ++it) {
149 it->claim();
150 it->render(*this, Output);
Daniel Dunbar7591f292009-03-18 09:29:36 +0000151 }
152}
Daniel Dunbare81cc832009-03-20 15:59:01 +0000153
Daniel Dunbar8c009572009-11-19 04:14:53 +0000154void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbarb8c2f7d2009-11-25 11:33:30 +0000155 OptSpecifier Id1, OptSpecifier Id2) const {
156 for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
157 ie = filtered_end(); it != ie; ++it) {
158 it->claim();
159 for (unsigned i = 0, e = it->getNumValues(); i != e; ++i)
160 Output.push_back(it->getValue(*this, i));
Daniel Dunbare81cc832009-03-20 15:59:01 +0000161 }
162}
Daniel Dunbardac54a82009-03-25 04:13:45 +0000163
Daniel Dunbar8c009572009-11-19 04:14:53 +0000164void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
Daniel Dunbar3ba94d82009-04-26 01:07:52 +0000165 const char *Translation,
166 bool Joined) const {
Daniel Dunbarb8c2f7d2009-11-25 11:33:30 +0000167 for (arg_iterator it = filtered_begin(Id0),
168 ie = filtered_end(); it != ie; ++it) {
169 it->claim();
Daniel Dunbar3ba94d82009-04-26 01:07:52 +0000170
Daniel Dunbarb8c2f7d2009-11-25 11:33:30 +0000171 if (Joined) {
172 Output.push_back(MakeArgString(llvm::StringRef(Translation) +
173 it->getValue(*this, 0)));
174 } else {
175 Output.push_back(Translation);
176 Output.push_back(it->getValue(*this, 0));
Daniel Dunbar4e5696b2009-03-26 15:39:22 +0000177 }
178 }
179}
180
Daniel Dunbar8c009572009-11-19 04:14:53 +0000181void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
Daniel Dunbarb8c2f7d2009-11-25 11:33:30 +0000182 for (arg_iterator it = filtered_begin(Id0),
183 ie = filtered_end(); it != ie; ++it)
184 it->claim();
Daniel Dunbarc2a71892009-04-03 20:51:31 +0000185}
186
Daniel Dunbar5f620c12009-09-09 22:32:26 +0000187const char *ArgList::MakeArgString(const llvm::Twine &T) const {
188 llvm::SmallString<256> Str;
189 T.toVector(Str);
190 return MakeArgString(Str.str());
191}
192
Daniel Dunbardac54a82009-03-25 04:13:45 +0000193//
194
Mike Stump11289f42009-09-09 15:08:12 +0000195InputArgList::InputArgList(const char **ArgBegin, const char **ArgEnd)
196 : ArgList(ActualArgs), NumInputArgStrings(ArgEnd - ArgBegin) {
Daniel Dunbardac54a82009-03-25 04:13:45 +0000197 ArgStrings.append(ArgBegin, ArgEnd);
198}
199
200InputArgList::~InputArgList() {
201 // An InputArgList always owns its arguments.
202 for (iterator it = begin(), ie = end(); it != ie; ++it)
203 delete *it;
204}
205
Daniel Dunbar5f620c12009-09-09 22:32:26 +0000206unsigned InputArgList::MakeIndex(llvm::StringRef String0) const {
Daniel Dunbardac54a82009-03-25 04:13:45 +0000207 unsigned Index = ArgStrings.size();
208
209 // Tuck away so we have a reliable const char *.
210 SynthesizedStrings.push_back(String0);
211 ArgStrings.push_back(SynthesizedStrings.back().c_str());
212
213 return Index;
214}
215
Daniel Dunbar5f620c12009-09-09 22:32:26 +0000216unsigned InputArgList::MakeIndex(llvm::StringRef String0,
217 llvm::StringRef String1) const {
Daniel Dunbardac54a82009-03-25 04:13:45 +0000218 unsigned Index0 = MakeIndex(String0);
219 unsigned Index1 = MakeIndex(String1);
220 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
221 (void) Index1;
222 return Index0;
223}
224
Daniel Dunbar5f620c12009-09-09 22:32:26 +0000225const char *InputArgList::MakeArgString(llvm::StringRef Str) const {
Daniel Dunbardac54a82009-03-25 04:13:45 +0000226 return getArgString(MakeIndex(Str));
227}
228
229//
230
231DerivedArgList::DerivedArgList(InputArgList &_BaseArgs, bool _OnlyProxy)
232 : ArgList(_OnlyProxy ? _BaseArgs.getArgs() : ActualArgs),
Mike Stump11289f42009-09-09 15:08:12 +0000233 BaseArgs(_BaseArgs), OnlyProxy(_OnlyProxy) {
Daniel Dunbardac54a82009-03-25 04:13:45 +0000234}
235
236DerivedArgList::~DerivedArgList() {
237 // We only own the arguments we explicitly synthesized.
Mike Stump11289f42009-09-09 15:08:12 +0000238 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
Daniel Dunbardac54a82009-03-25 04:13:45 +0000239 it != ie; ++it)
240 delete *it;
241}
242
Daniel Dunbar5f620c12009-09-09 22:32:26 +0000243const char *DerivedArgList::MakeArgString(llvm::StringRef Str) const {
Daniel Dunbardac54a82009-03-25 04:13:45 +0000244 return BaseArgs.MakeArgString(Str);
245}
246
Daniel Dunbar53b406f2009-03-29 22:29:05 +0000247Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
Daniel Dunbar86d83892010-03-11 18:04:53 +0000248 Arg *A = new FlagArg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
249 SynthesizedArgs.push_back(A);
250 return A;
Daniel Dunbardac54a82009-03-25 04:13:45 +0000251}
252
Mike Stump11289f42009-09-09 15:08:12 +0000253Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
Daniel Dunbar5f620c12009-09-09 22:32:26 +0000254 llvm::StringRef Value) const {
Daniel Dunbar86d83892010-03-11 18:04:53 +0000255 Arg *A = new PositionalArg(Opt, BaseArgs.MakeIndex(Value), BaseArg);
256 SynthesizedArgs.push_back(A);
257 return A;
Daniel Dunbardac54a82009-03-25 04:13:45 +0000258}
259
Mike Stump11289f42009-09-09 15:08:12 +0000260Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
Daniel Dunbar5f620c12009-09-09 22:32:26 +0000261 llvm::StringRef Value) const {
Daniel Dunbar86d83892010-03-11 18:04:53 +0000262 Arg *A = new SeparateArg(Opt, BaseArgs.MakeIndex(Opt->getName(), Value), 1,
263 BaseArg);
264 SynthesizedArgs.push_back(A);
265 return A;
Daniel Dunbardac54a82009-03-25 04:13:45 +0000266}
267
Mike Stump11289f42009-09-09 15:08:12 +0000268Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
Daniel Dunbar5f620c12009-09-09 22:32:26 +0000269 llvm::StringRef Value) const {
Daniel Dunbar86d83892010-03-11 18:04:53 +0000270 Arg *A = new JoinedArg(Opt, BaseArgs.MakeIndex(Opt->getName() + Value.str()),
271 BaseArg);
272 SynthesizedArgs.push_back(A);
273 return A;
Daniel Dunbardac54a82009-03-25 04:13:45 +0000274}