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