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 "clang/ASTMatchers/ASTMatchers.h" 24f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/Diagnostics.h" 25f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/VariantValue.h" 26f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/Basic/LLVM.h" 279d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen#include "llvm/ADT/STLExtras.h" 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <string> 29f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 30f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace clang { 31f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace ast_matchers { 32f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace dynamic { 33f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 34f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace internal { 35f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct ArgKind { 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines enum Kind { 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AK_Matcher, 39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AK_Unsigned, 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AK_String 41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines }; 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgKind(Kind K) 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : K(K) {} 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgKind(ast_type_traits::ASTNodeKind MatcherKind) 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : K(AK_Matcher), MatcherKind(MatcherKind) {} 46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::string asString() const { 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines switch (getArgKind()) { 49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case AK_Matcher: 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str(); 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case AK_Unsigned: 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return "unsigned"; 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case AK_String: 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return "string"; 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm_unreachable("unhandled ArgKind"); 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kind getArgKind() const { return K; } 60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind getMatcherKind() const { 61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(K == AK_Matcher); 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MatcherKind; 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool operator<(const ArgKind &Other) const { 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (K == AK_Matcher && Other.K == AK_Matcher) 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return MatcherKind < Other.MatcherKind; 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return K < Other.K; 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate: 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kind K; 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind MatcherKind; 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 76f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Helper template class to just from argument type to the right is/get 77f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// functions in VariantValue. 78f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// Used to verify and extract the matcher arguments below. 79f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <class T> struct ArgTypeTraits; 80f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> { 81f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 82f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 83f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <> struct ArgTypeTraits<std::string> { 84f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek static bool is(const VariantValue &Value) { return Value.isString(); } 85f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek static const std::string &get(const VariantValue &Value) { 86f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return Value.getString(); 87f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static ArgKind getKind() { 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ArgKind(ArgKind::AK_String); 90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 91f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 92f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 93ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquentemplate <> 94ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquenstruct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> { 95ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen}; 96ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 97f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > { 9876c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen static bool is(const VariantValue &Value) { 994e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>(); 10076c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen } 101f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) { 1024e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen return Value.getMatcher().getTypedMatcher<T>(); 103f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static ArgKind getKind() { 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1077a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen}; 108f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 1097a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <> struct ArgTypeTraits<unsigned> { 1107a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen static bool is(const VariantValue &Value) { return Value.isUnsigned(); } 1117a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen static unsigned get(const VariantValue &Value) { 1127a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen return Value.getUnsigned(); 1137a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen } 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static ArgKind getKind() { 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ArgKind(ArgKind::AK_Unsigned); 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 117f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 118f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Matcher descriptor interface. 120f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Provides a \c create() method that constructs the matcher from the provided 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// arguments, and various other methods for type introspection. 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass MatcherDescriptor { 124f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic: 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual ~MatcherDescriptor() {} 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual VariantMatcher create(const SourceRange &NameRange, 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParserValue> Args, 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diagnostics *Error) const = 0; 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Returns whether the matcher is variadic. Variadic matchers can take any 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// number of arguments, but they must be of the same type. 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual bool isVariadic() const = 0; 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Returns the number of arguments accepted by the matcher if not variadic. 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual unsigned getNumArgs() const = 0; 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Given that the matcher is being converted to type \p ThisKind, append the 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// set of argument types accepted for argument \p ArgNo to \p ArgKinds. 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: We should provide the ability to constrain the output of this 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // function based on the types of other matcher arguments. 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ArgKind> &ArgKinds) const = 0; 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Returns whether this matcher is convertible to the given type. If it is 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// so convertible, store in *Specificity a value corresponding to the 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// "specificity" of the converted matcher to the given context, and in 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// *LeastDerivedKind the least derived matcher kind which would result in the 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// same matcher overload. Zero specificity indicates that this conversion 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// would produce a trivial matcher that will either always or never match. 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Such matchers are excluded from code completion results. 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual bool isConvertibleTo( 1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr, 1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0; 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Returns whether the matcher will, given a matcher of any type T, yield a 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// matcher of type T. 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual bool isPolymorphic() const { return false; } 158f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 159f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline bool isRetKindConvertibleTo( 161ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ArrayRef<ast_type_traits::ASTNodeKind> RetKinds, 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) { 164ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for (ArrayRef<ast_type_traits::ASTNodeKind>::const_iterator 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines i = RetKinds.begin(), 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines e = RetKinds.end(); 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines i != e; ++i) { 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Distance; 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (i->isBaseOf(Kind, &Distance)) { 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Specificity) 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *Specificity = 100 - Distance; 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (LeastDerivedKind) 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *LeastDerivedKind = *i; 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 180f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Simple callback implementation. Marshaller and function are provided. 181cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// 182cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// This class wraps a function of arbitrary signature and a marshaller 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// function into a MatcherDescriptor. 184cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// The marshaller is in charge of taking the VariantValue arguments, checking 185cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// their types, unpacking them and calling the underlying function. 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass FixedArgCountMatcherDescriptor : public MatcherDescriptor { 187f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic: 1884e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen typedef VariantMatcher (*MarshallerType)(void (*Func)(), 1894e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen StringRef MatcherName, 1904e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen const SourceRange &NameRange, 1914e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen ArrayRef<ParserValue> Args, 1924e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen Diagnostics *Error); 193cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 194e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko /// \param Marshaller Function to unpack the arguments and call \c Func 195e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko /// \param Func Matcher construct function. This is the function that 196e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko /// compile-time matcher expressions would use to create the matcher. 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \param RetKinds The list of matcher types to which the matcher is 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// convertible. 199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \param ArgKinds The types of the arguments this matcher takes. 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FixedArgCountMatcherDescriptor( 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MarshallerType Marshaller, void (*Func)(), StringRef MatcherName, 202ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ArrayRef<ast_type_traits::ASTNodeKind> RetKinds, 203ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ArrayRef<ArgKind> ArgKinds) 204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName), 205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RetKinds(RetKinds.begin(), RetKinds.end()), 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgKinds(ArgKinds.begin(), ArgKinds.end()) {} 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariantMatcher create(const SourceRange &NameRange, 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParserValue> Args, Diagnostics *Error) const { 210f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return Marshaller(Func, MatcherName, NameRange, Args, Error); 211f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 212f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isVariadic() const { return false; } 214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getNumArgs() const { return ArgKinds.size(); } 215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ArgKind> &Kinds) const { 217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kinds.push_back(ArgKinds[ArgNo]); 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) const { 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LeastDerivedKind); 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 225f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekprivate: 226f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek const MarshallerType Marshaller; 2274e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen void (* const Func)(); 228f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek const std::string MatcherName; 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::vector<ast_type_traits::ASTNodeKind> RetKinds; 230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::vector<ArgKind> ArgKinds; 231f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 232f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Helper methods to extract and merge all possible typed matchers 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// out of the polymorphic object. 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <class PolyMatcher> 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void mergePolyMatchers(const PolyMatcher &Poly, 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> &Out, 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_matchers::internal::EmptyTypeList) {} 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <class PolyMatcher, class TypeList> 241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void mergePolyMatchers(const PolyMatcher &Poly, 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> &Out, TypeList) { 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)); 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mergePolyMatchers(Poly, Out, typename TypeList::tail()); 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Convert the return values of the functions into a VariantMatcher. 248cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// There are 2 cases right now: The return value is a Matcher<T> or is a 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// polymorphic matcher. For the former, we just construct the VariantMatcher. 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// For the latter, we instantiate all the possible Matcher<T> of the poly 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// matcher. 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) { 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VariantMatcher::SingleMatcher(Matcher); 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher, 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename T::ReturnTypes * = 260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NULL) { 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> Matchers; 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes()); 263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers)); 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Out; 265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline void buildReturnTypeVectorFromTypeList( 269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RetTypes.push_back( 271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>()); 272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes); 273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <> 276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline void 277651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesbuildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>( 278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {} 279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 281651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct BuildReturnTypeVector { 282651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 283651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes); 284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct BuildReturnTypeVector<ast_matchers::internal::Matcher<T> > { 289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T> > { 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Variadic marshaller function. 302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename ResultT, typename ArgT, 303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ResultT (*Func)(ArrayRef<const ArgT *>)> 304651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesVariantMatcher 305651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesvariadicMatcherDescriptor(StringRef MatcherName, const SourceRange &NameRange, 306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParserValue> Args, Diagnostics *Error) { 307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgT **InnerArgs = new ArgT *[Args.size()](); 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool HasError = false; 310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (size_t i = 0, e = Args.size(); i != e; ++i) { 311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef ArgTypeTraits<ArgT> ArgTraits; 312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ParserValue &Arg = Args[i]; 313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VariantValue &Value = Arg.Value; 314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!ArgTraits::is(Value)) { 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString(); 317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HasError = true; 318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InnerArgs[i] = new ArgT(ArgTraits::get(Value)); 321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariantMatcher Out; 324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!HasError) { 325651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Out = outvalueToVariantMatcher( 326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Func(ArrayRef<const ArgT *>(InnerArgs, Args.size()))); 327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (size_t i = 0, e = Args.size(); i != e; ++i) { 330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines delete InnerArgs[i]; 331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines delete[] InnerArgs; 333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Out; 334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 335651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Matcher descriptor for variadic functions. 337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// 338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// This class simply wraps a VariadicFunction with the right signature to export 339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// it as a MatcherDescriptor. 340cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// This allows us to have one implementation of the interface for as many free 341cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// functions as we want, reducing the number of symbols and size of the 342cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// object file. 343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass VariadicFuncMatcherDescriptor : public MatcherDescriptor { 344cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquenpublic: 3459d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen typedef VariantMatcher (*RunFunc)(StringRef MatcherName, 3469d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen const SourceRange &NameRange, 3479d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen ArrayRef<ParserValue> Args, 3489d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen Diagnostics *Error); 349cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template <typename ResultT, typename ArgT, 351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ResultT (*F)(ArrayRef<const ArgT *>)> 352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariadicFuncMatcherDescriptor(llvm::VariadicFunction<ResultT, ArgT, F> Func, 353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) 354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>), 355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MatcherName(MatcherName.str()), 356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgsKind(ArgTypeTraits<ArgT>::getKind()) { 357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BuildReturnTypeVector<ResultT>::build(RetKinds); 358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 359cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariantMatcher create(const SourceRange &NameRange, 361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParserValue> Args, Diagnostics *Error) const { 362cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen return Func(MatcherName, NameRange, Args, Error); 363cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen } 364cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isVariadic() const { return true; } 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getNumArgs() const { return 0; } 367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ArgKind> &Kinds) const { 369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kinds.push_back(ArgsKind); 370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) const { 373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LeastDerivedKind); 375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 377cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquenprivate: 378cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen const RunFunc Func; 379cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen const std::string MatcherName; 380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> RetKinds; 381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ArgKind ArgsKind; 382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers. 385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor { 386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template <typename BaseT, typename DerivedT> 388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DynCastAllOfMatcherDescriptor( 389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func, 390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) 391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : VariadicFuncMatcherDescriptor(Func, MatcherName), 392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) { 393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool 396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If Kind is not a base of DerivedKind, either DerivedKind is a base of 399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Kind (in which case the match will always succeed) or Kind and 400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // DerivedKind are unrelated (in which case it will always fail), so set 401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Specificity to 0. 402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity, 403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LeastDerivedKind)) { 404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) { 405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Specificity) 406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *Specificity = 0; 407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 411651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate: 415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ast_type_traits::ASTNodeKind DerivedKind; 416cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen}; 417f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 418f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Helper macros to check the arguments on all marshaller functions. 419f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#define CHECK_ARG_COUNT(count) \ 420f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (Args.size() != count) { \ 4218a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \ 422f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek << count << Args.size(); \ 4239d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen return VariantMatcher(); \ 424f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 425f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 426f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#define CHECK_ARG_TYPE(index, type) \ 427f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (!ArgTypeTraits<type>::is(Args[index].Value)) { \ 4288a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \ 429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << (index + 1) << ArgTypeTraits<type>::getKind().asString() \ 43076c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen << Args[index].Value.getTypeAsString(); \ 4319d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen return VariantMatcher(); \ 432f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 433f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 434ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 435f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 0-arg marshaller function. 436f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType> 4374e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquenstatic VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName, 4384e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen const SourceRange &NameRange, 4394e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen ArrayRef<ParserValue> Args, 4404e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen Diagnostics *Error) { 4414e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen typedef ReturnType (*FuncType)(); 442f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek CHECK_ARG_COUNT(0); 4434e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)()); 444f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 445f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 446f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 1-arg marshaller function. 4477a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <typename ReturnType, typename ArgType1> 4484e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquenstatic VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName, 4494e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen const SourceRange &NameRange, 4504e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen ArrayRef<ParserValue> Args, 4514e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen Diagnostics *Error) { 4524e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen typedef ReturnType (*FuncType)(ArgType1); 453f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek CHECK_ARG_COUNT(1); 454f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek CHECK_ARG_TYPE(0, ArgType1); 4554e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( 4564e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen ArgTypeTraits<ArgType1>::get(Args[0].Value))); 457f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 458f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 4597a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen/// \brief 2-arg marshaller function. 4607a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <typename ReturnType, typename ArgType1, typename ArgType2> 4614e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquenstatic VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName, 4624e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen const SourceRange &NameRange, 4634e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen ArrayRef<ParserValue> Args, 4644e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen Diagnostics *Error) { 4654e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen typedef ReturnType (*FuncType)(ArgType1, ArgType2); 4667a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen CHECK_ARG_COUNT(2); 4677a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen CHECK_ARG_TYPE(0, ArgType1); 4687a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen CHECK_ARG_TYPE(1, ArgType2); 4694e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)( 4704e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen ArgTypeTraits<ArgType1>::get(Args[0].Value), 4714e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen ArgTypeTraits<ArgType2>::get(Args[1].Value))); 4727a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen} 4737a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen 474cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen#undef CHECK_ARG_COUNT 475cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen#undef CHECK_ARG_TYPE 476cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 477ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen/// \brief Helper class used to collect all the possible overloads of an 478ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen/// argument adaptative matcher function. 479ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquentemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 480ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen typename FromTypes, typename ToTypes> 481ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquenclass AdaptativeOverloadCollector { 482ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquenpublic: 483ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen AdaptativeOverloadCollector(StringRef Name, 484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<MatcherDescriptor *> &Out) 485ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen : Name(Name), Out(Out) { 486ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen collect(FromTypes()); 487ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen } 488ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 489ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquenprivate: 490ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc< 491ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc; 492ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 493ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen /// \brief End case for the recursion 494ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen static void collect(ast_matchers::internal::EmptyTypeList) {} 495ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 496ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen /// \brief Recursive case. Get the overload for the head of the list, and 497ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen /// recurse to the tail. 498651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template <typename FromTypeList> 499651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines inline void collect(FromTypeList); 500ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 501ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen const StringRef Name; 502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<MatcherDescriptor *> &Out; 503ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen}; 504ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief MatcherDescriptor that wraps multiple "overloads" of the same 506ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen/// matcher. 507ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen/// 508ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen/// It will try every overload and generate appropriate errors for when none or 509ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen/// more than one overloads match the arguments. 510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass OverloadedMatcherDescriptor : public MatcherDescriptor { 511ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquenpublic: 512651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OverloadedMatcherDescriptor(ArrayRef<MatcherDescriptor *> Callbacks) 513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Overloads(Callbacks.begin(), Callbacks.end()) {} 514ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual ~OverloadedMatcherDescriptor() {} 516ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 517651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual VariantMatcher create(const SourceRange &NameRange, 518651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParserValue> Args, 519651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diagnostics *Error) const { 520ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen std::vector<VariantMatcher> Constructed; 521ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Diagnostics::OverloadContext Ctx(Error); 522651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &O : Overloads) { 523651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariantMatcher SubMatcher = O->create(NameRange, Args, Error); 524ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen if (!SubMatcher.isNull()) { 525ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Constructed.push_back(SubMatcher); 526ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen } 527ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen } 528ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 529ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen if (Constructed.empty()) return VariantMatcher(); // No overload matched. 530ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen // We ignore the errors if any matcher succeeded. 531ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Ctx.revertErrors(); 532ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen if (Constructed.size() > 1) { 533ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen // More than one constructed. It is ambiguous. 534ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload); 535ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen return VariantMatcher(); 536ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen } 537ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen return Constructed[0]; 538ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen } 539ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isVariadic() const { 541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Overload0Variadic = Overloads[0]->isVariadic(); 542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifndef NDEBUG 543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &O : Overloads) { 544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(Overload0Variadic == O->isVariadic()); 545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Overload0Variadic; 548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getNumArgs() const { 551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned Overload0NumArgs = Overloads[0]->getNumArgs(); 552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifndef NDEBUG 553651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &O : Overloads) { 554651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(Overload0NumArgs == O->getNumArgs()); 555651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 556651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif 557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Overload0NumArgs; 558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ArgKind> &Kinds) const { 562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &O : Overloads) { 563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (O->isConvertibleTo(ThisKind)) 564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines O->getArgKinds(ThisKind, ArgNo, Kinds); 565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) const { 570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &O : Overloads) { 571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind)) 572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 577ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquenprivate: 578651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<std::unique_ptr<MatcherDescriptor>> Overloads; 579ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen}; 580ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 581a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen/// \brief Variadic operator marshaller function. 582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass VariadicOperatorMatcherDescriptor : public MatcherDescriptor { 583a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquenpublic: 584a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen typedef ast_matchers::internal::VariadicOperatorFunction VarFunc; 585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount, 586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VarFunc Func, StringRef MatcherName) 587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : MinCount(MinCount), MaxCount(MaxCount), Func(Func), 588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MatcherName(MatcherName) {} 589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual VariantMatcher create(const SourceRange &NameRange, 591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParserValue> Args, 592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diagnostics *Error) const { 593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Args.size() < MinCount || MaxCount < Args.size()) { 594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::string MaxStr = 595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str(); 596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Error->addError(NameRange, Error->ET_RegistryWrongArgCount) 597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size(); 598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VariantMatcher(); 599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 600a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen 601a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen std::vector<VariantMatcher> InnerArgs; 602a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen for (size_t i = 0, e = Args.size(); i != e; ++i) { 603a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen const ParserValue &Arg = Args[i]; 604a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen const VariantValue &Value = Arg.Value; 605a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen if (!Value.isMatcher()) { 606a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 607a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen << (i + 1) << "Matcher<>" << Value.getTypeAsString(); 608a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen return VariantMatcher(); 609a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen } 610a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen InnerArgs.push_back(Value.getMatcher()); 611a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen } 612651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VariantMatcher::VariadicOperatorMatcher(Func, std::move(InnerArgs)); 613a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen } 614a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen 615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isVariadic() const { return true; } 616651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines unsigned getNumArgs() const { return 0; } 617651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 618651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ArgKind> &Kinds) const { 619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kinds.push_back(ThisKind); 620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) const { 623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Specificity) 624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *Specificity = 1; 625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (LeastDerivedKind) 626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *LeastDerivedKind = Kind; 627651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 628651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 629651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isPolymorphic() const override { return true; } 630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 631a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquenprivate: 632651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const unsigned MinCount; 633651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const unsigned MaxCount; 634a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen const VarFunc Func; 635a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen const StringRef MatcherName; 636a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen}; 637a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen 638f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// Helper functions to select the appropriate marshaller functions. 639cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// They detect the number of arguments, arguments types and return type. 640f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 641f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 0-arg overload 642f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType> 643651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(), 644651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> RetTypes; 646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BuildReturnTypeVector<ReturnType>::build(RetTypes); 647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new FixedArgCountMatcherDescriptor( 6484e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func), 649ef8225444452a1486bd721f3285301fe84643b00Stephen Hines MatcherName, RetTypes, None); 650f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 651f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 652f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 1-arg overload 653f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType, typename ArgType1> 654651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), 655651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> RetTypes; 657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BuildReturnTypeVector<ReturnType>::build(RetTypes); 658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgKind AK = ArgTypeTraits<ArgType1>::getKind(); 659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new FixedArgCountMatcherDescriptor( 6604e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen matcherMarshall1<ReturnType, ArgType1>, 661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK); 662f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 663f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 6647a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen/// \brief 2-arg overload 6657a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <typename ReturnType, typename ArgType1, typename ArgType2> 666651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2), 667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> RetTypes; 669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BuildReturnTypeVector<ReturnType>::build(RetTypes); 670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(), 671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgTypeTraits<ArgType2>::getKind() }; 672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new FixedArgCountMatcherDescriptor( 6734e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen matcherMarshall2<ReturnType, ArgType1, ArgType2>, 674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs); 6757a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen} 6767a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen 6773f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// \brief Variadic overload. 6783f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquentemplate <typename ResultT, typename ArgT, 6793f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen ResultT (*Func)(ArrayRef<const ArgT *>)> 680651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor * 6813f84bb341bfb1312842b09db71d76bc3898ba247Samuel BenzaquenmakeMatcherAutoMarshall(llvm::VariadicFunction<ResultT, ArgT, Func> VarFunc, 682f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek StringRef MatcherName) { 683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new VariadicFuncMatcherDescriptor(VarFunc, MatcherName); 684651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Overload for VariadicDynCastAllOfMatchers. 687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// 688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better 689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// completion results for that type of matcher. 690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename BaseT, typename DerivedT> 691651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor * 692651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesmakeMatcherAutoMarshall(ast_matchers::internal::VariadicDynCastAllOfMatcher< 693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BaseT, DerivedT> VarFunc, 694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new DynCastAllOfMatcherDescriptor(VarFunc, MatcherName); 696f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 697f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 698ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen/// \brief Argument adaptative overload. 699ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquentemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 700ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen typename FromTypes, typename ToTypes> 701651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor * 702ee0da9520fe94f701240e9e1c97773ee412be102Samuel BenzaquenmakeMatcherAutoMarshall(ast_matchers::internal::ArgumentAdaptingMatcherFunc< 703ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen ArgumentAdapterT, FromTypes, ToTypes>, 704ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen StringRef MatcherName) { 705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<MatcherDescriptor *> Overloads; 706ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName, 707ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Overloads); 708651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new OverloadedMatcherDescriptor(Overloads); 709ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen} 710ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 711ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquentemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 712ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen typename FromTypes, typename ToTypes> 713ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquentemplate <typename FromTypeList> 714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, 715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ToTypes>::collect(FromTypeList) { 716ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Out.push_back(makeMatcherAutoMarshall( 717ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen &AdaptativeFunc::template create<typename FromTypeList::head>, Name)); 718ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen collect(typename FromTypeList::tail()); 719ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen} 720ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 721a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen/// \brief Variadic operator overload. 722651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <unsigned MinCount, unsigned MaxCount> 723651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor * 724651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesmakeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc< 725651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MinCount, MaxCount> Func, 726651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Func, 728651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MatcherName); 729a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen} 730a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen 731f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} // namespace internal 732f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} // namespace dynamic 733f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} // namespace ast_matchers 734f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} // namespace clang 735f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 736f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H 737