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