1259701Sdim//===--- Marshallers.h - Generic matcher function marshallers -*- C++ -*-===//
2259701Sdim//
3259701Sdim//                     The LLVM Compiler Infrastructure
4259701Sdim//
5259701Sdim// This file is distributed under the University of Illinois Open Source
6259701Sdim// License. See LICENSE.TXT for details.
7259701Sdim//
8259701Sdim//===----------------------------------------------------------------------===//
9259701Sdim///
10259701Sdim/// \file
11259701Sdim/// \brief Functions templates and classes to wrap matcher construct functions.
12259701Sdim///
13259701Sdim/// A collection of template function and classes that provide a generic
14259701Sdim/// marshalling layer on top of matcher construct functions.
15259701Sdim/// These are used by the registry to export all marshaller constructors with
16259701Sdim/// the same generic interface.
17259701Sdim///
18259701Sdim//===----------------------------------------------------------------------===//
19259701Sdim
20259701Sdim#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
21259701Sdim#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
22259701Sdim
23259701Sdim#include <string>
24259701Sdim
25259701Sdim#include "clang/ASTMatchers/ASTMatchers.h"
26259701Sdim#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
27259701Sdim#include "clang/ASTMatchers/Dynamic/VariantValue.h"
28259701Sdim#include "clang/Basic/LLVM.h"
29259701Sdim#include "llvm/ADT/STLExtras.h"
30259701Sdim#include "llvm/Support/type_traits.h"
31259701Sdim
32259701Sdimnamespace clang {
33259701Sdimnamespace ast_matchers {
34259701Sdimnamespace dynamic {
35259701Sdim
36259701Sdimnamespace internal {
37259701Sdim
38259701Sdim/// \brief Helper template class to just from argument type to the right is/get
39259701Sdim///   functions in VariantValue.
40259701Sdim/// Used to verify and extract the matcher arguments below.
41259701Sdimtemplate <class T> struct ArgTypeTraits;
42259701Sdimtemplate <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
43259701Sdim};
44259701Sdim
45259701Sdimtemplate <> struct ArgTypeTraits<std::string> {
46259701Sdim  static StringRef asString() { return "String"; }
47259701Sdim  static bool is(const VariantValue &Value) { return Value.isString(); }
48259701Sdim  static const std::string &get(const VariantValue &Value) {
49259701Sdim    return Value.getString();
50259701Sdim  }
51259701Sdim};
52259701Sdim
53259701Sdimtemplate <>
54259701Sdimstruct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
55259701Sdim};
56259701Sdim
57259701Sdimtemplate <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
58259701Sdim  static std::string asString() {
59259701Sdim    return (Twine("Matcher<") +
60259701Sdim            ast_type_traits::ASTNodeKind::getFromNodeKind<T>().asStringRef() +
61259701Sdim            ">").str();
62259701Sdim  }
63259701Sdim  static bool is(const VariantValue &Value) {
64259701Sdim    return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
65259701Sdim  }
66259701Sdim  static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
67259701Sdim    return Value.getMatcher().getTypedMatcher<T>();
68259701Sdim  }
69259701Sdim};
70259701Sdim
71259701Sdimtemplate <> struct ArgTypeTraits<unsigned> {
72259701Sdim  static std::string asString() { return "Unsigned"; }
73259701Sdim  static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
74259701Sdim  static unsigned get(const VariantValue &Value) {
75259701Sdim    return Value.getUnsigned();
76259701Sdim  }
77259701Sdim};
78259701Sdim
79259701Sdim/// \brief Generic MatcherCreate interface.
80259701Sdim///
81259701Sdim/// Provides a \c run() method that constructs the matcher from the provided
82259701Sdim/// arguments.
83259701Sdimclass MatcherCreateCallback {
84259701Sdimpublic:
85259701Sdim  virtual ~MatcherCreateCallback() {}
86259701Sdim  virtual VariantMatcher run(const SourceRange &NameRange,
87259701Sdim                             ArrayRef<ParserValue> Args,
88259701Sdim                             Diagnostics *Error) const = 0;
89259701Sdim};
90259701Sdim
91259701Sdim/// \brief Simple callback implementation. Marshaller and function are provided.
92259701Sdim///
93259701Sdim/// This class wraps a function of arbitrary signature and a marshaller
94259701Sdim/// function into a MatcherCreateCallback.
95259701Sdim/// The marshaller is in charge of taking the VariantValue arguments, checking
96259701Sdim/// their types, unpacking them and calling the underlying function.
97259701Sdimclass FixedArgCountMatcherCreateCallback : public MatcherCreateCallback {
98259701Sdimpublic:
99259701Sdim  typedef VariantMatcher (*MarshallerType)(void (*Func)(),
100259701Sdim                                           StringRef MatcherName,
101259701Sdim                                           const SourceRange &NameRange,
102259701Sdim                                           ArrayRef<ParserValue> Args,
103259701Sdim                                           Diagnostics *Error);
104259701Sdim
105259701Sdim  /// \param Marshaller Function to unpack the arguments and call \c Func
106259701Sdim  /// \param Func Matcher construct function. This is the function that
107259701Sdim  ///   compile-time matcher expressions would use to create the matcher.
108259701Sdim  FixedArgCountMatcherCreateCallback(MarshallerType Marshaller, void (*Func)(),
109259701Sdim                                     StringRef MatcherName)
110259701Sdim      : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName) {}
111259701Sdim
112259701Sdim  VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
113259701Sdim                     Diagnostics *Error) const {
114259701Sdim    return Marshaller(Func, MatcherName, NameRange, Args, Error);
115259701Sdim  }
116259701Sdim
117259701Sdimprivate:
118259701Sdim  const MarshallerType Marshaller;
119259701Sdim  void (* const Func)();
120259701Sdim  const std::string MatcherName;
121259701Sdim};
122259701Sdim
123259701Sdim/// \brief Simple callback implementation. Free function is wrapped.
124259701Sdim///
125259701Sdim/// This class simply wraps a free function with the right signature to export
126259701Sdim/// it as a MatcherCreateCallback.
127259701Sdim/// This allows us to have one implementation of the interface for as many free
128259701Sdim/// functions as we want, reducing the number of symbols and size of the
129259701Sdim/// object file.
130259701Sdimclass FreeFuncMatcherCreateCallback : public MatcherCreateCallback {
131259701Sdimpublic:
132259701Sdim  typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
133259701Sdim                                    const SourceRange &NameRange,
134259701Sdim                                    ArrayRef<ParserValue> Args,
135259701Sdim                                    Diagnostics *Error);
136259701Sdim
137259701Sdim  FreeFuncMatcherCreateCallback(RunFunc Func, StringRef MatcherName)
138259701Sdim      : Func(Func), MatcherName(MatcherName.str()) {}
139259701Sdim
140259701Sdim  VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
141259701Sdim                     Diagnostics *Error) const {
142259701Sdim    return Func(MatcherName, NameRange, Args, Error);
143259701Sdim  }
144259701Sdim
145259701Sdimprivate:
146259701Sdim  const RunFunc Func;
147259701Sdim  const std::string MatcherName;
148259701Sdim};
149259701Sdim
150259701Sdim/// \brief Helper macros to check the arguments on all marshaller functions.
151259701Sdim#define CHECK_ARG_COUNT(count)                                                 \
152259701Sdim  if (Args.size() != count) {                                                  \
153259701Sdim    Error->addError(NameRange, Error->ET_RegistryWrongArgCount)                \
154259701Sdim        << count << Args.size();                                               \
155259701Sdim    return VariantMatcher();                                                   \
156259701Sdim  }
157259701Sdim
158259701Sdim#define CHECK_ARG_TYPE(index, type)                                            \
159259701Sdim  if (!ArgTypeTraits<type>::is(Args[index].Value)) {                           \
160259701Sdim    Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType)         \
161259701Sdim        << (index + 1) << ArgTypeTraits<type>::asString()                      \
162259701Sdim        << Args[index].Value.getTypeAsString();                                \
163259701Sdim    return VariantMatcher();                                                   \
164259701Sdim  }
165259701Sdim
166259701Sdim/// \brief Helper methods to extract and merge all possible typed matchers
167259701Sdim/// out of the polymorphic object.
168259701Sdimtemplate <class PolyMatcher>
169259701Sdimstatic void mergePolyMatchers(const PolyMatcher &Poly,
170259701Sdim                              std::vector<DynTypedMatcher> &Out,
171259701Sdim                              ast_matchers::internal::EmptyTypeList) {}
172259701Sdim
173259701Sdimtemplate <class PolyMatcher, class TypeList>
174259701Sdimstatic void mergePolyMatchers(const PolyMatcher &Poly,
175259701Sdim                              std::vector<DynTypedMatcher> &Out, TypeList) {
176259701Sdim  Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
177259701Sdim  mergePolyMatchers(Poly, Out, typename TypeList::tail());
178259701Sdim}
179259701Sdim
180259701Sdim/// \brief Convert the return values of the functions into a VariantMatcher.
181259701Sdim///
182259701Sdim/// There are 2 cases right now: The return value is a Matcher<T> or is a
183259701Sdim/// polymorphic matcher. For the former, we just construct the VariantMatcher.
184259701Sdim/// For the latter, we instantiate all the possible Matcher<T> of the poly
185259701Sdim/// matcher.
186259701Sdimstatic VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
187259701Sdim  return VariantMatcher::SingleMatcher(Matcher);
188259701Sdim}
189259701Sdim
190259701Sdimtemplate <typename T>
191259701Sdimstatic VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
192259701Sdim                                               typename T::ReturnTypes * =
193259701Sdim                                                   NULL) {
194259701Sdim  std::vector<DynTypedMatcher> Matchers;
195259701Sdim  mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
196259701Sdim  VariantMatcher Out = VariantMatcher::PolymorphicMatcher(Matchers);
197259701Sdim  return Out;
198259701Sdim}
199259701Sdim
200259701Sdim/// \brief 0-arg marshaller function.
201259701Sdimtemplate <typename ReturnType>
202259701Sdimstatic VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
203259701Sdim                                       const SourceRange &NameRange,
204259701Sdim                                       ArrayRef<ParserValue> Args,
205259701Sdim                                       Diagnostics *Error) {
206259701Sdim  typedef ReturnType (*FuncType)();
207259701Sdim  CHECK_ARG_COUNT(0);
208259701Sdim  return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
209259701Sdim}
210259701Sdim
211259701Sdim/// \brief 1-arg marshaller function.
212259701Sdimtemplate <typename ReturnType, typename ArgType1>
213259701Sdimstatic VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
214259701Sdim                                       const SourceRange &NameRange,
215259701Sdim                                       ArrayRef<ParserValue> Args,
216259701Sdim                                       Diagnostics *Error) {
217259701Sdim  typedef ReturnType (*FuncType)(ArgType1);
218259701Sdim  CHECK_ARG_COUNT(1);
219259701Sdim  CHECK_ARG_TYPE(0, ArgType1);
220259701Sdim  return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
221259701Sdim      ArgTypeTraits<ArgType1>::get(Args[0].Value)));
222259701Sdim}
223259701Sdim
224259701Sdim/// \brief 2-arg marshaller function.
225259701Sdimtemplate <typename ReturnType, typename ArgType1, typename ArgType2>
226259701Sdimstatic VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
227259701Sdim                                       const SourceRange &NameRange,
228259701Sdim                                       ArrayRef<ParserValue> Args,
229259701Sdim                                       Diagnostics *Error) {
230259701Sdim  typedef ReturnType (*FuncType)(ArgType1, ArgType2);
231259701Sdim  CHECK_ARG_COUNT(2);
232259701Sdim  CHECK_ARG_TYPE(0, ArgType1);
233259701Sdim  CHECK_ARG_TYPE(1, ArgType2);
234259701Sdim  return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
235259701Sdim      ArgTypeTraits<ArgType1>::get(Args[0].Value),
236259701Sdim      ArgTypeTraits<ArgType2>::get(Args[1].Value)));
237259701Sdim}
238259701Sdim
239259701Sdim#undef CHECK_ARG_COUNT
240259701Sdim#undef CHECK_ARG_TYPE
241259701Sdim
242259701Sdim/// \brief Variadic marshaller function.
243259701Sdimtemplate <typename ResultT, typename ArgT,
244259701Sdim          ResultT (*Func)(ArrayRef<const ArgT *>)>
245259701SdimVariantMatcher
246259701SdimvariadicMatcherCreateCallback(StringRef MatcherName,
247259701Sdim                              const SourceRange &NameRange,
248259701Sdim                              ArrayRef<ParserValue> Args, Diagnostics *Error) {
249259701Sdim  ArgT **InnerArgs = new ArgT *[Args.size()]();
250259701Sdim
251259701Sdim  bool HasError = false;
252259701Sdim  for (size_t i = 0, e = Args.size(); i != e; ++i) {
253259701Sdim    typedef ArgTypeTraits<ArgT> ArgTraits;
254259701Sdim    const ParserValue &Arg = Args[i];
255259701Sdim    const VariantValue &Value = Arg.Value;
256259701Sdim    if (!ArgTraits::is(Value)) {
257259701Sdim      Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
258259701Sdim          << (i + 1) << ArgTraits::asString() << Value.getTypeAsString();
259259701Sdim      HasError = true;
260259701Sdim      break;
261259701Sdim    }
262259701Sdim    InnerArgs[i] = new ArgT(ArgTraits::get(Value));
263259701Sdim  }
264259701Sdim
265259701Sdim  VariantMatcher Out;
266259701Sdim  if (!HasError) {
267259701Sdim    Out = outvalueToVariantMatcher(
268259701Sdim        Func(ArrayRef<const ArgT *>(InnerArgs, Args.size())));
269259701Sdim  }
270259701Sdim
271259701Sdim  for (size_t i = 0, e = Args.size(); i != e; ++i) {
272259701Sdim    delete InnerArgs[i];
273259701Sdim  }
274259701Sdim  delete[] InnerArgs;
275259701Sdim  return Out;
276259701Sdim}
277259701Sdim
278259701Sdim/// \brief Helper class used to collect all the possible overloads of an
279259701Sdim///   argument adaptative matcher function.
280259701Sdimtemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
281259701Sdim          typename FromTypes, typename ToTypes>
282259701Sdimclass AdaptativeOverloadCollector {
283259701Sdimpublic:
284259701Sdim  AdaptativeOverloadCollector(StringRef Name,
285259701Sdim                              std::vector<MatcherCreateCallback *> &Out)
286259701Sdim      : Name(Name), Out(Out) {
287259701Sdim    collect(FromTypes());
288259701Sdim  }
289259701Sdim
290259701Sdimprivate:
291259701Sdim  typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc<
292259701Sdim      ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc;
293259701Sdim
294259701Sdim  /// \brief End case for the recursion
295259701Sdim  static void collect(ast_matchers::internal::EmptyTypeList) {}
296259701Sdim
297259701Sdim  /// \brief Recursive case. Get the overload for the head of the list, and
298259701Sdim  ///   recurse to the tail.
299259701Sdim  template <typename FromTypeList> inline void collect(FromTypeList);
300259701Sdim
301259701Sdim  const StringRef Name;
302259701Sdim  std::vector<MatcherCreateCallback *> &Out;
303259701Sdim};
304259701Sdim
305259701Sdim/// \brief MatcherCreateCallback that wraps multiple "overloads" of the same
306259701Sdim///   matcher.
307259701Sdim///
308259701Sdim/// It will try every overload and generate appropriate errors for when none or
309259701Sdim/// more than one overloads match the arguments.
310259701Sdimclass OverloadedMatcherCreateCallback : public MatcherCreateCallback {
311259701Sdimpublic:
312259701Sdim  OverloadedMatcherCreateCallback(ArrayRef<MatcherCreateCallback *> Callbacks)
313259701Sdim      : Overloads(Callbacks) {}
314259701Sdim
315259701Sdim  virtual ~OverloadedMatcherCreateCallback() {
316259701Sdim    llvm::DeleteContainerPointers(Overloads);
317259701Sdim  }
318259701Sdim
319259701Sdim  virtual VariantMatcher run(const SourceRange &NameRange,
320259701Sdim                             ArrayRef<ParserValue> Args,
321259701Sdim                             Diagnostics *Error) const {
322259701Sdim    std::vector<VariantMatcher> Constructed;
323259701Sdim    Diagnostics::OverloadContext Ctx(Error);
324259701Sdim    for (size_t i = 0, e = Overloads.size(); i != e; ++i) {
325259701Sdim      VariantMatcher SubMatcher = Overloads[i]->run(NameRange, Args, Error);
326259701Sdim      if (!SubMatcher.isNull()) {
327259701Sdim        Constructed.push_back(SubMatcher);
328259701Sdim      }
329259701Sdim    }
330259701Sdim
331259701Sdim    if (Constructed.empty()) return VariantMatcher(); // No overload matched.
332259701Sdim    // We ignore the errors if any matcher succeeded.
333259701Sdim    Ctx.revertErrors();
334259701Sdim    if (Constructed.size() > 1) {
335259701Sdim      // More than one constructed. It is ambiguous.
336259701Sdim      Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
337259701Sdim      return VariantMatcher();
338259701Sdim    }
339259701Sdim    return Constructed[0];
340259701Sdim  }
341259701Sdim
342259701Sdimprivate:
343259701Sdim  std::vector<MatcherCreateCallback *> Overloads;
344259701Sdim};
345259701Sdim
346259701Sdim/// \brief Variadic operator marshaller function.
347259701Sdimclass VariadicOperatorMatcherCreateCallback : public MatcherCreateCallback {
348259701Sdimpublic:
349259701Sdim  typedef ast_matchers::internal::VariadicOperatorFunction VarFunc;
350259701Sdim  VariadicOperatorMatcherCreateCallback(VarFunc Func, StringRef MatcherName)
351259701Sdim      : Func(Func), MatcherName(MatcherName) {}
352259701Sdim
353259701Sdim  virtual VariantMatcher run(const SourceRange &NameRange,
354259701Sdim                             ArrayRef<ParserValue> Args,
355259701Sdim                             Diagnostics *Error) const {
356259701Sdim    std::vector<VariantMatcher> InnerArgs;
357259701Sdim    for (size_t i = 0, e = Args.size(); i != e; ++i) {
358259701Sdim      const ParserValue &Arg = Args[i];
359259701Sdim      const VariantValue &Value = Arg.Value;
360259701Sdim      if (!Value.isMatcher()) {
361259701Sdim        Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
362259701Sdim            << (i + 1) << "Matcher<>" << Value.getTypeAsString();
363259701Sdim        return VariantMatcher();
364259701Sdim      }
365259701Sdim      InnerArgs.push_back(Value.getMatcher());
366259701Sdim    }
367259701Sdim    return VariantMatcher::VariadicOperatorMatcher(Func, InnerArgs);
368259701Sdim  }
369259701Sdim
370259701Sdimprivate:
371259701Sdim  const VarFunc Func;
372259701Sdim  const StringRef MatcherName;
373259701Sdim};
374259701Sdim
375259701Sdim
376259701Sdim/// Helper functions to select the appropriate marshaller functions.
377259701Sdim/// They detect the number of arguments, arguments types and return type.
378259701Sdim
379259701Sdim/// \brief 0-arg overload
380259701Sdimtemplate <typename ReturnType>
381259701SdimMatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(),
382259701Sdim                                               StringRef MatcherName) {
383259701Sdim  return new FixedArgCountMatcherCreateCallback(
384259701Sdim      matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
385259701Sdim      MatcherName);
386259701Sdim}
387259701Sdim
388259701Sdim/// \brief 1-arg overload
389259701Sdimtemplate <typename ReturnType, typename ArgType1>
390259701SdimMatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1),
391259701Sdim                                               StringRef MatcherName) {
392259701Sdim  return new FixedArgCountMatcherCreateCallback(
393259701Sdim      matcherMarshall1<ReturnType, ArgType1>,
394259701Sdim      reinterpret_cast<void (*)()>(Func), MatcherName);
395259701Sdim}
396259701Sdim
397259701Sdim/// \brief 2-arg overload
398259701Sdimtemplate <typename ReturnType, typename ArgType1, typename ArgType2>
399259701SdimMatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1,
400259701Sdim                                                                  ArgType2),
401259701Sdim                                               StringRef MatcherName) {
402259701Sdim  return new FixedArgCountMatcherCreateCallback(
403259701Sdim      matcherMarshall2<ReturnType, ArgType1, ArgType2>,
404259701Sdim      reinterpret_cast<void (*)()>(Func), MatcherName);
405259701Sdim}
406259701Sdim
407259701Sdim/// \brief Variadic overload.
408259701Sdimtemplate <typename ResultT, typename ArgT,
409259701Sdim          ResultT (*Func)(ArrayRef<const ArgT *>)>
410259701SdimMatcherCreateCallback *
411259701SdimmakeMatcherAutoMarshall(llvm::VariadicFunction<ResultT, ArgT, Func> VarFunc,
412259701Sdim                        StringRef MatcherName) {
413259701Sdim  return new FreeFuncMatcherCreateCallback(
414259701Sdim      &variadicMatcherCreateCallback<ResultT, ArgT, Func>, MatcherName);
415259701Sdim}
416259701Sdim
417259701Sdim/// \brief Argument adaptative overload.
418259701Sdimtemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
419259701Sdim          typename FromTypes, typename ToTypes>
420259701SdimMatcherCreateCallback *
421259701SdimmakeMatcherAutoMarshall(ast_matchers::internal::ArgumentAdaptingMatcherFunc<
422259701Sdim                            ArgumentAdapterT, FromTypes, ToTypes>,
423259701Sdim                        StringRef MatcherName) {
424259701Sdim  std::vector<MatcherCreateCallback *> Overloads;
425259701Sdim  AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
426259701Sdim                                                                    Overloads);
427259701Sdim  return new OverloadedMatcherCreateCallback(Overloads);
428259701Sdim}
429259701Sdim
430259701Sdimtemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
431259701Sdim          typename FromTypes, typename ToTypes>
432259701Sdimtemplate <typename FromTypeList>
433259701Sdiminline void
434259701SdimAdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>::collect(
435259701Sdim    FromTypeList) {
436259701Sdim  Out.push_back(makeMatcherAutoMarshall(
437259701Sdim      &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
438259701Sdim  collect(typename FromTypeList::tail());
439259701Sdim}
440259701Sdim
441259701Sdim/// \brief Variadic operator overload.
442259701SdimMatcherCreateCallback *makeMatcherAutoMarshall(
443259701Sdim    ast_matchers::internal::VariadicOperatorMatcherFunc Func,
444259701Sdim    StringRef MatcherName) {
445259701Sdim  return new VariadicOperatorMatcherCreateCallback(Func.Func, MatcherName);
446259701Sdim}
447259701Sdim
448259701Sdim}  // namespace internal
449259701Sdim}  // namespace dynamic
450259701Sdim}  // namespace ast_matchers
451259701Sdim}  // namespace clang
452259701Sdim
453259701Sdim#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
454