14967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===--- 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 20176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H 21176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_LIB_ASTMATCHERS_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 Klimeknamespace internal { 34f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 35f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Helper template class to just from argument type to the right is/get 36f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// functions in VariantValue. 37f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// Used to verify and extract the matcher arguments below. 38f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <class T> struct ArgTypeTraits; 39f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> { 40f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 41f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 42f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <> struct ArgTypeTraits<std::string> { 43f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek static bool is(const VariantValue &Value) { return Value.isString(); } 44f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek static const std::string &get(const VariantValue &Value) { 45f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return Value.getString(); 46f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static ArgKind getKind() { 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ArgKind(ArgKind::AK_String); 49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 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 bool is(const VariantValue &Value) { 584e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>(); 5976c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen } 60f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) { 614e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen return Value.getMatcher().getTypedMatcher<T>(); 62f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static ArgKind getKind() { 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 667a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen}; 67f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 687a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <> struct ArgTypeTraits<unsigned> { 697a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen static bool is(const VariantValue &Value) { return Value.isUnsigned(); } 707a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen static unsigned get(const VariantValue &Value) { 717a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen return Value.getUnsigned(); 727a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen } 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static ArgKind getKind() { 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ArgKind(ArgKind::AK_Unsigned); 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 76f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 77f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 78176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate <> struct ArgTypeTraits<attr::Kind> { 79176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesprivate: 80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines static attr::Kind getAttrKind(llvm::StringRef AttrKind) { 81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return llvm::StringSwitch<attr::Kind>(AttrKind) 82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define ATTR(X) .Case("attr::" #X, attr:: X) 83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#include "clang/Basic/AttrList.inc" 84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines .Default(attr::Kind(-1)); 85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic: 87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines static bool is(const VariantValue &Value) { 88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return Value.isString() && 89176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getAttrKind(Value.getString()) != attr::Kind(-1); 90176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 91176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines static attr::Kind get(const VariantValue &Value) { 92176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return getAttrKind(Value.getString()); 93176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 94176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines static ArgKind getKind() { 95176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ArgKind(ArgKind::AK_String); 96176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 97176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}; 98176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainartemplate <> struct ArgTypeTraits<clang::CastKind> { 1004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprivate: 1014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar static clang::CastKind getCastKind(llvm::StringRef AttrKind) { 1024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return llvm::StringSwitch<clang::CastKind>(AttrKind) 1034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#define CAST_OPERATION(Name) .Case( #Name, CK_##Name) 1044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/AST/OperationKinds.def" 1054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar .Default(CK_Invalid); 1064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 1084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic: 1094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar static bool is(const VariantValue &Value) { 1104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return Value.isString() && 1114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar getCastKind(Value.getString()) != CK_Invalid; 1124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar static clang::CastKind get(const VariantValue &Value) { 1144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return getCastKind(Value.getString()); 1154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar static ArgKind getKind() { 1174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return ArgKind(ArgKind::AK_String); 1184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar } 1194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}; 1204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Matcher descriptor interface. 122f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Provides a \c create() method that constructs the matcher from the provided 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// arguments, and various other methods for type introspection. 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass MatcherDescriptor { 126f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic: 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual ~MatcherDescriptor() {} 12887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar virtual VariantMatcher create(SourceRange NameRange, 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParserValue> Args, 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diagnostics *Error) const = 0; 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Returns whether the matcher is variadic. Variadic matchers can take any 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// number of arguments, but they must be of the same type. 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual bool isVariadic() const = 0; 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Returns the number of arguments accepted by the matcher if not variadic. 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual unsigned getNumArgs() const = 0; 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Given that the matcher is being converted to type \p ThisKind, append the 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// set of argument types accepted for argument \p ArgNo to \p ArgKinds. 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: We should provide the ability to constrain the output of this 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // function based on the types of other matcher arguments. 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ArgKind> &ArgKinds) const = 0; 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Returns whether this matcher is convertible to the given type. If it is 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// so convertible, store in *Specificity a value corresponding to the 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// "specificity" of the converted matcher to the given context, and in 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// *LeastDerivedKind the least derived matcher kind which would result in the 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// same matcher overload. Zero specificity indicates that this conversion 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// would produce a trivial matcher that will either always or never match. 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Such matchers are excluded from code completion results. 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual bool isConvertibleTo( 1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr, 1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0; 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Returns whether the matcher will, given a matcher of any type T, yield a 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// matcher of type T. 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines virtual bool isPolymorphic() const { return false; } 160f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 161f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline bool isRetKindConvertibleTo( 163c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ArrayRef<ast_type_traits::ASTNodeKind> RetKinds, 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) { 166176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) { 167176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) { 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (LeastDerivedKind) 169176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines *LeastDerivedKind = NodeKind; 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 176f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Simple callback implementation. Marshaller and function are provided. 177cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// 178cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// This class wraps a function of arbitrary signature and a marshaller 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// function into a MatcherDescriptor. 180cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// The marshaller is in charge of taking the VariantValue arguments, checking 181cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// their types, unpacking them and calling the underlying function. 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass FixedArgCountMatcherDescriptor : public MatcherDescriptor { 183f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic: 1844e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen typedef VariantMatcher (*MarshallerType)(void (*Func)(), 1854e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen StringRef MatcherName, 18687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceRange NameRange, 1874e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen ArrayRef<ParserValue> Args, 1884e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen Diagnostics *Error); 189cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 190e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko /// \param Marshaller Function to unpack the arguments and call \c Func 191e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko /// \param Func Matcher construct function. This is the function that 192e3c63fce12a7a949106f04f251528c27bd81445bDmitri Gribenko /// compile-time matcher expressions would use to create the matcher. 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \param RetKinds The list of matcher types to which the matcher is 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// convertible. 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// \param ArgKinds The types of the arguments this matcher takes. 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FixedArgCountMatcherDescriptor( 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MarshallerType Marshaller, void (*Func)(), StringRef MatcherName, 198c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ArrayRef<ast_type_traits::ASTNodeKind> RetKinds, 199c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines ArrayRef<ArgKind> ArgKinds) 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName), 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RetKinds(RetKinds.begin(), RetKinds.end()), 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgKinds(ArgKinds.begin(), ArgKinds.end()) {} 203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 20487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar VariantMatcher create(SourceRange NameRange, 20558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ArrayRef<ParserValue> Args, 20658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar Diagnostics *Error) const override { 207f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek return Marshaller(Func, MatcherName, NameRange, Args, Error); 208f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 209f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 21058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar bool isVariadic() const override { return false; } 21158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar unsigned getNumArgs() const override { return ArgKinds.size(); } 212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 21358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar std::vector<ArgKind> &Kinds) const override { 214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kinds.push_back(ArgKinds[ArgNo]); 215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 21658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar bool isConvertibleTo( 21758878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 21858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LeastDerivedKind); 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 223f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekprivate: 224f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek const MarshallerType Marshaller; 2254e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen void (* const Func)(); 226f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek const std::string MatcherName; 227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::vector<ast_type_traits::ASTNodeKind> RetKinds; 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::vector<ArgKind> ArgKinds; 229f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}; 230f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Helper methods to extract and merge all possible typed matchers 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// out of the polymorphic object. 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <class PolyMatcher> 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void mergePolyMatchers(const PolyMatcher &Poly, 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> &Out, 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_matchers::internal::EmptyTypeList) {} 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <class PolyMatcher, class TypeList> 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void mergePolyMatchers(const PolyMatcher &Poly, 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> &Out, TypeList) { 241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly)); 242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mergePolyMatchers(Poly, Out, typename TypeList::tail()); 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Convert the return values of the functions into a VariantMatcher. 246cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// There are 2 cases right now: The return value is a Matcher<T> or is a 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// polymorphic matcher. For the former, we just construct the VariantMatcher. 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// For the latter, we instantiate all the possible Matcher<T> of the poly 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// matcher. 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) { 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VariantMatcher::SingleMatcher(Matcher); 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher, 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typename T::ReturnTypes * = 2584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar nullptr) { 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<DynTypedMatcher> Matchers; 260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes()); 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers)); 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Out; 263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline void buildReturnTypeVectorFromTypeList( 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RetTypes.push_back( 269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>()); 270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes); 271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <> 274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline void 275651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesbuildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>( 276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {} 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct BuildReturnTypeVector { 280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 281651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes); 282651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 283651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct BuildReturnTypeVector<ast_matchers::internal::Matcher<T> > { 287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T> 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T> > { 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) { 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Variadic marshaller function. 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename ResultT, typename ArgT, 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ResultT (*Func)(ArrayRef<const ArgT *>)> 302651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesVariantMatcher 30387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarvariadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange, 304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArrayRef<ParserValue> Args, Diagnostics *Error) { 305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgT **InnerArgs = new ArgT *[Args.size()](); 306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool HasError = false; 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (size_t i = 0, e = Args.size(); i != e; ++i) { 309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines typedef ArgTypeTraits<ArgT> ArgTraits; 310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ParserValue &Arg = Args[i]; 311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const VariantValue &Value = Arg.Value; 312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!ArgTraits::is(Value)) { 313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString(); 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HasError = true; 316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InnerArgs[i] = new ArgT(ArgTraits::get(Value)); 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariantMatcher Out; 322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!HasError) { 323176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs, 324176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Args.size()))); 325651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (size_t i = 0, e = Args.size(); i != e; ++i) { 328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines delete InnerArgs[i]; 329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines delete[] InnerArgs; 331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Out; 332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Matcher descriptor for variadic functions. 335651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// 336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// This class simply wraps a VariadicFunction with the right signature to export 337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// it as a MatcherDescriptor. 338cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// This allows us to have one implementation of the interface for as many free 339cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// functions as we want, reducing the number of symbols and size of the 340cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// object file. 341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass VariadicFuncMatcherDescriptor : public MatcherDescriptor { 342cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquenpublic: 3439d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen typedef VariantMatcher (*RunFunc)(StringRef MatcherName, 34487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceRange NameRange, 3459d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen ArrayRef<ParserValue> Args, 3469d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen Diagnostics *Error); 347cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template <typename ResultT, typename ArgT, 349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ResultT (*F)(ArrayRef<const ArgT *>)> 3504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar VariadicFuncMatcherDescriptor( 3514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func, 3524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar StringRef MatcherName) 353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>), 354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MatcherName(MatcherName.str()), 355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgsKind(ArgTypeTraits<ArgT>::getKind()) { 356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BuildReturnTypeVector<ResultT>::build(RetKinds); 357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 358cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 35987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar VariantMatcher create(SourceRange NameRange, 36058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ArrayRef<ParserValue> Args, 36158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar Diagnostics *Error) const override { 362cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen return Func(MatcherName, NameRange, Args, Error); 363cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen } 364cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen 36558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar bool isVariadic() const override { return true; } 36658878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar unsigned getNumArgs() const override { return 0; } 367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 36858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar std::vector<ArgKind> &Kinds) const override { 369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kinds.push_back(ArgsKind); 370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 37158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar bool isConvertibleTo( 37258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 37358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return isRetKindConvertibleTo(RetKinds, Kind, Specificity, 375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LeastDerivedKind); 376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 378cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquenprivate: 379cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen const RunFunc Func; 380cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen const std::string MatcherName; 381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> RetKinds; 382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ArgKind ArgsKind; 383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers. 386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor { 387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines template <typename BaseT, typename DerivedT> 389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DynCastAllOfMatcherDescriptor( 390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func, 391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) 392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : VariadicFuncMatcherDescriptor(Func, MatcherName), 393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) { 394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool 397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If Kind is not a base of DerivedKind, either DerivedKind is a base of 400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Kind (in which case the match will always succeed) or Kind and 401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // DerivedKind are unrelated (in which case it will always fail), so set 402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Specificity to 0. 403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity, 404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LeastDerivedKind)) { 405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) { 406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Specificity) 407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *Specificity = 0; 408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 411651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate: 416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ast_type_traits::ASTNodeKind DerivedKind; 417cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen}; 418f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 419f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Helper macros to check the arguments on all marshaller functions. 420f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#define CHECK_ARG_COUNT(count) \ 421f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (Args.size() != count) { \ 4228a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \ 423f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek << count << Args.size(); \ 4249d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen return VariantMatcher(); \ 425f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 426f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 427f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#define CHECK_ARG_TYPE(index, type) \ 428f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek if (!ArgTypeTraits<type>::is(Args[index].Value)) { \ 4298a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \ 430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << (index + 1) << ArgTypeTraits<type>::getKind().asString() \ 43176c2f92c4b4ab7e02857661a05e53ba4b501d87aSamuel Benzaquen << Args[index].Value.getTypeAsString(); \ 4329d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen return VariantMatcher(); \ 433f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek } 434f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 435f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 0-arg marshaller function. 436f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType> 4374e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquenstatic VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName, 43887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 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, 44987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 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, 46287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 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 501176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 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 51558878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ~OverloadedMatcherDescriptor() override {} 516ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 51787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar VariantMatcher create(SourceRange NameRange, 51858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ArrayRef<ParserValue> Args, 51958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar Diagnostics *Error) const override { 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 54058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar bool isVariadic() const override { 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 55058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar unsigned getNumArgs() const override { 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, 56158878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar std::vector<ArgKind> &Kinds) const override { 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 56858878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar bool isConvertibleTo( 56958878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 57058878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &O : Overloads) { 572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind)) 573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 577651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 578ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquenprivate: 579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<std::unique_ptr<MatcherDescriptor>> Overloads; 580ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen}; 581ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 582a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen/// \brief Variadic operator marshaller function. 583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass VariadicOperatorMatcherDescriptor : public MatcherDescriptor { 584a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquenpublic: 585176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines typedef DynTypedMatcher::VariadicOperator VarOp; 586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount, 587176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VarOp Op, StringRef MatcherName) 588176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines : MinCount(MinCount), MaxCount(MaxCount), Op(Op), 589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MatcherName(MatcherName) {} 590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 59187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar VariantMatcher create(SourceRange NameRange, 59258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar ArrayRef<ParserValue> Args, 59358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar Diagnostics *Error) const override { 594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Args.size() < MinCount || MaxCount < Args.size()) { 595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const std::string MaxStr = 596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str(); 597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Error->addError(NameRange, Error->ET_RegistryWrongArgCount) 598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size(); 599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VariantMatcher(); 600651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 601a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen 602a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen std::vector<VariantMatcher> InnerArgs; 603a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen for (size_t i = 0, e = Args.size(); i != e; ++i) { 604a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen const ParserValue &Arg = Args[i]; 605a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen const VariantValue &Value = Arg.Value; 606a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen if (!Value.isMatcher()) { 607a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen Error->addError(Arg.Range, Error->ET_RegistryWrongArgType) 608a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen << (i + 1) << "Matcher<>" << Value.getTypeAsString(); 609a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen return VariantMatcher(); 610a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen } 611a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen InnerArgs.push_back(Value.getMatcher()); 612a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen } 613176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs)); 614a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen } 615a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen 616176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool isVariadic() const override { return true; } 617176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unsigned getNumArgs() const override { return 0; } 618651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo, 619176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::vector<ArgKind> &Kinds) const override { 620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Kinds.push_back(ThisKind); 621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity, 623176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ast_type_traits::ASTNodeKind *LeastDerivedKind) const override { 624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Specificity) 625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *Specificity = 1; 626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (LeastDerivedKind) 627651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *LeastDerivedKind = Kind; 628651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 629651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isPolymorphic() const override { return true; } 631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 632a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquenprivate: 633651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const unsigned MinCount; 634651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const unsigned MaxCount; 635176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const VarOp Op; 636a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen const StringRef MatcherName; 637a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen}; 638a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen 639f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// Helper functions to select the appropriate marshaller functions. 640cf69590039a186e80b165619c8ac1aef599301b3Samuel Benzaquen/// They detect the number of arguments, arguments types and return type. 641f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 642f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 0-arg overload 643f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType> 644651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(), 645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> RetTypes; 647651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BuildReturnTypeVector<ReturnType>::build(RetTypes); 648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new FixedArgCountMatcherDescriptor( 6494e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func), 650c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines MatcherName, RetTypes, None); 651f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 652f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 653f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief 1-arg overload 654f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimektemplate <typename ReturnType, typename ArgType1> 655651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), 656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> RetTypes; 658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BuildReturnTypeVector<ReturnType>::build(RetTypes); 659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgKind AK = ArgTypeTraits<ArgType1>::getKind(); 660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new FixedArgCountMatcherDescriptor( 6614e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen matcherMarshall1<ReturnType, ArgType1>, 662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK); 663f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 664f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 6657a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen/// \brief 2-arg overload 6667a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquentemplate <typename ReturnType, typename ArgType1, typename ArgType2> 667651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2), 668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<ast_type_traits::ASTNodeKind> RetTypes; 670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BuildReturnTypeVector<ReturnType>::build(RetTypes); 671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(), 672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ArgTypeTraits<ArgType2>::getKind() }; 673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new FixedArgCountMatcherDescriptor( 6744e899d9b0b5aa31b0a3704374d245fc345c19fa8Samuel Benzaquen matcherMarshall2<ReturnType, ArgType1, ArgType2>, 675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs); 6767a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen} 6777a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen 6783f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen/// \brief Variadic overload. 6793f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquentemplate <typename ResultT, typename ArgT, 6803f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen ResultT (*Func)(ArrayRef<const ArgT *>)> 6814967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarMatcherDescriptor *makeMatcherAutoMarshall( 6824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc, 6834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar StringRef MatcherName) { 684651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new VariadicFuncMatcherDescriptor(VarFunc, MatcherName); 685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Overload for VariadicDynCastAllOfMatchers. 688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// 689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better 690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// completion results for that type of matcher. 691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename BaseT, typename DerivedT> 692651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor * 693651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesmakeMatcherAutoMarshall(ast_matchers::internal::VariadicDynCastAllOfMatcher< 694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BaseT, DerivedT> VarFunc, 695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new DynCastAllOfMatcherDescriptor(VarFunc, MatcherName); 697f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} 698f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 699ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen/// \brief Argument adaptative overload. 700ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquentemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 701ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen typename FromTypes, typename ToTypes> 702651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor * 703ee0da9520fe94f701240e9e1c97773ee412be102Samuel BenzaquenmakeMatcherAutoMarshall(ast_matchers::internal::ArgumentAdaptingMatcherFunc< 704ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen ArgumentAdapterT, FromTypes, ToTypes>, 705ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen StringRef MatcherName) { 706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<MatcherDescriptor *> Overloads; 707ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName, 708ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Overloads); 709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return new OverloadedMatcherDescriptor(Overloads); 710ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen} 711ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 712ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquentemplate <template <typename ToArg, typename FromArg> class ArgumentAdapterT, 713ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen typename FromTypes, typename ToTypes> 714ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquentemplate <typename FromTypeList> 715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesinline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, 716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ToTypes>::collect(FromTypeList) { 717ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen Out.push_back(makeMatcherAutoMarshall( 718ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen &AdaptativeFunc::template create<typename FromTypeList::head>, Name)); 719ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen collect(typename FromTypeList::tail()); 720ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen} 721ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen 722a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen/// \brief Variadic operator overload. 723651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <unsigned MinCount, unsigned MaxCount> 724651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesMatcherDescriptor * 725651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesmakeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc< 726651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MinCount, MaxCount> Func, 727651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef MatcherName) { 728176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Op, 729651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MatcherName); 730a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen} 731a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen 7324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // namespace internal 7334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // namespace dynamic 7344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // namespace ast_matchers 7354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // namespace clang 736f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek 7374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H 738