]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / 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 <vector>
21
22 #include "clang/ASTMatchers/ASTMatchers.h"
23 #include "clang/ASTMatchers/ASTMatchersInternal.h"
24 #include "llvm/ADT/IntrusiveRefCntPtr.h"
25 #include "llvm/ADT/Optional.h"
26 #include "llvm/ADT/Twine.h"
27 #include "llvm/Support/type_traits.h"
28
29 namespace clang {
30 namespace ast_matchers {
31 namespace dynamic {
32
33 using ast_matchers::internal::DynTypedMatcher;
34
35 /// \brief A variant matcher object.
36 ///
37 /// The purpose of this object is to abstract simple and polymorphic matchers
38 /// into a single object type.
39 /// Polymorphic matchers might be implemented as a list of all the possible
40 /// overloads of the matcher. \c VariantMatcher knows how to select the
41 /// appropriate overload when needed.
42 /// To get a real matcher object out of a \c VariantMatcher you can do:
43 ///  - getSingleMatcher() which returns a matcher, only if it is not ambiguous
44 ///    to decide which matcher to return. Eg. it contains only a single
45 ///    matcher, or a polymorphic one with only one overload.
46 ///  - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
47 ///    the underlying matcher(s) can unambiguously return a Matcher<T>.
48 class VariantMatcher {
49   /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
50   class MatcherOps {
51   public:
52     virtual ~MatcherOps();
53     virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const = 0;
54     virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
55     virtual void constructVariadicOperator(
56         ast_matchers::internal::VariadicOperatorFunction Func,
57         ArrayRef<VariantMatcher> InnerMatchers) = 0;
58   };
59
60   /// \brief Payload interface to be specialized by each matcher type.
61   ///
62   /// It follows a similar interface as VariantMatcher itself.
63   class Payload : public RefCountedBaseVPTR {
64   public:
65     virtual ~Payload();
66     virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
67     virtual std::string getTypeAsString() const = 0;
68     virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;
69   };
70
71 public:
72   /// \brief A null matcher.
73   VariantMatcher();
74
75   /// \brief Clones the provided matcher.
76   static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
77
78   /// \brief Clones the provided matchers.
79   ///
80   /// They should be the result of a polymorphic matcher.
81   static VariantMatcher PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers);
82
83   /// \brief Creates a 'variadic' operator matcher.
84   ///
85   /// It will bind to the appropriate type on getTypedMatcher<T>().
86   static VariantMatcher VariadicOperatorMatcher(
87       ast_matchers::internal::VariadicOperatorFunction Func,
88       ArrayRef<VariantMatcher> Args);
89
90   /// \brief Makes the matcher the "null" matcher.
91   void reset();
92
93   /// \brief Whether the matcher is null.
94   bool isNull() const { return !Value; }
95
96   /// \brief Return a single matcher, if there is no ambiguity.
97   ///
98   /// \returns the matcher, if there is only one matcher. An empty Optional, if
99   /// the underlying matcher is a polymorphic matcher with more than one
100   /// representation.
101   llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
102
103   /// \brief Determines if the contained matcher can be converted to
104   ///   \c Matcher<T>.
105   ///
106   /// For the Single case, it returns true if it can be converted to
107   /// \c Matcher<T>.
108   /// For the Polymorphic case, it returns true if one, and only one, of the
109   /// overloads can be converted to \c Matcher<T>. If there are more than one
110   /// that can, the result would be ambiguous and false is returned.
111   template <class T>
112   bool hasTypedMatcher() const {
113     TypedMatcherOps<T> Ops;
114     if (Value) Value->makeTypedMatcher(Ops);
115     return Ops.hasMatcher();
116   }
117
118   /// \brief Return this matcher as a \c Matcher<T>.
119   ///
120   /// Handles the different types (Single, Polymorphic) accordingly.
121   /// Asserts that \c hasTypedMatcher<T>() is true.
122   template <class T>
123   ast_matchers::internal::Matcher<T> getTypedMatcher() const {
124     TypedMatcherOps<T> Ops;
125     Value->makeTypedMatcher(Ops);
126     assert(Ops.hasMatcher() && "hasTypedMatcher<T>() == false");
127     return Ops.matcher();
128   }
129
130   /// \brief String representation of the type of the value.
131   ///
132   /// If the underlying matcher is a polymorphic one, the string will show all
133   /// the types.
134   std::string getTypeAsString() const;
135
136 private:
137   explicit VariantMatcher(Payload *Value) : Value(Value) {}
138
139   class SinglePayload;
140   class PolymorphicPayload;
141   class VariadicOpPayload;
142
143   template <typename T>
144   class TypedMatcherOps : public MatcherOps {
145   public:
146     typedef ast_matchers::internal::Matcher<T> MatcherT;
147
148     virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const {
149       return Matcher.canConvertTo<T>();
150     }
151
152     virtual void constructFrom(const DynTypedMatcher& Matcher) {
153       Out.reset(new MatcherT(Matcher.convertTo<T>()));
154     }
155
156     virtual void constructVariadicOperator(
157         ast_matchers::internal::VariadicOperatorFunction Func,
158         ArrayRef<VariantMatcher> InnerMatchers) {
159       const size_t NumArgs = InnerMatchers.size();
160       MatcherT **InnerArgs = new MatcherT *[NumArgs]();
161       bool HasError = false;
162       for (size_t i = 0; i != NumArgs; ++i) {
163         // Abort if any of the inner matchers can't be converted to
164         // Matcher<T>.
165         if (!InnerMatchers[i].hasTypedMatcher<T>()) {
166           HasError = true;
167           break;
168         }
169         InnerArgs[i] = new MatcherT(InnerMatchers[i].getTypedMatcher<T>());
170       }
171       if (!HasError) {
172         Out.reset(new MatcherT(
173             new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
174                 Func, ArrayRef<const MatcherT *>(InnerArgs, NumArgs))));
175       }
176       for (size_t i = 0; i != NumArgs; ++i) {
177         delete InnerArgs[i];
178       }
179       delete[] InnerArgs;
180     }
181
182     bool hasMatcher() const { return Out.get() != NULL; }
183     const MatcherT &matcher() const { return *Out; }
184
185   private:
186     OwningPtr<MatcherT> Out;
187   };
188
189   IntrusiveRefCntPtr<const Payload> Value;
190 };
191
192 /// \brief Variant value class.
193 ///
194 /// Basically, a tagged union with value type semantics.
195 /// It is used by the registry as the return value and argument type for the
196 /// matcher factory methods.
197 /// It can be constructed from any of the supported types. It supports
198 /// copy/assignment.
199 ///
200 /// Supported types:
201 ///  - \c unsigned
202 ///  - \c std::string
203 ///  - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
204 class VariantValue {
205 public:
206   VariantValue() : Type(VT_Nothing) {}
207
208   VariantValue(const VariantValue &Other);
209   ~VariantValue();
210   VariantValue &operator=(const VariantValue &Other);
211
212   /// \brief Specific constructors for each supported type.
213   VariantValue(unsigned Unsigned);
214   VariantValue(const std::string &String);
215   VariantValue(const VariantMatcher &Matchers);
216
217   /// \brief Unsigned value functions.
218   bool isUnsigned() const;
219   unsigned getUnsigned() const;
220   void setUnsigned(unsigned Unsigned);
221
222   /// \brief String value functions.
223   bool isString() const;
224   const std::string &getString() const;
225   void setString(const std::string &String);
226
227   /// \brief Matcher value functions.
228   bool isMatcher() const;
229   const VariantMatcher &getMatcher() const;
230   void setMatcher(const VariantMatcher &Matcher);
231
232   /// \brief String representation of the type of the value.
233   std::string getTypeAsString() const;
234
235 private:
236   void reset();
237
238   /// \brief All supported value types.
239   enum ValueType {
240     VT_Nothing,
241     VT_Unsigned,
242     VT_String,
243     VT_Matcher
244   };
245
246   /// \brief All supported value types.
247   union AllValues {
248     unsigned Unsigned;
249     std::string *String;
250     VariantMatcher *Matcher;
251   };
252
253   ValueType Type;
254   AllValues Value;
255 };
256
257 } // end namespace dynamic
258 } // end namespace ast_matchers
259 } // end namespace clang
260
261 #endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H