clang API Documentation

VariantValue.h
Go to the documentation of this file.
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