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_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
     18 #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_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 /// \brief Kind identifier.
     33 ///
     34 /// It supports all types that VariantValue can contain.
     35 class ArgKind {
     36  public:
     37   enum Kind {
     38     AK_Matcher,
     39     AK_Unsigned,
     40     AK_String
     41   };
     42   /// \brief Constructor for non-matcher types.
     43   ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
     44 
     45   /// \brief Constructor for matcher types.
     46   ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
     47       : K(AK_Matcher), MatcherKind(MatcherKind) {}
     48 
     49   Kind getArgKind() const { return K; }
     50   ast_type_traits::ASTNodeKind getMatcherKind() const {
     51     assert(K == AK_Matcher);
     52     return MatcherKind;
     53   }
     54 
     55   /// \brief Determines if this type can be converted to \p To.
     56   ///
     57   /// \param To the requested destination type.
     58   ///
     59   /// \param Specificity value corresponding to the "specificity" of the
     60   ///   convertion.
     61   bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
     62 
     63   bool operator<(const ArgKind &Other) const {
     64     if (K == AK_Matcher && Other.K == AK_Matcher)
     65       return MatcherKind < Other.MatcherKind;
     66     return K < Other.K;
     67   }
     68 
     69   /// \brief String representation of the type.
     70   std::string asString() const;
     71 
     72 private:
     73   Kind K;
     74   ast_type_traits::ASTNodeKind MatcherKind;
     75 };
     76 
     77 using ast_matchers::internal::DynTypedMatcher;
     78 
     79 /// \brief A variant matcher object.
     80 ///
     81 /// The purpose of this object is to abstract simple and polymorphic matchers
     82 /// into a single object type.
     83 /// Polymorphic matchers might be implemented as a list of all the possible
     84 /// overloads of the matcher. \c VariantMatcher knows how to select the
     85 /// appropriate overload when needed.
     86 /// To get a real matcher object out of a \c VariantMatcher you can do:
     87 ///  - getSingleMatcher() which returns a matcher, only if it is not ambiguous
     88 ///    to decide which matcher to return. Eg. it contains only a single
     89 ///    matcher, or a polymorphic one with only one overload.
     90 ///  - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
     91 ///    the underlying matcher(s) can unambiguously return a Matcher<T>.
     92 class VariantMatcher {
     93   /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
     94   class MatcherOps {
     95   public:
     96     MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
     97 
     98     bool canConstructFrom(const DynTypedMatcher &Matcher,
     99                           bool &IsExactMatch) const;
    100 
    101     /// \brief Convert \p Matcher the destination type and return it as a new
    102     /// DynTypedMatcher.
    103     virtual DynTypedMatcher
    104     convertMatcher(const DynTypedMatcher &Matcher) const = 0;
    105 
    106     /// \brief Constructs a variadic typed matcher from \p InnerMatchers.
    107     /// Will try to convert each inner matcher to the destination type and
    108     /// return llvm::None if it fails to do so.
    109     llvm::Optional<DynTypedMatcher>
    110     constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
    111                               ArrayRef<VariantMatcher> InnerMatchers) const;
    112 
    113   protected:
    114     ~MatcherOps() = default;
    115 
    116   private:
    117     ast_type_traits::ASTNodeKind NodeKind;
    118   };
    119 
    120   /// \brief Payload interface to be specialized by each matcher type.
    121   ///
    122   /// It follows a similar interface as VariantMatcher itself.
    123   class Payload : public RefCountedBaseVPTR {
    124   public:
    125     ~Payload() override;
    126     virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
    127     virtual std::string getTypeAsString() const = 0;
    128     virtual llvm::Optional<DynTypedMatcher>
    129     getTypedMatcher(const MatcherOps &Ops) const = 0;
    130     virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
    131                                  unsigned *Specificity) const = 0;
    132   };
    133 
    134 public:
    135   /// \brief A null matcher.
    136   VariantMatcher();
    137 
    138   /// \brief Clones the provided matcher.
    139   static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
    140 
    141   /// \brief Clones the provided matchers.
    142   ///
    143   /// They should be the result of a polymorphic matcher.
    144   static VariantMatcher
    145   PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
    146 
    147   /// \brief Creates a 'variadic' operator matcher.
    148   ///
    149   /// It will bind to the appropriate type on getTypedMatcher<T>().
    150   static VariantMatcher
    151   VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
    152                           std::vector<VariantMatcher> Args);
    153 
    154   /// \brief Makes the matcher the "null" matcher.
    155   void reset();
    156 
    157   /// \brief Whether the matcher is null.
    158   bool isNull() const { return !Value; }
    159 
    160   /// \brief Return a single matcher, if there is no ambiguity.
    161   ///
    162   /// \returns the matcher, if there is only one matcher. An empty Optional, if
    163   /// the underlying matcher is a polymorphic matcher with more than one
    164   /// representation.
    165   llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
    166 
    167   /// \brief Determines if the contained matcher can be converted to
    168   ///   \c Matcher<T>.
    169   ///
    170   /// For the Single case, it returns true if it can be converted to
    171   /// \c Matcher<T>.
    172   /// For the Polymorphic case, it returns true if one, and only one, of the
    173   /// overloads can be converted to \c Matcher<T>. If there are more than one
    174   /// that can, the result would be ambiguous and false is returned.
    175   template <class T>
    176   bool hasTypedMatcher() const {
    177     if (!Value) return false;
    178     return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue();
    179   }
    180 
    181   /// \brief Determines if the contained matcher can be converted to \p Kind.
    182   ///
    183   /// \param Kind the requested destination type.
    184   ///
    185   /// \param Specificity value corresponding to the "specificity" of the
    186   ///   convertion.
    187   bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
    188                        unsigned *Specificity) const {
    189     if (Value)
    190       return Value->isConvertibleTo(Kind, Specificity);
    191     return false;
    192   }
    193 
    194   /// \brief Return this matcher as a \c Matcher<T>.
    195   ///
    196   /// Handles the different types (Single, Polymorphic) accordingly.
    197   /// Asserts that \c hasTypedMatcher<T>() is true.
    198   template <class T>
    199   ast_matchers::internal::Matcher<T> getTypedMatcher() const {
    200     assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false");
    201     return Value->getTypedMatcher(TypedMatcherOps<T>())
    202         ->template convertTo<T>();
    203   }
    204 
    205   /// \brief String representation of the type of the value.
    206   ///
    207   /// If the underlying matcher is a polymorphic one, the string will show all
    208   /// the types.
    209   std::string getTypeAsString() const;
    210 
    211 private:
    212   explicit VariantMatcher(Payload *Value) : Value(Value) {}
    213 
    214   template <typename T> struct TypedMatcherOps;
    215 
    216   class SinglePayload;
    217   class PolymorphicPayload;
    218   class VariadicOpPayload;
    219 
    220   IntrusiveRefCntPtr<const Payload> Value;
    221 };
    222 
    223 template <typename T>
    224 struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps {
    225   TypedMatcherOps()
    226       : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {}
    227   typedef ast_matchers::internal::Matcher<T> MatcherT;
    228 
    229   DynTypedMatcher
    230   convertMatcher(const DynTypedMatcher &Matcher) const override {
    231     return DynTypedMatcher(Matcher.convertTo<T>());
    232   }
    233 };
    234 
    235 /// \brief Variant value class.
    236 ///
    237 /// Basically, a tagged union with value type semantics.
    238 /// It is used by the registry as the return value and argument type for the
    239 /// matcher factory methods.
    240 /// It can be constructed from any of the supported types. It supports
    241 /// copy/assignment.
    242 ///
    243 /// Supported types:
    244 ///  - \c unsigned
    245 ///  - \c llvm::StringRef
    246 ///  - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
    247 class VariantValue {
    248 public:
    249   VariantValue() : Type(VT_Nothing) {}
    250 
    251   VariantValue(const VariantValue &Other);
    252   ~VariantValue();
    253   VariantValue &operator=(const VariantValue &Other);
    254 
    255   /// \brief Specific constructors for each supported type.
    256   VariantValue(unsigned Unsigned);
    257   VariantValue(StringRef String);
    258   VariantValue(const VariantMatcher &Matchers);
    259 
    260   /// \brief Returns true iff this is not an empty value.
    261   explicit operator bool() const { return hasValue(); }
    262   bool hasValue() const { return Type != VT_Nothing; }
    263 
    264   /// \brief Unsigned value functions.
    265   bool isUnsigned() const;
    266   unsigned getUnsigned() const;
    267   void setUnsigned(unsigned Unsigned);
    268 
    269   /// \brief String value functions.
    270   bool isString() const;
    271   const std::string &getString() const;
    272   void setString(StringRef String);
    273 
    274   /// \brief Matcher value functions.
    275   bool isMatcher() const;
    276   const VariantMatcher &getMatcher() const;
    277   void setMatcher(const VariantMatcher &Matcher);
    278 
    279   /// \brief Determines if the contained value can be converted to \p Kind.
    280   ///
    281   /// \param Kind the requested destination type.
    282   ///
    283   /// \param Specificity value corresponding to the "specificity" of the
    284   ///   convertion.
    285   bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
    286 
    287   /// \brief Determines if the contained value can be converted to any kind
    288   /// in \p Kinds.
    289   ///
    290   /// \param Kinds the requested destination types.
    291   ///
    292   /// \param Specificity value corresponding to the "specificity" of the
    293   ///   convertion. It is the maximum specificity of all the possible
    294   ///   conversions.
    295   bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
    296 
    297   /// \brief String representation of the type of the value.
    298   std::string getTypeAsString() const;
    299 
    300 private:
    301   void reset();
    302 
    303   /// \brief All supported value types.
    304   enum ValueType {
    305     VT_Nothing,
    306     VT_Unsigned,
    307     VT_String,
    308     VT_Matcher
    309   };
    310 
    311   /// \brief All supported value types.
    312   union AllValues {
    313     unsigned Unsigned;
    314     std::string *String;
    315     VariantMatcher *Matcher;
    316   };
    317 
    318   ValueType Type;
    319   AllValues Value;
    320 };
    321 
    322 } // end namespace dynamic
    323 } // end namespace ast_matchers
    324 } // end namespace clang
    325 
    326 #endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
    327