Home | History | Annotate | Download | only in Dynamic
      1 //===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/
      2 //                     The LLVM Compiler Infrastructure
      3 //
      4 // This file is distributed under the University of Illinois Open Source
      5 // License. See LICENSE.TXT for details.
      6 //
      7 //===----------------------------------------------------------------------===//
      8 ///
      9 /// \file
     10 /// \brief Polymorphic value type.
     11 ///
     12 /// Supports all the types required for dynamic Matcher construction.
     13 ///  Used by the registry to construct matchers in a generic way.
     14 ///
     15 //===----------------------------------------------------------------------===//
     16 
     17 #ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
     18 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
     19 
     20 #include "clang/ASTMatchers/ASTMatchers.h"
     21 #include "clang/ASTMatchers/ASTMatchersInternal.h"
     22 #include "llvm/ADT/IntrusiveRefCntPtr.h"
     23 #include "llvm/ADT/Optional.h"
     24 #include "llvm/ADT/Twine.h"
     25 #include <memory>
     26 #include <vector>
     27 
     28 namespace clang {
     29 namespace ast_matchers {
     30 namespace dynamic {
     31 
     32 using ast_matchers::internal::DynTypedMatcher;
     33 
     34 /// \brief A variant matcher object.
     35 ///
     36 /// The purpose of this object is to abstract simple and polymorphic matchers
     37 /// into a single object type.
     38 /// Polymorphic matchers might be implemented as a list of all the possible
     39 /// overloads of the matcher. \c VariantMatcher knows how to select the
     40 /// appropriate overload when needed.
     41 /// To get a real matcher object out of a \c VariantMatcher you can do:
     42 ///  - getSingleMatcher() which returns a matcher, only if it is not ambiguous
     43 ///    to decide which matcher to return. Eg. it contains only a single
     44 ///    matcher, or a polymorphic one with only one overload.
     45 ///  - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
     46 ///    the underlying matcher(s) can unambiguously return a Matcher<T>.
     47 class VariantMatcher {
     48   /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
     49   class MatcherOps {
     50   public:
     51     virtual ~MatcherOps();
     52     virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
     53                                   bool &IsExactMatch) const = 0;
     54     virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
     55     virtual void constructVariadicOperator(
     56         ast_matchers::internal::VariadicOperatorFunction Func,
     57         ArrayRef<VariantMatcher> InnerMatchers) = 0;
     58   };
     59 
     60   /// \brief Payload interface to be specialized by each matcher type.
     61   ///
     62   /// It follows a similar interface as VariantMatcher itself.
     63   class Payload : public RefCountedBaseVPTR {
     64   public:
     65     virtual ~Payload();
     66     virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
     67     virtual std::string getTypeAsString() const = 0;
     68     virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;
     69   };
     70 
     71 public:
     72   /// \brief A null matcher.
     73   VariantMatcher();
     74 
     75   /// \brief Clones the provided matcher.
     76   static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
     77 
     78   /// \brief Clones the provided matchers.
     79   ///
     80   /// They should be the result of a polymorphic matcher.
     81   static VariantMatcher
     82   PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
     83 
     84   /// \brief Creates a 'variadic' operator matcher.
     85   ///
     86   /// It will bind to the appropriate type on getTypedMatcher<T>().
     87   static VariantMatcher VariadicOperatorMatcher(
     88       ast_matchers::internal::VariadicOperatorFunction Func,
     89       std::vector<VariantMatcher> Args);
     90 
     91   /// \brief Makes the matcher the "null" matcher.
     92   void reset();
     93 
     94   /// \brief Whether the matcher is null.
     95   bool isNull() const { return !Value; }
     96 
     97   /// \brief Return a single matcher, if there is no ambiguity.
     98   ///
     99   /// \returns the matcher, if there is only one matcher. An empty Optional, if
    100   /// the underlying matcher is a polymorphic matcher with more than one
    101   /// representation.
    102   llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
    103 
    104   /// \brief Determines if the contained matcher can be converted to
    105   ///   \c Matcher<T>.
    106   ///
    107   /// For the Single case, it returns true if it can be converted to
    108   /// \c Matcher<T>.
    109   /// For the Polymorphic case, it returns true if one, and only one, of the
    110   /// overloads can be converted to \c Matcher<T>. If there are more than one
    111   /// that can, the result would be ambiguous and false is returned.
    112   template <class T>
    113   bool hasTypedMatcher() const {
    114     TypedMatcherOps<T> Ops;
    115     if (Value) Value->makeTypedMatcher(Ops);
    116     return Ops.hasMatcher();
    117   }
    118 
    119   /// \brief Return this matcher as a \c Matcher<T>.
    120   ///
    121   /// Handles the different types (Single, Polymorphic) accordingly.
    122   /// Asserts that \c hasTypedMatcher<T>() is true.
    123   template <class T>
    124   ast_matchers::internal::Matcher<T> getTypedMatcher() const {
    125     TypedMatcherOps<T> Ops;
    126     Value->makeTypedMatcher(Ops);
    127     assert(Ops.hasMatcher() && "hasTypedMatcher<T>() == false");
    128     return Ops.matcher();
    129   }
    130 
    131   /// \brief String representation of the type of the value.
    132   ///
    133   /// If the underlying matcher is a polymorphic one, the string will show all
    134   /// the types.
    135   std::string getTypeAsString() const;
    136 
    137 private:
    138   explicit VariantMatcher(Payload *Value) : Value(Value) {}
    139 
    140   class SinglePayload;
    141   class PolymorphicPayload;
    142   class VariadicOpPayload;
    143 
    144   template <typename T>
    145   class TypedMatcherOps : public MatcherOps {
    146   public:
    147     typedef ast_matchers::internal::Matcher<T> MatcherT;
    148 
    149     virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
    150                                   bool &IsExactMatch) const {
    151       IsExactMatch = Matcher.getSupportedKind().isSame(
    152           ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
    153       return Matcher.canConvertTo<T>();
    154     }
    155 
    156     virtual void constructFrom(const DynTypedMatcher& Matcher) {
    157       Out.reset(new MatcherT(Matcher.convertTo<T>()));
    158     }
    159 
    160     virtual void constructVariadicOperator(
    161         ast_matchers::internal::VariadicOperatorFunction Func,
    162         ArrayRef<VariantMatcher> InnerMatchers) {
    163       std::vector<DynTypedMatcher> DynMatchers;
    164       for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
    165         // Abort if any of the inner matchers can't be converted to
    166         // Matcher<T>.
    167         if (!InnerMatchers[i].hasTypedMatcher<T>()) {
    168           return;
    169         }
    170         DynMatchers.push_back(InnerMatchers[i].getTypedMatcher<T>());
    171       }
    172       Out.reset(new MatcherT(
    173           new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
    174               Func, DynMatchers)));
    175     }
    176 
    177     bool hasMatcher() const { return Out.get() != nullptr; }
    178     const MatcherT &matcher() const { return *Out; }
    179 
    180   private:
    181     std::unique_ptr<MatcherT> Out;
    182   };
    183 
    184   IntrusiveRefCntPtr<const Payload> Value;
    185 };
    186 
    187 /// \brief Variant value class.
    188 ///
    189 /// Basically, a tagged union with value type semantics.
    190 /// It is used by the registry as the return value and argument type for the
    191 /// matcher factory methods.
    192 /// It can be constructed from any of the supported types. It supports
    193 /// copy/assignment.
    194 ///
    195 /// Supported types:
    196 ///  - \c unsigned
    197 ///  - \c std::string
    198 ///  - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
    199 class VariantValue {
    200 public:
    201   VariantValue() : Type(VT_Nothing) {}
    202 
    203   VariantValue(const VariantValue &Other);
    204   ~VariantValue();
    205   VariantValue &operator=(const VariantValue &Other);
    206 
    207   /// \brief Specific constructors for each supported type.
    208   VariantValue(unsigned Unsigned);
    209   VariantValue(const std::string &String);
    210   VariantValue(const VariantMatcher &Matchers);
    211 
    212   /// \brief Returns true iff this is not an empty value.
    213   LLVM_EXPLICIT operator bool() const { return hasValue(); }
    214   bool hasValue() const { return Type != VT_Nothing; }
    215 
    216   /// \brief Unsigned value functions.
    217   bool isUnsigned() const;
    218   unsigned getUnsigned() const;
    219   void setUnsigned(unsigned Unsigned);
    220 
    221   /// \brief String value functions.
    222   bool isString() const;
    223   const std::string &getString() const;
    224   void setString(const std::string &String);
    225 
    226   /// \brief Matcher value functions.
    227   bool isMatcher() const;
    228   const VariantMatcher &getMatcher() const;
    229   void setMatcher(const VariantMatcher &Matcher);
    230 
    231   /// \brief String representation of the type of the value.
    232   std::string getTypeAsString() const;
    233 
    234 private:
    235   void reset();
    236 
    237   /// \brief All supported value types.
    238   enum ValueType {
    239     VT_Nothing,
    240     VT_Unsigned,
    241     VT_String,
    242     VT_Matcher
    243   };
    244 
    245   /// \brief All supported value types.
    246   union AllValues {
    247     unsigned Unsigned;
    248     std::string *String;
    249     VariantMatcher *Matcher;
    250   };
    251 
    252   ValueType Type;
    253   AllValues Value;
    254 };
    255 
    256 } // end namespace dynamic
    257 } // end namespace ast_matchers
    258 } // end namespace clang
    259 
    260 #endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
    261