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 <memory> 25 #include <vector> 26 27 namespace clang { 28 namespace ast_matchers { 29 namespace dynamic { 30 31 /// \brief Kind identifier. 32 /// 33 /// It supports all types that VariantValue can contain. 34 class ArgKind { 35 public: 36 enum Kind { 37 AK_Matcher, 38 AK_Unsigned, 39 AK_String 40 }; 41 /// \brief Constructor for non-matcher types. 42 ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); } 43 44 /// \brief Constructor for matcher types. 45 ArgKind(ast_type_traits::ASTNodeKind MatcherKind) 46 : K(AK_Matcher), MatcherKind(MatcherKind) {} 47 48 Kind getArgKind() const { return K; } 49 ast_type_traits::ASTNodeKind getMatcherKind() const { 50 assert(K == AK_Matcher); 51 return MatcherKind; 52 } 53 54 /// \brief Determines if this type can be converted to \p To. 55 /// 56 /// \param To the requested destination type. 57 /// 58 /// \param Specificity value corresponding to the "specificity" of the 59 /// conversion. 60 bool isConvertibleTo(ArgKind To, unsigned *Specificity) const; 61 62 bool operator<(const ArgKind &Other) const { 63 if (K == AK_Matcher && Other.K == AK_Matcher) 64 return MatcherKind < Other.MatcherKind; 65 return K < Other.K; 66 } 67 68 /// \brief String representation of the type. 69 std::string asString() const; 70 71 private: 72 Kind K; 73 ast_type_traits::ASTNodeKind MatcherKind; 74 }; 75 76 using ast_matchers::internal::DynTypedMatcher; 77 78 /// \brief A variant matcher object. 79 /// 80 /// The purpose of this object is to abstract simple and polymorphic matchers 81 /// into a single object type. 82 /// Polymorphic matchers might be implemented as a list of all the possible 83 /// overloads of the matcher. \c VariantMatcher knows how to select the 84 /// appropriate overload when needed. 85 /// To get a real matcher object out of a \c VariantMatcher you can do: 86 /// - getSingleMatcher() which returns a matcher, only if it is not ambiguous 87 /// to decide which matcher to return. Eg. it contains only a single 88 /// matcher, or a polymorphic one with only one overload. 89 /// - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if 90 /// the underlying matcher(s) can unambiguously return a Matcher<T>. 91 class VariantMatcher { 92 /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher. 93 class MatcherOps { 94 public: 95 MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {} 96 97 bool canConstructFrom(const DynTypedMatcher &Matcher, 98 bool &IsExactMatch) const; 99 100 /// \brief Convert \p Matcher the destination type and return it as a new 101 /// DynTypedMatcher. 102 virtual DynTypedMatcher 103 convertMatcher(const DynTypedMatcher &Matcher) const = 0; 104 105 /// \brief Constructs a variadic typed matcher from \p InnerMatchers. 106 /// Will try to convert each inner matcher to the destination type and 107 /// return llvm::None if it fails to do so. 108 llvm::Optional<DynTypedMatcher> 109 constructVariadicOperator(DynTypedMatcher::VariadicOperator Op, 110 ArrayRef<VariantMatcher> InnerMatchers) const; 111 112 protected: 113 ~MatcherOps() = default; 114 115 private: 116 ast_type_traits::ASTNodeKind NodeKind; 117 }; 118 119 /// \brief Payload interface to be specialized by each matcher type. 120 /// 121 /// It follows a similar interface as VariantMatcher itself. 122 class Payload { 123 public: 124 virtual ~Payload(); 125 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0; 126 virtual std::string getTypeAsString() const = 0; 127 virtual llvm::Optional<DynTypedMatcher> 128 getTypedMatcher(const MatcherOps &Ops) const = 0; 129 virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, 130 unsigned *Specificity) const = 0; 131 }; 132 133 public: 134 /// \brief A null matcher. 135 VariantMatcher(); 136 137 /// \brief Clones the provided matcher. 138 static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher); 139 140 /// \brief Clones the provided matchers. 141 /// 142 /// They should be the result of a polymorphic matcher. 143 static VariantMatcher 144 PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers); 145 146 /// \brief Creates a 'variadic' operator matcher. 147 /// 148 /// It will bind to the appropriate type on getTypedMatcher<T>(). 149 static VariantMatcher 150 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, 151 std::vector<VariantMatcher> Args); 152 153 /// \brief Makes the matcher the "null" matcher. 154 void reset(); 155 156 /// \brief Whether the matcher is null. 157 bool isNull() const { return !Value; } 158 159 /// \brief Return a single matcher, if there is no ambiguity. 160 /// 161 /// \returns the matcher, if there is only one matcher. An empty Optional, if 162 /// the underlying matcher is a polymorphic matcher with more than one 163 /// representation. 164 llvm::Optional<DynTypedMatcher> getSingleMatcher() const; 165 166 /// \brief Determines if the contained matcher can be converted to 167 /// \c Matcher<T>. 168 /// 169 /// For the Single case, it returns true if it can be converted to 170 /// \c Matcher<T>. 171 /// For the Polymorphic case, it returns true if one, and only one, of the 172 /// overloads can be converted to \c Matcher<T>. If there are more than one 173 /// that can, the result would be ambiguous and false is returned. 174 template <class T> 175 bool hasTypedMatcher() const { 176 if (!Value) return false; 177 return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue(); 178 } 179 180 /// \brief Determines if the contained matcher can be converted to \p Kind. 181 /// 182 /// \param Kind the requested destination type. 183 /// 184 /// \param Specificity value corresponding to the "specificity" of the 185 /// conversion. 186 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, 187 unsigned *Specificity) const { 188 if (Value) 189 return Value->isConvertibleTo(Kind, Specificity); 190 return false; 191 } 192 193 /// \brief Return this matcher as a \c Matcher<T>. 194 /// 195 /// Handles the different types (Single, Polymorphic) accordingly. 196 /// Asserts that \c hasTypedMatcher<T>() is true. 197 template <class T> 198 ast_matchers::internal::Matcher<T> getTypedMatcher() const { 199 assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false"); 200 return Value->getTypedMatcher(TypedMatcherOps<T>()) 201 ->template convertTo<T>(); 202 } 203 204 /// \brief String representation of the type of the value. 205 /// 206 /// If the underlying matcher is a polymorphic one, the string will show all 207 /// the types. 208 std::string getTypeAsString() const; 209 210 private: 211 explicit VariantMatcher(std::shared_ptr<Payload> Value) 212 : Value(std::move(Value)) {} 213 214 template <typename T> struct TypedMatcherOps; 215 216 class SinglePayload; 217 class PolymorphicPayload; 218 class VariadicOpPayload; 219 220 std::shared_ptr<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 /// conversion. 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 /// conversion. 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