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