clang API Documentation
00001 //===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/ 00002 // The LLVM Compiler Infrastructure 00003 // 00004 // This file is distributed under the University of Illinois Open Source 00005 // License. See LICENSE.TXT for details. 00006 // 00007 //===----------------------------------------------------------------------===// 00008 /// 00009 /// \file 00010 /// \brief Polymorphic value type. 00011 /// 00012 /// Supports all the types required for dynamic Matcher construction. 00013 /// Used by the registry to construct matchers in a generic way. 00014 /// 00015 //===----------------------------------------------------------------------===// 00016 00017 #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H 00018 #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H 00019 00020 #include "clang/ASTMatchers/ASTMatchers.h" 00021 #include "clang/ASTMatchers/ASTMatchersInternal.h" 00022 #include "llvm/ADT/IntrusiveRefCntPtr.h" 00023 #include "llvm/ADT/Optional.h" 00024 #include "llvm/ADT/Twine.h" 00025 #include <memory> 00026 #include <vector> 00027 00028 namespace clang { 00029 namespace ast_matchers { 00030 namespace dynamic { 00031 00032 /// \brief Kind identifier. 00033 /// 00034 /// It supports all types that VariantValue can contain. 00035 class ArgKind { 00036 public: 00037 enum Kind { 00038 AK_Matcher, 00039 AK_Unsigned, 00040 AK_String 00041 }; 00042 /// \brief Constructor for non-matcher types. 00043 ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); } 00044 00045 /// \brief Constructor for matcher types. 00046 ArgKind(ast_type_traits::ASTNodeKind MatcherKind) 00047 : K(AK_Matcher), MatcherKind(MatcherKind) {} 00048 00049 Kind getArgKind() const { return K; } 00050 ast_type_traits::ASTNodeKind getMatcherKind() const { 00051 assert(K == AK_Matcher); 00052 return MatcherKind; 00053 } 00054 00055 /// \brief Determines if this type can be converted to \p To. 00056 /// 00057 /// \param To the requested destination type. 00058 /// 00059 /// \param Specificity value corresponding to the "specificity" of the 00060 /// convertion. 00061 bool isConvertibleTo(ArgKind To, unsigned *Specificity) const; 00062 00063 bool operator<(const ArgKind &Other) const { 00064 if (K == AK_Matcher && Other.K == AK_Matcher) 00065 return MatcherKind < Other.MatcherKind; 00066 return K < Other.K; 00067 } 00068 00069 /// \brief String representation of the type. 00070 std::string asString() const; 00071 00072 private: 00073 Kind K; 00074 ast_type_traits::ASTNodeKind MatcherKind; 00075 }; 00076 00077 using ast_matchers::internal::DynTypedMatcher; 00078 00079 /// \brief A variant matcher object. 00080 /// 00081 /// The purpose of this object is to abstract simple and polymorphic matchers 00082 /// into a single object type. 00083 /// Polymorphic matchers might be implemented as a list of all the possible 00084 /// overloads of the matcher. \c VariantMatcher knows how to select the 00085 /// appropriate overload when needed. 00086 /// To get a real matcher object out of a \c VariantMatcher you can do: 00087 /// - getSingleMatcher() which returns a matcher, only if it is not ambiguous 00088 /// to decide which matcher to return. Eg. it contains only a single 00089 /// matcher, or a polymorphic one with only one overload. 00090 /// - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if 00091 /// the underlying matcher(s) can unambiguously return a Matcher<T>. 00092 class VariantMatcher { 00093 /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher. 00094 class MatcherOps { 00095 public: 00096 MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {} 00097 00098 bool canConstructFrom(const DynTypedMatcher &Matcher, 00099 bool &IsExactMatch) const; 00100 00101 /// \brief Convert \p Matcher the destination type and return it as a new 00102 /// DynTypedMatcher. 00103 virtual DynTypedMatcher 00104 convertMatcher(const DynTypedMatcher &Matcher) const = 0; 00105 00106 /// \brief Constructs a variadic typed matcher from \p InnerMatchers. 00107 /// Will try to convert each inner matcher to the destination type and 00108 /// return llvm::None if it fails to do so. 00109 llvm::Optional<DynTypedMatcher> 00110 constructVariadicOperator(DynTypedMatcher::VariadicOperatorFunction Func, 00111 ArrayRef<VariantMatcher> InnerMatchers) const; 00112 00113 protected: 00114 ~MatcherOps() {} 00115 00116 private: 00117 ast_type_traits::ASTNodeKind NodeKind; 00118 }; 00119 00120 /// \brief Payload interface to be specialized by each matcher type. 00121 /// 00122 /// It follows a similar interface as VariantMatcher itself. 00123 class Payload : public RefCountedBaseVPTR { 00124 public: 00125 virtual ~Payload(); 00126 virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0; 00127 virtual std::string getTypeAsString() const = 0; 00128 virtual llvm::Optional<DynTypedMatcher> 00129 getTypedMatcher(const MatcherOps &Ops) const = 0; 00130 virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, 00131 unsigned *Specificity) const = 0; 00132 }; 00133 00134 public: 00135 /// \brief A null matcher. 00136 VariantMatcher(); 00137 00138 /// \brief Clones the provided matcher. 00139 static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher); 00140 00141 /// \brief Clones the provided matchers. 00142 /// 00143 /// They should be the result of a polymorphic matcher. 00144 static VariantMatcher 00145 PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers); 00146 00147 /// \brief Creates a 'variadic' operator matcher. 00148 /// 00149 /// It will bind to the appropriate type on getTypedMatcher<T>(). 00150 static VariantMatcher 00151 VariadicOperatorMatcher(DynTypedMatcher::VariadicOperatorFunction Func, 00152 std::vector<VariantMatcher> Args); 00153 00154 /// \brief Makes the matcher the "null" matcher. 00155 void reset(); 00156 00157 /// \brief Whether the matcher is null. 00158 bool isNull() const { return !Value; } 00159 00160 /// \brief Return a single matcher, if there is no ambiguity. 00161 /// 00162 /// \returns the matcher, if there is only one matcher. An empty Optional, if 00163 /// the underlying matcher is a polymorphic matcher with more than one 00164 /// representation. 00165 llvm::Optional<DynTypedMatcher> getSingleMatcher() const; 00166 00167 /// \brief Determines if the contained matcher can be converted to 00168 /// \c Matcher<T>. 00169 /// 00170 /// For the Single case, it returns true if it can be converted to 00171 /// \c Matcher<T>. 00172 /// For the Polymorphic case, it returns true if one, and only one, of the 00173 /// overloads can be converted to \c Matcher<T>. If there are more than one 00174 /// that can, the result would be ambiguous and false is returned. 00175 template <class T> 00176 bool hasTypedMatcher() const { 00177 if (!Value) return false; 00178 return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue(); 00179 } 00180 00181 /// \brief Determines if the contained matcher can be converted to \p Kind. 00182 /// 00183 /// \param Kind the requested destination type. 00184 /// 00185 /// \param Specificity value corresponding to the "specificity" of the 00186 /// convertion. 00187 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, 00188 unsigned *Specificity) const { 00189 if (Value) 00190 return Value->isConvertibleTo(Kind, Specificity); 00191 return false; 00192 } 00193 00194 /// \brief Return this matcher as a \c Matcher<T>. 00195 /// 00196 /// Handles the different types (Single, Polymorphic) accordingly. 00197 /// Asserts that \c hasTypedMatcher<T>() is true. 00198 template <class T> 00199 ast_matchers::internal::Matcher<T> getTypedMatcher() const { 00200 assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false"); 00201 return Value->getTypedMatcher(TypedMatcherOps<T>()) 00202 ->template convertTo<T>(); 00203 } 00204 00205 /// \brief String representation of the type of the value. 00206 /// 00207 /// If the underlying matcher is a polymorphic one, the string will show all 00208 /// the types. 00209 std::string getTypeAsString() const; 00210 00211 private: 00212 explicit VariantMatcher(Payload *Value) : Value(Value) {} 00213 00214 template <typename T> struct TypedMatcherOps; 00215 00216 class SinglePayload; 00217 class PolymorphicPayload; 00218 class VariadicOpPayload; 00219 00220 IntrusiveRefCntPtr<const Payload> Value; 00221 }; 00222 00223 template <typename T> 00224 struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps { 00225 TypedMatcherOps() 00226 : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {} 00227 typedef ast_matchers::internal::Matcher<T> MatcherT; 00228 00229 DynTypedMatcher 00230 convertMatcher(const DynTypedMatcher &Matcher) const override { 00231 return DynTypedMatcher(Matcher.convertTo<T>()); 00232 } 00233 }; 00234 00235 /// \brief Variant value class. 00236 /// 00237 /// Basically, a tagged union with value type semantics. 00238 /// It is used by the registry as the return value and argument type for the 00239 /// matcher factory methods. 00240 /// It can be constructed from any of the supported types. It supports 00241 /// copy/assignment. 00242 /// 00243 /// Supported types: 00244 /// - \c unsigned 00245 /// - \c std::string 00246 /// - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>) 00247 class VariantValue { 00248 public: 00249 VariantValue() : Type(VT_Nothing) {} 00250 00251 VariantValue(const VariantValue &Other); 00252 ~VariantValue(); 00253 VariantValue &operator=(const VariantValue &Other); 00254 00255 /// \brief Specific constructors for each supported type. 00256 VariantValue(unsigned Unsigned); 00257 VariantValue(const std::string &String); 00258 VariantValue(const VariantMatcher &Matchers); 00259 00260 /// \brief Returns true iff this is not an empty value. 00261 LLVM_EXPLICIT operator bool() const { return hasValue(); } 00262 bool hasValue() const { return Type != VT_Nothing; } 00263 00264 /// \brief Unsigned value functions. 00265 bool isUnsigned() const; 00266 unsigned getUnsigned() const; 00267 void setUnsigned(unsigned Unsigned); 00268 00269 /// \brief String value functions. 00270 bool isString() const; 00271 const std::string &getString() const; 00272 void setString(const std::string &String); 00273 00274 /// \brief Matcher value functions. 00275 bool isMatcher() const; 00276 const VariantMatcher &getMatcher() const; 00277 void setMatcher(const VariantMatcher &Matcher); 00278 00279 /// \brief Determines if the contained value can be converted to \p Kind. 00280 /// 00281 /// \param Kind the requested destination type. 00282 /// 00283 /// \param Specificity value corresponding to the "specificity" of the 00284 /// convertion. 00285 bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const; 00286 00287 /// \brief Determines if the contained value can be converted to any kind 00288 /// in \p Kinds. 00289 /// 00290 /// \param Kinds the requested destination types. 00291 /// 00292 /// \param Specificity value corresponding to the "specificity" of the 00293 /// convertion. It is the maximum specificity of all the possible 00294 /// conversions. 00295 bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const; 00296 00297 /// \brief String representation of the type of the value. 00298 std::string getTypeAsString() const; 00299 00300 private: 00301 void reset(); 00302 00303 /// \brief All supported value types. 00304 enum ValueType { 00305 VT_Nothing, 00306 VT_Unsigned, 00307 VT_String, 00308 VT_Matcher 00309 }; 00310 00311 /// \brief All supported value types. 00312 union AllValues { 00313 unsigned Unsigned; 00314 std::string *String; 00315 VariantMatcher *Matcher; 00316 }; 00317 00318 ValueType Type; 00319 AllValues Value; 00320 }; 00321 00322 } // end namespace dynamic 00323 } // end namespace ast_matchers 00324 } // end namespace clang 00325 00326 #endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H