LLVM API Documentation

ArgList.cpp
Go to the documentation of this file.
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 }