Home | History | Annotate | Download | only in Option
      1 //===--- ArgList.h - Argument List Management -------------------*- C++ -*-===//
      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 #ifndef LLVM_OPTION_ARGLIST_H
     11 #define LLVM_OPTION_ARGLIST_H
     12 
     13 #include "llvm/ADT/SmallVector.h"
     14 #include "llvm/ADT/SmallString.h"
     15 #include "llvm/ADT/StringRef.h"
     16 #include "llvm/ADT/Twine.h"
     17 #include "llvm/Option/Arg.h"
     18 #include "llvm/Option/OptSpecifier.h"
     19 #include "llvm/Option/Option.h"
     20 #include <list>
     21 #include <memory>
     22 #include <string>
     23 #include <vector>
     24 
     25 namespace llvm {
     26 namespace opt {
     27 class ArgList;
     28 class Option;
     29 
     30 /// arg_iterator - Iterates through arguments stored inside an ArgList.
     31 class arg_iterator {
     32   /// The current argument.
     33   SmallVectorImpl<Arg*>::const_iterator Current;
     34 
     35   /// The argument list we are iterating over.
     36   const ArgList &Args;
     37 
     38   /// Optional filters on the arguments which will be match. Most clients
     39   /// should never want to iterate over arguments without filters, so we won't
     40   /// bother to factor this into two separate iterator implementations.
     41   //
     42   // FIXME: Make efficient; the idea is to provide efficient iteration over
     43   // all arguments which match a particular id and then just provide an
     44   // iterator combinator which takes multiple iterators which can be
     45   // efficiently compared and returns them in order.
     46   OptSpecifier Id0, Id1, Id2;
     47 
     48   void SkipToNextArg();
     49 
     50 public:
     51   typedef Arg * const *                 value_type;
     52   typedef Arg * const &                 reference;
     53   typedef Arg * const *                 pointer;
     54   typedef std::forward_iterator_tag   iterator_category;
     55   typedef std::ptrdiff_t              difference_type;
     56 
     57   arg_iterator(SmallVectorImpl<Arg *>::const_iterator it, const ArgList &Args,
     58                OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
     59                OptSpecifier Id2 = 0U)
     60       : Current(it), Args(Args), Id0(Id0), Id1(Id1), Id2(Id2) {
     61     SkipToNextArg();
     62   }
     63 
     64   operator const Arg*() { return *Current; }
     65   reference operator*() const { return *Current; }
     66   pointer operator->() const { return Current; }
     67 
     68   arg_iterator &operator++() {
     69     ++Current;
     70     SkipToNextArg();
     71     return *this;
     72   }
     73 
     74   arg_iterator operator++(int) {
     75     arg_iterator tmp(*this);
     76     ++(*this);
     77     return tmp;
     78   }
     79 
     80   friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
     81     return LHS.Current == RHS.Current;
     82   }
     83   friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
     84     return !(LHS == RHS);
     85   }
     86 };
     87 
     88 /// ArgList - Ordered collection of driver arguments.
     89 ///
     90 /// The ArgList class manages a list of Arg instances as well as
     91 /// auxiliary data and convenience methods to allow Tools to quickly
     92 /// check for the presence of Arg instances for a particular Option
     93 /// and to iterate over groups of arguments.
     94 class ArgList {
     95 public:
     96   typedef SmallVector<Arg*, 16> arglist_type;
     97   typedef arglist_type::iterator iterator;
     98   typedef arglist_type::const_iterator const_iterator;
     99   typedef arglist_type::reverse_iterator reverse_iterator;
    100   typedef arglist_type::const_reverse_iterator const_reverse_iterator;
    101 
    102 private:
    103   /// The internal list of arguments.
    104   arglist_type Args;
    105 
    106 protected:
    107   // Make the default special members protected so they won't be used to slice
    108   // derived objects, but can still be used by derived objects to implement
    109   // their own special members.
    110   ArgList() = default;
    111   // Explicit move operations to ensure the container is cleared post-move
    112   // otherwise it could lead to a double-delete in the case of moving of an
    113   // InputArgList which deletes the contents of the container. If we could fix
    114   // up the ownership here (delegate storage/ownership to the derived class so
    115   // it can be a container of unique_ptr) this would be simpler.
    116   ArgList(ArgList &&RHS) : Args(std::move(RHS.Args)) { RHS.Args.clear(); }
    117   ArgList &operator=(ArgList &&RHS) {
    118     Args = std::move(RHS.Args);
    119     RHS.Args.clear();
    120     return *this;
    121   }
    122   // Protect the dtor to ensure this type is never destroyed polymorphically.
    123   ~ArgList() = default;
    124 
    125 public:
    126 
    127   /// @name Arg Access
    128   /// @{
    129 
    130   /// append - Append \p A to the arg list.
    131   void append(Arg *A);
    132 
    133   arglist_type &getArgs() { return Args; }
    134   const arglist_type &getArgs() const { return Args; }
    135 
    136   unsigned size() const { return Args.size(); }
    137 
    138   /// @}
    139   /// @name Arg Iteration
    140   /// @{
    141 
    142   iterator begin() { return Args.begin(); }
    143   iterator end() { return Args.end(); }
    144 
    145   reverse_iterator rbegin() { return Args.rbegin(); }
    146   reverse_iterator rend() { return Args.rend(); }
    147 
    148   const_iterator begin() const { return Args.begin(); }
    149   const_iterator end() const { return Args.end(); }
    150 
    151   const_reverse_iterator rbegin() const { return Args.rbegin(); }
    152   const_reverse_iterator rend() const { return Args.rend(); }
    153 
    154   arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
    155                               OptSpecifier Id2 = 0U) const {
    156     return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
    157   }
    158   arg_iterator filtered_end() const {
    159     return arg_iterator(Args.end(), *this);
    160   }
    161 
    162   iterator_range<arg_iterator> filtered(OptSpecifier Id0 = 0U,
    163                                         OptSpecifier Id1 = 0U,
    164                                         OptSpecifier Id2 = 0U) const {
    165     return make_range(filtered_begin(Id0, Id1, Id2), filtered_end());
    166   }
    167 
    168   /// @}
    169   /// @name Arg Removal
    170   /// @{
    171 
    172   /// eraseArg - Remove any option matching \p Id.
    173   void eraseArg(OptSpecifier Id);
    174 
    175   /// @}
    176   /// @name Arg Access
    177   /// @{
    178 
    179   /// hasArg - Does the arg list contain any option matching \p Id.
    180   ///
    181   /// \p Claim Whether the argument should be claimed, if it exists.
    182   bool hasArgNoClaim(OptSpecifier Id) const {
    183     return getLastArgNoClaim(Id) != nullptr;
    184   }
    185   bool hasArg(OptSpecifier Id) const {
    186     return getLastArg(Id) != nullptr;
    187   }
    188   bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
    189     return getLastArg(Id0, Id1) != nullptr;
    190   }
    191   bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
    192     return getLastArg(Id0, Id1, Id2) != nullptr;
    193   }
    194 
    195   /// getLastArg - Return the last argument matching \p Id, or null.
    196   ///
    197   /// \p Claim Whether the argument should be claimed, if it exists.
    198   Arg *getLastArgNoClaim(OptSpecifier Id) const;
    199   Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1) const;
    200   Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1,
    201                          OptSpecifier Id2) const;
    202   Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
    203                          OptSpecifier Id3) const;
    204   Arg *getLastArg(OptSpecifier Id) const;
    205   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
    206   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
    207   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
    208                   OptSpecifier Id3) const;
    209   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
    210                   OptSpecifier Id3, OptSpecifier Id4) const;
    211   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
    212                   OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5) const;
    213   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
    214                   OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
    215                   OptSpecifier Id6) const;
    216   Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
    217                   OptSpecifier Id3, OptSpecifier Id4, OptSpecifier Id5,
    218                   OptSpecifier Id6, OptSpecifier Id7) const;
    219 
    220   /// getArgString - Return the input argument string at \p Index.
    221   virtual const char *getArgString(unsigned Index) const = 0;
    222 
    223   /// getNumInputArgStrings - Return the number of original argument strings,
    224   /// which are guaranteed to be the first strings in the argument string
    225   /// list.
    226   virtual unsigned getNumInputArgStrings() const = 0;
    227 
    228   /// @}
    229   /// @name Argument Lookup Utilities
    230   /// @{
    231 
    232   /// getLastArgValue - Return the value of the last argument, or a default.
    233   StringRef getLastArgValue(OptSpecifier Id,
    234                                   StringRef Default = "") const;
    235 
    236   /// getAllArgValues - Get the values of all instances of the given argument
    237   /// as strings.
    238   std::vector<std::string> getAllArgValues(OptSpecifier Id) const;
    239 
    240   /// @}
    241   /// @name Translation Utilities
    242   /// @{
    243 
    244   /// hasFlag - Given an option \p Pos and its negative form \p Neg, return
    245   /// true if the option is present, false if the negation is present, and
    246   /// \p Default if neither option is given. If both the option and its
    247   /// negation are present, the last one wins.
    248   bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
    249 
    250   /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative
    251   /// form \p Neg, return true if the option or its alias is present, false if
    252   /// the negation is present, and \p Default if none of the options are
    253   /// given. If multiple options are present, the last one wins.
    254   bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
    255                bool Default = true) const;
    256 
    257   /// AddLastArg - Render only the last argument match \p Id0, if present.
    258   void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
    259   void AddLastArg(ArgStringList &Output, OptSpecifier Id0,
    260                   OptSpecifier Id1) const;
    261 
    262   /// AddAllArgs - Render all arguments matching any of the given ids.
    263   void AddAllArgs(ArgStringList &Output, ArrayRef<OptSpecifier> Ids) const;
    264 
    265   /// AddAllArgs - Render all arguments matching the given ids.
    266   void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
    267                   OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
    268 
    269   /// AddAllArgValues - Render the argument values of all arguments
    270   /// matching the given ids.
    271   void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
    272                         OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
    273 
    274   /// AddAllArgsTranslated - Render all the arguments matching the
    275   /// given ids, but forced to separate args and using the provided
    276   /// name instead of the first option value.
    277   ///
    278   /// \param Joined - If true, render the argument as joined with
    279   /// the option specifier.
    280   void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
    281                             const char *Translation,
    282                             bool Joined = false) const;
    283 
    284   /// ClaimAllArgs - Claim all arguments which match the given
    285   /// option id.
    286   void ClaimAllArgs(OptSpecifier Id0) const;
    287 
    288   /// ClaimAllArgs - Claim all arguments.
    289   ///
    290   void ClaimAllArgs() const;
    291 
    292   /// @}
    293   /// @name Arg Synthesis
    294   /// @{
    295 
    296   /// Construct a constant string pointer whose
    297   /// lifetime will match that of the ArgList.
    298   virtual const char *MakeArgStringRef(StringRef Str) const = 0;
    299   const char *MakeArgString(const Twine &Str) const {
    300     SmallString<256> Buf;
    301     return MakeArgStringRef(Str.toStringRef(Buf));
    302   }
    303 
    304   /// \brief Create an arg string for (\p LHS + \p RHS), reusing the
    305   /// string at \p Index if possible.
    306   const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS,
    307                                         StringRef RHS) const;
    308 
    309   void print(raw_ostream &O) const;
    310   void dump() const;
    311 
    312   /// @}
    313 };
    314 
    315 class InputArgList final : public ArgList {
    316 private:
    317   /// List of argument strings used by the contained Args.
    318   ///
    319   /// This is mutable since we treat the ArgList as being the list
    320   /// of Args, and allow routines to add new strings (to have a
    321   /// convenient place to store the memory) via MakeIndex.
    322   mutable ArgStringList ArgStrings;
    323 
    324   /// Strings for synthesized arguments.
    325   ///
    326   /// This is mutable since we treat the ArgList as being the list
    327   /// of Args, and allow routines to add new strings (to have a
    328   /// convenient place to store the memory) via MakeIndex.
    329   mutable std::list<std::string> SynthesizedStrings;
    330 
    331   /// The number of original input argument strings.
    332   unsigned NumInputArgStrings;
    333 
    334   /// Release allocated arguments.
    335   void releaseMemory();
    336 
    337 public:
    338   InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
    339   InputArgList(InputArgList &&RHS)
    340       : ArgList(std::move(RHS)), ArgStrings(std::move(RHS.ArgStrings)),
    341         SynthesizedStrings(std::move(RHS.SynthesizedStrings)),
    342         NumInputArgStrings(RHS.NumInputArgStrings) {}
    343   InputArgList &operator=(InputArgList &&RHS) {
    344     releaseMemory();
    345     ArgList::operator=(std::move(RHS));
    346     ArgStrings = std::move(RHS.ArgStrings);
    347     SynthesizedStrings = std::move(RHS.SynthesizedStrings);
    348     NumInputArgStrings = RHS.NumInputArgStrings;
    349     return *this;
    350   }
    351   ~InputArgList() { releaseMemory(); }
    352 
    353   const char *getArgString(unsigned Index) const override {
    354     return ArgStrings[Index];
    355   }
    356 
    357   unsigned getNumInputArgStrings() const override {
    358     return NumInputArgStrings;
    359   }
    360 
    361   /// @name Arg Synthesis
    362   /// @{
    363 
    364 public:
    365   /// MakeIndex - Get an index for the given string(s).
    366   unsigned MakeIndex(StringRef String0) const;
    367   unsigned MakeIndex(StringRef String0, StringRef String1) const;
    368 
    369   using ArgList::MakeArgString;
    370   const char *MakeArgStringRef(StringRef Str) const override;
    371 
    372   /// @}
    373 };
    374 
    375 /// DerivedArgList - An ordered collection of driver arguments,
    376 /// whose storage may be in another argument list.
    377 class DerivedArgList final : public ArgList {
    378   const InputArgList &BaseArgs;
    379 
    380   /// The list of arguments we synthesized.
    381   mutable SmallVector<std::unique_ptr<Arg>, 16> SynthesizedArgs;
    382 
    383 public:
    384   /// Construct a new derived arg list from \p BaseArgs.
    385   DerivedArgList(const InputArgList &BaseArgs);
    386 
    387   const char *getArgString(unsigned Index) const override {
    388     return BaseArgs.getArgString(Index);
    389   }
    390 
    391   unsigned getNumInputArgStrings() const override {
    392     return BaseArgs.getNumInputArgStrings();
    393   }
    394 
    395   const InputArgList &getBaseArgs() const {
    396     return BaseArgs;
    397   }
    398 
    399   /// @name Arg Synthesis
    400   /// @{
    401 
    402   /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
    403   /// (to be freed).
    404   void AddSynthesizedArg(Arg *A);
    405 
    406   using ArgList::MakeArgString;
    407   const char *MakeArgStringRef(StringRef Str) const override;
    408 
    409   /// AddFlagArg - Construct a new FlagArg for the given option \p Id and
    410   /// append it to the argument list.
    411   void AddFlagArg(const Arg *BaseArg, const Option Opt) {
    412     append(MakeFlagArg(BaseArg, Opt));
    413   }
    414 
    415   /// AddPositionalArg - Construct a new Positional arg for the given option
    416   /// \p Id, with the provided \p Value and append it to the argument
    417   /// list.
    418   void AddPositionalArg(const Arg *BaseArg, const Option Opt,
    419                         StringRef Value) {
    420     append(MakePositionalArg(BaseArg, Opt, Value));
    421   }
    422 
    423 
    424   /// AddSeparateArg - Construct a new Positional arg for the given option
    425   /// \p Id, with the provided \p Value and append it to the argument
    426   /// list.
    427   void AddSeparateArg(const Arg *BaseArg, const Option Opt,
    428                       StringRef Value) {
    429     append(MakeSeparateArg(BaseArg, Opt, Value));
    430   }
    431 
    432 
    433   /// AddJoinedArg - Construct a new Positional arg for the given option
    434   /// \p Id, with the provided \p Value and append it to the argument list.
    435   void AddJoinedArg(const Arg *BaseArg, const Option Opt,
    436                     StringRef Value) {
    437     append(MakeJoinedArg(BaseArg, Opt, Value));
    438   }
    439 
    440 
    441   /// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
    442   Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const;
    443 
    444   /// MakePositionalArg - Construct a new Positional arg for the
    445   /// given option \p Id, with the provided \p Value.
    446   Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt,
    447                           StringRef Value) const;
    448 
    449   /// MakeSeparateArg - Construct a new Positional arg for the
    450   /// given option \p Id, with the provided \p Value.
    451   Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt,
    452                         StringRef Value) const;
    453 
    454   /// MakeJoinedArg - Construct a new Positional arg for the
    455   /// given option \p Id, with the provided \p Value.
    456   Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt,
    457                       StringRef Value) const;
    458 
    459   /// @}
    460 };
    461 
    462 } // end namespace opt
    463 } // end namespace llvm
    464 
    465 #endif
    466