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