blob: 64d6b7814aeb63f149743fb82ee6be8e73c3c4af [file] [log] [blame]
Manuel Klimek24db0f02013-05-14 09:13:00 +00001//===--- Marshallers.h - Generic matcher function marshallers -*- C++ -*-===//
2//
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//===----------------------------------------------------------------------===//
9///
10/// \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.
17///
18//===----------------------------------------------------------------------===//
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
Manuel Klimek24db0f02013-05-14 09:13:00 +000023#include "clang/ASTMatchers/ASTMatchers.h"
24#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
25#include "clang/ASTMatchers/Dynamic/VariantValue.h"
26#include "clang/Basic/LLVM.h"
Samuel Benzaquen0239b692013-08-13 14:54:51 +000027#include "llvm/ADT/STLExtras.h"
Chandler Carruth5553d0d2014-01-07 11:51:46 +000028#include <string>
Manuel Klimek24db0f02013-05-14 09:13:00 +000029
30namespace clang {
31namespace ast_matchers {
32namespace dynamic {
Manuel Klimek24db0f02013-05-14 09:13:00 +000033namespace internal {
34
Peter Collingbourned32e28c2014-01-23 22:48:38 +000035
Manuel Klimek24db0f02013-05-14 09:13:00 +000036/// \brief Helper template class to just from argument type to the right is/get
37/// functions in VariantValue.
38/// Used to verify and extract the matcher arguments below.
39template <class T> struct ArgTypeTraits;
40template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
41};
42
43template <> struct ArgTypeTraits<std::string> {
44 static bool is(const VariantValue &Value) { return Value.isString(); }
45 static const std::string &get(const VariantValue &Value) {
46 return Value.getString();
47 }
Peter Collingbourned32e28c2014-01-23 22:48:38 +000048 static ArgKind getKind() {
49 return ArgKind(ArgKind::AK_String);
50 }
Manuel Klimek24db0f02013-05-14 09:13:00 +000051};
52
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +000053template <>
54struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
55};
56
Manuel Klimek24db0f02013-05-14 09:13:00 +000057template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
Samuel Benzaquen81ef9292013-06-20 14:28:32 +000058 static bool is(const VariantValue &Value) {
Samuel Benzaquen998cda232013-08-30 15:09:52 +000059 return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
Samuel Benzaquen81ef9292013-06-20 14:28:32 +000060 }
Manuel Klimek24db0f02013-05-14 09:13:00 +000061 static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
Samuel Benzaquen998cda232013-08-30 15:09:52 +000062 return Value.getMatcher().getTypedMatcher<T>();
Manuel Klimek24db0f02013-05-14 09:13:00 +000063 }
Peter Collingbourned32e28c2014-01-23 22:48:38 +000064 static ArgKind getKind() {
65 return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
66 }
Samuel Benzaquenc31b3522013-06-04 15:46:22 +000067};
Manuel Klimek24db0f02013-05-14 09:13:00 +000068
Samuel Benzaquenc31b3522013-06-04 15:46:22 +000069template <> struct ArgTypeTraits<unsigned> {
70 static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
71 static unsigned get(const VariantValue &Value) {
72 return Value.getUnsigned();
73 }
Peter Collingbourned32e28c2014-01-23 22:48:38 +000074 static ArgKind getKind() {
75 return ArgKind(ArgKind::AK_Unsigned);
76 }
Manuel Klimek24db0f02013-05-14 09:13:00 +000077};
78
Manuel Klimek3fe8a382014-08-25 11:23:50 +000079template <> struct ArgTypeTraits<attr::Kind> {
80private:
81 static attr::Kind getAttrKind(llvm::StringRef AttrKind) {
82 return llvm::StringSwitch<attr::Kind>(AttrKind)
83#define ATTR(X) .Case("attr::" #X, attr:: X)
84#include "clang/Basic/AttrList.inc"
85 .Default(attr::Kind(-1));
86 }
87public:
88 static bool is(const VariantValue &Value) {
89 return Value.isString() &&
90 getAttrKind(Value.getString()) != attr::Kind(-1);
91 }
92 static attr::Kind get(const VariantValue &Value) {
93 return getAttrKind(Value.getString());
94 }
95 static ArgKind getKind() {
96 return ArgKind(ArgKind::AK_String);
97 }
98};
99
Peter Collingbournef43e6942013-11-23 01:34:36 +0000100/// \brief Matcher descriptor interface.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000101///
Peter Collingbournef43e6942013-11-23 01:34:36 +0000102/// Provides a \c create() method that constructs the matcher from the provided
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000103/// arguments, and various other methods for type introspection.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000104class MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000105public:
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +0000106 virtual ~MatcherDescriptor() {}
Craig Toppere335f252015-10-04 04:53:55 +0000107 virtual VariantMatcher create(SourceRange NameRange,
Peter Collingbournef43e6942013-11-23 01:34:36 +0000108 ArrayRef<ParserValue> Args,
109 Diagnostics *Error) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000110
111 /// Returns whether the matcher is variadic. Variadic matchers can take any
112 /// number of arguments, but they must be of the same type.
113 virtual bool isVariadic() const = 0;
114
115 /// Returns the number of arguments accepted by the matcher if not variadic.
116 virtual unsigned getNumArgs() const = 0;
117
118 /// Given that the matcher is being converted to type \p ThisKind, append the
119 /// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
120 // FIXME: We should provide the ability to constrain the output of this
121 // function based on the types of other matcher arguments.
122 virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
123 std::vector<ArgKind> &ArgKinds) const = 0;
124
125 /// Returns whether this matcher is convertible to the given type. If it is
126 /// so convertible, store in *Specificity a value corresponding to the
127 /// "specificity" of the converted matcher to the given context, and in
128 /// *LeastDerivedKind the least derived matcher kind which would result in the
129 /// same matcher overload. Zero specificity indicates that this conversion
130 /// would produce a trivial matcher that will either always or never match.
131 /// Such matchers are excluded from code completion results.
132 virtual bool isConvertibleTo(
Craig Topper210e1ad2014-05-17 18:49:24 +0000133 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
134 ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000135
136 /// Returns whether the matcher will, given a matcher of any type T, yield a
137 /// matcher of type T.
138 virtual bool isPolymorphic() const { return false; }
Manuel Klimek24db0f02013-05-14 09:13:00 +0000139};
140
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000141inline bool isRetKindConvertibleTo(
Craig Topper00bbdcf2014-06-28 23:22:23 +0000142 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000143 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
144 ast_type_traits::ASTNodeKind *LeastDerivedKind) {
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000145 for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
146 if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000147 if (LeastDerivedKind)
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000148 *LeastDerivedKind = NodeKind;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000149 return true;
150 }
151 }
152 return false;
153}
154
Manuel Klimek24db0f02013-05-14 09:13:00 +0000155/// \brief Simple callback implementation. Marshaller and function are provided.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000156///
157/// This class wraps a function of arbitrary signature and a marshaller
Peter Collingbournef43e6942013-11-23 01:34:36 +0000158/// function into a MatcherDescriptor.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000159/// The marshaller is in charge of taking the VariantValue arguments, checking
160/// their types, unpacking them and calling the underlying function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000161class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000162public:
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000163 typedef VariantMatcher (*MarshallerType)(void (*Func)(),
164 StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000165 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000166 ArrayRef<ParserValue> Args,
167 Diagnostics *Error);
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000168
Dmitri Gribenkocb63baf2013-05-17 17:50:16 +0000169 /// \param Marshaller Function to unpack the arguments and call \c Func
170 /// \param Func Matcher construct function. This is the function that
171 /// compile-time matcher expressions would use to create the matcher.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000172 /// \param RetKinds The list of matcher types to which the matcher is
173 /// convertible.
174 /// \param ArgKinds The types of the arguments this matcher takes.
175 FixedArgCountMatcherDescriptor(
176 MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
Craig Topper00bbdcf2014-06-28 23:22:23 +0000177 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
178 ArrayRef<ArgKind> ArgKinds)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000179 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
180 RetKinds(RetKinds.begin(), RetKinds.end()),
181 ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
Manuel Klimek24db0f02013-05-14 09:13:00 +0000182
Craig Toppere335f252015-10-04 04:53:55 +0000183 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000184 ArrayRef<ParserValue> Args,
185 Diagnostics *Error) const override {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000186 return Marshaller(Func, MatcherName, NameRange, Args, Error);
187 }
188
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000189 bool isVariadic() const override { return false; }
190 unsigned getNumArgs() const override { return ArgKinds.size(); }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000191 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000192 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000193 Kinds.push_back(ArgKinds[ArgNo]);
194 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000195 bool isConvertibleTo(
196 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
197 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000198 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
199 LeastDerivedKind);
200 }
201
Manuel Klimek24db0f02013-05-14 09:13:00 +0000202private:
203 const MarshallerType Marshaller;
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000204 void (* const Func)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000205 const std::string MatcherName;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000206 const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
207 const std::vector<ArgKind> ArgKinds;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000208};
209
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000210/// \brief Helper methods to extract and merge all possible typed matchers
211/// out of the polymorphic object.
212template <class PolyMatcher>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000213static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000214 std::vector<DynTypedMatcher> &Out,
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000215 ast_matchers::internal::EmptyTypeList) {}
216
217template <class PolyMatcher, class TypeList>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000218static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000219 std::vector<DynTypedMatcher> &Out, TypeList) {
220 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000221 mergePolyMatchers(Poly, Out, typename TypeList::tail());
222}
223
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000224/// \brief Convert the return values of the functions into a VariantMatcher.
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000225///
226/// There are 2 cases right now: The return value is a Matcher<T> or is a
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000227/// polymorphic matcher. For the former, we just construct the VariantMatcher.
228/// For the latter, we instantiate all the possible Matcher<T> of the poly
229/// matcher.
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000230static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000231 return VariantMatcher::SingleMatcher(Matcher);
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000232}
233
234template <typename T>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000235static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
236 typename T::ReturnTypes * =
237 NULL) {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000238 std::vector<DynTypedMatcher> Matchers;
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000239 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
Benjamin Kramer3f755aa2014-03-10 17:55:02 +0000240 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000241 return Out;
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000242}
243
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000244template <typename T>
245inline void buildReturnTypeVectorFromTypeList(
246 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
247 RetTypes.push_back(
248 ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
249 buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
250}
251
252template <>
253inline void
254buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
255 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
256
257template <typename T>
258struct BuildReturnTypeVector {
259 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
260 buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
261 }
262};
263
264template <typename T>
265struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T> > {
266 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
267 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
268 }
269};
270
271template <typename T>
272struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T> > {
273 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
274 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
275 }
276};
277
278/// \brief Variadic marshaller function.
279template <typename ResultT, typename ArgT,
280 ResultT (*Func)(ArrayRef<const ArgT *>)>
281VariantMatcher
Craig Toppere335f252015-10-04 04:53:55 +0000282variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000283 ArrayRef<ParserValue> Args, Diagnostics *Error) {
284 ArgT **InnerArgs = new ArgT *[Args.size()]();
285
286 bool HasError = false;
287 for (size_t i = 0, e = Args.size(); i != e; ++i) {
288 typedef ArgTypeTraits<ArgT> ArgTraits;
289 const ParserValue &Arg = Args[i];
290 const VariantValue &Value = Arg.Value;
291 if (!ArgTraits::is(Value)) {
292 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
293 << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
294 HasError = true;
295 break;
296 }
297 InnerArgs[i] = new ArgT(ArgTraits::get(Value));
298 }
299
300 VariantMatcher Out;
301 if (!HasError) {
Craig Topper8c2a2a02014-08-30 16:55:39 +0000302 Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs,
303 Args.size())));
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000304 }
305
306 for (size_t i = 0, e = Args.size(); i != e; ++i) {
307 delete InnerArgs[i];
308 }
309 delete[] InnerArgs;
310 return Out;
311}
312
313/// \brief Matcher descriptor for variadic functions.
314///
315/// This class simply wraps a VariadicFunction with the right signature to export
316/// it as a MatcherDescriptor.
317/// This allows us to have one implementation of the interface for as many free
318/// functions as we want, reducing the number of symbols and size of the
319/// object file.
320class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
321public:
322 typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000323 SourceRange NameRange,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000324 ArrayRef<ParserValue> Args,
325 Diagnostics *Error);
326
327 template <typename ResultT, typename ArgT,
328 ResultT (*F)(ArrayRef<const ArgT *>)>
329 VariadicFuncMatcherDescriptor(llvm::VariadicFunction<ResultT, ArgT, F> Func,
330 StringRef MatcherName)
331 : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
332 MatcherName(MatcherName.str()),
333 ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
334 BuildReturnTypeVector<ResultT>::build(RetKinds);
335 }
336
Craig Toppere335f252015-10-04 04:53:55 +0000337 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000338 ArrayRef<ParserValue> Args,
339 Diagnostics *Error) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000340 return Func(MatcherName, NameRange, Args, Error);
341 }
342
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000343 bool isVariadic() const override { return true; }
344 unsigned getNumArgs() const override { return 0; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000345 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000346 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000347 Kinds.push_back(ArgsKind);
348 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000349 bool isConvertibleTo(
350 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
351 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000352 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
353 LeastDerivedKind);
354 }
355
356private:
357 const RunFunc Func;
358 const std::string MatcherName;
359 std::vector<ast_type_traits::ASTNodeKind> RetKinds;
360 const ArgKind ArgsKind;
361};
362
363/// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
364class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
365public:
366 template <typename BaseT, typename DerivedT>
367 DynCastAllOfMatcherDescriptor(
368 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
369 StringRef MatcherName)
370 : VariadicFuncMatcherDescriptor(Func, MatcherName),
371 DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
372 }
373
Craig Toppera798a9d2014-03-02 09:32:10 +0000374 bool
375 isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
376 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000377 // If Kind is not a base of DerivedKind, either DerivedKind is a base of
378 // Kind (in which case the match will always succeed) or Kind and
379 // DerivedKind are unrelated (in which case it will always fail), so set
380 // Specificity to 0.
381 if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
382 LeastDerivedKind)) {
383 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
384 if (Specificity)
385 *Specificity = 0;
386 }
387 return true;
388 } else {
389 return false;
390 }
391 }
392
393private:
394 const ast_type_traits::ASTNodeKind DerivedKind;
395};
396
397/// \brief Helper macros to check the arguments on all marshaller functions.
398#define CHECK_ARG_COUNT(count) \
399 if (Args.size() != count) { \
400 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \
401 << count << Args.size(); \
402 return VariantMatcher(); \
403 }
404
405#define CHECK_ARG_TYPE(index, type) \
406 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \
407 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
408 << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
409 << Args[index].Value.getTypeAsString(); \
410 return VariantMatcher(); \
411 }
412
413
Manuel Klimek24db0f02013-05-14 09:13:00 +0000414/// \brief 0-arg marshaller function.
415template <typename ReturnType>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000416static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000417 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000418 ArrayRef<ParserValue> Args,
419 Diagnostics *Error) {
420 typedef ReturnType (*FuncType)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000421 CHECK_ARG_COUNT(0);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000422 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
Manuel Klimek24db0f02013-05-14 09:13:00 +0000423}
424
425/// \brief 1-arg marshaller function.
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000426template <typename ReturnType, typename ArgType1>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000427static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000428 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000429 ArrayRef<ParserValue> Args,
430 Diagnostics *Error) {
431 typedef ReturnType (*FuncType)(ArgType1);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000432 CHECK_ARG_COUNT(1);
433 CHECK_ARG_TYPE(0, ArgType1);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000434 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
435 ArgTypeTraits<ArgType1>::get(Args[0].Value)));
Manuel Klimek24db0f02013-05-14 09:13:00 +0000436}
437
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000438/// \brief 2-arg marshaller function.
439template <typename ReturnType, typename ArgType1, typename ArgType2>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000440static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000441 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000442 ArrayRef<ParserValue> Args,
443 Diagnostics *Error) {
444 typedef ReturnType (*FuncType)(ArgType1, ArgType2);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000445 CHECK_ARG_COUNT(2);
446 CHECK_ARG_TYPE(0, ArgType1);
447 CHECK_ARG_TYPE(1, ArgType2);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000448 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
449 ArgTypeTraits<ArgType1>::get(Args[0].Value),
450 ArgTypeTraits<ArgType2>::get(Args[1].Value)));
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000451}
452
Manuel Klimek24db0f02013-05-14 09:13:00 +0000453#undef CHECK_ARG_COUNT
454#undef CHECK_ARG_TYPE
455
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000456/// \brief Helper class used to collect all the possible overloads of an
457/// argument adaptative matcher function.
458template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
459 typename FromTypes, typename ToTypes>
460class AdaptativeOverloadCollector {
461public:
462 AdaptativeOverloadCollector(StringRef Name,
Peter Collingbournef43e6942013-11-23 01:34:36 +0000463 std::vector<MatcherDescriptor *> &Out)
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000464 : Name(Name), Out(Out) {
465 collect(FromTypes());
466 }
467
468private:
469 typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc<
470 ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc;
471
472 /// \brief End case for the recursion
473 static void collect(ast_matchers::internal::EmptyTypeList) {}
474
475 /// \brief Recursive case. Get the overload for the head of the list, and
476 /// recurse to the tail.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000477 template <typename FromTypeList>
478 inline void collect(FromTypeList);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000479
Craig Topperbf3e3272014-08-30 16:55:52 +0000480 StringRef Name;
Peter Collingbournef43e6942013-11-23 01:34:36 +0000481 std::vector<MatcherDescriptor *> &Out;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000482};
483
Peter Collingbournef43e6942013-11-23 01:34:36 +0000484/// \brief MatcherDescriptor that wraps multiple "overloads" of the same
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000485/// matcher.
486///
487/// It will try every overload and generate appropriate errors for when none or
488/// more than one overloads match the arguments.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000489class OverloadedMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000490public:
Peter Collingbournef43e6942013-11-23 01:34:36 +0000491 OverloadedMatcherDescriptor(ArrayRef<MatcherDescriptor *> Callbacks)
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000492 : Overloads(Callbacks.begin(), Callbacks.end()) {}
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000493
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +0000494 ~OverloadedMatcherDescriptor() override {}
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000495
Craig Toppere335f252015-10-04 04:53:55 +0000496 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000497 ArrayRef<ParserValue> Args,
498 Diagnostics *Error) const override {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000499 std::vector<VariantMatcher> Constructed;
500 Diagnostics::OverloadContext Ctx(Error);
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000501 for (const auto &O : Overloads) {
502 VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000503 if (!SubMatcher.isNull()) {
504 Constructed.push_back(SubMatcher);
505 }
506 }
507
508 if (Constructed.empty()) return VariantMatcher(); // No overload matched.
509 // We ignore the errors if any matcher succeeded.
510 Ctx.revertErrors();
511 if (Constructed.size() > 1) {
512 // More than one constructed. It is ambiguous.
513 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
514 return VariantMatcher();
515 }
516 return Constructed[0];
517 }
518
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000519 bool isVariadic() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000520 bool Overload0Variadic = Overloads[0]->isVariadic();
521#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000522 for (const auto &O : Overloads) {
523 assert(Overload0Variadic == O->isVariadic());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000524 }
525#endif
526 return Overload0Variadic;
527 }
528
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000529 unsigned getNumArgs() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000530 unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
531#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000532 for (const auto &O : Overloads) {
533 assert(Overload0NumArgs == O->getNumArgs());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000534 }
535#endif
536 return Overload0NumArgs;
537 }
538
539 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000540 std::vector<ArgKind> &Kinds) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000541 for (const auto &O : Overloads) {
542 if (O->isConvertibleTo(ThisKind))
543 O->getArgKinds(ThisKind, ArgNo, Kinds);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000544 }
545 }
546
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000547 bool isConvertibleTo(
548 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
549 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000550 for (const auto &O : Overloads) {
551 if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000552 return true;
553 }
554 return false;
555 }
556
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000557private:
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000558 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000559};
560
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000561/// \brief Variadic operator marshaller function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000562class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000563public:
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000564 typedef DynTypedMatcher::VariadicOperator VarOp;
Peter Collingbournef43e6942013-11-23 01:34:36 +0000565 VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000566 VarOp Op, StringRef MatcherName)
567 : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000568 MatcherName(MatcherName) {}
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000569
Craig Toppere335f252015-10-04 04:53:55 +0000570 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000571 ArrayRef<ParserValue> Args,
572 Diagnostics *Error) const override {
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000573 if (Args.size() < MinCount || MaxCount < Args.size()) {
574 const std::string MaxStr =
575 (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str();
576 Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
577 << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
578 return VariantMatcher();
579 }
580
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000581 std::vector<VariantMatcher> InnerArgs;
582 for (size_t i = 0, e = Args.size(); i != e; ++i) {
583 const ParserValue &Arg = Args[i];
584 const VariantValue &Value = Arg.Value;
585 if (!Value.isMatcher()) {
586 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
587 << (i + 1) << "Matcher<>" << Value.getTypeAsString();
588 return VariantMatcher();
589 }
590 InnerArgs.push_back(Value.getMatcher());
591 }
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000592 return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000593 }
594
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000595 bool isVariadic() const override { return true; }
596 unsigned getNumArgs() const override { return 0; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000597 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000598 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000599 Kinds.push_back(ThisKind);
600 }
601 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000602 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000603 if (Specificity)
604 *Specificity = 1;
605 if (LeastDerivedKind)
606 *LeastDerivedKind = Kind;
607 return true;
608 }
Craig Topperbbc6d622014-03-02 10:02:43 +0000609 bool isPolymorphic() const override { return true; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000610
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000611private:
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000612 const unsigned MinCount;
613 const unsigned MaxCount;
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000614 const VarOp Op;
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000615 const StringRef MatcherName;
616};
617
Manuel Klimek24db0f02013-05-14 09:13:00 +0000618/// Helper functions to select the appropriate marshaller functions.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000619/// They detect the number of arguments, arguments types and return type.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000620
621/// \brief 0-arg overload
622template <typename ReturnType>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000623MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(),
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000624 StringRef MatcherName) {
625 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
626 BuildReturnTypeVector<ReturnType>::build(RetTypes);
627 return new FixedArgCountMatcherDescriptor(
628 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
Craig Topper00bbdcf2014-06-28 23:22:23 +0000629 MatcherName, RetTypes, None);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000630}
631
632/// \brief 1-arg overload
633template <typename ReturnType, typename ArgType1>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000634MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1),
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000635 StringRef MatcherName) {
636 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
637 BuildReturnTypeVector<ReturnType>::build(RetTypes);
638 ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
Peter Collingbournef43e6942013-11-23 01:34:36 +0000639 return new FixedArgCountMatcherDescriptor(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000640 matcherMarshall1<ReturnType, ArgType1>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000641 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000642}
643
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000644/// \brief 2-arg overload
645template <typename ReturnType, typename ArgType1, typename ArgType2>
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000646MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
647 StringRef MatcherName) {
648 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
649 BuildReturnTypeVector<ReturnType>::build(RetTypes);
650 ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
651 ArgTypeTraits<ArgType2>::getKind() };
Peter Collingbournef43e6942013-11-23 01:34:36 +0000652 return new FixedArgCountMatcherDescriptor(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000653 matcherMarshall2<ReturnType, ArgType1, ArgType2>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000654 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000655}
656
Samuel Benzaquen79656e12013-07-15 19:25:06 +0000657/// \brief Variadic overload.
658template <typename ResultT, typename ArgT,
659 ResultT (*Func)(ArrayRef<const ArgT *>)>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000660MatcherDescriptor *
Samuel Benzaquen79656e12013-07-15 19:25:06 +0000661makeMatcherAutoMarshall(llvm::VariadicFunction<ResultT, ArgT, Func> VarFunc,
Manuel Klimek24db0f02013-05-14 09:13:00 +0000662 StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000663 return new VariadicFuncMatcherDescriptor(VarFunc, MatcherName);
664}
665
666/// \brief Overload for VariadicDynCastAllOfMatchers.
667///
668/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
669/// completion results for that type of matcher.
670template <typename BaseT, typename DerivedT>
671MatcherDescriptor *
672makeMatcherAutoMarshall(ast_matchers::internal::VariadicDynCastAllOfMatcher<
673 BaseT, DerivedT> VarFunc,
674 StringRef MatcherName) {
675 return new DynCastAllOfMatcherDescriptor(VarFunc, MatcherName);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000676}
677
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000678/// \brief Argument adaptative overload.
679template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
680 typename FromTypes, typename ToTypes>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000681MatcherDescriptor *
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000682makeMatcherAutoMarshall(ast_matchers::internal::ArgumentAdaptingMatcherFunc<
683 ArgumentAdapterT, FromTypes, ToTypes>,
684 StringRef MatcherName) {
Peter Collingbournef43e6942013-11-23 01:34:36 +0000685 std::vector<MatcherDescriptor *> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000686 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
687 Overloads);
Peter Collingbournef43e6942013-11-23 01:34:36 +0000688 return new OverloadedMatcherDescriptor(Overloads);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000689}
690
691template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
692 typename FromTypes, typename ToTypes>
693template <typename FromTypeList>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000694inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
695 ToTypes>::collect(FromTypeList) {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000696 Out.push_back(makeMatcherAutoMarshall(
697 &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
698 collect(typename FromTypeList::tail());
699}
700
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000701/// \brief Variadic operator overload.
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000702template <unsigned MinCount, unsigned MaxCount>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000703MatcherDescriptor *
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000704makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc<
705 MinCount, MaxCount> Func,
706 StringRef MatcherName) {
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000707 return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Op,
Peter Collingbournef43e6942013-11-23 01:34:36 +0000708 MatcherName);
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000709}
710
Manuel Klimek24db0f02013-05-14 09:13:00 +0000711} // namespace internal
712} // namespace dynamic
713} // namespace ast_matchers
714} // namespace clang
715
716#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H