LLVM API Documentation
00001 //===--- ArgList.cpp - Argument List Management ---------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/Option/ArgList.h" 00011 #include "llvm/ADT/SmallString.h" 00012 #include "llvm/ADT/STLExtras.h" 00013 #include "llvm/ADT/Twine.h" 00014 #include "llvm/Option/Arg.h" 00015 #include "llvm/Option/Option.h" 00016 #include "llvm/Support/raw_ostream.h" 00017 00018 using namespace llvm; 00019 using namespace llvm::opt; 00020 00021 void arg_iterator::SkipToNextArg() { 00022 for (; Current != Args.end(); ++Current) { 00023 // Done if there are no filters. 00024 if (!Id0.isValid()) 00025 break; 00026 00027 // Otherwise require a match. 00028 const Option &O = (*Current)->getOption(); 00029 if (O.matches(Id0) || 00030 (Id1.isValid() && O.matches(Id1)) || 00031 (Id2.isValid() && O.matches(Id2))) 00032 break; 00033 } 00034 } 00035 00036 ArgList::~ArgList() { 00037 } 00038 00039 void ArgList::append(Arg *A) { 00040 Args.push_back(A); 00041 } 00042 00043 void ArgList::eraseArg(OptSpecifier Id) { 00044 Args.erase(std::remove_if(begin(), end(), 00045 [=](Arg *A) { return A->getOption().matches(Id); }), 00046 end()); 00047 } 00048 00049 Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const { 00050 // FIXME: Make search efficient? 00051 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) 00052 if ((*it)->getOption().matches(Id)) 00053 return *it; 00054 return nullptr; 00055 } 00056 00057 Arg *ArgList::getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1) const { 00058 // FIXME: Make search efficient? 00059 for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) 00060 if ((*it)->getOption().matches(Id0) || 00061 (*it)->getOption().matches(Id1)) 00062 return *it; 00063 return nullptr; 00064 } 00065 00066 Arg *ArgList::getLastArg(OptSpecifier Id) const { 00067 Arg *Res = nullptr; 00068 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00069 if ((*it)->getOption().matches(Id)) { 00070 Res = *it; 00071 Res->claim(); 00072 } 00073 } 00074 00075 return Res; 00076 } 00077 00078 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const { 00079 Arg *Res = nullptr; 00080 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00081 if ((*it)->getOption().matches(Id0) || 00082 (*it)->getOption().matches(Id1)) { 00083 Res = *it; 00084 Res->claim(); 00085 00086 } 00087 } 00088 00089 return Res; 00090 } 00091 00092 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00093 OptSpecifier Id2) const { 00094 Arg *Res = nullptr; 00095 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00096 if ((*it)->getOption().matches(Id0) || 00097 (*it)->getOption().matches(Id1) || 00098 (*it)->getOption().matches(Id2)) { 00099 Res = *it; 00100 Res->claim(); 00101 } 00102 } 00103 00104 return Res; 00105 } 00106 00107 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00108 OptSpecifier Id2, OptSpecifier Id3) const { 00109 Arg *Res = nullptr; 00110 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00111 if ((*it)->getOption().matches(Id0) || 00112 (*it)->getOption().matches(Id1) || 00113 (*it)->getOption().matches(Id2) || 00114 (*it)->getOption().matches(Id3)) { 00115 Res = *it; 00116 Res->claim(); 00117 } 00118 } 00119 00120 return Res; 00121 } 00122 00123 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00124 OptSpecifier Id2, OptSpecifier Id3, 00125 OptSpecifier Id4) const { 00126 Arg *Res = nullptr; 00127 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00128 if ((*it)->getOption().matches(Id0) || 00129 (*it)->getOption().matches(Id1) || 00130 (*it)->getOption().matches(Id2) || 00131 (*it)->getOption().matches(Id3) || 00132 (*it)->getOption().matches(Id4)) { 00133 Res = *it; 00134 Res->claim(); 00135 } 00136 } 00137 00138 return Res; 00139 } 00140 00141 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00142 OptSpecifier Id2, OptSpecifier Id3, 00143 OptSpecifier Id4, OptSpecifier Id5) const { 00144 Arg *Res = nullptr; 00145 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00146 if ((*it)->getOption().matches(Id0) || 00147 (*it)->getOption().matches(Id1) || 00148 (*it)->getOption().matches(Id2) || 00149 (*it)->getOption().matches(Id3) || 00150 (*it)->getOption().matches(Id4) || 00151 (*it)->getOption().matches(Id5)) { 00152 Res = *it; 00153 Res->claim(); 00154 } 00155 } 00156 00157 return Res; 00158 } 00159 00160 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00161 OptSpecifier Id2, OptSpecifier Id3, 00162 OptSpecifier Id4, OptSpecifier Id5, 00163 OptSpecifier Id6) const { 00164 Arg *Res = nullptr; 00165 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00166 if ((*it)->getOption().matches(Id0) || 00167 (*it)->getOption().matches(Id1) || 00168 (*it)->getOption().matches(Id2) || 00169 (*it)->getOption().matches(Id3) || 00170 (*it)->getOption().matches(Id4) || 00171 (*it)->getOption().matches(Id5) || 00172 (*it)->getOption().matches(Id6)) { 00173 Res = *it; 00174 Res->claim(); 00175 } 00176 } 00177 00178 return Res; 00179 } 00180 00181 Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1, 00182 OptSpecifier Id2, OptSpecifier Id3, 00183 OptSpecifier Id4, OptSpecifier Id5, 00184 OptSpecifier Id6, OptSpecifier Id7) const { 00185 Arg *Res = nullptr; 00186 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 00187 if ((*it)->getOption().matches(Id0) || 00188 (*it)->getOption().matches(Id1) || 00189 (*it)->getOption().matches(Id2) || 00190 (*it)->getOption().matches(Id3) || 00191 (*it)->getOption().matches(Id4) || 00192 (*it)->getOption().matches(Id5) || 00193 (*it)->getOption().matches(Id6) || 00194 (*it)->getOption().matches(Id7)) { 00195 Res = *it; 00196 Res->claim(); 00197 } 00198 } 00199 00200 return Res; 00201 } 00202 00203 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { 00204 if (Arg *A = getLastArg(Pos, Neg)) 00205 return A->getOption().matches(Pos); 00206 return Default; 00207 } 00208 00209 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, 00210 bool Default) const { 00211 if (Arg *A = getLastArg(Pos, PosAlias, Neg)) 00212 return A->getOption().matches(Pos) || A->getOption().matches(PosAlias); 00213 return Default; 00214 } 00215 00216 StringRef ArgList::getLastArgValue(OptSpecifier Id, 00217 StringRef Default) const { 00218 if (Arg *A = getLastArg(Id)) 00219 return A->getValue(); 00220 return Default; 00221 } 00222 00223 std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const { 00224 SmallVector<const char *, 16> Values; 00225 AddAllArgValues(Values, Id); 00226 return std::vector<std::string>(Values.begin(), Values.end()); 00227 } 00228 00229 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const { 00230 if (Arg *A = getLastArg(Id)) { 00231 A->claim(); 00232 A->render(*this, Output); 00233 } 00234 } 00235 00236 void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0, 00237 OptSpecifier Id1) const { 00238 if (Arg *A = getLastArg(Id0, Id1)) { 00239 A->claim(); 00240 A->render(*this, Output); 00241 } 00242 } 00243 00244 void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, 00245 OptSpecifier Id1, OptSpecifier Id2) const { 00246 for (auto Arg: filtered(Id0, Id1, Id2)) { 00247 Arg->claim(); 00248 Arg->render(*this, Output); 00249 } 00250 } 00251 00252 void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, 00253 OptSpecifier Id1, OptSpecifier Id2) const { 00254 for (auto Arg : filtered(Id0, Id1, Id2)) { 00255 Arg->claim(); 00256 for (unsigned i = 0, e = Arg->getNumValues(); i != e; ++i) 00257 Output.push_back(Arg->getValue(i)); 00258 } 00259 } 00260 00261 void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, 00262 const char *Translation, 00263 bool Joined) const { 00264 for (auto Arg: filtered(Id0)) { 00265 Arg->claim(); 00266 00267 if (Joined) { 00268 Output.push_back(MakeArgString(StringRef(Translation) + 00269 Arg->getValue(0))); 00270 } else { 00271 Output.push_back(Translation); 00272 Output.push_back(Arg->getValue(0)); 00273 } 00274 } 00275 } 00276 00277 void ArgList::ClaimAllArgs(OptSpecifier Id0) const { 00278 for (auto Arg : filtered(Id0)) 00279 Arg->claim(); 00280 } 00281 00282 void ArgList::ClaimAllArgs() const { 00283 for (const_iterator it = begin(), ie = end(); it != ie; ++it) 00284 if (!(*it)->isClaimed()) 00285 (*it)->claim(); 00286 } 00287 00288 const char *ArgList::MakeArgString(const Twine &T) const { 00289 SmallString<256> Str; 00290 return MakeArgString(T.toStringRef(Str)); 00291 } 00292 00293 const char *ArgList::GetOrMakeJoinedArgString(unsigned Index, 00294 StringRef LHS, 00295 StringRef RHS) const { 00296 StringRef Cur = getArgString(Index); 00297 if (Cur.size() == LHS.size() + RHS.size() && 00298 Cur.startswith(LHS) && Cur.endswith(RHS)) 00299 return Cur.data(); 00300 00301 return MakeArgString(LHS + RHS); 00302 } 00303 00304 // 00305 00306 InputArgList::InputArgList(const char* const *ArgBegin, 00307 const char* const *ArgEnd) 00308 : NumInputArgStrings(ArgEnd - ArgBegin) { 00309 ArgStrings.append(ArgBegin, ArgEnd); 00310 } 00311 00312 InputArgList::~InputArgList() { 00313 // An InputArgList always owns its arguments. 00314 for (iterator it = begin(), ie = end(); it != ie; ++it) 00315 delete *it; 00316 } 00317 00318 unsigned InputArgList::MakeIndex(StringRef String0) const { 00319 unsigned Index = ArgStrings.size(); 00320 00321 // Tuck away so we have a reliable const char *. 00322 SynthesizedStrings.push_back(String0); 00323 ArgStrings.push_back(SynthesizedStrings.back().c_str()); 00324 00325 return Index; 00326 } 00327 00328 unsigned InputArgList::MakeIndex(StringRef String0, 00329 StringRef String1) const { 00330 unsigned Index0 = MakeIndex(String0); 00331 unsigned Index1 = MakeIndex(String1); 00332 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!"); 00333 (void) Index1; 00334 return Index0; 00335 } 00336 00337 const char *InputArgList::MakeArgString(StringRef Str) const { 00338 return getArgString(MakeIndex(Str)); 00339 } 00340 00341 // 00342 00343 DerivedArgList::DerivedArgList(const InputArgList &_BaseArgs) 00344 : BaseArgs(_BaseArgs) { 00345 } 00346 00347 DerivedArgList::~DerivedArgList() {} 00348 00349 const char *DerivedArgList::MakeArgString(StringRef Str) const { 00350 return BaseArgs.MakeArgString(Str); 00351 } 00352 00353 void DerivedArgList::AddSynthesizedArg(Arg *A) { 00354 SynthesizedArgs.push_back(std::unique_ptr<Arg>(A)); 00355 } 00356 00357 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const { 00358 SynthesizedArgs.push_back( 00359 make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), 00360 BaseArgs.MakeIndex(Opt.getName()), BaseArg)); 00361 return SynthesizedArgs.back().get(); 00362 } 00363 00364 Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt, 00365 StringRef Value) const { 00366 unsigned Index = BaseArgs.MakeIndex(Value); 00367 SynthesizedArgs.push_back( 00368 make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), 00369 Index, BaseArgs.getArgString(Index), BaseArg)); 00370 return SynthesizedArgs.back().get(); 00371 } 00372 00373 Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt, 00374 StringRef Value) const { 00375 unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value); 00376 SynthesizedArgs.push_back( 00377 make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), 00378 Index, BaseArgs.getArgString(Index + 1), BaseArg)); 00379 return SynthesizedArgs.back().get(); 00380 } 00381 00382 Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt, 00383 StringRef Value) const { 00384 unsigned Index = BaseArgs.MakeIndex(Opt.getName().str() + Value.str()); 00385 SynthesizedArgs.push_back(make_unique<Arg>( 00386 Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index, 00387 BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg)); 00388 return SynthesizedArgs.back().get(); 00389 }