blob: c557ff162691a338d69ff75159c3d54c1ec70e7a [file] [log] [blame]
Eugene Zelenko1660a5d2016-01-26 19:01:06 +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//===----------------------------------------------------------------------===//
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
35/// \brief Helper template class to just from argument type to the right is/get
36/// functions in VariantValue.
37/// Used to verify and extract the matcher arguments below.
38template <class T> struct ArgTypeTraits;
39template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
40};
41
42template <> struct ArgTypeTraits<std::string> {
43 static bool is(const VariantValue &Value) { return Value.isString(); }
44 static const std::string &get(const VariantValue &Value) {
45 return Value.getString();
46 }
Peter Collingbourned32e28c2014-01-23 22:48:38 +000047 static ArgKind getKind() {
48 return ArgKind(ArgKind::AK_String);
49 }
Manuel Klimek24db0f02013-05-14 09:13:00 +000050};
51
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +000052template <>
53struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
54};
55
Manuel Klimek24db0f02013-05-14 09:13:00 +000056template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
Samuel Benzaquen81ef9292013-06-20 14:28:32 +000057 static bool is(const VariantValue &Value) {
Samuel Benzaquen998cda232013-08-30 15:09:52 +000058 return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
Samuel Benzaquen81ef9292013-06-20 14:28:32 +000059 }
Manuel Klimek24db0f02013-05-14 09:13:00 +000060 static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
Samuel Benzaquen998cda232013-08-30 15:09:52 +000061 return Value.getMatcher().getTypedMatcher<T>();
Manuel Klimek24db0f02013-05-14 09:13:00 +000062 }
Peter Collingbourned32e28c2014-01-23 22:48:38 +000063 static ArgKind getKind() {
64 return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
65 }
Samuel Benzaquenc31b3522013-06-04 15:46:22 +000066};
Manuel Klimek24db0f02013-05-14 09:13:00 +000067
Peter Wuc04b1982017-06-08 22:00:38 +000068template <> struct ArgTypeTraits<bool> {
69 static bool is(const VariantValue &Value) { return Value.isBoolean(); }
70 static bool get(const VariantValue &Value) {
71 return Value.getBoolean();
72 }
73 static ArgKind getKind() {
74 return ArgKind(ArgKind::AK_Boolean);
75 }
76};
77
Peter Wu2bbed502017-06-08 22:00:50 +000078template <> struct ArgTypeTraits<double> {
79 static bool is(const VariantValue &Value) { return Value.isDouble(); }
80 static double get(const VariantValue &Value) {
81 return Value.getDouble();
82 }
83 static ArgKind getKind() {
84 return ArgKind(ArgKind::AK_Double);
85 }
86};
87
Samuel Benzaquenc31b3522013-06-04 15:46:22 +000088template <> struct ArgTypeTraits<unsigned> {
89 static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
90 static unsigned get(const VariantValue &Value) {
91 return Value.getUnsigned();
92 }
Peter Collingbourned32e28c2014-01-23 22:48:38 +000093 static ArgKind getKind() {
94 return ArgKind(ArgKind::AK_Unsigned);
95 }
Manuel Klimek24db0f02013-05-14 09:13:00 +000096};
97
Manuel Klimek3fe8a382014-08-25 11:23:50 +000098template <> struct ArgTypeTraits<attr::Kind> {
99private:
100 static attr::Kind getAttrKind(llvm::StringRef AttrKind) {
101 return llvm::StringSwitch<attr::Kind>(AttrKind)
102#define ATTR(X) .Case("attr::" #X, attr:: X)
103#include "clang/Basic/AttrList.inc"
104 .Default(attr::Kind(-1));
105 }
106public:
107 static bool is(const VariantValue &Value) {
108 return Value.isString() &&
109 getAttrKind(Value.getString()) != attr::Kind(-1);
110 }
111 static attr::Kind get(const VariantValue &Value) {
112 return getAttrKind(Value.getString());
113 }
114 static ArgKind getKind() {
115 return ArgKind(ArgKind::AK_String);
116 }
117};
118
Etienne Bergeron75e52722016-05-13 19:36:55 +0000119template <> struct ArgTypeTraits<clang::CastKind> {
120private:
121 static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
122 return llvm::StringSwitch<clang::CastKind>(AttrKind)
123#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
124#include "clang/AST/OperationKinds.def"
125 .Default(CK_Invalid);
126 }
127
128public:
129 static bool is(const VariantValue &Value) {
130 return Value.isString() &&
131 getCastKind(Value.getString()) != CK_Invalid;
132 }
133 static clang::CastKind get(const VariantValue &Value) {
134 return getCastKind(Value.getString());
135 }
136 static ArgKind getKind() {
137 return ArgKind(ArgKind::AK_String);
138 }
139};
140
Peter Collingbournef43e6942013-11-23 01:34:36 +0000141/// \brief Matcher descriptor interface.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000142///
Peter Collingbournef43e6942013-11-23 01:34:36 +0000143/// Provides a \c create() method that constructs the matcher from the provided
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000144/// arguments, and various other methods for type introspection.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000145class MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000146public:
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +0000147 virtual ~MatcherDescriptor() {}
Craig Toppere335f252015-10-04 04:53:55 +0000148 virtual VariantMatcher create(SourceRange NameRange,
Peter Collingbournef43e6942013-11-23 01:34:36 +0000149 ArrayRef<ParserValue> Args,
150 Diagnostics *Error) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000151
152 /// Returns whether the matcher is variadic. Variadic matchers can take any
153 /// number of arguments, but they must be of the same type.
154 virtual bool isVariadic() const = 0;
155
156 /// Returns the number of arguments accepted by the matcher if not variadic.
157 virtual unsigned getNumArgs() const = 0;
158
159 /// Given that the matcher is being converted to type \p ThisKind, append the
160 /// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
161 // FIXME: We should provide the ability to constrain the output of this
162 // function based on the types of other matcher arguments.
163 virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
164 std::vector<ArgKind> &ArgKinds) const = 0;
165
166 /// Returns whether this matcher is convertible to the given type. If it is
167 /// so convertible, store in *Specificity a value corresponding to the
168 /// "specificity" of the converted matcher to the given context, and in
169 /// *LeastDerivedKind the least derived matcher kind which would result in the
170 /// same matcher overload. Zero specificity indicates that this conversion
171 /// would produce a trivial matcher that will either always or never match.
172 /// Such matchers are excluded from code completion results.
173 virtual bool isConvertibleTo(
Craig Topper210e1ad2014-05-17 18:49:24 +0000174 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
175 ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000176
177 /// Returns whether the matcher will, given a matcher of any type T, yield a
178 /// matcher of type T.
179 virtual bool isPolymorphic() const { return false; }
Manuel Klimek24db0f02013-05-14 09:13:00 +0000180};
181
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000182inline bool isRetKindConvertibleTo(
Craig Topper00bbdcf2014-06-28 23:22:23 +0000183 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000184 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
185 ast_type_traits::ASTNodeKind *LeastDerivedKind) {
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000186 for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
187 if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000188 if (LeastDerivedKind)
Samuel Benzaquen646f23b2014-08-12 21:11:37 +0000189 *LeastDerivedKind = NodeKind;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000190 return true;
191 }
192 }
193 return false;
194}
195
Manuel Klimek24db0f02013-05-14 09:13:00 +0000196/// \brief Simple callback implementation. Marshaller and function are provided.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000197///
198/// This class wraps a function of arbitrary signature and a marshaller
Peter Collingbournef43e6942013-11-23 01:34:36 +0000199/// function into a MatcherDescriptor.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000200/// The marshaller is in charge of taking the VariantValue arguments, checking
201/// their types, unpacking them and calling the underlying function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000202class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000203public:
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000204 typedef VariantMatcher (*MarshallerType)(void (*Func)(),
205 StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000206 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000207 ArrayRef<ParserValue> Args,
208 Diagnostics *Error);
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000209
Dmitri Gribenkocb63baf2013-05-17 17:50:16 +0000210 /// \param Marshaller Function to unpack the arguments and call \c Func
211 /// \param Func Matcher construct function. This is the function that
212 /// compile-time matcher expressions would use to create the matcher.
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000213 /// \param RetKinds The list of matcher types to which the matcher is
214 /// convertible.
215 /// \param ArgKinds The types of the arguments this matcher takes.
216 FixedArgCountMatcherDescriptor(
217 MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
Craig Topper00bbdcf2014-06-28 23:22:23 +0000218 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
219 ArrayRef<ArgKind> ArgKinds)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000220 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
221 RetKinds(RetKinds.begin(), RetKinds.end()),
222 ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
Manuel Klimek24db0f02013-05-14 09:13:00 +0000223
Craig Toppere335f252015-10-04 04:53:55 +0000224 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000225 ArrayRef<ParserValue> Args,
226 Diagnostics *Error) const override {
Manuel Klimek24db0f02013-05-14 09:13:00 +0000227 return Marshaller(Func, MatcherName, NameRange, Args, Error);
228 }
229
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000230 bool isVariadic() const override { return false; }
231 unsigned getNumArgs() const override { return ArgKinds.size(); }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000232 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000233 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000234 Kinds.push_back(ArgKinds[ArgNo]);
235 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000236 bool isConvertibleTo(
237 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
238 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000239 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
240 LeastDerivedKind);
241 }
242
Manuel Klimek24db0f02013-05-14 09:13:00 +0000243private:
244 const MarshallerType Marshaller;
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000245 void (* const Func)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000246 const std::string MatcherName;
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000247 const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
248 const std::vector<ArgKind> ArgKinds;
Manuel Klimek24db0f02013-05-14 09:13:00 +0000249};
250
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000251/// \brief Helper methods to extract and merge all possible typed matchers
252/// out of the polymorphic object.
253template <class PolyMatcher>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000254static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000255 std::vector<DynTypedMatcher> &Out,
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000256 ast_matchers::internal::EmptyTypeList) {}
257
258template <class PolyMatcher, class TypeList>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000259static void mergePolyMatchers(const PolyMatcher &Poly,
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000260 std::vector<DynTypedMatcher> &Out, TypeList) {
261 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000262 mergePolyMatchers(Poly, Out, typename TypeList::tail());
263}
264
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000265/// \brief Convert the return values of the functions into a VariantMatcher.
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000266///
267/// There are 2 cases right now: The return value is a Matcher<T> or is a
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000268/// polymorphic matcher. For the former, we just construct the VariantMatcher.
269/// For the latter, we instantiate all the possible Matcher<T> of the poly
270/// matcher.
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000271static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000272 return VariantMatcher::SingleMatcher(Matcher);
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000273}
274
275template <typename T>
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000276static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
277 typename T::ReturnTypes * =
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000278 nullptr) {
Samuel Benzaquenf34ac3e2013-10-29 14:37:15 +0000279 std::vector<DynTypedMatcher> Matchers;
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000280 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
Benjamin Kramer3f755aa2014-03-10 17:55:02 +0000281 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
Samuel Benzaquen0239b692013-08-13 14:54:51 +0000282 return Out;
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +0000283}
284
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000285template <typename T>
286inline void buildReturnTypeVectorFromTypeList(
287 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
288 RetTypes.push_back(
289 ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
290 buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
291}
292
293template <>
294inline void
295buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
296 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
297
298template <typename T>
299struct BuildReturnTypeVector {
300 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
301 buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
302 }
303};
304
305template <typename T>
306struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T> > {
307 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
308 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
309 }
310};
311
312template <typename T>
313struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T> > {
314 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
315 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
316 }
317};
318
319/// \brief Variadic marshaller function.
320template <typename ResultT, typename ArgT,
321 ResultT (*Func)(ArrayRef<const ArgT *>)>
322VariantMatcher
Craig Toppere335f252015-10-04 04:53:55 +0000323variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000324 ArrayRef<ParserValue> Args, Diagnostics *Error) {
325 ArgT **InnerArgs = new ArgT *[Args.size()]();
326
327 bool HasError = false;
328 for (size_t i = 0, e = Args.size(); i != e; ++i) {
329 typedef ArgTypeTraits<ArgT> ArgTraits;
330 const ParserValue &Arg = Args[i];
331 const VariantValue &Value = Arg.Value;
332 if (!ArgTraits::is(Value)) {
333 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
334 << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
335 HasError = true;
336 break;
337 }
338 InnerArgs[i] = new ArgT(ArgTraits::get(Value));
339 }
340
341 VariantMatcher Out;
342 if (!HasError) {
Craig Topper8c2a2a02014-08-30 16:55:39 +0000343 Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs,
344 Args.size())));
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000345 }
346
347 for (size_t i = 0, e = Args.size(); i != e; ++i) {
348 delete InnerArgs[i];
349 }
350 delete[] InnerArgs;
351 return Out;
352}
353
354/// \brief Matcher descriptor for variadic functions.
355///
356/// This class simply wraps a VariadicFunction with the right signature to export
357/// it as a MatcherDescriptor.
358/// This allows us to have one implementation of the interface for as many free
359/// functions as we want, reducing the number of symbols and size of the
360/// object file.
361class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
362public:
363 typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000364 SourceRange NameRange,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000365 ArrayRef<ParserValue> Args,
366 Diagnostics *Error);
367
368 template <typename ResultT, typename ArgT,
369 ResultT (*F)(ArrayRef<const ArgT *>)>
Samuel Benzaquenc1384c12016-03-25 16:29:30 +0000370 VariadicFuncMatcherDescriptor(
371 ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func,
372 StringRef MatcherName)
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000373 : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
374 MatcherName(MatcherName.str()),
375 ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
376 BuildReturnTypeVector<ResultT>::build(RetKinds);
377 }
378
Craig Toppere335f252015-10-04 04:53:55 +0000379 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000380 ArrayRef<ParserValue> Args,
381 Diagnostics *Error) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000382 return Func(MatcherName, NameRange, Args, Error);
383 }
384
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000385 bool isVariadic() const override { return true; }
386 unsigned getNumArgs() const override { return 0; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000387 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000388 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000389 Kinds.push_back(ArgsKind);
390 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000391 bool isConvertibleTo(
392 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
393 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000394 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
395 LeastDerivedKind);
396 }
397
398private:
399 const RunFunc Func;
400 const std::string MatcherName;
401 std::vector<ast_type_traits::ASTNodeKind> RetKinds;
402 const ArgKind ArgsKind;
403};
404
405/// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
406class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
407public:
408 template <typename BaseT, typename DerivedT>
409 DynCastAllOfMatcherDescriptor(
410 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
411 StringRef MatcherName)
412 : VariadicFuncMatcherDescriptor(Func, MatcherName),
413 DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
414 }
415
Craig Toppera798a9d2014-03-02 09:32:10 +0000416 bool
417 isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
418 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000419 // If Kind is not a base of DerivedKind, either DerivedKind is a base of
420 // Kind (in which case the match will always succeed) or Kind and
421 // DerivedKind are unrelated (in which case it will always fail), so set
422 // Specificity to 0.
423 if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
424 LeastDerivedKind)) {
425 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
426 if (Specificity)
427 *Specificity = 0;
428 }
429 return true;
430 } else {
431 return false;
432 }
433 }
434
435private:
436 const ast_type_traits::ASTNodeKind DerivedKind;
437};
438
439/// \brief Helper macros to check the arguments on all marshaller functions.
440#define CHECK_ARG_COUNT(count) \
441 if (Args.size() != count) { \
442 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \
443 << count << Args.size(); \
444 return VariantMatcher(); \
445 }
446
447#define CHECK_ARG_TYPE(index, type) \
448 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \
449 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
450 << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
451 << Args[index].Value.getTypeAsString(); \
452 return VariantMatcher(); \
453 }
454
Manuel Klimek24db0f02013-05-14 09:13:00 +0000455/// \brief 0-arg marshaller function.
456template <typename ReturnType>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000457static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000458 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000459 ArrayRef<ParserValue> Args,
460 Diagnostics *Error) {
461 typedef ReturnType (*FuncType)();
Manuel Klimek24db0f02013-05-14 09:13:00 +0000462 CHECK_ARG_COUNT(0);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000463 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
Manuel Klimek24db0f02013-05-14 09:13:00 +0000464}
465
466/// \brief 1-arg marshaller function.
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000467template <typename ReturnType, typename ArgType1>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000468static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000469 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000470 ArrayRef<ParserValue> Args,
471 Diagnostics *Error) {
472 typedef ReturnType (*FuncType)(ArgType1);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000473 CHECK_ARG_COUNT(1);
474 CHECK_ARG_TYPE(0, ArgType1);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000475 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
476 ArgTypeTraits<ArgType1>::get(Args[0].Value)));
Manuel Klimek24db0f02013-05-14 09:13:00 +0000477}
478
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000479/// \brief 2-arg marshaller function.
480template <typename ReturnType, typename ArgType1, typename ArgType2>
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000481static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
Craig Toppere335f252015-10-04 04:53:55 +0000482 SourceRange NameRange,
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000483 ArrayRef<ParserValue> Args,
484 Diagnostics *Error) {
485 typedef ReturnType (*FuncType)(ArgType1, ArgType2);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000486 CHECK_ARG_COUNT(2);
487 CHECK_ARG_TYPE(0, ArgType1);
488 CHECK_ARG_TYPE(1, ArgType2);
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000489 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
490 ArgTypeTraits<ArgType1>::get(Args[0].Value),
491 ArgTypeTraits<ArgType2>::get(Args[1].Value)));
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000492}
493
Manuel Klimek24db0f02013-05-14 09:13:00 +0000494#undef CHECK_ARG_COUNT
495#undef CHECK_ARG_TYPE
496
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000497/// \brief Helper class used to collect all the possible overloads of an
498/// argument adaptative matcher function.
499template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
500 typename FromTypes, typename ToTypes>
501class AdaptativeOverloadCollector {
502public:
Justin Lebar82380d82016-10-10 16:26:40 +0000503 AdaptativeOverloadCollector(
504 StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out)
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000505 : Name(Name), Out(Out) {
506 collect(FromTypes());
507 }
508
509private:
510 typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc<
511 ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc;
512
513 /// \brief End case for the recursion
514 static void collect(ast_matchers::internal::EmptyTypeList) {}
515
516 /// \brief Recursive case. Get the overload for the head of the list, and
517 /// recurse to the tail.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000518 template <typename FromTypeList>
519 inline void collect(FromTypeList);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000520
Craig Topperbf3e3272014-08-30 16:55:52 +0000521 StringRef Name;
Justin Lebar82380d82016-10-10 16:26:40 +0000522 std::vector<std::unique_ptr<MatcherDescriptor>> &Out;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000523};
524
Peter Collingbournef43e6942013-11-23 01:34:36 +0000525/// \brief MatcherDescriptor that wraps multiple "overloads" of the same
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000526/// matcher.
527///
528/// It will try every overload and generate appropriate errors for when none or
529/// more than one overloads match the arguments.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000530class OverloadedMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000531public:
Justin Lebar82380d82016-10-10 16:26:40 +0000532 OverloadedMatcherDescriptor(
533 MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks)
534 : Overloads(std::make_move_iterator(Callbacks.begin()),
535 std::make_move_iterator(Callbacks.end())) {}
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000536
Angel Garcia Gomez637d1e62015-10-20 13:23:58 +0000537 ~OverloadedMatcherDescriptor() override {}
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000538
Craig Toppere335f252015-10-04 04:53:55 +0000539 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000540 ArrayRef<ParserValue> Args,
541 Diagnostics *Error) const override {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000542 std::vector<VariantMatcher> Constructed;
543 Diagnostics::OverloadContext Ctx(Error);
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000544 for (const auto &O : Overloads) {
545 VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000546 if (!SubMatcher.isNull()) {
547 Constructed.push_back(SubMatcher);
548 }
549 }
550
551 if (Constructed.empty()) return VariantMatcher(); // No overload matched.
552 // We ignore the errors if any matcher succeeded.
553 Ctx.revertErrors();
554 if (Constructed.size() > 1) {
555 // More than one constructed. It is ambiguous.
556 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
557 return VariantMatcher();
558 }
559 return Constructed[0];
560 }
561
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000562 bool isVariadic() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000563 bool Overload0Variadic = Overloads[0]->isVariadic();
564#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000565 for (const auto &O : Overloads) {
566 assert(Overload0Variadic == O->isVariadic());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000567 }
568#endif
569 return Overload0Variadic;
570 }
571
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000572 unsigned getNumArgs() const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000573 unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
574#ifndef NDEBUG
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000575 for (const auto &O : Overloads) {
576 assert(Overload0NumArgs == O->getNumArgs());
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000577 }
578#endif
579 return Overload0NumArgs;
580 }
581
582 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000583 std::vector<ArgKind> &Kinds) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000584 for (const auto &O : Overloads) {
585 if (O->isConvertibleTo(ThisKind))
586 O->getArgKinds(ThisKind, ArgNo, Kinds);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000587 }
588 }
589
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000590 bool isConvertibleTo(
591 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
592 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000593 for (const auto &O : Overloads) {
594 if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000595 return true;
596 }
597 return false;
598 }
599
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000600private:
Ahmed Charlesbfb62322014-03-09 12:24:23 +0000601 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000602};
603
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000604/// \brief Variadic operator marshaller function.
Peter Collingbournef43e6942013-11-23 01:34:36 +0000605class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000606public:
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000607 typedef DynTypedMatcher::VariadicOperator VarOp;
Peter Collingbournef43e6942013-11-23 01:34:36 +0000608 VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000609 VarOp Op, StringRef MatcherName)
610 : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000611 MatcherName(MatcherName) {}
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000612
Craig Toppere335f252015-10-04 04:53:55 +0000613 VariantMatcher create(SourceRange NameRange,
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000614 ArrayRef<ParserValue> Args,
615 Diagnostics *Error) const override {
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000616 if (Args.size() < MinCount || MaxCount < Args.size()) {
617 const std::string MaxStr =
618 (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str();
619 Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
620 << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
621 return VariantMatcher();
622 }
623
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000624 std::vector<VariantMatcher> InnerArgs;
625 for (size_t i = 0, e = Args.size(); i != e; ++i) {
626 const ParserValue &Arg = Args[i];
627 const VariantValue &Value = Arg.Value;
628 if (!Value.isMatcher()) {
629 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
630 << (i + 1) << "Matcher<>" << Value.getTypeAsString();
631 return VariantMatcher();
632 }
633 InnerArgs.push_back(Value.getMatcher());
634 }
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000635 return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000636 }
637
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000638 bool isVariadic() const override { return true; }
639 unsigned getNumArgs() const override { return 0; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000640 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000641 std::vector<ArgKind> &Kinds) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000642 Kinds.push_back(ThisKind);
643 }
644 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
Fariborz Jahanian5afc8692014-10-01 16:56:40 +0000645 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000646 if (Specificity)
647 *Specificity = 1;
648 if (LeastDerivedKind)
649 *LeastDerivedKind = Kind;
650 return true;
651 }
Craig Topperbbc6d622014-03-02 10:02:43 +0000652 bool isPolymorphic() const override { return true; }
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000653
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000654private:
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000655 const unsigned MinCount;
656 const unsigned MaxCount;
Samuel Benzaquen2c15e8c2014-11-20 15:45:53 +0000657 const VarOp Op;
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000658 const StringRef MatcherName;
659};
660
Manuel Klimek24db0f02013-05-14 09:13:00 +0000661/// Helper functions to select the appropriate marshaller functions.
Samuel Benzaquenb5dd69f2013-06-11 18:51:07 +0000662/// They detect the number of arguments, arguments types and return type.
Manuel Klimek24db0f02013-05-14 09:13:00 +0000663
664/// \brief 0-arg overload
665template <typename ReturnType>
Justin Lebar82380d82016-10-10 16:26:40 +0000666std::unique_ptr<MatcherDescriptor>
667makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000668 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
669 BuildReturnTypeVector<ReturnType>::build(RetTypes);
Justin Lebar82380d82016-10-10 16:26:40 +0000670 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000671 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
Craig Topper00bbdcf2014-06-28 23:22:23 +0000672 MatcherName, RetTypes, None);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000673}
674
675/// \brief 1-arg overload
676template <typename ReturnType, typename ArgType1>
Justin Lebar82380d82016-10-10 16:26:40 +0000677std::unique_ptr<MatcherDescriptor>
678makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000679 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
680 BuildReturnTypeVector<ReturnType>::build(RetTypes);
681 ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
Justin Lebar82380d82016-10-10 16:26:40 +0000682 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000683 matcherMarshall1<ReturnType, ArgType1>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000684 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000685}
686
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000687/// \brief 2-arg overload
688template <typename ReturnType, typename ArgType1, typename ArgType2>
Justin Lebar82380d82016-10-10 16:26:40 +0000689std::unique_ptr<MatcherDescriptor>
690makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
691 StringRef MatcherName) {
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000692 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
693 BuildReturnTypeVector<ReturnType>::build(RetTypes);
694 ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
695 ArgTypeTraits<ArgType2>::getKind() };
Justin Lebar82380d82016-10-10 16:26:40 +0000696 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
Samuel Benzaquen998cda232013-08-30 15:09:52 +0000697 matcherMarshall2<ReturnType, ArgType1, ArgType2>,
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000698 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
Samuel Benzaquenc31b3522013-06-04 15:46:22 +0000699}
700
Samuel Benzaquen79656e12013-07-15 19:25:06 +0000701/// \brief Variadic overload.
702template <typename ResultT, typename ArgT,
703 ResultT (*Func)(ArrayRef<const ArgT *>)>
Justin Lebar82380d82016-10-10 16:26:40 +0000704std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
Samuel Benzaquenc1384c12016-03-25 16:29:30 +0000705 ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc,
706 StringRef MatcherName) {
Justin Lebar82380d82016-10-10 16:26:40 +0000707 return llvm::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName);
Peter Collingbourned32e28c2014-01-23 22:48:38 +0000708}
709
710/// \brief Overload for VariadicDynCastAllOfMatchers.
711///
712/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
713/// completion results for that type of matcher.
714template <typename BaseT, typename DerivedT>
Justin Lebar82380d82016-10-10 16:26:40 +0000715std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
716 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT>
717 VarFunc,
718 StringRef MatcherName) {
719 return llvm::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName);
Manuel Klimek24db0f02013-05-14 09:13:00 +0000720}
721
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000722/// \brief Argument adaptative overload.
723template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
724 typename FromTypes, typename ToTypes>
Justin Lebar82380d82016-10-10 16:26:40 +0000725std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
726 ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT,
727 FromTypes, ToTypes>,
728 StringRef MatcherName) {
729 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000730 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
731 Overloads);
Justin Lebar82380d82016-10-10 16:26:40 +0000732 return llvm::make_unique<OverloadedMatcherDescriptor>(Overloads);
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000733}
734
735template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
736 typename FromTypes, typename ToTypes>
737template <typename FromTypeList>
Peter Collingbournef43e6942013-11-23 01:34:36 +0000738inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
739 ToTypes>::collect(FromTypeList) {
Samuel Benzaquenbd7d8872013-08-16 16:19:42 +0000740 Out.push_back(makeMatcherAutoMarshall(
741 &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
742 collect(typename FromTypeList::tail());
743}
744
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000745/// \brief Variadic operator overload.
Samuel Benzaquen4d058742013-11-22 14:41:48 +0000746template <unsigned MinCount, unsigned MaxCount>
Justin Lebar82380d82016-10-10 16:26:40 +0000747std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
748 ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount>
749 Func,
750 StringRef MatcherName) {
751 return llvm::make_unique<VariadicOperatorMatcherDescriptor>(
752 MinCount, MaxCount, Func.Op, MatcherName);
Samuel Benzaquen4adca622013-08-28 18:42:04 +0000753}
754
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000755} // namespace internal
756} // namespace dynamic
757} // namespace ast_matchers
758} // namespace clang
Manuel Klimek24db0f02013-05-14 09:13:00 +0000759
Eugene Zelenko1660a5d2016-01-26 19:01:06 +0000760#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H