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/DriverDiagnostic.h"
13 #include "clang/Driver/Option.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/Support/raw_ostream.h"
19 using namespace clang
;
20 using namespace clang::driver
;
22 void arg_iterator::SkipToNextArg() {
23 for (; Current
!= Args
.end(); ++Current
) {
24 // Done if there are no filters.
28 // Otherwise require a match.
29 const Option
&O
= (*Current
)->getOption();
31 (Id1
.isValid() && O
.matches(Id1
)) ||
32 (Id2
.isValid() && O
.matches(Id2
)))
45 void ArgList::append(Arg
*A
) {
49 Arg
*ArgList::getLastArgNoClaim(OptSpecifier Id
) const {
50 // FIXME: Make search efficient?
51 for (const_reverse_iterator it
= rbegin(), ie
= rend(); it
!= ie
; ++it
)
52 if ((*it
)->getOption().matches(Id
))
57 Arg
*ArgList::getLastArg(OptSpecifier Id
) const {
59 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
60 if ((*it
)->getOption().matches(Id
)) {
69 Arg
*ArgList::getLastArg(OptSpecifier Id0
, OptSpecifier Id1
) const {
71 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
72 if ((*it
)->getOption().matches(Id0
) ||
73 (*it
)->getOption().matches(Id1
)) {
83 Arg
*ArgList::getLastArg(OptSpecifier Id0
, OptSpecifier Id1
,
84 OptSpecifier Id2
) const {
86 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
87 if ((*it
)->getOption().matches(Id0
) ||
88 (*it
)->getOption().matches(Id1
) ||
89 (*it
)->getOption().matches(Id2
)) {
98 Arg
*ArgList::getLastArg(OptSpecifier Id0
, OptSpecifier Id1
,
99 OptSpecifier Id2
, OptSpecifier Id3
) const {
101 for (const_iterator it
= begin(), ie
= end(); it
!= ie
; ++it
) {
102 if ((*it
)->getOption().matches(Id0
) ||
103 (*it
)->getOption().matches(Id1
) ||
104 (*it
)->getOption().matches(Id2
) ||
105 (*it
)->getOption().matches(Id3
)) {
114 bool ArgList::hasFlag(OptSpecifier Pos
, OptSpecifier Neg
, bool Default
) const {
115 if (Arg
*A
= getLastArg(Pos
, Neg
))
116 return A
->getOption().matches(Pos
);
120 llvm::StringRef
ArgList::getLastArgValue(OptSpecifier Id
,
121 llvm::StringRef Default
) const {
122 if (Arg
*A
= getLastArg(Id
))
123 return A
->getValue(*this);
127 int ArgList::getLastArgIntValue(OptSpecifier Id
, int Default
,
128 clang::Diagnostic
&Diags
) const {
131 if (Arg
*A
= getLastArg(Id
)) {
132 if (llvm::StringRef(A
->getValue(*this)).getAsInteger(10, Res
))
133 Diags
.Report(diag::err_drv_invalid_int_value
)
134 << A
->getAsString(*this) << A
->getValue(*this);
140 std::vector
<std::string
> ArgList::getAllArgValues(OptSpecifier Id
) const {
141 llvm::SmallVector
<const char *, 16> Values
;
142 AddAllArgValues(Values
, Id
);
143 return std::vector
<std::string
>(Values
.begin(), Values
.end());
146 void ArgList::AddLastArg(ArgStringList
&Output
, OptSpecifier Id
) const {
147 if (Arg
*A
= getLastArg(Id
)) {
149 A
->render(*this, Output
);
153 void ArgList::AddAllArgs(ArgStringList
&Output
, OptSpecifier Id0
,
154 OptSpecifier Id1
, OptSpecifier Id2
) const {
155 for (arg_iterator it
= filtered_begin(Id0
, Id1
, Id2
),
156 ie
= filtered_end(); it
!= ie
; ++it
) {
158 (*it
)->render(*this, Output
);
162 void ArgList::AddAllArgValues(ArgStringList
&Output
, OptSpecifier Id0
,
163 OptSpecifier Id1
, OptSpecifier Id2
) const {
164 for (arg_iterator it
= filtered_begin(Id0
, Id1
, Id2
),
165 ie
= filtered_end(); it
!= ie
; ++it
) {
167 for (unsigned i
= 0, e
= (*it
)->getNumValues(); i
!= e
; ++i
)
168 Output
.push_back((*it
)->getValue(*this, i
));
172 void ArgList::AddAllArgsTranslated(ArgStringList
&Output
, OptSpecifier Id0
,
173 const char *Translation
,
175 for (arg_iterator it
= filtered_begin(Id0
),
176 ie
= filtered_end(); it
!= ie
; ++it
) {
180 Output
.push_back(MakeArgString(llvm::StringRef(Translation
) +
181 (*it
)->getValue(*this, 0)));
183 Output
.push_back(Translation
);
184 Output
.push_back((*it
)->getValue(*this, 0));
189 void ArgList::ClaimAllArgs(OptSpecifier Id0
) const {
190 for (arg_iterator it
= filtered_begin(Id0
),
191 ie
= filtered_end(); it
!= ie
; ++it
)
195 const char *ArgList::MakeArgString(const llvm::Twine
&T
) const {
196 llvm::SmallString
<256> Str
;
198 return MakeArgString(Str
.str());
201 const char *ArgList::GetOrMakeJoinedArgString(unsigned Index
,
203 llvm::StringRef RHS
) const {
204 llvm::StringRef Cur
= getArgString(Index
);
205 if (Cur
.size() == LHS
.size() + RHS
.size() &&
206 Cur
.startswith(LHS
) && Cur
.endswith(RHS
))
209 return MakeArgString(LHS
+ RHS
);
214 InputArgList::InputArgList(const char* const *ArgBegin
,
215 const char* const *ArgEnd
)
216 : NumInputArgStrings(ArgEnd
- ArgBegin
) {
217 ArgStrings
.append(ArgBegin
, ArgEnd
);
220 InputArgList::~InputArgList() {
221 // An InputArgList always owns its arguments.
222 for (iterator it
= begin(), ie
= end(); it
!= ie
; ++it
)
226 unsigned InputArgList::MakeIndex(llvm::StringRef String0
) const {
227 unsigned Index
= ArgStrings
.size();
229 // Tuck away so we have a reliable const char *.
230 SynthesizedStrings
.push_back(String0
);
231 ArgStrings
.push_back(SynthesizedStrings
.back().c_str());
236 unsigned InputArgList::MakeIndex(llvm::StringRef String0
,
237 llvm::StringRef String1
) const {
238 unsigned Index0
= MakeIndex(String0
);
239 unsigned Index1
= MakeIndex(String1
);
240 assert(Index0
+ 1 == Index1
&& "Unexpected non-consecutive indices!");
245 const char *InputArgList::MakeArgString(llvm::StringRef Str
) const {
246 return getArgString(MakeIndex(Str
));
251 DerivedArgList::DerivedArgList(const InputArgList
&_BaseArgs
)
252 : BaseArgs(_BaseArgs
) {
255 DerivedArgList::~DerivedArgList() {
256 // We only own the arguments we explicitly synthesized.
257 for (iterator it
= SynthesizedArgs
.begin(), ie
= SynthesizedArgs
.end();
262 const char *DerivedArgList::MakeArgString(llvm::StringRef Str
) const {
263 return BaseArgs
.MakeArgString(Str
);
266 Arg
*DerivedArgList::MakeFlagArg(const Arg
*BaseArg
, const Option
*Opt
) const {
267 Arg
*A
= new Arg(Opt
, BaseArgs
.MakeIndex(Opt
->getName()), BaseArg
);
268 SynthesizedArgs
.push_back(A
);
272 Arg
*DerivedArgList::MakePositionalArg(const Arg
*BaseArg
, const Option
*Opt
,
273 llvm::StringRef Value
) const {
274 unsigned Index
= BaseArgs
.MakeIndex(Value
);
275 Arg
*A
= new Arg(Opt
, Index
, BaseArgs
.getArgString(Index
), BaseArg
);
276 SynthesizedArgs
.push_back(A
);
280 Arg
*DerivedArgList::MakeSeparateArg(const Arg
*BaseArg
, const Option
*Opt
,
281 llvm::StringRef Value
) const {
282 unsigned Index
= BaseArgs
.MakeIndex(Opt
->getName(), Value
);
283 Arg
*A
= new Arg(Opt
, Index
, BaseArgs
.getArgString(Index
+ 1), BaseArg
);
284 SynthesizedArgs
.push_back(A
);
288 Arg
*DerivedArgList::MakeJoinedArg(const Arg
*BaseArg
, const Option
*Opt
,
289 llvm::StringRef Value
) const {
290 unsigned Index
= BaseArgs
.MakeIndex(Opt
->getName() + Value
.str());
291 Arg
*A
= new Arg(Opt
, Index
,
292 BaseArgs
.getArgString(Index
) + strlen(Opt
->getName()),
294 SynthesizedArgs
.push_back(A
);