VariantValue.h revision 355940
11195Srgrimes//===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/
22619Srgrimes// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
337Srgrimes// See https://llvm.org/LICENSE.txt for license information.
437Srgrimes// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
537Srgrimes//
6147Srgrimes//===----------------------------------------------------------------------===//
7147Srgrimes///
8147Srgrimes/// \file
9207Snate/// Polymorphic value type.
101734Sjkh///
111518Sguido/// Supports all the types required for dynamic Matcher construction.
121518Sguido///  Used by the registry to construct matchers in a generic way.
131734Sjkh///
141734Sjkh//===----------------------------------------------------------------------===//
151734Sjkh
1637Srgrimes#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
1737Srgrimes#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
1837Srgrimes
1937Srgrimes#include "clang/ASTMatchers/ASTMatchers.h"
201773Sjkh#include "clang/ASTMatchers/ASTMatchersInternal.h"
21147Srgrimes#include "llvm/ADT/IntrusiveRefCntPtr.h"
22147Srgrimes#include "llvm/ADT/Optional.h"
232570Srgrimes#include <memory>
242570Srgrimes#include <vector>
252570Srgrimes
261767Sjkhnamespace clang {
272570Srgrimesnamespace ast_matchers {
282570Srgrimesnamespace dynamic {
292570Srgrimes
302570Srgrimes/// Kind identifier.
312570Srgrimes///
322570Srgrimes/// It supports all types that VariantValue can contain.
332570Srgrimesclass ArgKind {
342570Srgrimes public:
351782Sjkh  enum Kind {
361782Sjkh    AK_Matcher,
37491Srgrimes    AK_Boolean,
3837Srgrimes    AK_Double,
3937Srgrimes    AK_Unsigned,
4037Srgrimes    AK_String
4137Srgrimes  };
4237Srgrimes  /// Constructor for non-matcher types.
43263Srgrimes  ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
441130Srgrimes
451767Sjkh  /// Constructor for matcher types.
461126Srgrimes  ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
47993Srgrimes      : K(AK_Matcher), MatcherKind(MatcherKind) {}
48277Srgrimes
49277Srgrimes  Kind getArgKind() const { return K; }
50284Srgrimes  ast_type_traits::ASTNodeKind getMatcherKind() const {
51463Srgrimes    assert(K == AK_Matcher);
521205Srgrimes    return MatcherKind;
53284Srgrimes  }
54284Srgrimes
55284Srgrimes  /// Determines if this type can be converted to \p To.
56284Srgrimes  ///
57284Srgrimes  /// \param To the requested destination type.
581285Srgrimes  ///
59284Srgrimes  /// \param Specificity value corresponding to the "specificity" of the
601767Sjkh  ///   conversion.
611285Srgrimes  bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
622499Sgpalmer
631285Srgrimes  bool operator<(const ArgKind &Other) const {
64284Srgrimes    if (K == AK_Matcher && Other.K == AK_Matcher)
651371Srgrimes      return MatcherKind < Other.MatcherKind;
661371Srgrimes    return K < Other.K;
671194Srgrimes  }
68358Srgrimes
69358Srgrimes  /// String representation of the type.
70412Salm  std::string asString() const;
71358Srgrimes
72452Srgrimesprivate:
73358Srgrimes  Kind K;
741194Srgrimes  ast_type_traits::ASTNodeKind MatcherKind;
751767Sjkh};
761194Srgrimes
771194Srgrimesusing ast_matchers::internal::DynTypedMatcher;
781194Srgrimes
791194Srgrimes/// A variant matcher object.
801194Srgrimes///
811194Srgrimes/// The purpose of this object is to abstract simple and polymorphic matchers
821194Srgrimes/// into a single object type.
831194Srgrimes/// Polymorphic matchers might be implemented as a list of all the possible
841194Srgrimes/// overloads of the matcher. \c VariantMatcher knows how to select the
851194Srgrimes/// appropriate overload when needed.
861194Srgrimes/// To get a real matcher object out of a \c VariantMatcher you can do:
871194Srgrimes///  - getSingleMatcher() which returns a matcher, only if it is not ambiguous
881194Srgrimes///    to decide which matcher to return. Eg. it contains only a single
891194Srgrimes///    matcher, or a polymorphic one with only one overload.
901194Srgrimes///  - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
911194Srgrimes///    the underlying matcher(s) can unambiguously return a Matcher<T>.
921194Srgrimesclass VariantMatcher {
931194Srgrimes  /// Methods that depend on T from hasTypedMatcher/getTypedMatcher.
941243Srgrimes  class MatcherOps {
95263Srgrimes  public:
96358Srgrimes    MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
971194Srgrimes
981194Srgrimes    bool canConstructFrom(const DynTypedMatcher &Matcher,
991194Srgrimes                          bool &IsExactMatch) const;
1001773Sjkh
1012499Sgpalmer    /// Convert \p Matcher the destination type and return it as a new
1021194Srgrimes    /// DynTypedMatcher.
103452Srgrimes    virtual DynTypedMatcher
1041194Srgrimes    convertMatcher(const DynTypedMatcher &Matcher) const = 0;
1051194Srgrimes
106358Srgrimes    /// Constructs a variadic typed matcher from \p InnerMatchers.
1071194Srgrimes    /// Will try to convert each inner matcher to the destination type and
1081695Scsgr    /// return llvm::None if it fails to do so.
1091695Scsgr    llvm::Optional<DynTypedMatcher>
1101695Scsgr    constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
1111695Scsgr                              ArrayRef<VariantMatcher> InnerMatchers) const;
1121695Scsgr
1131695Scsgr  protected:
1141695Scsgr    ~MatcherOps() = default;
1151243Srgrimes
1161194Srgrimes  private:
1171194Srgrimes    ast_type_traits::ASTNodeKind NodeKind;
1181243Srgrimes  };
1191243Srgrimes
120284Srgrimes  /// Payload interface to be specialized by each matcher type.
1212570Srgrimes  ///
1222570Srgrimes  /// It follows a similar interface as VariantMatcher itself.
123372Srgrimes  class Payload {
124372Srgrimes  public:
125372Srgrimes    virtual ~Payload();
1262570Srgrimes    virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
1272570Srgrimes    virtual std::string getTypeAsString() const = 0;
128372Srgrimes    virtual llvm::Optional<DynTypedMatcher>
1291126Srgrimes    getTypedMatcher(const MatcherOps &Ops) const = 0;
130347Srgrimes    virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
1311767Sjkh                                 unsigned *Specificity) const = 0;
13237Srgrimes  };
1332538Spst
134347Srgrimespublic:
1352538Spst  /// A null matcher.
136355Srgrimes  VariantMatcher();
137372Srgrimes
138347Srgrimes  /// Clones the provided matcher.
139355Srgrimes  static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
140347Srgrimes
1412538Spst  /// Clones the provided matchers.
1422538Spst  ///
1432538Spst  /// They should be the result of a polymorphic matcher.
1442538Spst  static VariantMatcher
1452538Spst  PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
146372Srgrimes
147347Srgrimes  /// Creates a 'variadic' operator matcher.
148355Srgrimes  ///
149347Srgrimes  /// It will bind to the appropriate type on getTypedMatcher<T>().
150347Srgrimes  static VariantMatcher
1512538Spst  VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
152147Srgrimes                          std::vector<VariantMatcher> Args);
1531759Sjkh
1541759Sjkh  /// Makes the matcher the "null" matcher.
1551759Sjkh  void reset();
1561759Sjkh
1571759Sjkh  /// Whether the matcher is null.
1581731Sjkh  bool isNull() const { return !Value; }
1591759Sjkh
1601731Sjkh  /// Return a single matcher, if there is no ambiguity.
1611759Sjkh  ///
1621759Sjkh  /// \returns the matcher, if there is only one matcher. An empty Optional, if
16337Srgrimes  /// the underlying matcher is a polymorphic matcher with more than one
1641759Sjkh  /// representation.
165347Srgrimes  llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
1661759Sjkh
167347Srgrimes  /// Determines if the contained matcher can be converted to
1681731Sjkh  ///   \c Matcher<T>.
1691731Sjkh  ///
17037Srgrimes  /// For the Single case, it returns true if it can be converted to
1711731Sjkh  /// \c Matcher<T>.
17237Srgrimes  /// For the Polymorphic case, it returns true if one, and only one, of the
1731731Sjkh  /// overloads can be converted to \c Matcher<T>. If there are more than one
17437Srgrimes  /// that can, the result would be ambiguous and false is returned.
1751731Sjkh  template <class T>
17637Srgrimes  bool hasTypedMatcher() const {
17737Srgrimes    if (!Value) return false;
17837Srgrimes    return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue();
17937Srgrimes  }
1801731Sjkh
1811731Sjkh  /// Determines if the contained matcher can be converted to \p Kind.
1821731Sjkh  ///
1831731Sjkh  /// \param Kind the requested destination type.
18437Srgrimes  ///
18537Srgrimes  /// \param Specificity value corresponding to the "specificity" of the
186147Srgrimes  ///   conversion.
187147Srgrimes  bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
18837Srgrimes                       unsigned *Specificity) const {
189147Srgrimes    if (Value)
19037Srgrimes      return Value->isConvertibleTo(Kind, Specificity);
19137Srgrimes    return false;
19237Srgrimes  }
193288Srgrimes
194288Srgrimes  /// Return this matcher as a \c Matcher<T>.
195147Srgrimes  ///
19637Srgrimes  /// Handles the different types (Single, Polymorphic) accordingly.
197147Srgrimes  /// Asserts that \c hasTypedMatcher<T>() is true.
198147Srgrimes  template <class T>
19937Srgrimes  ast_matchers::internal::Matcher<T> getTypedMatcher() const {
2001759Sjkh    assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false");
2011759Sjkh    return Value->getTypedMatcher(TypedMatcherOps<T>())
2021759Sjkh        ->template convertTo<T>();
2031759Sjkh  }
204347Srgrimes
2052538Spst  /// String representation of the type of the value.
2062538Spst  ///
207347Srgrimes  /// If the underlying matcher is a polymorphic one, the string will show all
2082538Spst  /// the types.
2091775Sjkh  std::string getTypeAsString() const;
210347Srgrimes
2111759Sjkhprivate:
212355Srgrimes  explicit VariantMatcher(std::shared_ptr<Payload> Value)
213277Srgrimes      : Value(std::move(Value)) {}
2141126Srgrimes
2151126Srgrimes  template <typename T> struct TypedMatcherOps;
2161731Sjkh
217238Sroot  class SinglePayload;
2181759Sjkh  class PolymorphicPayload;
2191731Sjkh  class VariadicOpPayload;
2201759Sjkh
221333Srgrimes  std::shared_ptr<const Payload> Value;
2221759Sjkh};
2231759Sjkh
224168Srgrimestemplate <typename T>
225333Srgrimesstruct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps {
2261759Sjkh  TypedMatcherOps()
2271759Sjkh      : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {}
228333Srgrimes  typedef ast_matchers::internal::Matcher<T> MatcherT;
22937Srgrimes
2301731Sjkh  DynTypedMatcher
2312619Srgrimes  convertMatcher(const DynTypedMatcher &Matcher) const override {
2321782Sjkh    return DynTypedMatcher(Matcher.convertTo<T>());
2332619Srgrimes  }
2341782Sjkh};
2351731Sjkh
2361731Sjkh/// Variant value class.
2371731Sjkh///
2382570Srgrimes/// Basically, a tagged union with value type semantics.
2392570Srgrimes/// It is used by the registry as the return value and argument type for the
2401731Sjkh/// matcher factory methods.
2412570Srgrimes/// It can be constructed from any of the supported types. It supports
2422570Srgrimes/// copy/assignment.
2431731Sjkh///
2442570Srgrimes/// Supported types:
2452570Srgrimes///  - \c bool
2461731Sjkh//   - \c double
24737Srgrimes///  - \c unsigned
2481759Sjkh///  - \c llvm::StringRef
2491759Sjkh///  - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
25037Srgrimesclass VariantValue {
2511759Sjkhpublic:
2521759Sjkh  VariantValue() : Type(VT_Nothing) {}
2531759Sjkh
2541759Sjkh  VariantValue(const VariantValue &Other);
2551731Sjkh  ~VariantValue();
256320Srgrimes  VariantValue &operator=(const VariantValue &Other);
2571759Sjkh
2581731Sjkh  /// Specific constructors for each supported type.
259320Srgrimes  VariantValue(bool Boolean);
260320Srgrimes  VariantValue(double Double);
261358Srgrimes  VariantValue(unsigned Unsigned);
262568Srgrimes  VariantValue(StringRef String);
2631672Sjkh  VariantValue(const VariantMatcher &Matchers);
2641762Sjkh
2651027Sache  /// Constructs an \c unsigned value (disambiguation from bool).
2661027Sache  VariantValue(int Signed) : VariantValue(static_cast<unsigned>(Signed)) {}
2671731Sjkh
268333Srgrimes  /// Returns true iff this is not an empty value.
269284Srgrimes  explicit operator bool() const { return hasValue(); }
270320Srgrimes  bool hasValue() const { return Type != VT_Nothing; }
2712570Srgrimes
272284Srgrimes  /// Boolean value functions.
273320Srgrimes  bool isBoolean() const;
2741731Sjkh  bool getBoolean() const;
2751731Sjkh  void setBoolean(bool Boolean);
2761731Sjkh
2771762Sjkh  /// Double value functions.
2781194Srgrimes  bool isDouble() const;
2791194Srgrimes  double getDouble() const;
2801194Srgrimes  void setDouble(double Double);
2811194Srgrimes
282320Srgrimes  /// Unsigned value functions.
2831205Srgrimes  bool isUnsigned() const;
2842570Srgrimes  unsigned getUnsigned() const;
2851759Sjkh  void setUnsigned(unsigned Unsigned);
2861731Sjkh
287277Srgrimes  /// String value functions.
2881027Sache  bool isString() const;
2891027Sache  const std::string &getString() const;
2901205Srgrimes  void setString(StringRef String);
291358Srgrimes
2921205Srgrimes  /// Matcher value functions.
2931782Sjkh  bool isMatcher() const;
294277Srgrimes  const VariantMatcher &getMatcher() const;
2951205Srgrimes  void setMatcher(const VariantMatcher &Matcher);
2962570Srgrimes
2971759Sjkh  /// Determines if the contained value can be converted to \p Kind.
2981731Sjkh  ///
299320Srgrimes  /// \param Kind the requested destination type.
3001027Sache  ///
3011027Sache  /// \param Specificity value corresponding to the "specificity" of the
3021205Srgrimes  ///   conversion.
303358Srgrimes  bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
3041205Srgrimes
3051782Sjkh  /// Determines if the contained value can be converted to any kind
306320Srgrimes  /// in \p Kinds.
3071285Srgrimes  ///
3082570Srgrimes  /// \param Kinds the requested destination types.
3091371Srgrimes  ///
3101371Srgrimes  /// \param Specificity value corresponding to the "specificity" of the
3111371Srgrimes  ///   conversion. It is the maximum specificity of all the possible
3121371Srgrimes  ///   conversions.
3131371Srgrimes  bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
3141285Srgrimes
3151731Sjkh  /// String representation of the type of the value.
3161285Srgrimes  std::string getTypeAsString() const;
3171731Sjkh
3181731Sjkhprivate:
3191731Sjkh  void reset();
3201731Sjkh
3211285Srgrimes  /// All supported value types.
3221285Srgrimes  enum ValueType {
3232570Srgrimes    VT_Nothing,
3241759Sjkh    VT_Boolean,
3251731Sjkh    VT_Double,
3261285Srgrimes    VT_Unsigned,
3271285Srgrimes    VT_String,
3281285Srgrimes    VT_Matcher
3291285Srgrimes  };
3301285Srgrimes
3311285Srgrimes  /// All supported value types.
3321782Sjkh  union AllValues {
3331285Srgrimes    unsigned Unsigned;
3341285Srgrimes    double Double;
3352570Srgrimes    bool Boolean;
3361759Sjkh    std::string *String;
3371731Sjkh    VariantMatcher *Matcher;
3381285Srgrimes  };
3391285Srgrimes
3401285Srgrimes  ValueType Type;
3411285Srgrimes  AllValues Value;
3421285Srgrimes};
3431285Srgrimes
3441782Sjkh} // end namespace dynamic
3451285Srgrimes} // end namespace ast_matchers
3461205Srgrimes} // end namespace clang
347568Srgrimes
3481672Sjkh#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
349568Srgrimes