ArgList.cpp revision 2da13b15959365df7edf1ed12a049b599b39c276
1//===--- 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" 12#include "clang/Driver/DriverDiagnostic.h" 13#include "clang/Driver/Option.h" 14 15#include "llvm/ADT/SmallString.h" 16#include "llvm/ADT/Twine.h" 17#include "llvm/Support/raw_ostream.h" 18 19using namespace clang; 20using namespace clang::driver; 21 22void 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 39ArgList::ArgList() { 40} 41 42ArgList::~ArgList() { 43} 44 45void ArgList::append(Arg *A) { 46 Args.push_back(A); 47} 48 49void ArgList::eraseArg(OptSpecifier Id) { 50 for (iterator it = begin(), ie = end(); it != ie; ++it) { 51 if ((*it)->getOption().matches(Id)) { 52 Args.erase(it); 53 it = begin(); 54 ie = end(); 55 } 56 } 57} 58 59Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const { 60 // FIXME: Make search efficient? 61 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) 62 if ((*it)->getOption().matches(Id)) 63 return *it; 64 return 0; 65} 66 67Arg *ArgList::getLastArg(OptSpecifier Id) const { 68 Arg *Res = 0; 69 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 70 if ((*it)->getOption().matches(Id)) { 71 Res = *it; 72 Res->claim(); 73 } 74 } 75 76 return Res; 77} 78 79Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const { 80 Arg *Res = 0; 81 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 82 if ((*it)->getOption().matches(Id0) || 83 (*it)->getOption().matches(Id1)) { 84 Res = *it; 85 Res->claim(); 86 87 } 88 } 89 90 return Res; 91} 92 93Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 94 OptSpecifier Id2) const { 95 Arg *Res = 0; 96 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 97 if ((*it)->getOption().matches(Id0) || 98 (*it)->getOption().matches(Id1) || 99 (*it)->getOption().matches(Id2)) { 100 Res = *it; 101 Res->claim(); 102 } 103 } 104 105 return Res; 106} 107 108Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 109 OptSpecifier Id2, OptSpecifier Id3) const { 110 Arg *Res = 0; 111 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 112 if ((*it)->getOption().matches(Id0) || 113 (*it)->getOption().matches(Id1) || 114 (*it)->getOption().matches(Id2) || 115 (*it)->getOption().matches(Id3)) { 116 Res = *it; 117 Res->claim(); 118 } 119 } 120 121 return Res; 122} 123 124bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { 125 if (Arg *A = getLastArg(Pos, Neg)) 126 return A->getOption().matches(Pos); 127 return Default; 128} 129 130llvm::StringRef ArgList::getLastArgValue(OptSpecifier Id, 131 llvm::StringRef Default) const { 132 if (Arg *A = getLastArg(Id)) 133 return A->getValue(*this); 134 return Default; 135} 136 137int ArgList::getLastArgIntValue(OptSpecifier Id, int Default, 138 clang::Diagnostic &Diags) const { 139 int Res = Default; 140 141 if (Arg *A = getLastArg(Id)) { 142 if (llvm::StringRef(A->getValue(*this)).getAsInteger(10, Res)) 143 Diags.Report(diag::err_drv_invalid_int_value) 144 << A->getAsString(*this) << A->getValue(*this); 145 } 146 147 return Res; 148} 149 150std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const { 151 llvm::SmallVector<const char *, 16> Values; 152 AddAllArgValues(Values, Id); 153 return std::vector<std::string>(Values.begin(), Values.end()); 154} 155 156void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { 157 if (Arg *A = getLastArg(Id)) { 158 A->claim(); 159 A->render(*this, Output); 160 } 161} 162 163void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, 164 OptSpecifier Id1, OptSpecifier Id2) const { 165 for (arg_iterator it = filtered_begin(Id0, Id1, Id2), 166 ie = filtered_end(); it != ie; ++it) { 167 (*it)->claim(); 168 (*it)->render(*this, Output); 169 } 170} 171 172void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, 173 OptSpecifier Id1, OptSpecifier Id2) const { 174 for (arg_iterator it = filtered_begin(Id0, Id1, Id2), 175 ie = filtered_end(); it != ie; ++it) { 176 (*it)->claim(); 177 for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) 178 Output.push_back((*it)->getValue(*this, i)); 179 } 180} 181 182void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, 183 const char *Translation, 184 bool Joined) const { 185 for (arg_iterator it = filtered_begin(Id0), 186 ie = filtered_end(); it != ie; ++it) { 187 (*it)->claim(); 188 189 if (Joined) { 190 Output.push_back(MakeArgString(llvm::StringRef(Translation) + 191 (*it)->getValue(*this, 0))); 192 } else { 193 Output.push_back(Translation); 194 Output.push_back((*it)->getValue(*this, 0)); 195 } 196 } 197} 198 199void ArgList::ClaimAllArgs(OptSpecifier Id0) const { 200 for (arg_iterator it = filtered_begin(Id0), 201 ie = filtered_end(); it != ie; ++it) 202 (*it)->claim(); 203} 204 205void ArgList::ClaimAllArgs() const { 206 for (const_iterator it = begin(), ie = end(); it != ie; ++it) 207 if (!(*it)->isClaimed()) 208 (*it)->claim(); 209} 210 211const char *ArgList::MakeArgString(const llvm::Twine &T) const { 212 llvm::SmallString<256> Str; 213 T.toVector(Str); 214 return MakeArgString(Str.str()); 215} 216 217const char *ArgList::GetOrMakeJoinedArgString(unsigned Index, 218 llvm::StringRef LHS, 219 llvm::StringRef RHS) const { 220 llvm::StringRef Cur = getArgString(Index); 221 if (Cur.size() == LHS.size() + RHS.size() && 222 Cur.startswith(LHS) && Cur.endswith(RHS)) 223 return Cur.data(); 224 225 return MakeArgString(LHS + RHS); 226} 227 228// 229 230InputArgList::InputArgList(const char* const *ArgBegin, 231 const char* const *ArgEnd) 232 : NumInputArgStrings(ArgEnd - ArgBegin) { 233 ArgStrings.append(ArgBegin, ArgEnd); 234} 235 236InputArgList::~InputArgList() { 237 // An InputArgList always owns its arguments. 238 for (iterator it = begin(), ie = end(); it != ie; ++it) 239 delete *it; 240} 241 242unsigned InputArgList::MakeIndex(llvm::StringRef String0) const { 243 unsigned Index = ArgStrings.size(); 244 245 // Tuck away so we have a reliable const char *. 246 SynthesizedStrings.push_back(String0); 247 ArgStrings.push_back(SynthesizedStrings.back().c_str()); 248 249 return Index; 250} 251 252unsigned InputArgList::MakeIndex(llvm::StringRef String0, 253 llvm::StringRef String1) const { 254 unsigned Index0 = MakeIndex(String0); 255 unsigned Index1 = MakeIndex(String1); 256 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!"); 257 (void) Index1; 258 return Index0; 259} 260 261const char *InputArgList::MakeArgString(llvm::StringRef Str) const { 262 return getArgString(MakeIndex(Str)); 263} 264 265// 266 267DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs) 268 : BaseArgs(_BaseArgs) { 269} 270 271DerivedArgList::~DerivedArgList() { 272 // We only own the arguments we explicitly synthesized. 273 for (iterator it = SynthesizedArgs.begin(), ie = SynthesizedArgs.end(); 274 it != ie; ++it) 275 delete *it; 276} 277 278const char *DerivedArgList::MakeArgString(llvm::StringRef Str) const { 279 return BaseArgs.MakeArgString(Str); 280} 281 282Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option *Opt) const { 283 Arg *A = new Arg(Opt, BaseArgs.MakeIndex(Opt->getName()), BaseArg); 284 SynthesizedArgs.push_back(A); 285 return A; 286} 287 288Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option *Opt, 289 llvm::StringRef Value) const { 290 unsigned Index = BaseArgs.MakeIndex(Value); 291 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index), BaseArg); 292 SynthesizedArgs.push_back(A); 293 return A; 294} 295 296Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option *Opt, 297 llvm::StringRef Value) const { 298 unsigned Index = BaseArgs.MakeIndex(Opt->getName(), Value); 299 Arg *A = new Arg(Opt, Index, BaseArgs.getArgString(Index + 1), BaseArg); 300 SynthesizedArgs.push_back(A); 301 return A; 302} 303 304Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option *Opt, 305 llvm::StringRef Value) const { 306 unsigned Index = BaseArgs.MakeIndex(Opt->getName().str() + Value.str()); 307 Arg *A = new Arg(Opt, Index, 308 BaseArgs.getArgString(Index) + Opt->getName().size(), 309 BaseArg); 310 SynthesizedArgs.push_back(A); 311 return A; 312} 313