blob: d5626b22187d66d5e3aaf92c2348721b9a374054 [file] [log] [blame]
Eugene Zelenko06becf82017-11-01 23:09:49 +00001//===- Marshallers.h - Generic matcher function marshallers -----*- C++ -*-===//
Manuel Klimek24db0f02013-05-14 09:13:00 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Eugene Zelenko06becf82017-11-01 23:09:49 +00009//
Manuel Klimek24db0f02013-05-14 09:13:00 +000010/// \file
11/// \brief Functions templates and classes to wrap matcher construct functions.
12///
13/// A collection of template function and classes that provide a generic
14/// marshalling layer on top of matcher construct functions.
15/// These are used by the registry to export all marshaller constructors with
16/// the same generic interface.
Eugene Zelenko06becf82017-11-01 23:09:49 +000017//
Manuel Klimek24db0f02013-05-14 09:13:00 +000018//===----------------------------------------------------------------------===//
19
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +000020#ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
21#define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
Manuel Klimek24db0f02013-05-14 09:13:00 +000022
Eugene Zelenko06becf82017-11-01 23:09:49 +000023#include "clang/AST/ASTTypeTraits.h"
24#include "clang/AST/OperationKinds.h"
25#include "clang/ASTMatchers/ASTMatchersInternal.h"
Manuel Klimek24db0f02013-05-14 09:13:00 +000026#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
27#include "clang/ASTMatchers/Dynamic/VariantValue.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000028#include "clang/Basic/AttrKinds.h"
Manuel Klimek24db0f02013-05-14 09:13:00 +000029#include "clang/Basic/LLVM.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000030#include "llvm/ADT/ArrayRef.h"
31#include "llvm/ADT/None.h"
Samuel Benzaquen0239b692013-08-13 14:54:51 +000032#include "llvm/ADT/STLExtras.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000033#include "llvm/ADT/StringRef.h"
34#include "llvm/ADT/StringSwitch.h"
35#include "llvm/ADT/Twine.h"
36#include <cassert>
37#include <cstddef>
38#include <iterator>
39#include <limits>
40#include <memory>
Chandler Carruth5553d0d2014-01-07 11:51:46 +000041#include <string>
Eugene Zelenko06becf82017-11-01 23:09:49 +000042#include <utility>
43#include <vector>
Manuel Klimek24db0f02013-05-14 09:13:00 +000044
45namespace clang {
46namespace ast_matchers {
47namespace dynamic {
Manuel Klimek24db0f02013-05-14 09:13:00 +000048namespace internal {
49
50/// \brief Helper template class to just from argument type to the right is/get
51/// functions in VariantValue.
52/// Used to verify and extract the matcher arguments below.
53template <class T> struct ArgTypeTraits;
54template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
55};
56
57template <> struct ArgTypeTraits<std::string> {
58 static bool is(const VariantValue &Value) { return Value.isString(); }
Eugene Zelenko06becf82017-11-01 23:09:49 +000059
Manuel Klimek24db0f02013-05-14 09:13:00 +000060 static const std::string &get(const VariantValue &Value) {
61 return Value.getString();
62 }
Eugene Zelenko06becf82017-11-01 23:09:49 +000063
Peter Collingbourned32e28c2014-01-23 22:48:38 +000064 static ArgKind getKind() {
65 return ArgKind(ArgKind::AK_String);
66 }
Manuel Klimek24db0f02013-05-14 09:13:00 +000067};
68
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +000069template <>
70struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
71};
72
Eugene Zelenko06becf82017-11-01 23:09:49 +000073template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> {
Samuel Benzaquen81ef9292013-06-20 14:28:32 +000074 static bool is(const VariantValue &Value) {
Samuel Benzaquen998cda232013-08-30 15:09:52 +000075 return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
Samuel Benzaquen81ef9292013-06-20 14:28:32 +000076 }
Eugene Zelenko06becf82017-11-01 23:09:49 +000077
Manuel Klimek24db0f02013-05-14 09:13:00 +000078 static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
Samuel Benzaquen998cda232013-08-30 15:09:52 +000079 return Value.getMatcher().getTypedMatcher<T>();
Manuel Klimek24db0f02013-05-14 09:13:00 +000080 }
Eugene Zelenko06becf82017-11-01 23:09:49 +000081
Peter Collingbourned32e28c2014-01-23 22:48:38 +000082 static ArgKind getKind() {
83 return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
84 }
Samuel Benzaquenc31b3522013-06-04 15:46:22 +000085};
Manuel Klimek24db0f02013-05-14 09:13:00 +000086
Peter Wuc04b1982017-06-08 22:00:38 +000087template <> struct ArgTypeTraits<bool> {
88 static bool is(const VariantValue &Value) { return Value.isBoolean(); }
Eugene Zelenko06becf82017-11-01 23:09:49 +000089
Peter Wuc04b1982017-06-08 22:00:38 +000090 static bool get(const VariantValue &Value) {
91 return Value.getBoolean();
92 }
Eugene Zelenko06becf82017-11-01 23:09:49 +000093
Peter Wuc04b1982017-06-08 22:00:38 +000094 static ArgKind getKind() {
95 return ArgKind(ArgKind::AK_Boolean);
96 }
97};
98
Peter Wu2bbed502017-06-08 22:00:50 +000099template <> struct ArgTypeTraits<double> {
100 static bool is(const VariantValue &Value) { return Value.isDouble(); }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000101
Peter Wu2bbed502017-06-08 22:00:50 +0000102 static double get(const VariantValue &Value) {
103 return Value.getDouble();
104 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000105
Peter Wu2bbed502017-06-08 22:00:50 +0000106 static ArgKind getKind() {
107 return ArgKind(ArgKind::AK_Double);
108 }
109};
110
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000111template <> struct ArgTypeTraits<unsigned> {
112 static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000113
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000114 static unsigned get(const VariantValue &Value) {
115 return Value.getUnsigned();
116 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000117
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000118 static ArgKind getKind() {
119 return ArgKind(ArgKind::AK_Unsigned);
120 }
Manuel Klimek24db0f02013-05-14 09:13:00 +0000121};
122
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000123template <> struct ArgTypeTraits<attr::Kind> {
124private:
125 static attr::Kind getAttrKind(llvm::StringRef AttrKind) {
126 return llvm::StringSwitch<attr::Kind>(AttrKind)
127#define ATTR(X) .Case("attr::" #X, attr:: X)
128#include "clang/Basic/AttrList.inc"
129 .Default(attr::Kind(-1));
130 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000131
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000132public:
133 static bool is(const VariantValue &Value) {
134 return Value.isString() &&
135 getAttrKind(Value.getString()) != attr::Kind(-1);
136 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000137
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000138 static attr::Kind get(const VariantValue &Value) {
139 return getAttrKind(Value.getString());
140 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000141
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000142 static ArgKind getKind() {
143 return ArgKind(ArgKind::AK_String);
144 }
145};
146
Eugene Zelenko06becf82017-11-01 23:09:49 +0000147template <> struct ArgTypeTraits<CastKind> {
Etienne Bergeron75e52722016-05-13 19:36:55 +0000148private:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000149 static CastKind getCastKind(llvm::StringRef AttrKind) {
150 return llvm::StringSwitch<CastKind>(AttrKind)
Etienne Bergeron75e52722016-05-13 19:36:55 +0000151#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
152#include "clang/AST/OperationKinds.def"
153 .Default(CK_Invalid);
154 }
155
156public:
157 static bool is(const VariantValue &Value) {
158 return Value.isString() &&
159 getCastKind(Value.getString()) != CK_Invalid;
160 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000161
162 static CastKind get(const VariantValue &Value) {
Etienne Bergeron75e52722016-05-13 19:36:55 +0000163 return getCastKind(Value.getString());
164 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000165
Etienne Bergeron75e52722016-05-13 19:36:55 +0000166 static ArgKind getKind() {
167 return ArgKind(ArgKind::AK_String);
168 }
169};
170
Peter Collingbournef43e6942013-11-23 01:34:36 +0000171/// \brief Matcher descriptor interface.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000172///
Peter Collingbournef43e6942013-11-23 01:34:36 +0000173/// Provides a \c create() method that constructs the matcher from the provided
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000174/// arguments, and various other methods for type introspection.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000175class MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000176public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000177 virtual ~MatcherDescriptor() = default;
178
Craig Toppere335f252015-10-04 04:53:55 +0000179 virtual VariantMatcher create(SourceRange NameRange,
Peter Collingbournef43e6942013-11-23 01:34:36 +0000180 ArrayRef<ParserValue> Args,
181 Diagnostics *Error) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000182
183 /// Returns whether the matcher is variadic. Variadic matchers can take any
184 /// number of arguments, but they must be of the same type.
185 virtual bool isVariadic() const = 0;
186
187 /// Returns the number of arguments accepted by the matcher if not variadic.
188 virtual unsigned getNumArgs() const = 0;
189
190 /// Given that the matcher is being converted to type \p ThisKind, append the
191 /// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
192 // FIXME: We should provide the ability to constrain the output of this
193 // function based on the types of other matcher arguments.
194 virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
195 std::vector<ArgKind> &ArgKinds) const = 0;
196
197 /// Returns whether this matcher is convertible to the given type. If it is
198 /// so convertible, store in *Specificity a value corresponding to the
199 /// "specificity" of the converted matcher to the given context, and in
200 /// *LeastDerivedKind the least derived matcher kind which would result in the
201 /// same matcher overload. Zero specificity indicates that this conversion
202 /// would produce a trivial matcher that will either always or never match.
203 /// Such matchers are excluded from code completion results.
204 virtual bool isConvertibleTo(
Craig Topper210e1ad2014-05-17 18:49:24 +0000205 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
206 ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000207
208 /// Returns whether the matcher will, given a matcher of any type T, yield a
209 /// matcher of type T.
210 virtual bool isPolymorphic() const { return false; }
Manuel Klimek24db0f02013-05-14 09:13:00 +0000211};
212
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000213inline bool isRetKindConvertibleTo(
Craig Topper00bbdcf2014-06-28 23:22:23 +0000214 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000215 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
216 ast_type_traits::ASTNodeKind *LeastDerivedKind) {
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000217 for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
218 if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000219 if (LeastDerivedKind)
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000220 *LeastDerivedKind = NodeKind;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000221 return true;
222 }
223 }
224 return false;
225}
226
Manuel Klimek24db0f02013-05-14 09:13:00 +0000227/// \brief Simple callback implementation. Marshaller and function are provided.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000228///
229/// This class wraps a function of arbitrary signature and a marshaller
Peter Collingbournef43e6942013-11-23 01:34:36 +0000230/// function into a MatcherDescriptor.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000231/// The marshaller is in charge of taking the VariantValue arguments, checking
232/// their types, unpacking them and calling the underlying function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000233class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000234public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000235 using MarshallerType = VariantMatcher (*)(void (*Func)(),
236 StringRef MatcherName,
237 SourceRange NameRange,
238 ArrayRef<ParserValue> Args,
239 Diagnostics *Error);
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000240
Dmitri Gribenkocb63baf2013-05-17 17:50:16 +0000241 /// \param Marshaller Function to unpack the arguments and call \c Func
242 /// \param Func Matcher construct function. This is the function that
243 /// compile-time matcher expressions would use to create the matcher.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000244 /// \param RetKinds The list of matcher types to which the matcher is
245 /// convertible.
246 /// \param ArgKinds The types of the arguments this matcher takes.
247 FixedArgCountMatcherDescriptor(
248 MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
Craig Topper00bbdcf2014-06-28 23:22:23 +0000249 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
250 ArrayRef<ArgKind> ArgKinds)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000251 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
252 RetKinds(RetKinds.begin(), RetKinds.end()),
253 ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
Manuel Klimek24db0f02013-05-14 09:13:00 +0000254
Craig Toppere335f252015-10-04 04:53:55 +0000255 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000256 ArrayRef<ParserValue> Args,
257 Diagnostics *Error) const override {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000258 return Marshaller(Func, MatcherName, NameRange, Args, Error);
259 }
260
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000261 bool isVariadic() const override { return false; }
262 unsigned getNumArgs() const override { return ArgKinds.size(); }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000263
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000264 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000265 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000266 Kinds.push_back(ArgKinds[ArgNo]);
267 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000268
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000269 bool isConvertibleTo(
270 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
271 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000272 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
273 LeastDerivedKind);
274 }
275
Manuel Klimek24db0f02013-05-14 09:13:00 +0000276private:
277 const MarshallerType Marshaller;
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000278 void (* const Func)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000279 const std::string MatcherName;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000280 const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
281 const std::vector<ArgKind> ArgKinds;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000282};
283
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000284/// \brief Helper methods to extract and merge all possible typed matchers
285/// out of the polymorphic object.
286template <class PolyMatcher>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000287static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000288 std::vector<DynTypedMatcher> &Out,
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000289 ast_matchers::internal::EmptyTypeList) {}
290
291template <class PolyMatcher, class TypeList>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000292static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000293 std::vector<DynTypedMatcher> &Out, TypeList) {
294 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000295 mergePolyMatchers(Poly, Out, typename TypeList::tail());
296}
297
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000298/// \brief Convert the return values of the functions into a VariantMatcher.
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000299///
300/// There are 2 cases right now: The return value is a Matcher<T> or is a
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000301/// polymorphic matcher. For the former, we just construct the VariantMatcher.
302/// For the latter, we instantiate all the possible Matcher<T> of the poly
303/// matcher.
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000304static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000305 return VariantMatcher::SingleMatcher(Matcher);
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000306}
307
308template <typename T>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000309static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
310 typename T::ReturnTypes * =
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000311 nullptr) {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000312 std::vector<DynTypedMatcher> Matchers;
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000313 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
Benjamin Kramer3f755aa2014-03-10 17:55:02 +0000314 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000315 return Out;
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000316}
317
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000318template <typename T>
319inline void buildReturnTypeVectorFromTypeList(
320 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
321 RetTypes.push_back(
322 ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
323 buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
324}
325
326template <>
327inline void
328buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
329 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
330
331template <typename T>
332struct BuildReturnTypeVector {
333 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
334 buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
335 }
336};
337
338template <typename T>
Eugene Zelenko06becf82017-11-01 23:09:49 +0000339struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000340 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
341 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
342 }
343};
344
345template <typename T>
Eugene Zelenko06becf82017-11-01 23:09:49 +0000346struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000347 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
348 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
349 }
350};
351
352/// \brief Variadic marshaller function.
353template <typename ResultT, typename ArgT,
354 ResultT (*Func)(ArrayRef<const ArgT *>)>
355VariantMatcher
Craig Toppere335f252015-10-04 04:53:55 +0000356variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000357 ArrayRef<ParserValue> Args, Diagnostics *Error) {
358 ArgT **InnerArgs = new ArgT *[Args.size()]();
359
360 bool HasError = false;
361 for (size_t i = 0, e = Args.size(); i != e; ++i) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000362 using ArgTraits = ArgTypeTraits<ArgT>;
363
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000364 const ParserValue &Arg = Args[i];
365 const VariantValue &Value = Arg.Value;
366 if (!ArgTraits::is(Value)) {
367 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
368 << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
369 HasError = true;
370 break;
371 }
372 InnerArgs[i] = new ArgT(ArgTraits::get(Value));
373 }
374
375 VariantMatcher Out;
376 if (!HasError) {
Craig Topper8c2a2a02014-08-30 16:55:39 +0000377 Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs,
378 Args.size())));
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000379 }
380
381 for (size_t i = 0, e = Args.size(); i != e; ++i) {
382 delete InnerArgs[i];
383 }
384 delete[] InnerArgs;
385 return Out;
386}
387
388/// \brief Matcher descriptor for variadic functions.
389///
390/// This class simply wraps a VariadicFunction with the right signature to export
391/// it as a MatcherDescriptor.
392/// This allows us to have one implementation of the interface for as many free
393/// functions as we want, reducing the number of symbols and size of the
394/// object file.
395class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
396public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000397 using RunFunc = VariantMatcher (*)(StringRef MatcherName,
398 SourceRange NameRange,
399 ArrayRef<ParserValue> Args,
400 Diagnostics *Error);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000401
402 template <typename ResultT, typename ArgT,
403 ResultT (*F)(ArrayRef<const ArgT *>)>
Samuel Benzaquenc1384c12016-03-25 16:29:30 +0000404 VariadicFuncMatcherDescriptor(
405 ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func,
406 StringRef MatcherName)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000407 : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
408 MatcherName(MatcherName.str()),
409 ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
410 BuildReturnTypeVector<ResultT>::build(RetKinds);
411 }
412
Craig Toppere335f252015-10-04 04:53:55 +0000413 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000414 ArrayRef<ParserValue> Args,
415 Diagnostics *Error) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000416 return Func(MatcherName, NameRange, Args, Error);
417 }
418
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000419 bool isVariadic() const override { return true; }
420 unsigned getNumArgs() const override { return 0; }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000421
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000422 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000423 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000424 Kinds.push_back(ArgsKind);
425 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000426
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000427 bool isConvertibleTo(
428 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
429 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000430 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
431 LeastDerivedKind);
432 }
433
434private:
435 const RunFunc Func;
436 const std::string MatcherName;
437 std::vector<ast_type_traits::ASTNodeKind> RetKinds;
438 const ArgKind ArgsKind;
439};
440
441/// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
442class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
443public:
444 template <typename BaseT, typename DerivedT>
445 DynCastAllOfMatcherDescriptor(
446 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
447 StringRef MatcherName)
448 : VariadicFuncMatcherDescriptor(Func, MatcherName),
449 DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
450 }
451
Craig Toppera798a9d2014-03-02 09:32:10 +0000452 bool
453 isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
454 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000455 // If Kind is not a base of DerivedKind, either DerivedKind is a base of
456 // Kind (in which case the match will always succeed) or Kind and
457 // DerivedKind are unrelated (in which case it will always fail), so set
458 // Specificity to 0.
459 if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
460 LeastDerivedKind)) {
461 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
462 if (Specificity)
463 *Specificity = 0;
464 }
465 return true;
466 } else {
467 return false;
468 }
469 }
470
471private:
472 const ast_type_traits::ASTNodeKind DerivedKind;
473};
474
475/// \brief Helper macros to check the arguments on all marshaller functions.
476#define CHECK_ARG_COUNT(count) \
477 if (Args.size() != count) { \
478 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \
479 << count << Args.size(); \
480 return VariantMatcher(); \
481 }
482
483#define CHECK_ARG_TYPE(index, type) \
484 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \
485 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
486 << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
487 << Args[index].Value.getTypeAsString(); \
488 return VariantMatcher(); \
489 }
490
Manuel Klimek24db0f02013-05-14 09:13:00 +0000491/// \brief 0-arg marshaller function.
492template <typename ReturnType>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000493static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000494 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000495 ArrayRef<ParserValue> Args,
496 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000497 using FuncType = ReturnType (*)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000498 CHECK_ARG_COUNT(0);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000499 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
Manuel Klimek24db0f02013-05-14 09:13:00 +0000500}
501
502/// \brief 1-arg marshaller function.
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000503template <typename ReturnType, typename ArgType1>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000504static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000505 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000506 ArrayRef<ParserValue> Args,
507 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000508 using FuncType = ReturnType (*)(ArgType1);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000509 CHECK_ARG_COUNT(1);
510 CHECK_ARG_TYPE(0, ArgType1);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000511 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
512 ArgTypeTraits<ArgType1>::get(Args[0].Value)));
Manuel Klimek24db0f02013-05-14 09:13:00 +0000513}
514
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000515/// \brief 2-arg marshaller function.
516template <typename ReturnType, typename ArgType1, typename ArgType2>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000517static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000518 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000519 ArrayRef<ParserValue> Args,
520 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000521 using FuncType = ReturnType (*)(ArgType1, ArgType2);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000522 CHECK_ARG_COUNT(2);
523 CHECK_ARG_TYPE(0, ArgType1);
524 CHECK_ARG_TYPE(1, ArgType2);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000525 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
526 ArgTypeTraits<ArgType1>::get(Args[0].Value),
527 ArgTypeTraits<ArgType2>::get(Args[1].Value)));
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000528}
529
Manuel Klimek24db0f02013-05-14 09:13:00 +0000530#undef CHECK_ARG_COUNT
531#undef CHECK_ARG_TYPE
532
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000533/// \brief Helper class used to collect all the possible overloads of an
534/// argument adaptative matcher function.
535template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
536 typename FromTypes, typename ToTypes>
537class AdaptativeOverloadCollector {
538public:
Justin Lebar82380d82016-10-10 16:26:40 +0000539 AdaptativeOverloadCollector(
540 StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out)
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000541 : Name(Name), Out(Out) {
542 collect(FromTypes());
543 }
544
545private:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000546 using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc<
547 ArgumentAdapterT, FromTypes, ToTypes>;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000548
549 /// \brief End case for the recursion
550 static void collect(ast_matchers::internal::EmptyTypeList) {}
551
552 /// \brief Recursive case. Get the overload for the head of the list, and
553 /// recurse to the tail.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000554 template <typename FromTypeList>
555 inline void collect(FromTypeList);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000556
Craig Topperbf3e3272014-08-30 16:55:52 +0000557 StringRef Name;
Justin Lebar82380d82016-10-10 16:26:40 +0000558 std::vector<std::unique_ptr<MatcherDescriptor>> &Out;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000559};
560
Peter Collingbournef43e6942013-11-23 01:34:36 +0000561/// \brief MatcherDescriptor that wraps multiple "overloads" of the same
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000562/// matcher.
563///
564/// It will try every overload and generate appropriate errors for when none or
565/// more than one overloads match the arguments.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000566class OverloadedMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000567public:
Justin Lebar82380d82016-10-10 16:26:40 +0000568 OverloadedMatcherDescriptor(
569 MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks)
570 : Overloads(std::make_move_iterator(Callbacks.begin()),
571 std::make_move_iterator(Callbacks.end())) {}
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000572
Eugene Zelenko06becf82017-11-01 23:09:49 +0000573 ~OverloadedMatcherDescriptor() override = default;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000574
Craig Toppere335f252015-10-04 04:53:55 +0000575 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000576 ArrayRef<ParserValue> Args,
577 Diagnostics *Error) const override {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000578 std::vector<VariantMatcher> Constructed;
579 Diagnostics::OverloadContext Ctx(Error);
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000580 for (const auto &O : Overloads) {
581 VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000582 if (!SubMatcher.isNull()) {
583 Constructed.push_back(SubMatcher);
584 }
585 }
586
587 if (Constructed.empty()) return VariantMatcher(); // No overload matched.
588 // We ignore the errors if any matcher succeeded.
589 Ctx.revertErrors();
590 if (Constructed.size() > 1) {
591 // More than one constructed. It is ambiguous.
592 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
593 return VariantMatcher();
594 }
595 return Constructed[0];
596 }
597
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000598 bool isVariadic() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000599 bool Overload0Variadic = Overloads[0]->isVariadic();
600#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000601 for (const auto &O : Overloads) {
602 assert(Overload0Variadic == O->isVariadic());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000603 }
604#endif
605 return Overload0Variadic;
606 }
607
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000608 unsigned getNumArgs() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000609 unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
610#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000611 for (const auto &O : Overloads) {
612 assert(Overload0NumArgs == O->getNumArgs());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000613 }
614#endif
615 return Overload0NumArgs;
616 }
617
618 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000619 std::vector<ArgKind> &Kinds) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000620 for (const auto &O : Overloads) {
621 if (O->isConvertibleTo(ThisKind))
622 O->getArgKinds(ThisKind, ArgNo, Kinds);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000623 }
624 }
625
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000626 bool isConvertibleTo(
627 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
628 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000629 for (const auto &O : Overloads) {
630 if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000631 return true;
632 }
633 return false;
634 }
635
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000636private:
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000637 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000638};
639
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000640/// \brief Variadic operator marshaller function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000641class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000642public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000643 using VarOp = DynTypedMatcher::VariadicOperator;
644
Peter Collingbournef43e6942013-11-23 01:34:36 +0000645 VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000646 VarOp Op, StringRef MatcherName)
647 : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000648 MatcherName(MatcherName) {}
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000649
Craig Toppere335f252015-10-04 04:53:55 +0000650 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000651 ArrayRef<ParserValue> Args,
652 Diagnostics *Error) const override {
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000653 if (Args.size() < MinCount || MaxCount < Args.size()) {
654 const std::string MaxStr =
Eugene Zelenko06becf82017-11-01 23:09:49 +0000655 (MaxCount == std::numeric_limits<unsigned>::max() ? ""
656 : Twine(MaxCount))
657 .str();
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000658 Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
659 << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
660 return VariantMatcher();
661 }
662
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000663 std::vector<VariantMatcher> InnerArgs;
664 for (size_t i = 0, e = Args.size(); i != e; ++i) {
665 const ParserValue &Arg = Args[i];
666 const VariantValue &Value = Arg.Value;
667 if (!Value.isMatcher()) {
668 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
669 << (i + 1) << "Matcher<>" << Value.getTypeAsString();
670 return VariantMatcher();
671 }
672 InnerArgs.push_back(Value.getMatcher());
673 }
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000674 return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000675 }
676
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000677 bool isVariadic() const override { return true; }
678 unsigned getNumArgs() const override { return 0; }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000679
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000680 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000681 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000682 Kinds.push_back(ThisKind);
683 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000684
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000685 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000686 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000687 if (Specificity)
688 *Specificity = 1;
689 if (LeastDerivedKind)
690 *LeastDerivedKind = Kind;
691 return true;
692 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000693
Craig Topperbbc6d622014-03-02 10:02:43 +0000694 bool isPolymorphic() const override { return true; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000695
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000696private:
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000697 const unsigned MinCount;
698 const unsigned MaxCount;
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000699 const VarOp Op;
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000700 const StringRef MatcherName;
701};
702
Manuel Klimek24db0f02013-05-14 09:13:00 +0000703/// Helper functions to select the appropriate marshaller functions.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000704/// They detect the number of arguments, arguments types and return type.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000705
706/// \brief 0-arg overload
707template <typename ReturnType>
Justin Lebar82380d82016-10-10 16:26:40 +0000708std::unique_ptr<MatcherDescriptor>
709makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000710 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
711 BuildReturnTypeVector<ReturnType>::build(RetTypes);
Justin Lebar82380d82016-10-10 16:26:40 +0000712 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000713 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
Craig Topper00bbdcf2014-06-28 23:22:23 +0000714 MatcherName, RetTypes, None);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000715}
716
717/// \brief 1-arg overload
718template <typename ReturnType, typename ArgType1>
Justin Lebar82380d82016-10-10 16:26:40 +0000719std::unique_ptr<MatcherDescriptor>
720makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000721 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
722 BuildReturnTypeVector<ReturnType>::build(RetTypes);
723 ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
Justin Lebar82380d82016-10-10 16:26:40 +0000724 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000725 matcherMarshall1<ReturnType, ArgType1>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000726 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000727}
728
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000729/// \brief 2-arg overload
730template <typename ReturnType, typename ArgType1, typename ArgType2>
Justin Lebar82380d82016-10-10 16:26:40 +0000731std::unique_ptr<MatcherDescriptor>
732makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
733 StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000734 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
735 BuildReturnTypeVector<ReturnType>::build(RetTypes);
736 ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
737 ArgTypeTraits<ArgType2>::getKind() };
Justin Lebar82380d82016-10-10 16:26:40 +0000738 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000739 matcherMarshall2<ReturnType, ArgType1, ArgType2>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000740 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000741}
742
Samuel Benzaquen79656e12013-07-15 19:25:06 +0000743/// \brief Variadic overload.
744template <typename ResultT, typename ArgT,
745 ResultT (*Func)(ArrayRef<const ArgT *>)>
Justin Lebar82380d82016-10-10 16:26:40 +0000746std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
Samuel Benzaquenc1384c12016-03-25 16:29:30 +0000747 ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc,
748 StringRef MatcherName) {
Justin Lebar82380d82016-10-10 16:26:40 +0000749 return llvm::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000750}
751
752/// \brief Overload for VariadicDynCastAllOfMatchers.
753///
754/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
755/// completion results for that type of matcher.
756template <typename BaseT, typename DerivedT>
Justin Lebar82380d82016-10-10 16:26:40 +0000757std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
758 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT>
759 VarFunc,
760 StringRef MatcherName) {
761 return llvm::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000762}
763
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000764/// \brief Argument adaptative overload.
765template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
766 typename FromTypes, typename ToTypes>
Justin Lebar82380d82016-10-10 16:26:40 +0000767std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
768 ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT,
769 FromTypes, ToTypes>,
770 StringRef MatcherName) {
771 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000772 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
773 Overloads);
Justin Lebar82380d82016-10-10 16:26:40 +0000774 return llvm::make_unique<OverloadedMatcherDescriptor>(Overloads);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000775}
776
777template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
778 typename FromTypes, typename ToTypes>
779template <typename FromTypeList>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000780inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
781 ToTypes>::collect(FromTypeList) {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000782 Out.push_back(makeMatcherAutoMarshall(
783 &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
784 collect(typename FromTypeList::tail());
785}
786
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000787/// \brief Variadic operator overload.
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000788template <unsigned MinCount, unsigned MaxCount>
Justin Lebar82380d82016-10-10 16:26:40 +0000789std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
790 ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount>
791 Func,
792 StringRef MatcherName) {
793 return llvm::make_unique<VariadicOperatorMatcherDescriptor>(
794 MinCount, MaxCount, Func.Op, MatcherName);
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000795}
796
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000797} // namespace internal
798} // namespace dynamic
799} // namespace ast_matchers
800} // namespace clang
Manuel Klimek24db0f02013-05-14 09:13:00 +0000801
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000802#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H