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-10-20 13:21:21 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     3456717 : void ArgList::append(Arg *A) {
      35     3456717 :   Args.push_back(A);
      36             : 
      37             :   // Update ranges for the option and all of its groups.
      38    15906744 :   for (Option O = A->getOption().getUnaliasedOption(); O.isValid();
      39             :        O = O.getGroup()) {
      40             :     auto &R =
      41    17986620 :         OptRanges.insert(std::make_pair(O.getID(), emptyRange())).first->second;
      42     8993310 :     R.first = std::min<unsigned>(R.first, Args.size() - 1);
      43     8993310 :     R.second = Args.size();
      44             :   }
      45     3456717 : }
      46             : 
      47        2115 : 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        4252 :   for (Arg *const &A : filtered(Id)) {
      51             :     // Avoid the need for a non-const filtered iterator variant.
      52             :     Arg **ArgsBegin = Args.data();
      53          22 :     ArgsBegin[&A - ArgsBegin] = nullptr;
      54             :   }
      55        2115 :   OptRanges.erase(Id.getID());
      56        2115 : }
      57             : 
      58             : ArgList::OptRange
      59    34165840 : ArgList::getRange(std::initializer_list<OptSpecifier> Ids) const {
      60    34165840 :   OptRange R = emptyRange();
      61    78951545 :   for (auto Id : Ids) {
      62    44785775 :     auto I = OptRanges.find(Id.getID());
      63    44785705 :     if (I != OptRanges.end()) {
      64     1032643 :       R.first = std::min(R.first, I->second.first);
      65     2064943 :       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    34165770 :   if (R.first == -1u)
      70    33146111 :     R.first = 0;
      71    34165770 :   return R;
      72             : }
      73             : 
      74     3942539 : bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
      75     3942539 :   if (Arg *A = getLastArg(Pos, Neg))
      76       40731 :     return A->getOption().matches(Pos);
      77             :   return Default;
      78             : }
      79             : 
      80      133311 : bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
      81             :                       bool Default) const {
      82      133311 :   if (Arg *A = getLastArg(Pos, PosAlias, Neg))
      83        2077 :     return A->getOption().matches(Pos) || A->getOption().matches(PosAlias);
      84             :   return Default;
      85             : }
      86             : 
      87     1943097 : StringRef ArgList::getLastArgValue(OptSpecifier Id, StringRef Default) const {
      88     1943097 :   if (Arg *A = getLastArg(Id))
      89      124240 :     return A->getValue();
      90     1818857 :   return Default;
      91             : }
      92             : 
      93     1146532 : std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
      94             :   SmallVector<const char *, 16> Values;
      95     1146532 :   AddAllArgValues(Values, Id);
      96     1146533 :   return std::vector<std::string>(Values.begin(), Values.end());
      97             : }
      98             : 
      99     1174205 : void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
     100     1174205 :   if (Arg *A = getLastArg(Id)) {
     101             :     A->claim();
     102        7941 :     A->render(*this, Output);
     103             :   }
     104     1174205 : }
     105             : 
     106      177284 : void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0,
     107             :                          OptSpecifier Id1) const {
     108      177284 :   if (Arg *A = getLastArg(Id0, Id1)) {
     109             :     A->claim();
     110         145 :     A->render(*this, Output);
     111             :   }
     112      177284 : }
     113             : 
     114       21115 : void ArgList::AddAllArgsExcept(ArgStringList &Output,
     115             :                                ArrayRef<OptSpecifier> Ids,
     116             :                                ArrayRef<OptSpecifier> ExcludeIds) const {
     117      646671 :   for (const Arg *Arg : *this) {
     118             :     bool Excluded = false;
     119      625610 :     for (OptSpecifier Id : ExcludeIds) {
     120          55 :       if (Arg->getOption().matches(Id)) {
     121             :         Excluded = true;
     122             :         break;
     123             :       }
     124             :     }
     125      625556 :     if (!Excluded) {
     126     1955355 :       for (OptSpecifier Id : Ids) {
     127     1698130 :         if (Arg->getOption().matches(Id)) {
     128             :           Arg->claim();
     129      368330 :           Arg->render(*this, Output);
     130      368330 :           break;
     131             :         }
     132             :       }
     133             :     }
     134             :   }
     135       21115 : }
     136             : 
     137             : /// This is a nicer interface when you don't have a list of Ids to exclude.
     138       21108 : void ArgList::AddAllArgs(ArgStringList &Output,
     139             :                          ArrayRef<OptSpecifier> Ids) const {
     140             :   ArrayRef<OptSpecifier> Exclude = None;
     141       21108 :   AddAllArgsExcept(Output, Ids, Exclude);
     142       21108 : }
     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      214947 : void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
     147             :                          OptSpecifier Id1, OptSpecifier Id2) const {
     148      553891 :   for (auto Arg: filtered(Id0, Id1, Id2)) {
     149             :     Arg->claim();
     150      123997 :     Arg->render(*this, Output);
     151             :   }
     152      214947 : }
     153             : 
     154     1197066 : void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
     155             :                               OptSpecifier Id1, OptSpecifier Id2) const {
     156     2434688 :   for (auto Arg : filtered(Id0, Id1, Id2)) {
     157             :     Arg->claim();
     158             :     const auto &Values = Arg->getValues();
     159       81110 :     Output.append(Values.begin(), Values.end());
     160             :   }
     161     1197067 : }
     162             : 
     163        6794 : void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
     164             :                                    const char *Translation,
     165             :                                    bool Joined) const {
     166       13588 :   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        6794 : }
     178             : 
     179      407316 : void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
     180     1179741 :   for (auto *Arg : filtered(Id0))
     181             :     Arg->claim();
     182      407316 : }
     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      185454 : const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
     191             :                                               StringRef LHS,
     192             :                                               StringRef RHS) const {
     193      185454 :   StringRef Cur = getArgString(Index);
     194      185454 :   if (Cur.size() == LHS.size() + RHS.size() &&
     195      185454 :       Cur.startswith(LHS) && Cur.endswith(RHS))
     196             :     return Cur.data();
     197             : 
     198         476 :   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      177066 : void InputArgList::releaseMemory() {
     213             :   // An InputArgList always owns its arguments.
     214     2875819 :   for (Arg *A : *this)
     215     2698753 :     delete A;
     216      177066 : }
     217             : 
     218       94160 : InputArgList::InputArgList(const char* const *ArgBegin,
     219       94160 :                            const char* const *ArgEnd)
     220       94160 :   : NumInputArgStrings(ArgEnd - ArgBegin) {
     221       94160 :   ArgStrings.append(ArgBegin, ArgEnd);
     222       94160 : }
     223             : 
     224      829272 : unsigned InputArgList::MakeIndex(StringRef String0) const {
     225      829272 :   unsigned Index = ArgStrings.size();
     226             : 
     227             :   // Tuck away so we have a reliable const char *.
     228     1658544 :   SynthesizedStrings.push_back(String0);
     229     1658544 :   ArgStrings.push_back(SynthesizedStrings.back().c_str());
     230             : 
     231      829272 :   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      826439 : const char *InputArgList::MakeArgStringRef(StringRef Str) const {
     244      826439 :   return getArgString(MakeIndex(Str));
     245             : }
     246             : 
     247       28503 : DerivedArgList::DerivedArgList(const InputArgList &BaseArgs)
     248       57006 :     : BaseArgs(BaseArgs) {}
     249             : 
     250      801517 : const char *DerivedArgList::MakeArgStringRef(StringRef Str) const {
     251     1603034 :   return BaseArgs.MakeArgString(Str);
     252             : }
     253             : 
     254         512 : void DerivedArgList::AddSynthesizedArg(Arg *A) {
     255        1024 :   SynthesizedArgs.push_back(std::unique_ptr<Arg>(A));
     256         512 : }
     257             : 
     258         614 : Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
     259         614 :   SynthesizedArgs.push_back(
     260        3070 :       make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
     261        1228 :                        BaseArgs.MakeIndex(Opt.getName()), BaseArg));
     262         614 :   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          11 :   SynthesizedArgs.push_back(
     278          55 :       make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
     279          11 :                        Index, BaseArgs.getArgString(Index + 1), BaseArg));
     280          11 :   return SynthesizedArgs.back().get();
     281             : }
     282             : 
     283        1496 : Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
     284             :                                    StringRef Value) const {
     285        2992 :   unsigned Index = BaseArgs.MakeIndex((Opt.getName() + Value).str());
     286        1496 :   SynthesizedArgs.push_back(make_unique<Arg>(
     287        4488 :       Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index,
     288        2992 :       BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg));
     289        1496 :   return SynthesizedArgs.back().get();
     290             : }

Generated by: LCOV version 1.13