blob: af90e2c7eca1d8c44574de45c9250324b84019cb [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:
Richard Smith354abec2017-12-08 23:29:59 +0000125 static Optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) {
126 return llvm::StringSwitch<Optional<attr::Kind>>(AttrKind)
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000127#define ATTR(X) .Case("attr::" #X, attr:: X)
128#include "clang/Basic/AttrList.inc"
Richard Smith354abec2017-12-08 23:29:59 +0000129 .Default(llvm::None);
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000130 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000131
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000132public:
133 static bool is(const VariantValue &Value) {
Richard Smith354abec2017-12-08 23:29:59 +0000134 return Value.isString() && getAttrKind(Value.getString());
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000135 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000136
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000137 static attr::Kind get(const VariantValue &Value) {
Richard Smith354abec2017-12-08 23:29:59 +0000138 return *getAttrKind(Value.getString());
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000139 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000140
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000141 static ArgKind getKind() {
142 return ArgKind(ArgKind::AK_String);
143 }
144};
145
Eugene Zelenko06becf82017-11-01 23:09:49 +0000146template <> struct ArgTypeTraits<CastKind> {
Etienne Bergeron75e52722016-05-13 19:36:55 +0000147private:
Richard Smith354abec2017-12-08 23:29:59 +0000148 static Optional<CastKind> getCastKind(llvm::StringRef AttrKind) {
149 return llvm::StringSwitch<Optional<CastKind>>(AttrKind)
Etienne Bergeron75e52722016-05-13 19:36:55 +0000150#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
151#include "clang/AST/OperationKinds.def"
Richard Smith354abec2017-12-08 23:29:59 +0000152 .Default(llvm::None);
Etienne Bergeron75e52722016-05-13 19:36:55 +0000153 }
154
155public:
156 static bool is(const VariantValue &Value) {
Richard Smith354abec2017-12-08 23:29:59 +0000157 return Value.isString() && getCastKind(Value.getString());
Etienne Bergeron75e52722016-05-13 19:36:55 +0000158 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000159
160 static CastKind get(const VariantValue &Value) {
Richard Smith354abec2017-12-08 23:29:59 +0000161 return *getCastKind(Value.getString());
Etienne Bergeron75e52722016-05-13 19:36:55 +0000162 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000163
Etienne Bergeron75e52722016-05-13 19:36:55 +0000164 static ArgKind getKind() {
165 return ArgKind(ArgKind::AK_String);
166 }
167};
168
Peter Collingbournef43e6942013-11-23 01:34:36 +0000169/// \brief Matcher descriptor interface.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000170///
Peter Collingbournef43e6942013-11-23 01:34:36 +0000171/// Provides a \c create() method that constructs the matcher from the provided
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000172/// arguments, and various other methods for type introspection.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000173class MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000174public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000175 virtual ~MatcherDescriptor() = default;
176
Craig Toppere335f252015-10-04 04:53:55 +0000177 virtual VariantMatcher create(SourceRange NameRange,
Peter Collingbournef43e6942013-11-23 01:34:36 +0000178 ArrayRef<ParserValue> Args,
179 Diagnostics *Error) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000180
181 /// Returns whether the matcher is variadic. Variadic matchers can take any
182 /// number of arguments, but they must be of the same type.
183 virtual bool isVariadic() const = 0;
184
185 /// Returns the number of arguments accepted by the matcher if not variadic.
186 virtual unsigned getNumArgs() const = 0;
187
188 /// Given that the matcher is being converted to type \p ThisKind, append the
189 /// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
190 // FIXME: We should provide the ability to constrain the output of this
191 // function based on the types of other matcher arguments.
192 virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
193 std::vector<ArgKind> &ArgKinds) const = 0;
194
195 /// Returns whether this matcher is convertible to the given type. If it is
196 /// so convertible, store in *Specificity a value corresponding to the
197 /// "specificity" of the converted matcher to the given context, and in
198 /// *LeastDerivedKind the least derived matcher kind which would result in the
199 /// same matcher overload. Zero specificity indicates that this conversion
200 /// would produce a trivial matcher that will either always or never match.
201 /// Such matchers are excluded from code completion results.
202 virtual bool isConvertibleTo(
Craig Topper210e1ad2014-05-17 18:49:24 +0000203 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
204 ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000205
206 /// Returns whether the matcher will, given a matcher of any type T, yield a
207 /// matcher of type T.
208 virtual bool isPolymorphic() const { return false; }
Manuel Klimek24db0f02013-05-14 09:13:00 +0000209};
210
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000211inline bool isRetKindConvertibleTo(
Craig Topper00bbdcf2014-06-28 23:22:23 +0000212 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000213 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
214 ast_type_traits::ASTNodeKind *LeastDerivedKind) {
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000215 for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
216 if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000217 if (LeastDerivedKind)
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000218 *LeastDerivedKind = NodeKind;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000219 return true;
220 }
221 }
222 return false;
223}
224
Manuel Klimek24db0f02013-05-14 09:13:00 +0000225/// \brief Simple callback implementation. Marshaller and function are provided.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000226///
227/// This class wraps a function of arbitrary signature and a marshaller
Peter Collingbournef43e6942013-11-23 01:34:36 +0000228/// function into a MatcherDescriptor.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000229/// The marshaller is in charge of taking the VariantValue arguments, checking
230/// their types, unpacking them and calling the underlying function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000231class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000232public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000233 using MarshallerType = VariantMatcher (*)(void (*Func)(),
234 StringRef MatcherName,
235 SourceRange NameRange,
236 ArrayRef<ParserValue> Args,
237 Diagnostics *Error);
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000238
Dmitri Gribenkocb63baf2013-05-17 17:50:16 +0000239 /// \param Marshaller Function to unpack the arguments and call \c Func
240 /// \param Func Matcher construct function. This is the function that
241 /// compile-time matcher expressions would use to create the matcher.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000242 /// \param RetKinds The list of matcher types to which the matcher is
243 /// convertible.
244 /// \param ArgKinds The types of the arguments this matcher takes.
245 FixedArgCountMatcherDescriptor(
246 MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
Craig Topper00bbdcf2014-06-28 23:22:23 +0000247 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
248 ArrayRef<ArgKind> ArgKinds)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000249 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
250 RetKinds(RetKinds.begin(), RetKinds.end()),
251 ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
Manuel Klimek24db0f02013-05-14 09:13:00 +0000252
Craig Toppere335f252015-10-04 04:53:55 +0000253 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000254 ArrayRef<ParserValue> Args,
255 Diagnostics *Error) const override {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000256 return Marshaller(Func, MatcherName, NameRange, Args, Error);
257 }
258
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000259 bool isVariadic() const override { return false; }
260 unsigned getNumArgs() const override { return ArgKinds.size(); }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000261
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000262 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000263 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000264 Kinds.push_back(ArgKinds[ArgNo]);
265 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000266
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000267 bool isConvertibleTo(
268 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
269 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000270 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
271 LeastDerivedKind);
272 }
273
Manuel Klimek24db0f02013-05-14 09:13:00 +0000274private:
275 const MarshallerType Marshaller;
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000276 void (* const Func)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000277 const std::string MatcherName;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000278 const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
279 const std::vector<ArgKind> ArgKinds;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000280};
281
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000282/// \brief Helper methods to extract and merge all possible typed matchers
283/// out of the polymorphic object.
284template <class PolyMatcher>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000285static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000286 std::vector<DynTypedMatcher> &Out,
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000287 ast_matchers::internal::EmptyTypeList) {}
288
289template <class PolyMatcher, class TypeList>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000290static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000291 std::vector<DynTypedMatcher> &Out, TypeList) {
292 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000293 mergePolyMatchers(Poly, Out, typename TypeList::tail());
294}
295
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000296/// \brief Convert the return values of the functions into a VariantMatcher.
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000297///
298/// There are 2 cases right now: The return value is a Matcher<T> or is a
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000299/// polymorphic matcher. For the former, we just construct the VariantMatcher.
300/// For the latter, we instantiate all the possible Matcher<T> of the poly
301/// matcher.
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000302static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000303 return VariantMatcher::SingleMatcher(Matcher);
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000304}
305
306template <typename T>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000307static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
308 typename T::ReturnTypes * =
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000309 nullptr) {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000310 std::vector<DynTypedMatcher> Matchers;
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000311 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
Benjamin Kramer3f755aa2014-03-10 17:55:02 +0000312 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000313 return Out;
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000314}
315
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000316template <typename T>
317inline void buildReturnTypeVectorFromTypeList(
318 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
319 RetTypes.push_back(
320 ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
321 buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
322}
323
324template <>
325inline void
326buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
327 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
328
329template <typename T>
330struct BuildReturnTypeVector {
331 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
332 buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
333 }
334};
335
336template <typename T>
Eugene Zelenko06becf82017-11-01 23:09:49 +0000337struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000338 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
339 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
340 }
341};
342
343template <typename T>
Eugene Zelenko06becf82017-11-01 23:09:49 +0000344struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000345 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
346 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
347 }
348};
349
350/// \brief Variadic marshaller function.
351template <typename ResultT, typename ArgT,
352 ResultT (*Func)(ArrayRef<const ArgT *>)>
353VariantMatcher
Craig Toppere335f252015-10-04 04:53:55 +0000354variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000355 ArrayRef<ParserValue> Args, Diagnostics *Error) {
356 ArgT **InnerArgs = new ArgT *[Args.size()]();
357
358 bool HasError = false;
359 for (size_t i = 0, e = Args.size(); i != e; ++i) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000360 using ArgTraits = ArgTypeTraits<ArgT>;
361
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000362 const ParserValue &Arg = Args[i];
363 const VariantValue &Value = Arg.Value;
364 if (!ArgTraits::is(Value)) {
365 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
366 << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
367 HasError = true;
368 break;
369 }
370 InnerArgs[i] = new ArgT(ArgTraits::get(Value));
371 }
372
373 VariantMatcher Out;
374 if (!HasError) {
Craig Topper8c2a2a02014-08-30 16:55:39 +0000375 Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs,
376 Args.size())));
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000377 }
378
379 for (size_t i = 0, e = Args.size(); i != e; ++i) {
380 delete InnerArgs[i];
381 }
382 delete[] InnerArgs;
383 return Out;
384}
385
386/// \brief Matcher descriptor for variadic functions.
387///
388/// This class simply wraps a VariadicFunction with the right signature to export
389/// it as a MatcherDescriptor.
390/// This allows us to have one implementation of the interface for as many free
391/// functions as we want, reducing the number of symbols and size of the
392/// object file.
393class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
394public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000395 using RunFunc = VariantMatcher (*)(StringRef MatcherName,
396 SourceRange NameRange,
397 ArrayRef<ParserValue> Args,
398 Diagnostics *Error);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000399
400 template <typename ResultT, typename ArgT,
401 ResultT (*F)(ArrayRef<const ArgT *>)>
Samuel Benzaquenc1384c12016-03-25 16:29:30 +0000402 VariadicFuncMatcherDescriptor(
403 ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func,
404 StringRef MatcherName)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000405 : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
406 MatcherName(MatcherName.str()),
407 ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
408 BuildReturnTypeVector<ResultT>::build(RetKinds);
409 }
410
Craig Toppere335f252015-10-04 04:53:55 +0000411 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000412 ArrayRef<ParserValue> Args,
413 Diagnostics *Error) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000414 return Func(MatcherName, NameRange, Args, Error);
415 }
416
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000417 bool isVariadic() const override { return true; }
418 unsigned getNumArgs() const override { return 0; }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000419
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000420 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000421 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000422 Kinds.push_back(ArgsKind);
423 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000424
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000425 bool isConvertibleTo(
426 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
427 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000428 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
429 LeastDerivedKind);
430 }
431
432private:
433 const RunFunc Func;
434 const std::string MatcherName;
435 std::vector<ast_type_traits::ASTNodeKind> RetKinds;
436 const ArgKind ArgsKind;
437};
438
439/// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
440class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
441public:
442 template <typename BaseT, typename DerivedT>
443 DynCastAllOfMatcherDescriptor(
444 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
445 StringRef MatcherName)
446 : VariadicFuncMatcherDescriptor(Func, MatcherName),
447 DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
448 }
449
Craig Toppera798a9d2014-03-02 09:32:10 +0000450 bool
451 isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
452 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000453 // If Kind is not a base of DerivedKind, either DerivedKind is a base of
454 // Kind (in which case the match will always succeed) or Kind and
455 // DerivedKind are unrelated (in which case it will always fail), so set
456 // Specificity to 0.
457 if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
458 LeastDerivedKind)) {
459 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
460 if (Specificity)
461 *Specificity = 0;
462 }
463 return true;
464 } else {
465 return false;
466 }
467 }
468
469private:
470 const ast_type_traits::ASTNodeKind DerivedKind;
471};
472
473/// \brief Helper macros to check the arguments on all marshaller functions.
474#define CHECK_ARG_COUNT(count) \
475 if (Args.size() != count) { \
476 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \
477 << count << Args.size(); \
478 return VariantMatcher(); \
479 }
480
481#define CHECK_ARG_TYPE(index, type) \
482 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \
483 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
484 << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
485 << Args[index].Value.getTypeAsString(); \
486 return VariantMatcher(); \
487 }
488
Manuel Klimek24db0f02013-05-14 09:13:00 +0000489/// \brief 0-arg marshaller function.
490template <typename ReturnType>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000491static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000492 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000493 ArrayRef<ParserValue> Args,
494 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000495 using FuncType = ReturnType (*)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000496 CHECK_ARG_COUNT(0);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000497 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
Manuel Klimek24db0f02013-05-14 09:13:00 +0000498}
499
500/// \brief 1-arg marshaller function.
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000501template <typename ReturnType, typename ArgType1>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000502static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000503 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000504 ArrayRef<ParserValue> Args,
505 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000506 using FuncType = ReturnType (*)(ArgType1);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000507 CHECK_ARG_COUNT(1);
508 CHECK_ARG_TYPE(0, ArgType1);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000509 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
510 ArgTypeTraits<ArgType1>::get(Args[0].Value)));
Manuel Klimek24db0f02013-05-14 09:13:00 +0000511}
512
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000513/// \brief 2-arg marshaller function.
514template <typename ReturnType, typename ArgType1, typename ArgType2>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000515static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000516 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000517 ArrayRef<ParserValue> Args,
518 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000519 using FuncType = ReturnType (*)(ArgType1, ArgType2);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000520 CHECK_ARG_COUNT(2);
521 CHECK_ARG_TYPE(0, ArgType1);
522 CHECK_ARG_TYPE(1, ArgType2);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000523 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
524 ArgTypeTraits<ArgType1>::get(Args[0].Value),
525 ArgTypeTraits<ArgType2>::get(Args[1].Value)));
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000526}
527
Manuel Klimek24db0f02013-05-14 09:13:00 +0000528#undef CHECK_ARG_COUNT
529#undef CHECK_ARG_TYPE
530
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000531/// \brief Helper class used to collect all the possible overloads of an
532/// argument adaptative matcher function.
533template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
534 typename FromTypes, typename ToTypes>
535class AdaptativeOverloadCollector {
536public:
Justin Lebar82380d82016-10-10 16:26:40 +0000537 AdaptativeOverloadCollector(
538 StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out)
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000539 : Name(Name), Out(Out) {
540 collect(FromTypes());
541 }
542
543private:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000544 using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc<
545 ArgumentAdapterT, FromTypes, ToTypes>;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000546
547 /// \brief End case for the recursion
548 static void collect(ast_matchers::internal::EmptyTypeList) {}
549
550 /// \brief Recursive case. Get the overload for the head of the list, and
551 /// recurse to the tail.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000552 template <typename FromTypeList>
553 inline void collect(FromTypeList);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000554
Craig Topperbf3e3272014-08-30 16:55:52 +0000555 StringRef Name;
Justin Lebar82380d82016-10-10 16:26:40 +0000556 std::vector<std::unique_ptr<MatcherDescriptor>> &Out;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000557};
558
Peter Collingbournef43e6942013-11-23 01:34:36 +0000559/// \brief MatcherDescriptor that wraps multiple "overloads" of the same
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000560/// matcher.
561///
562/// It will try every overload and generate appropriate errors for when none or
563/// more than one overloads match the arguments.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000564class OverloadedMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000565public:
Justin Lebar82380d82016-10-10 16:26:40 +0000566 OverloadedMatcherDescriptor(
567 MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks)
568 : Overloads(std::make_move_iterator(Callbacks.begin()),
569 std::make_move_iterator(Callbacks.end())) {}
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000570
Eugene Zelenko06becf82017-11-01 23:09:49 +0000571 ~OverloadedMatcherDescriptor() override = default;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000572
Craig Toppere335f252015-10-04 04:53:55 +0000573 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000574 ArrayRef<ParserValue> Args,
575 Diagnostics *Error) const override {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000576 std::vector<VariantMatcher> Constructed;
577 Diagnostics::OverloadContext Ctx(Error);
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000578 for (const auto &O : Overloads) {
579 VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000580 if (!SubMatcher.isNull()) {
581 Constructed.push_back(SubMatcher);
582 }
583 }
584
585 if (Constructed.empty()) return VariantMatcher(); // No overload matched.
586 // We ignore the errors if any matcher succeeded.
587 Ctx.revertErrors();
588 if (Constructed.size() > 1) {
589 // More than one constructed. It is ambiguous.
590 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
591 return VariantMatcher();
592 }
593 return Constructed[0];
594 }
595
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000596 bool isVariadic() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000597 bool Overload0Variadic = Overloads[0]->isVariadic();
598#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000599 for (const auto &O : Overloads) {
600 assert(Overload0Variadic == O->isVariadic());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000601 }
602#endif
603 return Overload0Variadic;
604 }
605
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000606 unsigned getNumArgs() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000607 unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
608#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000609 for (const auto &O : Overloads) {
610 assert(Overload0NumArgs == O->getNumArgs());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000611 }
612#endif
613 return Overload0NumArgs;
614 }
615
616 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000617 std::vector<ArgKind> &Kinds) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000618 for (const auto &O : Overloads) {
619 if (O->isConvertibleTo(ThisKind))
620 O->getArgKinds(ThisKind, ArgNo, Kinds);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000621 }
622 }
623
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000624 bool isConvertibleTo(
625 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
626 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000627 for (const auto &O : Overloads) {
628 if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000629 return true;
630 }
631 return false;
632 }
633
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000634private:
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000635 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000636};
637
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000638/// \brief Variadic operator marshaller function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000639class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000640public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000641 using VarOp = DynTypedMatcher::VariadicOperator;
642
Peter Collingbournef43e6942013-11-23 01:34:36 +0000643 VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000644 VarOp Op, StringRef MatcherName)
645 : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000646 MatcherName(MatcherName) {}
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000647
Craig Toppere335f252015-10-04 04:53:55 +0000648 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000649 ArrayRef<ParserValue> Args,
650 Diagnostics *Error) const override {
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000651 if (Args.size() < MinCount || MaxCount < Args.size()) {
652 const std::string MaxStr =
Eugene Zelenko06becf82017-11-01 23:09:49 +0000653 (MaxCount == std::numeric_limits<unsigned>::max() ? ""
654 : Twine(MaxCount))
655 .str();
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000656 Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
657 << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
658 return VariantMatcher();
659 }
660
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000661 std::vector<VariantMatcher> InnerArgs;
662 for (size_t i = 0, e = Args.size(); i != e; ++i) {
663 const ParserValue &Arg = Args[i];
664 const VariantValue &Value = Arg.Value;
665 if (!Value.isMatcher()) {
666 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
667 << (i + 1) << "Matcher<>" << Value.getTypeAsString();
668 return VariantMatcher();
669 }
670 InnerArgs.push_back(Value.getMatcher());
671 }
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000672 return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000673 }
674
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000675 bool isVariadic() const override { return true; }
676 unsigned getNumArgs() const override { return 0; }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000677
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000678 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000679 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000680 Kinds.push_back(ThisKind);
681 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000682
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000683 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000684 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000685 if (Specificity)
686 *Specificity = 1;
687 if (LeastDerivedKind)
688 *LeastDerivedKind = Kind;
689 return true;
690 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000691
Craig Topperbbc6d622014-03-02 10:02:43 +0000692 bool isPolymorphic() const override { return true; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000693
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000694private:
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000695 const unsigned MinCount;
696 const unsigned MaxCount;
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000697 const VarOp Op;
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000698 const StringRef MatcherName;
699};
700
Manuel Klimek24db0f02013-05-14 09:13:00 +0000701/// Helper functions to select the appropriate marshaller functions.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000702/// They detect the number of arguments, arguments types and return type.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000703
704/// \brief 0-arg overload
705template <typename ReturnType>
Justin Lebar82380d82016-10-10 16:26:40 +0000706std::unique_ptr<MatcherDescriptor>
707makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000708 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
709 BuildReturnTypeVector<ReturnType>::build(RetTypes);
Justin Lebar82380d82016-10-10 16:26:40 +0000710 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000711 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
Craig Topper00bbdcf2014-06-28 23:22:23 +0000712 MatcherName, RetTypes, None);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000713}
714
715/// \brief 1-arg overload
716template <typename ReturnType, typename ArgType1>
Justin Lebar82380d82016-10-10 16:26:40 +0000717std::unique_ptr<MatcherDescriptor>
718makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000719 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
720 BuildReturnTypeVector<ReturnType>::build(RetTypes);
721 ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
Justin Lebar82380d82016-10-10 16:26:40 +0000722 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000723 matcherMarshall1<ReturnType, ArgType1>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000724 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000725}
726
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000727/// \brief 2-arg overload
728template <typename ReturnType, typename ArgType1, typename ArgType2>
Justin Lebar82380d82016-10-10 16:26:40 +0000729std::unique_ptr<MatcherDescriptor>
730makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
731 StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000732 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
733 BuildReturnTypeVector<ReturnType>::build(RetTypes);
734 ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
735 ArgTypeTraits<ArgType2>::getKind() };
Justin Lebar82380d82016-10-10 16:26:40 +0000736 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000737 matcherMarshall2<ReturnType, ArgType1, ArgType2>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000738 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000739}
740
Samuel Benzaquen79656e12013-07-15 19:25:06 +0000741/// \brief Variadic overload.
742template <typename ResultT, typename ArgT,
743 ResultT (*Func)(ArrayRef<const ArgT *>)>
Justin Lebar82380d82016-10-10 16:26:40 +0000744std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
Samuel Benzaquenc1384c12016-03-25 16:29:30 +0000745 ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc,
746 StringRef MatcherName) {
Justin Lebar82380d82016-10-10 16:26:40 +0000747 return llvm::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000748}
749
750/// \brief Overload for VariadicDynCastAllOfMatchers.
751///
752/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
753/// completion results for that type of matcher.
754template <typename BaseT, typename DerivedT>
Justin Lebar82380d82016-10-10 16:26:40 +0000755std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
756 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT>
757 VarFunc,
758 StringRef MatcherName) {
759 return llvm::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000760}
761
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000762/// \brief Argument adaptative overload.
763template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
764 typename FromTypes, typename ToTypes>
Justin Lebar82380d82016-10-10 16:26:40 +0000765std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
766 ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT,
767 FromTypes, ToTypes>,
768 StringRef MatcherName) {
769 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000770 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
771 Overloads);
Justin Lebar82380d82016-10-10 16:26:40 +0000772 return llvm::make_unique<OverloadedMatcherDescriptor>(Overloads);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000773}
774
775template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
776 typename FromTypes, typename ToTypes>
777template <typename FromTypeList>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000778inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
779 ToTypes>::collect(FromTypeList) {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000780 Out.push_back(makeMatcherAutoMarshall(
781 &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
782 collect(typename FromTypeList::tail());
783}
784
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000785/// \brief Variadic operator overload.
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000786template <unsigned MinCount, unsigned MaxCount>
Justin Lebar82380d82016-10-10 16:26:40 +0000787std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
788 ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount>
789 Func,
790 StringRef MatcherName) {
791 return llvm::make_unique<VariadicOperatorMatcherDescriptor>(
792 MinCount, MaxCount, Func.Op, MatcherName);
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000793}
794
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000795} // namespace internal
796} // namespace dynamic
797} // namespace ast_matchers
798} // namespace clang
Manuel Klimek24db0f02013-05-14 09:13:00 +0000799
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000800#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H