blob: fac2fc98e09cd1221405e0d2ddacd4dfb5c81b84 [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//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Manuel Klimek24db0f02013-05-14 09:13:00 +00006//
7//===----------------------------------------------------------------------===//
Eugene Zelenko06becf82017-11-01 23:09:49 +00008//
Manuel Klimek24db0f02013-05-14 09:13:00 +00009/// \file
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000010/// Functions templates and classes to wrap matcher construct functions.
Manuel Klimek24db0f02013-05-14 09:13:00 +000011///
12/// A collection of template function and classes that provide a generic
13/// marshalling layer on top of matcher construct functions.
14/// These are used by the registry to export all marshaller constructors with
15/// the same generic interface.
Eugene Zelenko06becf82017-11-01 23:09:49 +000016//
Manuel Klimek24db0f02013-05-14 09:13:00 +000017//===----------------------------------------------------------------------===//
18
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +000019#ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
20#define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
Manuel Klimek24db0f02013-05-14 09:13:00 +000021
Eugene Zelenko06becf82017-11-01 23:09:49 +000022#include "clang/AST/ASTTypeTraits.h"
23#include "clang/AST/OperationKinds.h"
24#include "clang/ASTMatchers/ASTMatchersInternal.h"
Manuel Klimek24db0f02013-05-14 09:13:00 +000025#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
26#include "clang/ASTMatchers/Dynamic/VariantValue.h"
Eugene Zelenko06becf82017-11-01 23:09:49 +000027#include "clang/Basic/AttrKinds.h"
Manuel Klimek24db0f02013-05-14 09:13:00 +000028#include "clang/Basic/LLVM.h"
Roman Lebedev33ef20e2019-03-21 15:33:24 +000029#include "clang/Basic/OpenMPKinds.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
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000050/// Helper template class to just from argument type to the right is/get
Manuel Klimek24db0f02013-05-14 09:13:00 +000051/// 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
Roman Lebedev33ef20e2019-03-21 15:33:24 +0000169template <> struct ArgTypeTraits<OpenMPClauseKind> {
170private:
171 static Optional<OpenMPClauseKind> getClauseKind(llvm::StringRef ClauseKind) {
172 return llvm::StringSwitch<Optional<OpenMPClauseKind>>(ClauseKind)
173#define OPENMP_CLAUSE(TextualSpelling, Class) \
174 .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling)
175#include "clang/Basic/OpenMPKinds.def"
176 .Default(llvm::None);
177 }
178
179public:
180 static bool is(const VariantValue &Value) {
181 return Value.isString() && getClauseKind(Value.getString());
182 }
183
184 static OpenMPClauseKind get(const VariantValue &Value) {
185 return *getClauseKind(Value.getString());
186 }
187
188 static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }
189};
190
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000191/// Matcher descriptor interface.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000192///
Peter Collingbournef43e6942013-11-23 01:34:36 +0000193/// Provides a \c create() method that constructs the matcher from the provided
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000194/// arguments, and various other methods for type introspection.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000195class MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000196public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000197 virtual ~MatcherDescriptor() = default;
198
Craig Toppere335f252015-10-04 04:53:55 +0000199 virtual VariantMatcher create(SourceRange NameRange,
Peter Collingbournef43e6942013-11-23 01:34:36 +0000200 ArrayRef<ParserValue> Args,
201 Diagnostics *Error) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000202
203 /// Returns whether the matcher is variadic. Variadic matchers can take any
204 /// number of arguments, but they must be of the same type.
205 virtual bool isVariadic() const = 0;
206
207 /// Returns the number of arguments accepted by the matcher if not variadic.
208 virtual unsigned getNumArgs() const = 0;
209
210 /// Given that the matcher is being converted to type \p ThisKind, append the
211 /// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
212 // FIXME: We should provide the ability to constrain the output of this
213 // function based on the types of other matcher arguments.
214 virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
215 std::vector<ArgKind> &ArgKinds) const = 0;
216
217 /// Returns whether this matcher is convertible to the given type. If it is
218 /// so convertible, store in *Specificity a value corresponding to the
219 /// "specificity" of the converted matcher to the given context, and in
220 /// *LeastDerivedKind the least derived matcher kind which would result in the
221 /// same matcher overload. Zero specificity indicates that this conversion
222 /// would produce a trivial matcher that will either always or never match.
223 /// Such matchers are excluded from code completion results.
224 virtual bool isConvertibleTo(
Craig Topper210e1ad2014-05-17 18:49:24 +0000225 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
226 ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000227
228 /// Returns whether the matcher will, given a matcher of any type T, yield a
229 /// matcher of type T.
230 virtual bool isPolymorphic() const { return false; }
Manuel Klimek24db0f02013-05-14 09:13:00 +0000231};
232
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000233inline bool isRetKindConvertibleTo(
Craig Topper00bbdcf2014-06-28 23:22:23 +0000234 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000235 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
236 ast_type_traits::ASTNodeKind *LeastDerivedKind) {
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000237 for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
238 if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000239 if (LeastDerivedKind)
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000240 *LeastDerivedKind = NodeKind;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000241 return true;
242 }
243 }
244 return false;
245}
246
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000247/// Simple callback implementation. Marshaller and function are provided.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000248///
249/// This class wraps a function of arbitrary signature and a marshaller
Peter Collingbournef43e6942013-11-23 01:34:36 +0000250/// function into a MatcherDescriptor.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000251/// The marshaller is in charge of taking the VariantValue arguments, checking
252/// their types, unpacking them and calling the underlying function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000253class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000254public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000255 using MarshallerType = VariantMatcher (*)(void (*Func)(),
256 StringRef MatcherName,
257 SourceRange NameRange,
258 ArrayRef<ParserValue> Args,
259 Diagnostics *Error);
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000260
Dmitri Gribenkocb63baf2013-05-17 17:50:16 +0000261 /// \param Marshaller Function to unpack the arguments and call \c Func
262 /// \param Func Matcher construct function. This is the function that
263 /// compile-time matcher expressions would use to create the matcher.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000264 /// \param RetKinds The list of matcher types to which the matcher is
265 /// convertible.
266 /// \param ArgKinds The types of the arguments this matcher takes.
267 FixedArgCountMatcherDescriptor(
268 MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
Craig Topper00bbdcf2014-06-28 23:22:23 +0000269 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
270 ArrayRef<ArgKind> ArgKinds)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000271 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
272 RetKinds(RetKinds.begin(), RetKinds.end()),
273 ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
Manuel Klimek24db0f02013-05-14 09:13:00 +0000274
Craig Toppere335f252015-10-04 04:53:55 +0000275 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000276 ArrayRef<ParserValue> Args,
277 Diagnostics *Error) const override {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000278 return Marshaller(Func, MatcherName, NameRange, Args, Error);
279 }
280
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000281 bool isVariadic() const override { return false; }
282 unsigned getNumArgs() const override { return ArgKinds.size(); }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000283
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000284 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000285 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000286 Kinds.push_back(ArgKinds[ArgNo]);
287 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000288
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000289 bool isConvertibleTo(
290 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
291 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000292 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
293 LeastDerivedKind);
294 }
295
Manuel Klimek24db0f02013-05-14 09:13:00 +0000296private:
297 const MarshallerType Marshaller;
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000298 void (* const Func)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000299 const std::string MatcherName;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000300 const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
301 const std::vector<ArgKind> ArgKinds;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000302};
303
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000304/// Helper methods to extract and merge all possible typed matchers
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000305/// out of the polymorphic object.
306template <class PolyMatcher>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000307static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000308 std::vector<DynTypedMatcher> &Out,
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000309 ast_matchers::internal::EmptyTypeList) {}
310
311template <class PolyMatcher, class TypeList>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000312static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000313 std::vector<DynTypedMatcher> &Out, TypeList) {
314 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000315 mergePolyMatchers(Poly, Out, typename TypeList::tail());
316}
317
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000318/// Convert the return values of the functions into a VariantMatcher.
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000319///
320/// There are 2 cases right now: The return value is a Matcher<T> or is a
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000321/// polymorphic matcher. For the former, we just construct the VariantMatcher.
322/// For the latter, we instantiate all the possible Matcher<T> of the poly
323/// matcher.
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000324static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000325 return VariantMatcher::SingleMatcher(Matcher);
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000326}
327
328template <typename T>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000329static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
330 typename T::ReturnTypes * =
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000331 nullptr) {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000332 std::vector<DynTypedMatcher> Matchers;
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000333 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
Benjamin Kramer3f755aa2014-03-10 17:55:02 +0000334 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000335 return Out;
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000336}
337
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000338template <typename T>
339inline void buildReturnTypeVectorFromTypeList(
340 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
341 RetTypes.push_back(
342 ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
343 buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
344}
345
346template <>
347inline void
348buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
349 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
350
351template <typename T>
352struct BuildReturnTypeVector {
353 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
354 buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
355 }
356};
357
358template <typename T>
Eugene Zelenko06becf82017-11-01 23:09:49 +0000359struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000360 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
361 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
362 }
363};
364
365template <typename T>
Eugene Zelenko06becf82017-11-01 23:09:49 +0000366struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000367 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
368 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
369 }
370};
371
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000372/// Variadic marshaller function.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000373template <typename ResultT, typename ArgT,
374 ResultT (*Func)(ArrayRef<const ArgT *>)>
375VariantMatcher
Craig Toppere335f252015-10-04 04:53:55 +0000376variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000377 ArrayRef<ParserValue> Args, Diagnostics *Error) {
378 ArgT **InnerArgs = new ArgT *[Args.size()]();
379
380 bool HasError = false;
381 for (size_t i = 0, e = Args.size(); i != e; ++i) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000382 using ArgTraits = ArgTypeTraits<ArgT>;
383
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000384 const ParserValue &Arg = Args[i];
385 const VariantValue &Value = Arg.Value;
386 if (!ArgTraits::is(Value)) {
387 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
388 << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
389 HasError = true;
390 break;
391 }
392 InnerArgs[i] = new ArgT(ArgTraits::get(Value));
393 }
394
395 VariantMatcher Out;
396 if (!HasError) {
Craig Topper8c2a2a02014-08-30 16:55:39 +0000397 Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs,
398 Args.size())));
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000399 }
400
401 for (size_t i = 0, e = Args.size(); i != e; ++i) {
402 delete InnerArgs[i];
403 }
404 delete[] InnerArgs;
405 return Out;
406}
407
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000408/// Matcher descriptor for variadic functions.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000409///
410/// This class simply wraps a VariadicFunction with the right signature to export
411/// it as a MatcherDescriptor.
412/// This allows us to have one implementation of the interface for as many free
413/// functions as we want, reducing the number of symbols and size of the
414/// object file.
415class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
416public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000417 using RunFunc = VariantMatcher (*)(StringRef MatcherName,
418 SourceRange NameRange,
419 ArrayRef<ParserValue> Args,
420 Diagnostics *Error);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000421
422 template <typename ResultT, typename ArgT,
423 ResultT (*F)(ArrayRef<const ArgT *>)>
Samuel Benzaquenc1384c12016-03-25 16:29:30 +0000424 VariadicFuncMatcherDescriptor(
425 ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func,
426 StringRef MatcherName)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000427 : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
428 MatcherName(MatcherName.str()),
429 ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
430 BuildReturnTypeVector<ResultT>::build(RetKinds);
431 }
432
Craig Toppere335f252015-10-04 04:53:55 +0000433 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000434 ArrayRef<ParserValue> Args,
435 Diagnostics *Error) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000436 return Func(MatcherName, NameRange, Args, Error);
437 }
438
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000439 bool isVariadic() const override { return true; }
440 unsigned getNumArgs() const override { return 0; }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000441
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000442 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000443 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000444 Kinds.push_back(ArgsKind);
445 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000446
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000447 bool isConvertibleTo(
448 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
449 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000450 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
451 LeastDerivedKind);
452 }
453
454private:
455 const RunFunc Func;
456 const std::string MatcherName;
457 std::vector<ast_type_traits::ASTNodeKind> RetKinds;
458 const ArgKind ArgsKind;
459};
460
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000461/// Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000462class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
463public:
464 template <typename BaseT, typename DerivedT>
465 DynCastAllOfMatcherDescriptor(
466 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
467 StringRef MatcherName)
468 : VariadicFuncMatcherDescriptor(Func, MatcherName),
469 DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
470 }
471
Craig Toppera798a9d2014-03-02 09:32:10 +0000472 bool
473 isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
474 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000475 // If Kind is not a base of DerivedKind, either DerivedKind is a base of
476 // Kind (in which case the match will always succeed) or Kind and
477 // DerivedKind are unrelated (in which case it will always fail), so set
478 // Specificity to 0.
479 if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
480 LeastDerivedKind)) {
481 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
482 if (Specificity)
483 *Specificity = 0;
484 }
485 return true;
486 } else {
487 return false;
488 }
489 }
490
491private:
492 const ast_type_traits::ASTNodeKind DerivedKind;
493};
494
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000495/// Helper macros to check the arguments on all marshaller functions.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000496#define CHECK_ARG_COUNT(count) \
497 if (Args.size() != count) { \
498 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \
499 << count << Args.size(); \
500 return VariantMatcher(); \
501 }
502
503#define CHECK_ARG_TYPE(index, type) \
504 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \
505 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
506 << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
507 << Args[index].Value.getTypeAsString(); \
508 return VariantMatcher(); \
509 }
510
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000511/// 0-arg marshaller function.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000512template <typename ReturnType>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000513static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000514 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000515 ArrayRef<ParserValue> Args,
516 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000517 using FuncType = ReturnType (*)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000518 CHECK_ARG_COUNT(0);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000519 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
Manuel Klimek24db0f02013-05-14 09:13:00 +0000520}
521
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000522/// 1-arg marshaller function.
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000523template <typename ReturnType, typename ArgType1>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000524static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000525 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000526 ArrayRef<ParserValue> Args,
527 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000528 using FuncType = ReturnType (*)(ArgType1);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000529 CHECK_ARG_COUNT(1);
530 CHECK_ARG_TYPE(0, ArgType1);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000531 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
532 ArgTypeTraits<ArgType1>::get(Args[0].Value)));
Manuel Klimek24db0f02013-05-14 09:13:00 +0000533}
534
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000535/// 2-arg marshaller function.
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000536template <typename ReturnType, typename ArgType1, typename ArgType2>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000537static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000538 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000539 ArrayRef<ParserValue> Args,
540 Diagnostics *Error) {
Eugene Zelenko06becf82017-11-01 23:09:49 +0000541 using FuncType = ReturnType (*)(ArgType1, ArgType2);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000542 CHECK_ARG_COUNT(2);
543 CHECK_ARG_TYPE(0, ArgType1);
544 CHECK_ARG_TYPE(1, ArgType2);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000545 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
546 ArgTypeTraits<ArgType1>::get(Args[0].Value),
547 ArgTypeTraits<ArgType2>::get(Args[1].Value)));
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000548}
549
Manuel Klimek24db0f02013-05-14 09:13:00 +0000550#undef CHECK_ARG_COUNT
551#undef CHECK_ARG_TYPE
552
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000553/// Helper class used to collect all the possible overloads of an
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000554/// argument adaptative matcher function.
555template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
556 typename FromTypes, typename ToTypes>
557class AdaptativeOverloadCollector {
558public:
Justin Lebar82380d82016-10-10 16:26:40 +0000559 AdaptativeOverloadCollector(
560 StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out)
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000561 : Name(Name), Out(Out) {
562 collect(FromTypes());
563 }
564
565private:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000566 using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc<
567 ArgumentAdapterT, FromTypes, ToTypes>;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000568
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000569 /// End case for the recursion
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000570 static void collect(ast_matchers::internal::EmptyTypeList) {}
571
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000572 /// Recursive case. Get the overload for the head of the list, and
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000573 /// recurse to the tail.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000574 template <typename FromTypeList>
575 inline void collect(FromTypeList);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000576
Craig Topperbf3e3272014-08-30 16:55:52 +0000577 StringRef Name;
Justin Lebar82380d82016-10-10 16:26:40 +0000578 std::vector<std::unique_ptr<MatcherDescriptor>> &Out;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000579};
580
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000581/// MatcherDescriptor that wraps multiple "overloads" of the same
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000582/// matcher.
583///
584/// It will try every overload and generate appropriate errors for when none or
585/// more than one overloads match the arguments.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000586class OverloadedMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000587public:
Justin Lebar82380d82016-10-10 16:26:40 +0000588 OverloadedMatcherDescriptor(
589 MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks)
590 : Overloads(std::make_move_iterator(Callbacks.begin()),
591 std::make_move_iterator(Callbacks.end())) {}
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000592
Eugene Zelenko06becf82017-11-01 23:09:49 +0000593 ~OverloadedMatcherDescriptor() override = default;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000594
Craig Toppere335f252015-10-04 04:53:55 +0000595 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000596 ArrayRef<ParserValue> Args,
597 Diagnostics *Error) const override {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000598 std::vector<VariantMatcher> Constructed;
599 Diagnostics::OverloadContext Ctx(Error);
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000600 for (const auto &O : Overloads) {
601 VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000602 if (!SubMatcher.isNull()) {
603 Constructed.push_back(SubMatcher);
604 }
605 }
606
607 if (Constructed.empty()) return VariantMatcher(); // No overload matched.
608 // We ignore the errors if any matcher succeeded.
609 Ctx.revertErrors();
610 if (Constructed.size() > 1) {
611 // More than one constructed. It is ambiguous.
612 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
613 return VariantMatcher();
614 }
615 return Constructed[0];
616 }
617
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000618 bool isVariadic() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000619 bool Overload0Variadic = Overloads[0]->isVariadic();
620#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000621 for (const auto &O : Overloads) {
622 assert(Overload0Variadic == O->isVariadic());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000623 }
624#endif
625 return Overload0Variadic;
626 }
627
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000628 unsigned getNumArgs() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000629 unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
630#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000631 for (const auto &O : Overloads) {
632 assert(Overload0NumArgs == O->getNumArgs());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000633 }
634#endif
635 return Overload0NumArgs;
636 }
637
638 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000639 std::vector<ArgKind> &Kinds) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000640 for (const auto &O : Overloads) {
641 if (O->isConvertibleTo(ThisKind))
642 O->getArgKinds(ThisKind, ArgNo, Kinds);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000643 }
644 }
645
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000646 bool isConvertibleTo(
647 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
648 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000649 for (const auto &O : Overloads) {
650 if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000651 return true;
652 }
653 return false;
654 }
655
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000656private:
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000657 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000658};
659
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000660/// Variadic operator marshaller function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000661class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000662public:
Eugene Zelenko06becf82017-11-01 23:09:49 +0000663 using VarOp = DynTypedMatcher::VariadicOperator;
664
Peter Collingbournef43e6942013-11-23 01:34:36 +0000665 VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000666 VarOp Op, StringRef MatcherName)
667 : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000668 MatcherName(MatcherName) {}
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000669
Craig Toppere335f252015-10-04 04:53:55 +0000670 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000671 ArrayRef<ParserValue> Args,
672 Diagnostics *Error) const override {
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000673 if (Args.size() < MinCount || MaxCount < Args.size()) {
674 const std::string MaxStr =
Eugene Zelenko06becf82017-11-01 23:09:49 +0000675 (MaxCount == std::numeric_limits<unsigned>::max() ? ""
676 : Twine(MaxCount))
677 .str();
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000678 Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
679 << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
680 return VariantMatcher();
681 }
682
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000683 std::vector<VariantMatcher> InnerArgs;
684 for (size_t i = 0, e = Args.size(); i != e; ++i) {
685 const ParserValue &Arg = Args[i];
686 const VariantValue &Value = Arg.Value;
687 if (!Value.isMatcher()) {
688 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
689 << (i + 1) << "Matcher<>" << Value.getTypeAsString();
690 return VariantMatcher();
691 }
692 InnerArgs.push_back(Value.getMatcher());
693 }
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000694 return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000695 }
696
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000697 bool isVariadic() const override { return true; }
698 unsigned getNumArgs() const override { return 0; }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000699
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000700 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000701 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000702 Kinds.push_back(ThisKind);
703 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000704
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000705 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000706 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000707 if (Specificity)
708 *Specificity = 1;
709 if (LeastDerivedKind)
710 *LeastDerivedKind = Kind;
711 return true;
712 }
Eugene Zelenko06becf82017-11-01 23:09:49 +0000713
Craig Topperbbc6d622014-03-02 10:02:43 +0000714 bool isPolymorphic() const override { return true; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000715
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000716private:
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000717 const unsigned MinCount;
718 const unsigned MaxCount;
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000719 const VarOp Op;
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000720 const StringRef MatcherName;
721};
722
Manuel Klimek24db0f02013-05-14 09:13:00 +0000723/// Helper functions to select the appropriate marshaller functions.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000724/// They detect the number of arguments, arguments types and return type.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000725
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000726/// 0-arg overload
Manuel Klimek24db0f02013-05-14 09:13:00 +0000727template <typename ReturnType>
Justin Lebar82380d82016-10-10 16:26:40 +0000728std::unique_ptr<MatcherDescriptor>
729makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000730 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
731 BuildReturnTypeVector<ReturnType>::build(RetTypes);
Justin Lebar82380d82016-10-10 16:26:40 +0000732 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000733 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
Craig Topper00bbdcf2014-06-28 23:22:23 +0000734 MatcherName, RetTypes, None);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000735}
736
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000737/// 1-arg overload
Manuel Klimek24db0f02013-05-14 09:13:00 +0000738template <typename ReturnType, typename ArgType1>
Justin Lebar82380d82016-10-10 16:26:40 +0000739std::unique_ptr<MatcherDescriptor>
740makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000741 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
742 BuildReturnTypeVector<ReturnType>::build(RetTypes);
743 ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
Justin Lebar82380d82016-10-10 16:26:40 +0000744 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000745 matcherMarshall1<ReturnType, ArgType1>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000746 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000747}
748
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000749/// 2-arg overload
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000750template <typename ReturnType, typename ArgType1, typename ArgType2>
Justin Lebar82380d82016-10-10 16:26:40 +0000751std::unique_ptr<MatcherDescriptor>
752makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
753 StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000754 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
755 BuildReturnTypeVector<ReturnType>::build(RetTypes);
756 ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
757 ArgTypeTraits<ArgType2>::getKind() };
Justin Lebar82380d82016-10-10 16:26:40 +0000758 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000759 matcherMarshall2<ReturnType, ArgType1, ArgType2>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000760 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000761}
762
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000763/// Variadic overload.
Samuel Benzaquen79656e12013-07-15 19:25:06 +0000764template <typename ResultT, typename ArgT,
765 ResultT (*Func)(ArrayRef<const ArgT *>)>
Justin Lebar82380d82016-10-10 16:26:40 +0000766std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
Samuel Benzaquenc1384c12016-03-25 16:29:30 +0000767 ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc,
768 StringRef MatcherName) {
Justin Lebar82380d82016-10-10 16:26:40 +0000769 return llvm::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000770}
771
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000772/// Overload for VariadicDynCastAllOfMatchers.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000773///
774/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
775/// completion results for that type of matcher.
776template <typename BaseT, typename DerivedT>
Justin Lebar82380d82016-10-10 16:26:40 +0000777std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
778 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT>
779 VarFunc,
780 StringRef MatcherName) {
781 return llvm::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000782}
783
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000784/// Argument adaptative overload.
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000785template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
786 typename FromTypes, typename ToTypes>
Justin Lebar82380d82016-10-10 16:26:40 +0000787std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
788 ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT,
789 FromTypes, ToTypes>,
790 StringRef MatcherName) {
791 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000792 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
793 Overloads);
Justin Lebar82380d82016-10-10 16:26:40 +0000794 return llvm::make_unique<OverloadedMatcherDescriptor>(Overloads);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000795}
796
797template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
798 typename FromTypes, typename ToTypes>
799template <typename FromTypeList>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000800inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
801 ToTypes>::collect(FromTypeList) {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000802 Out.push_back(makeMatcherAutoMarshall(
803 &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
804 collect(typename FromTypeList::tail());
805}
806
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000807/// Variadic operator overload.
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000808template <unsigned MinCount, unsigned MaxCount>
Justin Lebar82380d82016-10-10 16:26:40 +0000809std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
810 ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount>
811 Func,
812 StringRef MatcherName) {
813 return llvm::make_unique<VariadicOperatorMatcherDescriptor>(
814 MinCount, MaxCount, Func.Op, MatcherName);
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000815}
816
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000817} // namespace internal
818} // namespace dynamic
819} // namespace ast_matchers
820} // namespace clang
Manuel Klimek24db0f02013-05-14 09:13:00 +0000821
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000822#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H