LCOV - code coverage report
Current view: top level - lib/Option - ArgList.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 123 138 89.1 %
Date: 2018-07-13 00:08:38 Functions: 28 30 93.3 %
Legend: Lines: hit not hit

          Line data    Source code
       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/ADT/ArrayRef.h"
      11             : #include "llvm/ADT/None.h"
      12             : #include "llvm/ADT/SmallVector.h"
      13             : #include "llvm/ADT/STLExtras.h"
      14             : #include "llvm/ADT/StringRef.h"
      15             : #include "llvm/ADT/Twine.h"
      16             : #include "llvm/Config/llvm-config.h"
      17             : #include "llvm/Option/Arg.h"
      18             : #include "llvm/Option/ArgList.h"
      19             : #include "llvm/Option/Option.h"
      20             : #include "llvm/Option/OptSpecifier.h"
      21             : #include "llvm/Support/Compiler.h"
      22             : #include "llvm/Support/Debug.h"
      23             : #include "llvm/Support/raw_ostream.h"
      24             : #include <algorithm>
      25             : #include <cassert>
      26             : #include <memory>
      27             : #include <string>
      28             : #include <utility>
      29             : #include <vector>
      30             : 
      31             : using namespace llvm;
      32             : using namespace llvm::opt;
      33             : 
      34     2176811 : void ArgList::append(Arg *A) {
      35     2176811 :   Args.push_back(A);
      36             : 
      37             :   // Update ranges for the option and all of its groups.
      38     9858675 :   for (Option O = A->getOption().getUnaliasedOption(); O.isValid();
      39             :        O = O.getGroup()) {
      40             :     auto &R =
      41    16515159 :         OptRanges.insert(std::make_pair(O.getID(), emptyRange())).first->second;
      42    11010106 :     R.first = std::min<unsigned>(R.first, Args.size() - 1);
      43     5505053 :     R.second = Args.size();
      44             :   }
      45     2176811 : }
      46             : 
      47         245 : void ArgList::eraseArg(OptSpecifier Id) {
      48             :   // Zero out the removed entries but keep them around so that we don't
      49             :   // need to invalidate OptRanges.
      50         508 :   for (Arg *const &A : filtered(Id)) {
      51             :     // Avoid the need for a non-const filtered iterator variant.
      52             :     Arg **ArgsBegin = Args.data();
      53          18 :     ArgsBegin[&A - ArgsBegin] = nullptr;
      54             :   }
      55         490 :   OptRanges.erase(Id.getID());
      56         245 : }
      57             : 
      58             : ArgList::OptRange
      59    26990213 : ArgList::getRange(std::initializer_list<OptSpecifier> Ids) const {
      60    26990213 :   OptRange R = emptyRange();
      61    97329707 :   for (auto Id : Ids) {
      62    35171856 :     auto I = OptRanges.find(Id.getID());
      63    35169747 :     if (I != OptRanges.end()) {
      64     1439860 :       R.first = std::min(R.first, I->second.first);
      65     1439860 :       R.second = std::max(R.second, I->second.second);
      66             :     }
      67             :   }
      68             :   // Map an empty {-1, 0} range to {0, 0} so it can be used to form iterators.
      69    26988104 :   if (R.first == -1u)
      70    26276656 :     R.first = 0;
      71    26988104 :   return R;
      72             : }
      73             : 
      74     2963808 : bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
      75     2963808 :   if (Arg *A = getLastArg(Pos, Neg))
      76       39332 :     return A->getOption().matches(Pos);
      77             :   return Default;
      78             : }
      79             : 
      80      100964 : bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
      81             :                       bool Default) const {
      82      100964 :   if (Arg *A = getLastArg(Pos, PosAlias, Neg))
      83        1227 :     return A->getOption().matches(Pos) || A->getOption().matches(PosAlias);
      84             :   return Default;
      85             : }
      86             : 
      87     1593125 : StringRef ArgList::getLastArgValue(OptSpecifier Id, StringRef Default) const {
      88     1593125 :   if (Arg *A = getLastArg(Id))
      89       94825 :     return A->getValue();
      90     1498300 :   return Default;
      91             : }
      92             : 
      93      973465 : std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
      94             :   SmallVector<const char *, 16> Values;
      95      973465 :   AddAllArgValues(Values, Id);
      96      973465 :   return std::vector<std::string>(Values.begin(), Values.end());
      97             : }
      98             : 
      99      871365 : void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
     100      871365 :   if (Arg *A = getLastArg(Id)) {
     101             :     A->claim();
     102        1512 :     A->render(*this, Output);
     103             :   }
     104      871371 : }
     105             : 
     106      106951 : void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0,
     107             :                          OptSpecifier Id1) const {
     108      106951 :   if (Arg *A = getLastArg(Id0, Id1)) {
     109             :     A->claim();
     110         151 :     A->render(*this, Output);
     111             :   }
     112      106952 : }
     113             : 
     114       16266 : void ArgList::AddAllArgsExcept(ArgStringList &Output,
     115             :                                ArrayRef<OptSpecifier> Ids,
     116             :                                ArrayRef<OptSpecifier> ExcludeIds) const {
     117      430282 :   for (const Arg *Arg : *this) {
     118             :     bool Excluded = false;
     119      414123 :     for (OptSpecifier Id : ExcludeIds) {
     120          55 :       if (Arg->getOption().matches(Id)) {
     121             :         Excluded = true;
     122             :         break;
     123             :       }
     124             :     }
     125      414015 :     if (!Excluded) {
     126     1499362 :       for (OptSpecifier Id : Ids) {
     127      852771 :         if (Arg->getOption().matches(Id)) {
     128             :           Arg->claim();
     129      310098 :           Arg->render(*this, Output);
     130      310098 :           break;
     131             :         }
     132             :       }
     133             :     }
     134             :   }
     135       16267 : }
     136             : 
     137             : /// This is a nicer interface when you don't have a list of Ids to exclude.
     138       16260 : void ArgList::AddAllArgs(ArgStringList &Output,
     139             :                          ArrayRef<OptSpecifier> Ids) const {
     140             :   ArrayRef<OptSpecifier> Exclude = None;
     141       16260 :   AddAllArgsExcept(Output, Ids, Exclude);
     142       16260 : }
     143             : 
     144             : /// This 3-opt variant of AddAllArgs could be eliminated in favor of one
     145             : /// that accepts a single specifier, given the above which accepts any number.
     146      161969 : void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
     147             :                          OptSpecifier Id1, OptSpecifier Id2) const {
     148      325723 :   for (auto Arg: filtered(Id0, Id1, Id2)) {
     149             :     Arg->claim();
     150        1785 :     Arg->render(*this, Output);
     151             :   }
     152      161969 : }
     153             : 
     154     1009697 : void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
     155             :                               OptSpecifier Id1, OptSpecifier Id2) const {
     156     2055333 :   for (auto Arg : filtered(Id0, Id1, Id2)) {
     157             :     Arg->claim();
     158             :     const auto &Values = Arg->getValues();
     159       71878 :     Output.append(Values.begin(), Values.end());
     160             :   }
     161     1009697 : }
     162             : 
     163        7050 : void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
     164             :                                    const char *Translation,
     165             :                                    bool Joined) const {
     166       14100 :   for (auto Arg: filtered(Id0)) {
     167             :     Arg->claim();
     168             : 
     169           0 :     if (Joined) {
     170           0 :       Output.push_back(MakeArgString(StringRef(Translation) +
     171             :                                      Arg->getValue(0)));
     172             :     } else {
     173           0 :       Output.push_back(Translation);
     174           0 :       Output.push_back(Arg->getValue(0));
     175             :     }
     176             :   }
     177        7050 : }
     178             : 
     179      280962 : void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
     180      882078 :   for (auto *Arg : filtered(Id0))
     181             :     Arg->claim();
     182      280965 : }
     183             : 
     184          17 : void ArgList::ClaimAllArgs() const {
     185         111 :   for (auto *Arg : *this)
     186          94 :     if (!Arg->isClaimed())
     187             :       Arg->claim();
     188          17 : }
     189             : 
     190        9009 : const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
     191             :                                               StringRef LHS,
     192             :                                               StringRef RHS) const {
     193        9009 :   StringRef Cur = getArgString(Index);
     194        9009 :   if (Cur.size() == LHS.size() + RHS.size() &&
     195        9009 :       Cur.startswith(LHS) && Cur.endswith(RHS))
     196             :     return Cur.data();
     197             : 
     198         291 :   return MakeArgString(LHS + RHS);
     199             : }
     200             : 
     201           0 : void ArgList::print(raw_ostream &O) const {
     202           0 :   for (Arg *A : *this) {
     203           0 :     O << "* ";
     204           0 :     A->print(O);
     205             :   }
     206           0 : }
     207             : 
     208             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     209             : LLVM_DUMP_METHOD void ArgList::dump() const { print(dbgs()); }
     210             : #endif
     211             : 
     212      125648 : void InputArgList::releaseMemory() {
     213             :   // An InputArgList always owns its arguments.
     214     1863152 :   for (Arg *A : *this)
     215     1737504 :     delete A;
     216      125648 : }
     217             : 
     218       70463 : InputArgList::InputArgList(const char* const *ArgBegin,
     219       70463 :                            const char* const *ArgEnd)
     220      140926 :   : NumInputArgStrings(ArgEnd - ArgBegin) {
     221       70463 :   ArgStrings.append(ArgBegin, ArgEnd);
     222       70463 : }
     223             : 
     224      642079 : unsigned InputArgList::MakeIndex(StringRef String0) const {
     225      642079 :   unsigned Index = ArgStrings.size();
     226             : 
     227             :   // Tuck away so we have a reliable const char *.
     228     1926236 :   SynthesizedStrings.push_back(String0);
     229     1284156 :   ArgStrings.push_back(SynthesizedStrings.back().c_str());
     230             : 
     231      642078 :   return Index;
     232             : }
     233             : 
     234          11 : unsigned InputArgList::MakeIndex(StringRef String0,
     235             :                                  StringRef String1) const {
     236          11 :   unsigned Index0 = MakeIndex(String0);
     237          11 :   unsigned Index1 = MakeIndex(String1);
     238             :   assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
     239             :   (void) Index1;
     240          11 :   return Index0;
     241             : }
     242             : 
     243      639394 : const char *InputArgList::MakeArgStringRef(StringRef Str) const {
     244     1278787 :   return getArgString(MakeIndex(Str));
     245             : }
     246             : 
     247       19252 : DerivedArgList::DerivedArgList(const InputArgList &BaseArgs)
     248       38504 :     : BaseArgs(BaseArgs) {}
     249             : 
     250      608604 : const char *DerivedArgList::MakeArgStringRef(StringRef Str) const {
     251     1217208 :   return BaseArgs.MakeArgString(Str);
     252             : }
     253             : 
     254         482 : void DerivedArgList::AddSynthesizedArg(Arg *A) {
     255         964 :   SynthesizedArgs.push_back(std::unique_ptr<Arg>(A));
     256         482 : }
     257             : 
     258         556 : Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
     259        1112 :   SynthesizedArgs.push_back(
     260        2780 :       make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
     261        1112 :                        BaseArgs.MakeIndex(Opt.getName()), BaseArg));
     262        1112 :   return SynthesizedArgs.back().get();
     263             : }
     264             : 
     265           0 : Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
     266             :                                        StringRef Value) const {
     267           0 :   unsigned Index = BaseArgs.MakeIndex(Value);
     268           0 :   SynthesizedArgs.push_back(
     269           0 :       make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
     270           0 :                        Index, BaseArgs.getArgString(Index), BaseArg));
     271           0 :   return SynthesizedArgs.back().get();
     272             : }
     273             : 
     274          11 : Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
     275             :                                      StringRef Value) const {
     276          22 :   unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
     277          22 :   SynthesizedArgs.push_back(
     278          55 :       make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
     279          11 :                        Index, BaseArgs.getArgString(Index + 1), BaseArg));
     280          22 :   return SynthesizedArgs.back().get();
     281             : }
     282             : 
     283        1436 : Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
     284             :                                    StringRef Value) const {
     285        8616 :   unsigned Index = BaseArgs.MakeIndex((Opt.getName() + Value).str());
     286        2872 :   SynthesizedArgs.push_back(make_unique<Arg>(
     287        5744 :       Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index,
     288        4308 :       BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg));
     289        2872 :   return SynthesizedArgs.back().get();
     290             : }

Generated by: LCOV version 1.13