LCOV - code coverage report
Current view: top level - lib/Option - ArgList.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 134 151 88.7 %
Date: 2017-09-14 15:23:50 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/Option/Arg.h"
      17             : #include "llvm/Option/ArgList.h"
      18             : #include "llvm/Option/Option.h"
      19             : #include "llvm/Option/OptSpecifier.h"
      20             : #include "llvm/Support/Compiler.h"
      21             : #include "llvm/Support/Debug.h"
      22             : #include "llvm/Support/raw_ostream.h"
      23             : #include <algorithm>
      24             : #include <cassert>
      25             : #include <memory>
      26             : #include <string>
      27             : #include <utility>
      28             : #include <vector>
      29             : 
      30             : using namespace llvm;
      31             : using namespace llvm::opt;
      32             : 
      33     1692365 : void ArgList::append(Arg *A) {
      34     1692365 :   Args.push_back(A);
      35             : 
      36             :   // Update ranges for the option and all of its groups.
      37     7788482 :   for (Option O = A->getOption().getUnaliasedOption(); O.isValid();
      38             :        O = O.getGroup()) {
      39             :     auto &R =
      40    22018760 :         OptRanges.insert(std::make_pair(O.getID(), emptyRange())).first->second;
      41    13211256 :     R.first = std::min<unsigned>(R.first, Args.size() - 1);
      42     8807504 :     R.second = Args.size();
      43             :   }
      44     1692365 : }
      45             : 
      46         180 : void ArgList::eraseArg(OptSpecifier Id) {
      47             :   // Zero out the removed entries but keep them around so that we don't
      48             :   // need to invalidate OptRanges.
      49         564 :   for (Arg *const &A : filtered(Id)) {
      50             :     // Avoid the need for a non-const filtered iterator variant.
      51          48 :     Arg **ArgsBegin = Args.data();
      52          24 :     ArgsBegin[&A - ArgsBegin] = nullptr;
      53             :   }
      54         360 :   OptRanges.erase(Id.getID());
      55         180 : }
      56             : 
      57             : ArgList::OptRange
      58    16171092 : ArgList::getRange(std::initializer_list<OptSpecifier> Ids) const {
      59    16171092 :   OptRange R = emptyRange();
      60    53179562 :   for (auto Id : Ids) {
      61    20837378 :     auto I = OptRanges.find(Id.getID());
      62    41674756 :     if (I != OptRanges.end()) {
      63      749262 :       R.first = std::min(R.first, I->second.first);
      64      749262 :       R.second = std::max(R.second, I->second.second);
      65             :     }
      66             :   }
      67             :   // Map an empty {-1, 0} range to {0, 0} so it can be used to form iterators.
      68    16171092 :   if (R.first == -1u)
      69    15800186 :     R.first = 0;
      70    16171092 :   return R;
      71             : }
      72             : 
      73     1530829 : bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
      74     1530829 :   if (Arg *A = getLastArg(Pos, Neg))
      75       16214 :     return A->getOption().matches(Pos);
      76             :   return Default;
      77             : }
      78             : 
      79       54594 : bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
      80             :                       bool Default) const {
      81       54594 :   if (Arg *A = getLastArg(Pos, PosAlias, Neg))
      82         810 :     return A->getOption().matches(Pos) || A->getOption().matches(PosAlias);
      83             :   return Default;
      84             : }
      85             : 
      86      990113 : StringRef ArgList::getLastArgValue(OptSpecifier Id, StringRef Default) const {
      87      990113 :   if (Arg *A = getLastArg(Id))
      88      102010 :     return A->getValue();
      89      939108 :   return Default;
      90             : }
      91             : 
      92      592011 : std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
      93     1184022 :   SmallVector<const char *, 16> Values;
      94     1184022 :   AddAllArgValues(Values, Id);
      95     3552066 :   return std::vector<std::string>(Values.begin(), Values.end());
      96             : }
      97             : 
      98      583797 : void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
      99      583797 :   if (Arg *A = getLastArg(Id)) {
     100        1142 :     A->claim();
     101        1142 :     A->render(*this, Output);
     102             :   }
     103      583797 : }
     104             : 
     105       29252 : void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0,
     106             :                          OptSpecifier Id1) const {
     107       29252 :   if (Arg *A = getLastArg(Id0, Id1)) {
     108         111 :     A->claim();
     109         111 :     A->render(*this, Output);
     110             :   }
     111       29252 : }
     112             : 
     113       10781 : void ArgList::AddAllArgsExcept(ArgStringList &Output,
     114             :                                ArrayRef<OptSpecifier> Ids,
     115             :                                ArrayRef<OptSpecifier> ExcludeIds) const {
     116      395052 :   for (const Arg *Arg : *this) {
     117      362709 :     bool Excluded = false;
     118      725472 :     for (OptSpecifier Id : ExcludeIds) {
     119          55 :       if (Arg->getOption().matches(Id)) {
     120             :         Excluded = true;
     121             :         break;
     122             :       }
     123             :     }
     124      362709 :     if (!Excluded) {
     125     1039711 :       for (OptSpecifier Id : Ids) {
     126      615307 :         if (Arg->getOption().matches(Id)) {
     127      301012 :           Arg->claim();
     128      301012 :           Arg->render(*this, Output);
     129      301012 :           break;
     130             :         }
     131             :       }
     132             :     }
     133             :   }
     134       10781 : }
     135             : 
     136             : /// This is a nicer interface when you don't have a list of Ids to exclude.
     137       10774 : void ArgList::AddAllArgs(ArgStringList &Output,
     138             :                          ArrayRef<OptSpecifier> Ids) const {
     139       10774 :   ArrayRef<OptSpecifier> Exclude = None;
     140       10774 :   AddAllArgsExcept(Output, Ids, Exclude);
     141       10774 : }
     142             : 
     143             : /// This 3-opt variant of AddAllArgs could be eliminated in favor of one
     144             : /// that accepts a single specifier, given the above which accepts any number.
     145      108703 : void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
     146             :                          OptSpecifier Id1, OptSpecifier Id2) const {
     147      327633 :   for (auto Arg: filtered(Id0, Id1, Id2)) {
     148        1524 :     Arg->claim();
     149        1524 :     Arg->render(*this, Output);
     150             :   }
     151      108703 : }
     152             : 
     153      615552 : void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
     154             :                               OptSpecifier Id1, OptSpecifier Id2) const {
     155     1869924 :   for (auto Arg : filtered(Id0, Id1, Id2)) {
     156       23268 :     Arg->claim();
     157       23268 :     const auto &Values = Arg->getValues();
     158       69804 :     Output.append(Values.begin(), Values.end());
     159             :   }
     160      615552 : }
     161             : 
     162        5450 : void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
     163             :                                    const char *Translation,
     164             :                                    bool Joined) const {
     165       16350 :   for (auto Arg: filtered(Id0)) {
     166           0 :     Arg->claim();
     167             : 
     168           0 :     if (Joined) {
     169           0 :       Output.push_back(MakeArgString(StringRef(Translation) +
     170           0 :                                      Arg->getValue(0)));
     171             :     } else {
     172           0 :       Output.push_back(Translation);
     173           0 :       Output.push_back(Arg->getValue(0));
     174             :     }
     175             :   }
     176        5450 : }
     177             : 
     178      177737 : void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
     179      835365 :   for (auto *Arg : filtered(Id0))
     180      302154 :     Arg->claim();
     181      177737 : }
     182             : 
     183          13 : void ArgList::ClaimAllArgs() const {
     184         118 :   for (auto *Arg : *this)
     185          79 :     if (!Arg->isClaimed())
     186             :       Arg->claim();
     187          13 : }
     188             : 
     189        5057 : const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
     190             :                                               StringRef LHS,
     191             :                                               StringRef RHS) const {
     192       10114 :   StringRef Cur = getArgString(Index);
     193       15171 :   if (Cur.size() == LHS.size() + RHS.size() &&
     194        5057 :       Cur.startswith(LHS) && Cur.endswith(RHS))
     195             :     return Cur.data();
     196             : 
     197         342 :   return MakeArgString(LHS + RHS);
     198             : }
     199             : 
     200           0 : void ArgList::print(raw_ostream &O) const {
     201           0 :   for (Arg *A : *this) {
     202           0 :     O << "* ";
     203           0 :     A->print(O);
     204             :   }
     205           0 : }
     206             : 
     207             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     208             : LLVM_DUMP_METHOD void ArgList::dump() const { print(dbgs()); }
     209             : #endif
     210             : 
     211       57005 : void InputArgList::releaseMemory() {
     212             :   // An InputArgList always owns its arguments.
     213     1492487 :   for (Arg *A : *this)
     214     1321472 :     delete A;
     215       57005 : }
     216             : 
     217       44540 : InputArgList::InputArgList(const char* const *ArgBegin,
     218       44540 :                            const char* const *ArgEnd)
     219      178160 :   : NumInputArgStrings(ArgEnd - ArgBegin) {
     220       44540 :   ArgStrings.append(ArgBegin, ArgEnd);
     221       44540 : }
     222             : 
     223      485804 : unsigned InputArgList::MakeIndex(StringRef String0) const {
     224      971608 :   unsigned Index = ArgStrings.size();
     225             : 
     226             :   // Tuck away so we have a reliable const char *.
     227     1457412 :   SynthesizedStrings.push_back(String0);
     228      971608 :   ArgStrings.push_back(SynthesizedStrings.back().c_str());
     229             : 
     230      485804 :   return Index;
     231             : }
     232             : 
     233          43 : unsigned InputArgList::MakeIndex(StringRef String0,
     234             :                                  StringRef String1) const {
     235          43 :   unsigned Index0 = MakeIndex(String0);
     236          43 :   unsigned Index1 = MakeIndex(String1);
     237             :   assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
     238             :   (void) Index1;
     239          43 :   return Index0;
     240             : }
     241             : 
     242      483441 : const char *InputArgList::MakeArgStringRef(StringRef Str) const {
     243      966882 :   return getArgString(MakeIndex(Str));
     244             : }
     245             : 
     246       12187 : DerivedArgList::DerivedArgList(const InputArgList &BaseArgs)
     247       36561 :     : BaseArgs(BaseArgs) {}
     248             : 
     249      464039 : const char *DerivedArgList::MakeArgStringRef(StringRef Str) const {
     250      928078 :   return BaseArgs.MakeArgString(Str);
     251             : }
     252             : 
     253         459 : void DerivedArgList::AddSynthesizedArg(Arg *A) {
     254         918 :   SynthesizedArgs.push_back(std::unique_ptr<Arg>(A));
     255         459 : }
     256             : 
     257         443 : Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
     258         886 :   SynthesizedArgs.push_back(
     259        2658 :       make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
     260         886 :                        BaseArgs.MakeIndex(Opt.getName()), BaseArg));
     261        1329 :   return SynthesizedArgs.back().get();
     262             : }
     263             : 
     264           0 : Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
     265             :                                        StringRef Value) const {
     266           0 :   unsigned Index = BaseArgs.MakeIndex(Value);
     267           0 :   SynthesizedArgs.push_back(
     268           0 :       make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
     269           0 :                        Index, BaseArgs.getArgString(Index), BaseArg));
     270           0 :   return SynthesizedArgs.back().get();
     271             : }
     272             : 
     273          43 : Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
     274             :                                      StringRef Value) const {
     275          86 :   unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
     276          86 :   SynthesizedArgs.push_back(
     277         258 :       make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
     278          86 :                        Index, BaseArgs.getArgString(Index + 1), BaseArg));
     279         129 :   return SynthesizedArgs.back().get();
     280             : }
     281             : 
     282        1372 : Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
     283             :                                    StringRef Value) const {
     284        9604 :   unsigned Index = BaseArgs.MakeIndex((Opt.getName() + Value).str());
     285        2744 :   SynthesizedArgs.push_back(make_unique<Arg>(
     286        8232 :       Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index,
     287        4116 :       BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg));
     288        4116 :   return SynthesizedArgs.back().get();
     289             : }

Generated by: LCOV version 1.13