1 //===--- ArgList.cpp - Argument List Management -------------------------*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/Driver/ArgList.h"
11 #include "clang/Driver/Arg.h"
12 #include "clang/Driver/Option.h"
14 using namespace clang::driver
;
16 ArgList::ArgList(arglist_type
&_Args
) : Args(_Args
) {
22 void ArgList::append(Arg
*A
) {
26 Arg
*ArgList::getLastArg(options::ID Id
, bool Claim
) const {
27 // FIXME: Make search efficient?
28 for (const_reverse_iterator it
= rbegin(), ie
= rend(); it
!= ie
; ++it
) {
29 if ((*it
)->getOption().matches(Id
)) {
30 if (Claim
) (*it
)->claim();
38 Arg
*ArgList::getLastArg(options::ID Id0
, options::ID Id1
, bool Claim
) const {
39 Arg
*Res
, *A0
= getLastArg(Id0
, false), *A1
= getLastArg(Id1
, false);
42 Res
= A0
->getIndex() > A1
->getIndex() ? A0
: A1
;
52 Arg
*ArgList::getLastArg(options::ID Id0
, options::ID Id1
, options::ID Id2
,
55 Arg
*A0
= getLastArg(Id0
, false);
56 Arg
*A1
= getLastArg(Id1
, false);
57 Arg
*A2
= getLastArg(Id2
, false);
59 int A0Idx
= A0
? A0
->getIndex() : -1;
60 int A1Idx
= A1
? A1
->getIndex() : -1;
61 int A2Idx
= A2
? A2
->getIndex() : -1;
81 bool ArgList::hasFlag(options::ID Pos
, options::ID Neg
, bool Default
) const {
82 if (Arg
*A
= getLastArg(Pos
, Neg
))
83 return A
->getOption().matches(Pos
);
87 void ArgList::AddLastArg(ArgStringList
&Output
, options::ID Id
) const {
88 if (Arg
*A
= getLastArg(Id
)) {
90 A
->render(*this, Output
);
94 void ArgList::AddAllArgs(ArgStringList
&Output
, options::ID Id0
) const {
96 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
98 if (A
->getOption().matches(Id0
)) {
100 A
->render(*this, Output
);
105 void ArgList::AddAllArgs(ArgStringList
&Output
, options::ID Id0
,
106 options::ID Id1
) const {
108 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
110 if (A
->getOption().matches(Id0
) || A
->getOption().matches(Id1
)) {
112 A
->render(*this, Output
);
117 void ArgList::AddAllArgs(ArgStringList
&Output
, options::ID Id0
,
118 options::ID Id1
, options::ID Id2
) const {
120 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
122 if (A
->getOption().matches(Id0
) || A
->getOption().matches(Id1
) ||
123 A
->getOption().matches(Id2
)) {
125 A
->render(*this, Output
);
130 void ArgList::AddAllArgValues(ArgStringList
&Output
, options::ID Id0
) const {
132 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
134 if (A
->getOption().matches(Id0
)) {
136 for (unsigned i
= 0, e
= A
->getNumValues(); i
!= e
; ++i
)
137 Output
.push_back(A
->getValue(*this, i
));
142 void ArgList::AddAllArgValues(ArgStringList
&Output
, options::ID Id0
,
143 options::ID Id1
) const {
145 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
147 if (A
->getOption().matches(Id0
) || A
->getOption().matches(Id1
)) {
149 for (unsigned i
= 0, e
= A
->getNumValues(); i
!= e
; ++i
)
150 Output
.push_back(A
->getValue(*this, i
));
155 void ArgList::AddAllArgsTranslated(ArgStringList
&Output
, options::ID Id0
,
156 const char *Translation
,
159 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
161 if (A
->getOption().matches(Id0
)) {
165 std::string Value
= Translation
;
166 Value
+= A
->getValue(*this, 0);
167 Output
.push_back(MakeArgString(Value
.c_str()));
169 Output
.push_back(Translation
);
170 Output
.push_back(A
->getValue(*this, 0));
176 void ArgList::ClaimAllArgs(options::ID Id0
) const {
178 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
180 if (A
->getOption().matches(Id0
))
187 InputArgList::InputArgList(const char **ArgBegin
, const char **ArgEnd
)
188 : ArgList(ActualArgs
), NumInputArgStrings(ArgEnd
- ArgBegin
)
190 ArgStrings
.append(ArgBegin
, ArgEnd
);
193 InputArgList::~InputArgList() {
194 // An InputArgList always owns its arguments.
195 for (iterator it
= begin(), ie
= end(); it
!= ie
; ++it
)
199 unsigned InputArgList::MakeIndex(const char *String0
) const {
200 unsigned Index
= ArgStrings
.size();
202 // Tuck away so we have a reliable const char *.
203 SynthesizedStrings
.push_back(String0
);
204 ArgStrings
.push_back(SynthesizedStrings
.back().c_str());
209 unsigned InputArgList::MakeIndex(const char *String0
,
210 const char *String1
) const {
211 unsigned Index0
= MakeIndex(String0
);
212 unsigned Index1
= MakeIndex(String1
);
213 assert(Index0
+ 1 == Index1
&& "Unexpected non-consecutive indices!");
218 const char *InputArgList::MakeArgString(const char *Str
) const {
219 return getArgString(MakeIndex(Str
));
224 DerivedArgList::DerivedArgList(InputArgList
&_BaseArgs
, bool _OnlyProxy
)
225 : ArgList(_OnlyProxy
? _BaseArgs
.getArgs() : ActualArgs
),
226 BaseArgs(_BaseArgs
), OnlyProxy(_OnlyProxy
)
230 DerivedArgList::~DerivedArgList() {
231 // We only own the arguments we explicitly synthesized.
232 for (iterator it
= SynthesizedArgs
.begin(), ie
= SynthesizedArgs
.end();
237 const char *DerivedArgList::MakeArgString(const char *Str
) const {
238 return BaseArgs
.MakeArgString(Str
);
241 Arg
*DerivedArgList::MakeFlagArg(const Arg
*BaseArg
, const Option
*Opt
) const {
242 return new FlagArg(Opt
, BaseArgs
.MakeIndex(Opt
->getName()), BaseArg
);
245 Arg
*DerivedArgList::MakePositionalArg(const Arg
*BaseArg
, const Option
*Opt
,
246 const char *Value
) const {
247 return new PositionalArg(Opt
, BaseArgs
.MakeIndex(Value
), BaseArg
);
250 Arg
*DerivedArgList::MakeSeparateArg(const Arg
*BaseArg
, const Option
*Opt
,
251 const char *Value
) const {
252 return new SeparateArg(Opt
, BaseArgs
.MakeIndex(Opt
->getName(), Value
), 1,
256 Arg
*DerivedArgList::MakeJoinedArg(const Arg
*BaseArg
, const Option
*Opt
,
257 const char *Value
) const {
258 std::string
Joined(Opt
->getName());
260 return new JoinedArg(Opt
, BaseArgs
.MakeIndex(Joined
.c_str()), BaseArg
);