]> granicus.if.org Git - clang/blob - include/clang/ASTMatchers/Dynamic/VariantValue.h
8b38ec8e5955e2d89aa13cdf09a791a32d28c048
[clang] / include / clang / ASTMatchers / Dynamic / VariantValue.h
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_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
18 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_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 "llvm/ADT/Twine.h"
25 #include <memory>
26 #include <vector>
27
28 namespace clang {
29 namespace ast_matchers {
30 namespace dynamic {
31
32 /// \brief Kind identifier.
33 ///
34 /// It supports all types that VariantValue can contain.
35 class ArgKind {
36  public:
37   enum Kind {
38     AK_Matcher,
39     AK_Unsigned,
40     AK_String
41   };
42   /// \brief Constructor for non-matcher types.
43   ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
44
45   /// \brief Constructor for matcher types.
46   ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
47       : K(AK_Matcher), MatcherKind(MatcherKind) {}
48
49   Kind getArgKind() const { return K; }
50   ast_type_traits::ASTNodeKind getMatcherKind() const {
51     assert(K == AK_Matcher);
52     return MatcherKind;
53   }
54
55   /// \brief Determines if this type can be converted to \p To.
56   ///
57   /// \param To the requested destination type.
58   ///
59   /// \param Specificity value corresponding to the "specificity" of the
60   ///   convertion.
61   bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
62
63   bool operator<(const ArgKind &Other) const {
64     if (K == AK_Matcher && Other.K == AK_Matcher)
65       return MatcherKind < Other.MatcherKind;
66     return K < Other.K;
67   }
68
69   /// \brief String representation of the type.
70   std::string asString() const;
71
72 private:
73   Kind K;
74   ast_type_traits::ASTNodeKind MatcherKind;
75 };
76
77 using ast_matchers::internal::DynTypedMatcher;
78
79 /// \brief A variant matcher object.
80 ///
81 /// The purpose of this object is to abstract simple and polymorphic matchers
82 /// into a single object type.
83 /// Polymorphic matchers might be implemented as a list of all the possible
84 /// overloads of the matcher. \c VariantMatcher knows how to select the
85 /// appropriate overload when needed.
86 /// To get a real matcher object out of a \c VariantMatcher you can do:
87 ///  - getSingleMatcher() which returns a matcher, only if it is not ambiguous
88 ///    to decide which matcher to return. Eg. it contains only a single
89 ///    matcher, or a polymorphic one with only one overload.
90 ///  - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
91 ///    the underlying matcher(s) can unambiguously return a Matcher<T>.
92 class VariantMatcher {
93   /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
94   class MatcherOps {
95   public:
96     virtual ~MatcherOps();
97     virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
98                                   bool &IsExactMatch) const = 0;
99     virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
100     virtual void constructVariadicOperator(
101         ast_matchers::internal::VariadicOperatorFunction Func,
102         ArrayRef<VariantMatcher> InnerMatchers) = 0;
103   };
104
105   /// \brief Payload interface to be specialized by each matcher type.
106   ///
107   /// It follows a similar interface as VariantMatcher itself.
108   class Payload : public RefCountedBaseVPTR {
109   public:
110     virtual ~Payload();
111     virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
112     virtual std::string getTypeAsString() const = 0;
113     virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;
114     virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
115                                  unsigned *Specificity) const = 0;
116   };
117
118 public:
119   /// \brief A null matcher.
120   VariantMatcher();
121
122   /// \brief Clones the provided matcher.
123   static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
124
125   /// \brief Clones the provided matchers.
126   ///
127   /// They should be the result of a polymorphic matcher.
128   static VariantMatcher
129   PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
130
131   /// \brief Creates a 'variadic' operator matcher.
132   ///
133   /// It will bind to the appropriate type on getTypedMatcher<T>().
134   static VariantMatcher VariadicOperatorMatcher(
135       ast_matchers::internal::VariadicOperatorFunction Func,
136       std::vector<VariantMatcher> Args);
137
138   /// \brief Makes the matcher the "null" matcher.
139   void reset();
140
141   /// \brief Whether the matcher is null.
142   bool isNull() const { return !Value; }
143
144   /// \brief Return a single matcher, if there is no ambiguity.
145   ///
146   /// \returns the matcher, if there is only one matcher. An empty Optional, if
147   /// the underlying matcher is a polymorphic matcher with more than one
148   /// representation.
149   llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
150
151   /// \brief Determines if the contained matcher can be converted to
152   ///   \c Matcher<T>.
153   ///
154   /// For the Single case, it returns true if it can be converted to
155   /// \c Matcher<T>.
156   /// For the Polymorphic case, it returns true if one, and only one, of the
157   /// overloads can be converted to \c Matcher<T>. If there are more than one
158   /// that can, the result would be ambiguous and false is returned.
159   template <class T>
160   bool hasTypedMatcher() const {
161     TypedMatcherOps<T> Ops;
162     if (Value) Value->makeTypedMatcher(Ops);
163     return Ops.hasMatcher();
164   }
165
166   /// \brief Determines if the contained matcher can be converted to \p Kind.
167   ///
168   /// \param Kind the requested destination type.
169   ///
170   /// \param Specificity value corresponding to the "specificity" of the
171   ///   convertion.
172   bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
173                        unsigned *Specificity) const {
174     if (Value)
175       return Value->isConvertibleTo(Kind, Specificity);
176     return false;
177   }
178
179   /// \brief Return this matcher as a \c Matcher<T>.
180   ///
181   /// Handles the different types (Single, Polymorphic) accordingly.
182   /// Asserts that \c hasTypedMatcher<T>() is true.
183   template <class T>
184   ast_matchers::internal::Matcher<T> getTypedMatcher() const {
185     TypedMatcherOps<T> Ops;
186     Value->makeTypedMatcher(Ops);
187     assert(Ops.hasMatcher() && "hasTypedMatcher<T>() == false");
188     return Ops.matcher();
189   }
190
191   /// \brief String representation of the type of the value.
192   ///
193   /// If the underlying matcher is a polymorphic one, the string will show all
194   /// the types.
195   std::string getTypeAsString() const;
196
197 private:
198   explicit VariantMatcher(Payload *Value) : Value(Value) {}
199
200   class SinglePayload;
201   class PolymorphicPayload;
202   class VariadicOpPayload;
203
204   template <typename T>
205   class TypedMatcherOps : public MatcherOps {
206   public:
207     typedef ast_matchers::internal::Matcher<T> MatcherT;
208
209     virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
210                                   bool &IsExactMatch) const {
211       IsExactMatch = Matcher.getSupportedKind().isSame(
212           ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
213       return Matcher.canConvertTo<T>();
214     }
215
216     virtual void constructFrom(const DynTypedMatcher& Matcher) {
217       Out.reset(new MatcherT(Matcher.convertTo<T>()));
218     }
219
220     virtual void constructVariadicOperator(
221         ast_matchers::internal::VariadicOperatorFunction Func,
222         ArrayRef<VariantMatcher> InnerMatchers) {
223       std::vector<DynTypedMatcher> DynMatchers;
224       for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
225         // Abort if any of the inner matchers can't be converted to
226         // Matcher<T>.
227         if (!InnerMatchers[i].hasTypedMatcher<T>()) {
228           return;
229         }
230         DynMatchers.push_back(InnerMatchers[i].getTypedMatcher<T>());
231       }
232       Out.reset(new MatcherT(
233           new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
234               Func, DynMatchers)));
235     }
236
237     bool hasMatcher() const { return Out.get() != nullptr; }
238     const MatcherT &matcher() const { return *Out; }
239
240   private:
241     std::unique_ptr<MatcherT> Out;
242   };
243
244   IntrusiveRefCntPtr<const Payload> Value;
245 };
246
247 /// \brief Variant value class.
248 ///
249 /// Basically, a tagged union with value type semantics.
250 /// It is used by the registry as the return value and argument type for the
251 /// matcher factory methods.
252 /// It can be constructed from any of the supported types. It supports
253 /// copy/assignment.
254 ///
255 /// Supported types:
256 ///  - \c unsigned
257 ///  - \c std::string
258 ///  - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
259 class VariantValue {
260 public:
261   VariantValue() : Type(VT_Nothing) {}
262
263   VariantValue(const VariantValue &Other);
264   ~VariantValue();
265   VariantValue &operator=(const VariantValue &Other);
266
267   /// \brief Specific constructors for each supported type.
268   VariantValue(unsigned Unsigned);
269   VariantValue(const std::string &String);
270   VariantValue(const VariantMatcher &Matchers);
271
272   /// \brief Returns true iff this is not an empty value.
273   LLVM_EXPLICIT operator bool() const { return hasValue(); }
274   bool hasValue() const { return Type != VT_Nothing; }
275
276   /// \brief Unsigned value functions.
277   bool isUnsigned() const;
278   unsigned getUnsigned() const;
279   void setUnsigned(unsigned Unsigned);
280
281   /// \brief String value functions.
282   bool isString() const;
283   const std::string &getString() const;
284   void setString(const std::string &String);
285
286   /// \brief Matcher value functions.
287   bool isMatcher() const;
288   const VariantMatcher &getMatcher() const;
289   void setMatcher(const VariantMatcher &Matcher);
290
291   /// \brief Determines if the contained value can be converted to \p Kind.
292   ///
293   /// \param Kind the requested destination type.
294   ///
295   /// \param Specificity value corresponding to the "specificity" of the
296   ///   convertion.
297   bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
298
299   /// \brief Determines if the contained value can be converted to any kind
300   /// in \p Kinds.
301   ///
302   /// \param Kinds the requested destination types.
303   ///
304   /// \param Specificity value corresponding to the "specificity" of the
305   ///   convertion. It is the maximum specificity of all the possible
306   ///   conversions.
307   bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
308
309   /// \brief String representation of the type of the value.
310   std::string getTypeAsString() const;
311
312 private:
313   void reset();
314
315   /// \brief All supported value types.
316   enum ValueType {
317     VT_Nothing,
318     VT_Unsigned,
319     VT_String,
320     VT_Matcher
321   };
322
323   /// \brief All supported value types.
324   union AllValues {
325     unsigned Unsigned;
326     std::string *String;
327     VariantMatcher *Matcher;
328   };
329
330   ValueType Type;
331   AllValues Value;
332 };
333
334 } // end namespace dynamic
335 } // end namespace ast_matchers
336 } // end namespace clang
337
338 #endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H