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