blob: 8d2138df85e83dcf2d4a728d227743ba99dbc148 [file] [log] [blame]
Daniel Dunbar6ac1e222009-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 Dunbar9358dc82009-03-04 22:40:08 +000012#include "clang/Driver/Option.h"
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000013
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
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000018using namespace clang::driver;
19
Daniel Dunbarf3cad362009-03-25 04:13:45 +000020ArgList::ArgList(arglist_type &_Args) : Args(_Args) {
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000021}
22
23ArgList::~ArgList() {
Daniel Dunbar6ac1e222009-03-04 17:10:42 +000024}
Daniel Dunbar9358dc82009-03-04 22:40:08 +000025
26void ArgList::append(Arg *A) {
Daniel Dunbar9358dc82009-03-04 22:40:08 +000027 Args.push_back(A);
28}
Daniel Dunbard8cadd42009-03-12 01:36:44 +000029
Daniel Dunbar8022fd42009-03-15 00:48:16 +000030Arg *ArgList::getLastArg(options::ID Id, bool Claim) const {
Daniel Dunbard8cadd42009-03-12 01:36:44 +000031 // FIXME: Make search efficient?
Daniel Dunbarfe2e04a2009-03-24 17:31:30 +000032 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) {
Daniel Dunbar8022fd42009-03-15 00:48:16 +000033 if ((*it)->getOption().matches(Id)) {
34 if (Claim) (*it)->claim();
Daniel Dunbar0c562a22009-03-12 16:03:38 +000035 return *it;
Daniel Dunbar8022fd42009-03-15 00:48:16 +000036 }
37 }
Mike Stump1eb44332009-09-09 15:08:12 +000038
Daniel Dunbar0c562a22009-03-12 16:03:38 +000039 return 0;
Daniel Dunbard8cadd42009-03-12 01:36:44 +000040}
Daniel Dunbarbca58cb2009-03-12 18:20:18 +000041
Daniel Dunbarcd4e1862009-03-17 18:51:42 +000042Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
43 Arg *Res, *A0 = getLastArg(Id0, false), *A1 = getLastArg(Id1, false);
Mike Stump1eb44332009-09-09 15:08:12 +000044
Daniel Dunbarcd4e1862009-03-17 18:51:42 +000045 if (A0 && A1)
46 Res = A0->getIndex() > A1->getIndex() ? A0 : A1;
47 else
48 Res = A0 ? A0 : A1;
49
50 if (Claim && Res)
51 Res->claim();
52
53 return Res;
54}
55
Bill Wendling45483f72009-06-28 07:36:13 +000056Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
57 bool Claim) const {
58 Arg *Res = 0;
59 Arg *A0 = getLastArg(Id0, false);
60 Arg *A1 = getLastArg(Id1, false);
61 Arg *A2 = getLastArg(Id2, false);
62
63 int A0Idx = A0 ? A0->getIndex() : -1;
64 int A1Idx = A1 ? A1->getIndex() : -1;
65 int A2Idx = A2 ? A2->getIndex() : -1;
66
67 if (A0Idx > A1Idx) {
68 if (A0Idx > A2Idx)
69 Res = A0;
70 else if (A2Idx != -1)
71 Res = A2;
72 } else {
73 if (A1Idx > A2Idx)
74 Res = A1;
75 else if (A2Idx != -1)
76 Res = A2;
77 }
78
79 if (Claim && Res)
80 Res->claim();
81
82 return Res;
83}
84
Daniel Dunbar18a7f332009-03-18 09:29:36 +000085bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
Daniel Dunbar9af66682009-04-07 21:08:57 +000086 if (Arg *A = getLastArg(Pos, Neg))
87 return A->getOption().matches(Pos);
Daniel Dunbar18a7f332009-03-18 09:29:36 +000088 return Default;
89}
90
Daniel Dunbar18a7f332009-03-18 09:29:36 +000091void ArgList::AddLastArg(ArgStringList &Output, options::ID Id) const {
92 if (Arg *A = getLastArg(Id)) {
93 A->claim();
94 A->render(*this, Output);
95 }
96}
97
98void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const {
99 // FIXME: Make fast.
100 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
101 const Arg *A = *it;
102 if (A->getOption().matches(Id0)) {
103 A->claim();
104 A->render(*this, Output);
105 }
106 }
107}
108
Mike Stump1eb44332009-09-09 15:08:12 +0000109void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000110 options::ID Id1) const {
111 // FIXME: Make fast.
112 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
113 const Arg *A = *it;
114 if (A->getOption().matches(Id0) || A->getOption().matches(Id1)) {
115 A->claim();
116 A->render(*this, Output);
117 }
118 }
119}
120
Mike Stump1eb44332009-09-09 15:08:12 +0000121void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
Daniel Dunbar18a7f332009-03-18 09:29:36 +0000122 options::ID Id1, options::ID Id2) const {
123 // FIXME: Make fast.
124 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
125 const Arg *A = *it;
126 if (A->getOption().matches(Id0) || A->getOption().matches(Id1) ||
127 A->getOption().matches(Id2)) {
128 A->claim();
129 A->render(*this, Output);
130 }
131 }
132}
133
134void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const {
135 // FIXME: Make fast.
136 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
137 const Arg *A = *it;
138 if (A->getOption().matches(Id0)) {
139 A->claim();
140 for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
141 Output.push_back(A->getValue(*this, i));
142 }
143 }
144}
Daniel Dunbaree510312009-03-20 15:59:01 +0000145
Mike Stump1eb44332009-09-09 15:08:12 +0000146void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0,
Daniel Dunbaree510312009-03-20 15:59:01 +0000147 options::ID Id1) const {
148 // FIXME: Make fast.
149 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
150 const Arg *A = *it;
151 if (A->getOption().matches(Id0) || A->getOption().matches(Id1)) {
152 A->claim();
153 for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
154 Output.push_back(A->getValue(*this, i));
155 }
156 }
157}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000158
Daniel Dunbar524b9fb2009-03-26 15:39:22 +0000159void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000160 const char *Translation,
161 bool Joined) const {
Daniel Dunbar524b9fb2009-03-26 15:39:22 +0000162 // FIXME: Make fast.
163 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
164 const Arg *A = *it;
165 if (A->getOption().matches(Id0)) {
166 A->claim();
Daniel Dunbar4df9a662009-04-26 01:07:52 +0000167
168 if (Joined) {
169 std::string Value = Translation;
170 Value += A->getValue(*this, 0);
171 Output.push_back(MakeArgString(Value.c_str()));
172 } else {
173 Output.push_back(Translation);
174 Output.push_back(A->getValue(*this, 0));
175 }
Daniel Dunbar524b9fb2009-03-26 15:39:22 +0000176 }
177 }
178}
179
Daniel Dunbar68fb4692009-04-03 20:51:31 +0000180void ArgList::ClaimAllArgs(options::ID Id0) const {
181 // FIXME: Make fast.
182 for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
183 const Arg *A = *it;
184 if (A->getOption().matches(Id0))
185 A->claim();
186 }
187}
188
Daniel Dunbar16484af2009-09-09 22:32:26 +0000189const char *ArgList::MakeArgString(const llvm::Twine &T) const {
190 llvm::SmallString<256> Str;
191 T.toVector(Str);
192 return MakeArgString(Str.str());
193}
194
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000195//
196
Mike Stump1eb44332009-09-09 15:08:12 +0000197InputArgList::InputArgList(const char **ArgBegin, const char **ArgEnd)
198 : ArgList(ActualArgs), NumInputArgStrings(ArgEnd - ArgBegin) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000199 ArgStrings.append(ArgBegin, ArgEnd);
200}
201
202InputArgList::~InputArgList() {
203 // An InputArgList always owns its arguments.
204 for (iterator it = begin(), ie = end(); it != ie; ++it)
205 delete *it;
206}
207
Daniel Dunbar16484af2009-09-09 22:32:26 +0000208unsigned InputArgList::MakeIndex(llvm::StringRef String0) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000209 unsigned Index = ArgStrings.size();
210
211 // Tuck away so we have a reliable const char *.
212 SynthesizedStrings.push_back(String0);
213 ArgStrings.push_back(SynthesizedStrings.back().c_str());
214
215 return Index;
216}
217
Daniel Dunbar16484af2009-09-09 22:32:26 +0000218unsigned InputArgList::MakeIndex(llvm::StringRef String0,
219 llvm::StringRef String1) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000220 unsigned Index0 = MakeIndex(String0);
221 unsigned Index1 = MakeIndex(String1);
222 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
223 (void) Index1;
224 return Index0;
225}
226
Daniel Dunbar16484af2009-09-09 22:32:26 +0000227const char *InputArgList::MakeArgString(llvm::StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000228 return getArgString(MakeIndex(Str));
229}
230
231//
232
233DerivedArgList::DerivedArgList(InputArgList &_BaseArgs, bool _OnlyProxy)
234 : ArgList(_OnlyProxy ? _BaseArgs.getArgs() : ActualArgs),
Mike Stump1eb44332009-09-09 15:08:12 +0000235 BaseArgs(_BaseArgs), OnlyProxy(_OnlyProxy) {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000236}
237
238DerivedArgList::~DerivedArgList() {
239 // We only own the arguments we explicitly synthesized.
Mike Stump1eb44332009-09-09 15:08:12 +0000240 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end();
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000241 it != ie; ++it)
242 delete *it;
243}
244
Daniel Dunbar16484af2009-09-09 22:32:26 +0000245const char *DerivedArgList::MakeArgString(llvm::StringRef Str) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000246 return BaseArgs.MakeArgString(Str);
247}
248
Daniel Dunbar478edc22009-03-29 22:29:05 +0000249Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const {
250 return new FlagArg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg);
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000251}
252
Mike Stump1eb44332009-09-09 15:08:12 +0000253Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt,
Daniel Dunbar16484af2009-09-09 22:32:26 +0000254 llvm::StringRef Value) const {
Daniel Dunbar478edc22009-03-29 22:29:05 +0000255 return new PositionalArg(Opt, BaseArgs.MakeIndex(Value), BaseArg);
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000256}
257
Mike Stump1eb44332009-09-09 15:08:12 +0000258Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt,
Daniel Dunbar16484af2009-09-09 22:32:26 +0000259 llvm::StringRef Value) const {
Mike Stump1eb44332009-09-09 15:08:12 +0000260 return new SeparateArg(Opt, BaseArgs.MakeIndex(Opt->getName(), Value), 1,
Daniel Dunbar478edc22009-03-29 22:29:05 +0000261 BaseArg);
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000262}
263
Mike Stump1eb44332009-09-09 15:08:12 +0000264Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt,
Daniel Dunbar16484af2009-09-09 22:32:26 +0000265 llvm::StringRef Value) const {
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000266 std::string Joined(Opt->getName());
267 Joined += Value;
Daniel Dunbar478edc22009-03-29 22:29:05 +0000268 return new JoinedArg(Opt, BaseArgs.MakeIndex(Joined.c_str()), BaseArg);
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000269}