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 "llvm/Option/ArgList.h" 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/ADT/Twine.h" 14 #include "llvm/Option/Arg.h" 15 #include "llvm/Option/Option.h" 16 #include "llvm/Support/raw_ostream.h" 17 18 using namespace llvm; 19 using namespace llvm::opt; 20 21 void arg_iterator::SkipToNextArg() { 22 for (; Current != Args.end(); ++Current) { 23 // Done if there are no filters. 24 if (!Id0.isValid()) 25 break; 26 27 // Otherwise require a match. 28 const Option &O = (*Current)->getOption(); 29 if (O.matches(Id0) || 30 (Id1.isValid() && O.matches(Id1)) || 31 (Id2.isValid() && O.matches(Id2))) 32 break; 33 } 34 } 35 36 ArgList::~ArgList() { 37 } 38 39 void ArgList::append(Arg *A) { 40 Args.push_back(A); 41 } 42 43 void ArgList::eraseArg(OptSpecifier Id) { 44 for (iterator it = begin(), ie = end(); it != ie; ) { 45 if ((*it)->getOption().matches(Id)) { 46 it = Args.erase(it); 47 ie = end(); 48 } else { 49 ++it; 50 } 51 } 52 } 53 54 Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const { 55 // FIXME: Make search efficient? 56 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) 57 if ((*it)->getOption().matches(Id)) 58 return *it; 59 return nullptr; 60 } 61 62 Arg *ArgList::getLastArg(OptSpecifier Id) const { 63 Arg *Res = nullptr; 64 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 65 if ((*it)->getOption().matches(Id)) { 66 Res = *it; 67 Res->claim(); 68 } 69 } 70 71 return Res; 72 } 73 74 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const { 75 Arg *Res = nullptr; 76 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 77 if ((*it)->getOption().matches(Id0) || 78 (*it)->getOption().matches(Id1)) { 79 Res = *it; 80 Res->claim(); 81 82 } 83 } 84 85 return Res; 86 } 87 88 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 89 OptSpecifier Id2) const { 90 Arg *Res = nullptr; 91 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 92 if ((*it)->getOption().matches(Id0) || 93 (*it)->getOption().matches(Id1) || 94 (*it)->getOption().matches(Id2)) { 95 Res = *it; 96 Res->claim(); 97 } 98 } 99 100 return Res; 101 } 102 103 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 104 OptSpecifier Id2, OptSpecifier Id3) const { 105 Arg *Res = nullptr; 106 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 107 if ((*it)->getOption().matches(Id0) || 108 (*it)->getOption().matches(Id1) || 109 (*it)->getOption().matches(Id2) || 110 (*it)->getOption().matches(Id3)) { 111 Res = *it; 112 Res->claim(); 113 } 114 } 115 116 return Res; 117 } 118 119 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 120 OptSpecifier Id2, OptSpecifier Id3, 121 OptSpecifier Id4) const { 122 Arg *Res = nullptr; 123 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 124 if ((*it)->getOption().matches(Id0) || 125 (*it)->getOption().matches(Id1) || 126 (*it)->getOption().matches(Id2) || 127 (*it)->getOption().matches(Id3) || 128 (*it)->getOption().matches(Id4)) { 129 Res = *it; 130 Res->claim(); 131 } 132 } 133 134 return Res; 135 } 136 137 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 138 OptSpecifier Id2, OptSpecifier Id3, 139 OptSpecifier Id4, OptSpecifier Id5) const { 140 Arg *Res = nullptr; 141 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 142 if ((*it)->getOption().matches(Id0) || 143 (*it)->getOption().matches(Id1) || 144 (*it)->getOption().matches(Id2) || 145 (*it)->getOption().matches(Id3) || 146 (*it)->getOption().matches(Id4) || 147 (*it)->getOption().matches(Id5)) { 148 Res = *it; 149 Res->claim(); 150 } 151 } 152 153 return Res; 154 } 155 156 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 157 OptSpecifier Id2, OptSpecifier Id3, 158 OptSpecifier Id4, OptSpecifier Id5, 159 OptSpecifier Id6) const { 160 Arg *Res = nullptr; 161 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 162 if ((*it)->getOption().matches(Id0) || 163 (*it)->getOption().matches(Id1) || 164 (*it)->getOption().matches(Id2) || 165 (*it)->getOption().matches(Id3) || 166 (*it)->getOption().matches(Id4) || 167 (*it)->getOption().matches(Id5) || 168 (*it)->getOption().matches(Id6)) { 169 Res = *it; 170 Res->claim(); 171 } 172 } 173 174 return Res; 175 } 176 177 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 178 OptSpecifier Id2, OptSpecifier Id3, 179 OptSpecifier Id4, OptSpecifier Id5, 180 OptSpecifier Id6, OptSpecifier Id7) const { 181 Arg *Res = nullptr; 182 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 183 if ((*it)->getOption().matches(Id0) || 184 (*it)->getOption().matches(Id1) || 185 (*it)->getOption().matches(Id2) || 186 (*it)->getOption().matches(Id3) || 187 (*it)->getOption().matches(Id4) || 188 (*it)->getOption().matches(Id5) || 189 (*it)->getOption().matches(Id6) || 190 (*it)->getOption().matches(Id7)) { 191 Res = *it; 192 Res->claim(); 193 } 194 } 195 196 return Res; 197 } 198 199 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { 200 if (Arg *A = getLastArg(Pos, Neg)) 201 return A->getOption().matches(Pos); 202 return Default; 203 } 204 205 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, 206 bool Default) const { 207 if (Arg *A = getLastArg(Pos, PosAlias, Neg)) 208 return A->getOption().matches(Pos) || A->getOption().matches(PosAlias); 209 return Default; 210 } 211 212 StringRef ArgList::getLastArgValue(OptSpecifier Id, 213 StringRef Default) const { 214 if (Arg *A = getLastArg(Id)) 215 return A->getValue(); 216 return Default; 217 } 218 219 std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const { 220 SmallVector<const char *, 16> Values; 221 AddAllArgValues(Values, Id); 222 return std::vector<std::string>(Values.begin(), Values.end()); 223 } 224 225 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { 226 if (Arg *A = getLastArg(Id)) { 227 A->claim(); 228 A->render(*this, Output); 229 } 230 } 231 232 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0, 233 OptSpecifier Id1) const { 234 if (Arg *A = getLastArg(Id0, Id1)) { 235 A->claim(); 236 A->render(*this, Output); 237 } 238 } 239 240 void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, 241 OptSpecifier Id1, OptSpecifier Id2) const { 242 for (arg_iterator it = filtered_begin(Id0, Id1, Id2), 243 ie = filtered_end(); it != ie; ++it) { 244 (*it)->claim(); 245 (*it)->render(*this, Output); 246 } 247 } 248 249 void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, 250 OptSpecifier Id1, OptSpecifier Id2) const { 251 for (arg_iterator it = filtered_begin(Id0, Id1, Id2), 252 ie = filtered_end(); it != ie; ++it) { 253 (*it)->claim(); 254 for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) 255 Output.push_back((*it)->getValue(i)); 256 } 257 } 258 259 void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, 260 const char *Translation, 261 bool Joined) const { 262 for (arg_iterator it = filtered_begin(Id0), 263 ie = filtered_end(); it != ie; ++it) { 264 (*it)->claim(); 265 266 if (Joined) { 267 Output.push_back(MakeArgString(StringRef(Translation) + 268 (*it)->getValue(0))); 269 } else { 270 Output.push_back(Translation); 271 Output.push_back((*it)->getValue(0)); 272 } 273 } 274 } 275 276 void ArgList::ClaimAllArgs(OptSpecifier Id0) const { 277 for (arg_iterator it = filtered_begin(Id0), 278 ie = filtered_end(); it != ie; ++it) 279 (*it)->claim(); 280 } 281 282 void ArgList::ClaimAllArgs() const { 283 for (const_iterator it = begin(), ie = end(); it != ie; ++it) 284 if (!(*it)->isClaimed()) 285 (*it)->claim(); 286 } 287 288 const char *ArgList::MakeArgString(const Twine &T) const { 289 SmallString<256> Str; 290 return MakeArgString(T.toStringRef(Str)); 291 } 292 293 const char *ArgList::GetOrMakeJoinedArgString(unsigned Index, 294 StringRef LHS, 295 StringRef RHS) const { 296 StringRef Cur = getArgString(Index); 297 if (Cur.size() == LHS.size() + RHS.size() && 298 Cur.startswith(LHS) && Cur.endswith(RHS)) 299 return Cur.data(); 300 301 return MakeArgString(LHS + RHS); 302 } 303 304 // 305 306 InputArgList::InputArgList(const char* const *ArgBegin, 307 const char* const *ArgEnd) 308 : NumInputArgStrings(ArgEnd - ArgBegin) { 309 ArgStrings.append(ArgBegin, ArgEnd); 310 } 311 312 InputArgList::~InputArgList() { 313 // An InputArgList always owns its arguments. 314 for (iterator it = begin(), ie = end(); it != ie; ++it) 315 delete *it; 316 } 317 318 unsigned InputArgList::MakeIndex(StringRef String0) const { 319 unsigned Index = ArgStrings.size(); 320 321 // Tuck away so we have a reliable const char *. 322 SynthesizedStrings.push_back(String0); 323 ArgStrings.push_back(SynthesizedStrings.back().c_str()); 324 325 return Index; 326 } 327 328 unsigned InputArgList::MakeIndex(StringRef String0, 329 StringRef String1) const { 330 unsigned Index0 = MakeIndex(String0); 331 unsigned Index1 = MakeIndex(String1); 332 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!"); 333 (void) Index1; 334 return Index0; 335 } 336 337 const char *InputArgList::MakeArgString(StringRef Str) const { 338 return getArgString(MakeIndex(Str)); 339 } 340 341 // 342 343 DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs) 344 : BaseArgs(_BaseArgs) { 345 } 346 347 DerivedArgList::~DerivedArgList() {} 348 349 const char *DerivedArgList::MakeArgString(StringRef Str) const { 350 return BaseArgs.MakeArgString(Str); 351 } 352 353 void DerivedArgList::AddSynthesizedArg(Arg *A) { 354 SynthesizedArgs.push_back(std::unique_ptr<Arg>(A)); 355 } 356 357 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const { 358 SynthesizedArgs.push_back(make_unique<Arg>( 359 Opt, 360 ArgList::MakeArgString(Twine(Opt.getPrefix()) + Twine(Opt.getName())), 361 BaseArgs.MakeIndex(Opt.getName()), BaseArg)); 362 return SynthesizedArgs.back().get(); 363 } 364 365 Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt, 366 StringRef Value) const { 367 unsigned Index = BaseArgs.MakeIndex(Value); 368 SynthesizedArgs.push_back(make_unique<Arg>( 369 Opt, 370 ArgList::MakeArgString(Twine(Opt.getPrefix()) + Twine(Opt.getName())), 371 Index, BaseArgs.getArgString(Index), BaseArg)); 372 return SynthesizedArgs.back().get(); 373 } 374 375 Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt, 376 StringRef Value) const { 377 unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value); 378 SynthesizedArgs.push_back(make_unique<Arg>( 379 Opt, 380 ArgList::MakeArgString(Twine(Opt.getPrefix()) + Twine(Opt.getName())), 381 Index, BaseArgs.getArgString(Index + 1), BaseArg)); 382 return SynthesizedArgs.back().get(); 383 } 384 385 Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt, 386 StringRef Value) const { 387 unsigned Index = BaseArgs.MakeIndex(Opt.getName().str() + Value.str()); 388 SynthesizedArgs.push_back(make_unique<Arg>( 389 Opt, 390 ArgList::MakeArgString(Twine(Opt.getPrefix()) + Twine(Opt.getName())), 391 Index, BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg)); 392 return SynthesizedArgs.back().get(); 393 } 394