Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- ArgList.h - Argument List Management ---------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_OPTION_ARGLIST_H
  10. #define LLVM_OPTION_ARGLIST_H
  11.  
  12. #include "llvm/ADT/ArrayRef.h"
  13. #include "llvm/ADT/DenseMap.h"
  14. #include "llvm/ADT/iterator_range.h"
  15. #include "llvm/ADT/SmallString.h"
  16. #include "llvm/ADT/SmallVector.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/ADT/Twine.h"
  19. #include "llvm/Option/Arg.h"
  20. #include "llvm/Option/OptSpecifier.h"
  21. #include "llvm/Option/Option.h"
  22. #include <algorithm>
  23. #include <cstddef>
  24. #include <initializer_list>
  25. #include <iterator>
  26. #include <list>
  27. #include <memory>
  28. #include <string>
  29. #include <utility>
  30. #include <vector>
  31.  
  32. namespace llvm {
  33.  
  34. class raw_ostream;
  35.  
  36. namespace opt {
  37.  
  38. /// arg_iterator - Iterates through arguments stored inside an ArgList.
  39. template<typename BaseIter, unsigned NumOptSpecifiers = 0>
  40. class arg_iterator {
  41.   /// The current argument and the end of the sequence we're iterating.
  42.   BaseIter Current, End;
  43.  
  44.   /// Optional filters on the arguments which will be match. To avoid a
  45.   /// zero-sized array, we store one specifier even if we're asked for none.
  46.   OptSpecifier Ids[NumOptSpecifiers ? NumOptSpecifiers : 1];
  47.  
  48.   void SkipToNextArg() {
  49.     for (; Current != End; ++Current) {
  50.       // Skip erased elements.
  51.       if (!*Current)
  52.         continue;
  53.  
  54.       // Done if there are no filters.
  55.       if (!NumOptSpecifiers)
  56.         return;
  57.  
  58.       // Otherwise require a match.
  59.       const Option &O = (*Current)->getOption();
  60.       for (auto Id : Ids) {
  61.         if (!Id.isValid())
  62.           break;
  63.         if (O.matches(Id))
  64.           return;
  65.       }
  66.     }
  67.   }
  68.  
  69.   using Traits = std::iterator_traits<BaseIter>;
  70.  
  71. public:
  72.   using value_type = typename Traits::value_type;
  73.   using reference = typename Traits::reference;
  74.   using pointer = typename Traits::pointer;
  75.   using iterator_category = std::forward_iterator_tag;
  76.   using difference_type = std::ptrdiff_t;
  77.  
  78.   arg_iterator(
  79.       BaseIter Current, BaseIter End,
  80.       const OptSpecifier (&Ids)[NumOptSpecifiers ? NumOptSpecifiers : 1] = {})
  81.       : Current(Current), End(End) {
  82.     for (unsigned I = 0; I != NumOptSpecifiers; ++I)
  83.       this->Ids[I] = Ids[I];
  84.     SkipToNextArg();
  85.   }
  86.  
  87.   reference operator*() const { return *Current; }
  88.   pointer operator->() const { return Current; }
  89.  
  90.   arg_iterator &operator++() {
  91.     ++Current;
  92.     SkipToNextArg();
  93.     return *this;
  94.   }
  95.  
  96.   arg_iterator operator++(int) {
  97.     arg_iterator tmp(*this);
  98.     ++(*this);
  99.     return tmp;
  100.   }
  101.  
  102.   friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
  103.     return LHS.Current == RHS.Current;
  104.   }
  105.   friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
  106.     return !(LHS == RHS);
  107.   }
  108. };
  109.  
  110. /// ArgList - Ordered collection of driver arguments.
  111. ///
  112. /// The ArgList class manages a list of Arg instances as well as
  113. /// auxiliary data and convenience methods to allow Tools to quickly
  114. /// check for the presence of Arg instances for a particular Option
  115. /// and to iterate over groups of arguments.
  116. class ArgList {
  117. public:
  118.   using arglist_type = SmallVector<Arg *, 16>;
  119.   using iterator = arg_iterator<arglist_type::iterator>;
  120.   using const_iterator = arg_iterator<arglist_type::const_iterator>;
  121.   using reverse_iterator = arg_iterator<arglist_type::reverse_iterator>;
  122.   using const_reverse_iterator =
  123.       arg_iterator<arglist_type::const_reverse_iterator>;
  124.  
  125.   template<unsigned N> using filtered_iterator =
  126.       arg_iterator<arglist_type::const_iterator, N>;
  127.   template<unsigned N> using filtered_reverse_iterator =
  128.       arg_iterator<arglist_type::const_reverse_iterator, N>;
  129.  
  130. private:
  131.   /// The internal list of arguments.
  132.   arglist_type Args;
  133.  
  134.   using OptRange = std::pair<unsigned, unsigned>;
  135.   static OptRange emptyRange() { return {-1u, 0u}; }
  136.  
  137.   /// The first and last index of each different OptSpecifier ID.
  138.   DenseMap<unsigned, OptRange> OptRanges;
  139.  
  140.   /// Get the range of indexes in which options with the specified IDs might
  141.   /// reside, or (0, 0) if there are no such options.
  142.   OptRange getRange(std::initializer_list<OptSpecifier> Ids) const;
  143.  
  144. protected:
  145.   // Make the default special members protected so they won't be used to slice
  146.   // derived objects, but can still be used by derived objects to implement
  147.   // their own special members.
  148.   ArgList() = default;
  149.  
  150.   // Explicit move operations to ensure the container is cleared post-move
  151.   // otherwise it could lead to a double-delete in the case of moving of an
  152.   // InputArgList which deletes the contents of the container. If we could fix
  153.   // up the ownership here (delegate storage/ownership to the derived class so
  154.   // it can be a container of unique_ptr) this would be simpler.
  155.   ArgList(ArgList &&RHS)
  156.       : Args(std::move(RHS.Args)), OptRanges(std::move(RHS.OptRanges)) {
  157.     RHS.Args.clear();
  158.     RHS.OptRanges.clear();
  159.   }
  160.  
  161.   ArgList &operator=(ArgList &&RHS) {
  162.     Args = std::move(RHS.Args);
  163.     RHS.Args.clear();
  164.     OptRanges = std::move(RHS.OptRanges);
  165.     RHS.OptRanges.clear();
  166.     return *this;
  167.   }
  168.  
  169.   // Protect the dtor to ensure this type is never destroyed polymorphically.
  170.   ~ArgList() = default;
  171.  
  172.   // Implicitly convert a value to an OptSpecifier. Used to work around a bug
  173.   // in MSVC's implementation of narrowing conversion checking.
  174.   static OptSpecifier toOptSpecifier(OptSpecifier S) { return S; }
  175.  
  176. public:
  177.   /// @name Arg Access
  178.   /// @{
  179.  
  180.   /// append - Append \p A to the arg list.
  181.   void append(Arg *A);
  182.  
  183.   const arglist_type &getArgs() const { return Args; }
  184.  
  185.   unsigned size() const { return Args.size(); }
  186.  
  187.   /// @}
  188.   /// @name Arg Iteration
  189.   /// @{
  190.  
  191.   iterator begin() { return {Args.begin(), Args.end()}; }
  192.   iterator end() { return {Args.end(), Args.end()}; }
  193.  
  194.   reverse_iterator rbegin() { return {Args.rbegin(), Args.rend()}; }
  195.   reverse_iterator rend() { return {Args.rend(), Args.rend()}; }
  196.  
  197.   const_iterator begin() const { return {Args.begin(), Args.end()}; }
  198.   const_iterator end() const { return {Args.end(), Args.end()}; }
  199.  
  200.   const_reverse_iterator rbegin() const { return {Args.rbegin(), Args.rend()}; }
  201.   const_reverse_iterator rend() const { return {Args.rend(), Args.rend()}; }
  202.  
  203.   template<typename ...OptSpecifiers>
  204.   iterator_range<filtered_iterator<sizeof...(OptSpecifiers)>>
  205.   filtered(OptSpecifiers ...Ids) const {
  206.     OptRange Range = getRange({toOptSpecifier(Ids)...});
  207.     auto B = Args.begin() + Range.first;
  208.     auto E = Args.begin() + Range.second;
  209.     using Iterator = filtered_iterator<sizeof...(OptSpecifiers)>;
  210.     return make_range(Iterator(B, E, {toOptSpecifier(Ids)...}),
  211.                       Iterator(E, E, {toOptSpecifier(Ids)...}));
  212.   }
  213.  
  214.   template<typename ...OptSpecifiers>
  215.   iterator_range<filtered_reverse_iterator<sizeof...(OptSpecifiers)>>
  216.   filtered_reverse(OptSpecifiers ...Ids) const {
  217.     OptRange Range = getRange({toOptSpecifier(Ids)...});
  218.     auto B = Args.rend() - Range.second;
  219.     auto E = Args.rend() - Range.first;
  220.     using Iterator = filtered_reverse_iterator<sizeof...(OptSpecifiers)>;
  221.     return make_range(Iterator(B, E, {toOptSpecifier(Ids)...}),
  222.                       Iterator(E, E, {toOptSpecifier(Ids)...}));
  223.   }
  224.  
  225.   /// @}
  226.   /// @name Arg Removal
  227.   /// @{
  228.  
  229.   /// eraseArg - Remove any option matching \p Id.
  230.   void eraseArg(OptSpecifier Id);
  231.  
  232.   /// @}
  233.   /// @name Arg Access
  234.   /// @{
  235.  
  236.   /// hasArg - Does the arg list contain any option matching \p Id.
  237.   ///
  238.   /// \p Claim Whether the argument should be claimed, if it exists.
  239.   template<typename ...OptSpecifiers>
  240.   bool hasArgNoClaim(OptSpecifiers ...Ids) const {
  241.     return getLastArgNoClaim(Ids...) != nullptr;
  242.   }
  243.   template<typename ...OptSpecifiers>
  244.   bool hasArg(OptSpecifiers ...Ids) const {
  245.     return getLastArg(Ids...) != nullptr;
  246.   }
  247.  
  248.   /// Return true if the arg list contains multiple arguments matching \p Id.
  249.   bool hasMultipleArgs(OptSpecifier Id) const {
  250.     auto Args = filtered(Id);
  251.     return (Args.begin() != Args.end()) && (++Args.begin()) != Args.end();
  252.   }
  253.  
  254.   /// Return the last argument matching \p Id, or null.
  255.   template<typename ...OptSpecifiers>
  256.   Arg *getLastArg(OptSpecifiers ...Ids) const {
  257.     Arg *Res = nullptr;
  258.     for (Arg *A : filtered(Ids...)) {
  259.       Res = A;
  260.       Res->claim();
  261.     }
  262.     return Res;
  263.   }
  264.  
  265.   /// Return the last argument matching \p Id, or null. Do not "claim" the
  266.   /// option (don't mark it as having been used).
  267.   template<typename ...OptSpecifiers>
  268.   Arg *getLastArgNoClaim(OptSpecifiers ...Ids) const {
  269.     for (Arg *A : filtered_reverse(Ids...))
  270.       return A;
  271.     return nullptr;
  272.   }
  273.  
  274.   /// getArgString - Return the input argument string at \p Index.
  275.   virtual const char *getArgString(unsigned Index) const = 0;
  276.  
  277.   /// getNumInputArgStrings - Return the number of original argument strings,
  278.   /// which are guaranteed to be the first strings in the argument string
  279.   /// list.
  280.   virtual unsigned getNumInputArgStrings() const = 0;
  281.  
  282.   /// @}
  283.   /// @name Argument Lookup Utilities
  284.   /// @{
  285.  
  286.   /// getLastArgValue - Return the value of the last argument, or a default.
  287.   StringRef getLastArgValue(OptSpecifier Id, StringRef Default = "") const;
  288.  
  289.   /// getAllArgValues - Get the values of all instances of the given argument
  290.   /// as strings.
  291.   std::vector<std::string> getAllArgValues(OptSpecifier Id) const;
  292.  
  293.   /// @}
  294.   /// @name Translation Utilities
  295.   /// @{
  296.  
  297.   /// hasFlag - Given an option \p Pos and its negative form \p Neg, return
  298.   /// true if the option is present, false if the negation is present, and
  299.   /// \p Default if neither option is given. If both the option and its
  300.   /// negation are present, the last one wins.
  301.   bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const;
  302.  
  303.   /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative
  304.   /// form \p Neg, return true if the option or its alias is present, false if
  305.   /// the negation is present, and \p Default if none of the options are
  306.   /// given. If multiple options are present, the last one wins.
  307.   bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
  308.                bool Default) const;
  309.  
  310.   /// Given an option Pos and its negative form Neg, render the option if Pos is
  311.   /// present.
  312.   void addOptInFlag(ArgStringList &Output, OptSpecifier Pos,
  313.                     OptSpecifier Neg) const;
  314.   /// Render the option if Neg is present.
  315.   void addOptOutFlag(ArgStringList &Output, OptSpecifier Pos,
  316.                      OptSpecifier Neg) const {
  317.     addOptInFlag(Output, Neg, Pos);
  318.   }
  319.  
  320.   /// Render only the last argument match \p Id0, if present.
  321.   template<typename ...OptSpecifiers>
  322.   void AddLastArg(ArgStringList &Output, OptSpecifiers ...Ids) const {
  323.     if (Arg *A = getLastArg(Ids...)) // Calls claim() on all Ids's Args.
  324.       A->render(*this, Output);
  325.   }
  326.  
  327.   /// AddAllArgsExcept - Render all arguments matching any of the given ids
  328.   /// and not matching any of the excluded ids.
  329.   void AddAllArgsExcept(ArgStringList &Output, ArrayRef<OptSpecifier> Ids,
  330.                         ArrayRef<OptSpecifier> ExcludeIds) const;
  331.   /// AddAllArgs - Render all arguments matching any of the given ids.
  332.   void AddAllArgs(ArgStringList &Output, ArrayRef<OptSpecifier> Ids) const;
  333.  
  334.   /// AddAllArgs - Render all arguments matching the given ids.
  335.   void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
  336.                   OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
  337.  
  338.   /// AddAllArgValues - Render the argument values of all arguments
  339.   /// matching the given ids.
  340.   void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
  341.                        OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
  342.  
  343.   /// AddAllArgsTranslated - Render all the arguments matching the
  344.   /// given ids, but forced to separate args and using the provided
  345.   /// name instead of the first option value.
  346.   ///
  347.   /// \param Joined - If true, render the argument as joined with
  348.   /// the option specifier.
  349.   void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
  350.                             const char *Translation,
  351.                             bool Joined = false) const;
  352.  
  353.   /// ClaimAllArgs - Claim all arguments which match the given
  354.   /// option id.
  355.   void ClaimAllArgs(OptSpecifier Id0) const;
  356.  
  357.   /// ClaimAllArgs - Claim all arguments.
  358.   ///
  359.   void ClaimAllArgs() const;
  360.   /// @}
  361.   /// @name Arg Synthesis
  362.   /// @{
  363.  
  364.   /// Construct a constant string pointer whose
  365.   /// lifetime will match that of the ArgList.
  366.   virtual const char *MakeArgStringRef(StringRef Str) const = 0;
  367.   const char *MakeArgString(const Twine &Str) const {
  368.     SmallString<256> Buf;
  369.     return MakeArgStringRef(Str.toStringRef(Buf));
  370.   }
  371.  
  372.   /// Create an arg string for (\p LHS + \p RHS), reusing the
  373.   /// string at \p Index if possible.
  374.   const char *GetOrMakeJoinedArgString(unsigned Index, StringRef LHS,
  375.                                         StringRef RHS) const;
  376.  
  377.   void print(raw_ostream &O) const;
  378.   void dump() const;
  379.  
  380.   /// @}
  381. };
  382.  
  383. class InputArgList final : public ArgList {
  384. private:
  385.   /// List of argument strings used by the contained Args.
  386.   ///
  387.   /// This is mutable since we treat the ArgList as being the list
  388.   /// of Args, and allow routines to add new strings (to have a
  389.   /// convenient place to store the memory) via MakeIndex.
  390.   mutable ArgStringList ArgStrings;
  391.  
  392.   /// Strings for synthesized arguments.
  393.   ///
  394.   /// This is mutable since we treat the ArgList as being the list
  395.   /// of Args, and allow routines to add new strings (to have a
  396.   /// convenient place to store the memory) via MakeIndex.
  397.   mutable std::list<std::string> SynthesizedStrings;
  398.  
  399.   /// The number of original input argument strings.
  400.   unsigned NumInputArgStrings;
  401.  
  402.   /// Release allocated arguments.
  403.   void releaseMemory();
  404.  
  405. public:
  406.   InputArgList() : NumInputArgStrings(0) {}
  407.  
  408.   InputArgList(const char* const *ArgBegin, const char* const *ArgEnd);
  409.  
  410.   InputArgList(InputArgList &&RHS)
  411.       : ArgList(std::move(RHS)), ArgStrings(std::move(RHS.ArgStrings)),
  412.         SynthesizedStrings(std::move(RHS.SynthesizedStrings)),
  413.         NumInputArgStrings(RHS.NumInputArgStrings) {}
  414.  
  415.   InputArgList &operator=(InputArgList &&RHS) {
  416.     releaseMemory();
  417.     ArgList::operator=(std::move(RHS));
  418.     ArgStrings = std::move(RHS.ArgStrings);
  419.     SynthesizedStrings = std::move(RHS.SynthesizedStrings);
  420.     NumInputArgStrings = RHS.NumInputArgStrings;
  421.     return *this;
  422.   }
  423.  
  424.   ~InputArgList() { releaseMemory(); }
  425.  
  426.   const char *getArgString(unsigned Index) const override {
  427.     return ArgStrings[Index];
  428.   }
  429.  
  430.   void replaceArgString(unsigned Index, const Twine &S) {
  431.     ArgStrings[Index] = MakeArgString(S);
  432.   }
  433.  
  434.   unsigned getNumInputArgStrings() const override {
  435.     return NumInputArgStrings;
  436.   }
  437.  
  438.   /// @name Arg Synthesis
  439.   /// @{
  440.  
  441. public:
  442.   /// MakeIndex - Get an index for the given string(s).
  443.   unsigned MakeIndex(StringRef String0) const;
  444.   unsigned MakeIndex(StringRef String0, StringRef String1) const;
  445.  
  446.   using ArgList::MakeArgString;
  447.   const char *MakeArgStringRef(StringRef Str) const override;
  448.  
  449.   /// @}
  450. };
  451.  
  452. /// DerivedArgList - An ordered collection of driver arguments,
  453. /// whose storage may be in another argument list.
  454. class DerivedArgList final : public ArgList {
  455.   const InputArgList &BaseArgs;
  456.  
  457.   /// The list of arguments we synthesized.
  458.   mutable SmallVector<std::unique_ptr<Arg>, 16> SynthesizedArgs;
  459.  
  460. public:
  461.   /// Construct a new derived arg list from \p BaseArgs.
  462.   DerivedArgList(const InputArgList &BaseArgs);
  463.  
  464.   const char *getArgString(unsigned Index) const override {
  465.     return BaseArgs.getArgString(Index);
  466.   }
  467.  
  468.   unsigned getNumInputArgStrings() const override {
  469.     return BaseArgs.getNumInputArgStrings();
  470.   }
  471.  
  472.   const InputArgList &getBaseArgs() const {
  473.     return BaseArgs;
  474.   }
  475.  
  476.   /// @name Arg Synthesis
  477.   /// @{
  478.  
  479.   /// AddSynthesizedArg - Add a argument to the list of synthesized arguments
  480.   /// (to be freed).
  481.   void AddSynthesizedArg(Arg *A);
  482.  
  483.   using ArgList::MakeArgString;
  484.   const char *MakeArgStringRef(StringRef Str) const override;
  485.  
  486.   /// AddFlagArg - Construct a new FlagArg for the given option \p Id and
  487.   /// append it to the argument list.
  488.   void AddFlagArg(const Arg *BaseArg, const Option Opt) {
  489.     append(MakeFlagArg(BaseArg, Opt));
  490.   }
  491.  
  492.   /// AddPositionalArg - Construct a new Positional arg for the given option
  493.   /// \p Id, with the provided \p Value and append it to the argument
  494.   /// list.
  495.   void AddPositionalArg(const Arg *BaseArg, const Option Opt,
  496.                         StringRef Value) {
  497.     append(MakePositionalArg(BaseArg, Opt, Value));
  498.   }
  499.  
  500.   /// AddSeparateArg - Construct a new Positional arg for the given option
  501.   /// \p Id, with the provided \p Value and append it to the argument
  502.   /// list.
  503.   void AddSeparateArg(const Arg *BaseArg, const Option Opt,
  504.                       StringRef Value) {
  505.     append(MakeSeparateArg(BaseArg, Opt, Value));
  506.   }
  507.  
  508.   /// AddJoinedArg - Construct a new Positional arg for the given option
  509.   /// \p Id, with the provided \p Value and append it to the argument list.
  510.   void AddJoinedArg(const Arg *BaseArg, const Option Opt,
  511.                     StringRef Value) {
  512.     append(MakeJoinedArg(BaseArg, Opt, Value));
  513.   }
  514.  
  515.   /// MakeFlagArg - Construct a new FlagArg for the given option \p Id.
  516.   Arg *MakeFlagArg(const Arg *BaseArg, const Option Opt) const;
  517.  
  518.   /// MakePositionalArg - Construct a new Positional arg for the
  519.   /// given option \p Id, with the provided \p Value.
  520.   Arg *MakePositionalArg(const Arg *BaseArg, const Option Opt,
  521.                           StringRef Value) const;
  522.  
  523.   /// MakeSeparateArg - Construct a new Positional arg for the
  524.   /// given option \p Id, with the provided \p Value.
  525.   Arg *MakeSeparateArg(const Arg *BaseArg, const Option Opt,
  526.                         StringRef Value) const;
  527.  
  528.   /// MakeJoinedArg - Construct a new Positional arg for the
  529.   /// given option \p Id, with the provided \p Value.
  530.   Arg *MakeJoinedArg(const Arg *BaseArg, const Option Opt,
  531.                       StringRef Value) const;
  532.  
  533.   /// @}
  534. };
  535.  
  536. } // end namespace opt
  537.  
  538. } // end namespace llvm
  539.  
  540. #endif // LLVM_OPTION_ARGLIST_H
  541.