Marshallers.h revision 8a77c20375874c0759a5cd5b4a34e83465d821b2
1f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===--- Marshallers.h - Generic matcher function marshallers -*- C++ -*-===//
2f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
3f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//                     The LLVM Compiler Infrastructure
4f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
5f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// This file is distributed under the University of Illinois Open Source
6f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// License. See LICENSE.TXT for details.
7f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
8f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===----------------------------------------------------------------------===//
9f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
10f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \file
11f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Functions templates and classes to wrap matcher construct functions.
12f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
13f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// A collection of template function and classes that provide a generic
14f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// marshalling layer on top of matcher construct functions.
15f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// These are used by the registry to export all marshaller constructors with
16f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// the same generic interface.
17f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
18f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//===----------------------------------------------------------------------===//
19f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
20f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
21f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
22f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
23f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include <string>
24f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
25f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/ASTMatchers.h"
26f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
27f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/VariantValue.h"
28f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/Basic/LLVM.h"
29f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "llvm/Support/type_traits.h"
30f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
31f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace clang {
32f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace ast_matchers {
33f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace dynamic {
34f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
35f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace internal {
36f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
37f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Helper template class to just from argument type to the right is/get
38f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///   functions in VariantValue.
39f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// Used to verify and extract the matcher arguments below.
40f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <class T> struct ArgTypeTraits;
41f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
42f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek};
43f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
44f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <> struct ArgTypeTraits<std::string> {
4576c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen  static StringRef asString() { return "String"; }
46f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  static bool is(const VariantValue &Value) { return Value.isString(); }
47f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  static const std::string &get(const VariantValue &Value) {
48f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek    return Value.getString();
49f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  }
50f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek};
51f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
52ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <>
53ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstruct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
54ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen};
55ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen
56f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
5776c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen  static std::string asString() {
5876c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen    return (Twine("Matcher<") +
5976c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen            ast_type_traits::ASTNodeKind::getFromNodeKind<T>().asStringRef() +
6076c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen            ">").str();
6176c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen  }
6276c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen  static bool is(const VariantValue &Value) {
6376c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen    return Value.hasTypedMatcher<T>();
6476c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen  }
65f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
66f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek    return Value.getTypedMatcher<T>();
67f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  }
687a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen};
69f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
707a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <> struct ArgTypeTraits<unsigned> {
7176c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen  static std::string asString() { return "Unsigned"; }
727a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
737a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  static unsigned get(const VariantValue &Value) {
747a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen    return Value.getUnsigned();
757a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  }
76f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek};
77f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
78f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Generic MatcherCreate interface.
79f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
80f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// Provides a \c run() method that constructs the matcher from the provided
81f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// arguments.
82f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekclass MatcherCreateCallback {
83f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic:
84f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  virtual ~MatcherCreateCallback() {}
85ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  virtual MatcherList run(const SourceRange &NameRange,
86ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                          ArrayRef<ParserValue> Args,
87ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                          Diagnostics *Error) const = 0;
88f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek};
89f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
90f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Simple callback implementation. Marshaller and function are provided.
91cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen///
92cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// This class wraps a function of arbitrary signature and a marshaller
93cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// function into a MatcherCreateCallback.
94cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// The marshaller is in charge of taking the VariantValue arguments, checking
95cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// their types, unpacking them and calling the underlying function.
96cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquentemplate <typename FuncType>
97f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekclass FixedArgCountMatcherCreateCallback : public MatcherCreateCallback {
98f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic:
99cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  /// FIXME: Use void(*)() as FuncType on this interface to remove the template
100cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  /// argument of this class. The marshaller can cast the function pointer back
101cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  /// to the original type.
102ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  typedef MatcherList (*MarshallerType)(FuncType, StringRef,
103ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                        const SourceRange &,
104ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                        ArrayRef<ParserValue>,
105ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                        Diagnostics *);
106cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen
107e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko  /// \param Marshaller Function to unpack the arguments and call \c Func
108e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko  /// \param Func Matcher construct function. This is the function that
109e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko  ///   compile-time matcher expressions would use to create the matcher.
110f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  FixedArgCountMatcherCreateCallback(MarshallerType Marshaller, FuncType Func,
111f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek                                     StringRef MatcherName)
112f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek      : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName.str()) {}
113f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
114ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  MatcherList run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
115ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                  Diagnostics *Error) const {
116f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek    return Marshaller(Func, MatcherName, NameRange, Args, Error);
117f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  }
118f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
119f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekprivate:
120f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  const MarshallerType Marshaller;
121f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  const FuncType Func;
122f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  const std::string MatcherName;
123f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek};
124f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
125cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// \brief Simple callback implementation. Free function is wrapped.
126cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen///
127cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// This class simply wraps a free function with the right signature to export
128cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// it as a MatcherCreateCallback.
129cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// This allows us to have one implementation of the interface for as many free
130cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// functions as we want, reducing the number of symbols and size of the
131cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// object file.
132cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquenclass FreeFuncMatcherCreateCallback : public MatcherCreateCallback {
133cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquenpublic:
134ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  typedef MatcherList (*RunFunc)(StringRef MatcherName,
135ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                 const SourceRange &NameRange,
136ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                 ArrayRef<ParserValue> Args,
137ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                 Diagnostics *Error);
138cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen
139cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  FreeFuncMatcherCreateCallback(RunFunc Func, StringRef MatcherName)
140cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen      : Func(Func), MatcherName(MatcherName.str()) {}
141cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen
142ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  MatcherList run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
143ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                  Diagnostics *Error) const {
144cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen    return Func(MatcherName, NameRange, Args, Error);
145cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  }
146cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen
147cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquenprivate:
148cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  const RunFunc Func;
149cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  const std::string MatcherName;
150cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen};
151f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
152f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Helper macros to check the arguments on all marshaller functions.
153f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#define CHECK_ARG_COUNT(count)                                                 \
154f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  if (Args.size() != count) {                                                  \
1558a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen    Error->addError(NameRange, Error->ET_RegistryWrongArgCount)                \
156f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek        << count << Args.size();                                               \
157ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen    return MatcherList();                                                      \
158f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  }
159f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
160f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#define CHECK_ARG_TYPE(index, type)                                            \
161f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  if (!ArgTypeTraits<type>::is(Args[index].Value)) {                           \
1628a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen    Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType)         \
16376c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen        << (index + 1) << ArgTypeTraits<type>::asString()                      \
16476c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen        << Args[index].Value.getTypeAsString();                                \
165ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen    return MatcherList();                                                      \
166f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  }
167f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
168ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \brief Helper methods to extract and merge all possible typed matchers
169ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// out of the polymorphic object.
170ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <class PolyMatcher>
171ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstatic void mergePolyMatchers(const PolyMatcher &Poly, MatcherList *Out,
172ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                              ast_matchers::internal::EmptyTypeList) {}
173ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen
174ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <class PolyMatcher, class TypeList>
175ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstatic void mergePolyMatchers(const PolyMatcher &Poly, MatcherList *Out,
176ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                              TypeList) {
177ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  Out->add(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
178ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  mergePolyMatchers(Poly, Out, typename TypeList::tail());
179ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen}
180ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen
181ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \brief Convert the return values of the functions into a MatcherList.
182ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen///
183ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// There are 2 cases right now: The return value is a Matcher<T> or is a
184ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// polymorphic matcher. For the former, we just construct the MatcherList. For
185ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// the latter, we instantiate all the possible Matcher<T> of the poly matcher.
186ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <typename T>
187ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstatic MatcherList
188ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel BenzaquenoutvalueToMatcherList(const ast_matchers::internal::Matcher<T> &Matcher) {
189ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  return MatcherList(Matcher);
190ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen}
191ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen
192ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <typename T>
193ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstatic MatcherList
194ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel BenzaquenoutvalueToMatcherList(const T& PolyMatcher, typename T::ReturnTypes* = NULL) {
195ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  MatcherList Matchers;
196ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  mergePolyMatchers(PolyMatcher, &Matchers, typename T::ReturnTypes());
197ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  return Matchers;
198ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen}
199ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen
200f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 0-arg marshaller function.
201f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType>
202ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstatic MatcherList matcherMarshall0(ReturnType (*Func)(),
203ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    StringRef MatcherName,
204ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    const SourceRange &NameRange,
205ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    ArrayRef<ParserValue> Args,
206ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    Diagnostics *Error) {
207f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  CHECK_ARG_COUNT(0);
208ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  return outvalueToMatcherList(Func());
209f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
210f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
211f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 1-arg marshaller function.
2127a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <typename ReturnType, typename ArgType1>
213ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstatic MatcherList matcherMarshall1(ReturnType (*Func)(ArgType1),
214ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    StringRef MatcherName,
215ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    const SourceRange &NameRange,
216ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    ArrayRef<ParserValue> Args,
217ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    Diagnostics *Error) {
218f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  CHECK_ARG_COUNT(1);
219f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  CHECK_ARG_TYPE(0, ArgType1);
220ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  return outvalueToMatcherList(
221ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen      Func(ArgTypeTraits<ArgType1>::get(Args[0].Value)));
222f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
223f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
2247a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen/// \brief 2-arg marshaller function.
2257a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <typename ReturnType, typename ArgType1, typename ArgType2>
226ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstatic MatcherList matcherMarshall2(ReturnType (*Func)(ArgType1, ArgType2),
227ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    StringRef MatcherName,
228ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    const SourceRange &NameRange,
229ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    ArrayRef<ParserValue> Args,
230ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                    Diagnostics *Error) {
2317a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  CHECK_ARG_COUNT(2);
2327a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  CHECK_ARG_TYPE(0, ArgType1);
2337a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  CHECK_ARG_TYPE(1, ArgType2);
234ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  return outvalueToMatcherList(
235ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen      Func(ArgTypeTraits<ArgType1>::get(Args[0].Value),
236ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen           ArgTypeTraits<ArgType2>::get(Args[1].Value)));
2377a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen}
2387a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen
239cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen#undef CHECK_ARG_COUNT
240cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen#undef CHECK_ARG_TYPE
241cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen
242f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Variadic marshaller function.
2433f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquentemplate <typename ResultT, typename ArgT,
2443f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen          ResultT (*Func)(ArrayRef<const ArgT *>)>
2453f84bb341bfb1312842b09db71d76bc3898ba247Samuel BenzaquenMatcherList variadicMatcherCreateCallback(StringRef MatcherName,
246ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                          const SourceRange &NameRange,
247ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                          ArrayRef<ParserValue> Args,
248ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                          Diagnostics *Error) {
2493f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  ArgT **InnerArgs = new ArgT *[Args.size()]();
250cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen
251cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  bool HasError = false;
252cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  for (size_t i = 0, e = Args.size(); i != e; ++i) {
2533f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen    typedef ArgTypeTraits<ArgT> ArgTraits;
25476c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen    const ParserValue &Arg = Args[i];
25576c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen    const VariantValue &Value = Arg.Value;
2563f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen    if (!ArgTraits::is(Value)) {
2578a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen      Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
2583f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen          << (i + 1) << ArgTraits::asString() << Value.getTypeAsString();
259cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen      HasError = true;
260cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen      break;
261f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek    }
2623f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen    InnerArgs[i] = new ArgT(ArgTraits::get(Value));
263f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  }
264f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
265ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  MatcherList Out;
266cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  if (!HasError) {
2673f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen    Out = outvalueToMatcherList(
2683f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen        Func(ArrayRef<const ArgT *>(InnerArgs, Args.size())));
269cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  }
270f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
271cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  for (size_t i = 0, e = Args.size(); i != e; ++i) {
272cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen    delete InnerArgs[i];
273cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  }
274cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  delete[] InnerArgs;
275cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  return Out;
276cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen}
277f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
278f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// Helper functions to select the appropriate marshaller functions.
279cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// They detect the number of arguments, arguments types and return type.
280f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
281f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 0-arg overload
282f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType>
283f7f295f321fd434e1e542844a71f538a56f2f8fbManuel KlimekMatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(),
284f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek                                               StringRef MatcherName) {
285cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  return new FixedArgCountMatcherCreateCallback<ReturnType (*)()>(
286cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen      matcherMarshall0, Func, MatcherName);
287f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
288f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
289f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 1-arg overload
290f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType, typename ArgType1>
291f7f295f321fd434e1e542844a71f538a56f2f8fbManuel KlimekMatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1),
292f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek                                               StringRef MatcherName) {
293cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  return new FixedArgCountMatcherCreateCallback<ReturnType (*)(ArgType1)>(
294cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen      matcherMarshall1, Func, MatcherName);
295f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
296f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
2977a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen/// \brief 2-arg overload
2987a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <typename ReturnType, typename ArgType1, typename ArgType2>
2997a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel BenzaquenMatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1,
3007a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen                                                                  ArgType2),
3017a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen                                               StringRef MatcherName) {
302cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  return new FixedArgCountMatcherCreateCallback<
303cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen      ReturnType (*)(ArgType1, ArgType2)>(matcherMarshall2, Func, MatcherName);
3047a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen}
3057a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen
3063f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// \brief Variadic overload.
3073f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquentemplate <typename ResultT, typename ArgT,
3083f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen          ResultT (*Func)(ArrayRef<const ArgT *>)>
309f7f295f321fd434e1e542844a71f538a56f2f8fbManuel KlimekMatcherCreateCallback *
3103f84bb341bfb1312842b09db71d76bc3898ba247Samuel BenzaquenmakeMatcherAutoMarshall(llvm::VariadicFunction<ResultT, ArgT, Func> VarFunc,
311f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek                        StringRef MatcherName) {
312cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen  return new FreeFuncMatcherCreateCallback(
3133f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen      &variadicMatcherCreateCallback<ResultT, ArgT, Func>, MatcherName);
314f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
315f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
316f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace internal
317f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace dynamic
318f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace ast_matchers
319f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace clang
320f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
321f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#endif  // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
322