1 //===--- Marshallers.h - Generic matcher function marshallers -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Functions templates and classes to wrap matcher construct functions.
13 /// A collection of template function and classes that provide a generic
14 /// marshalling layer on top of matcher construct functions.
15 /// These are used by the registry to export all marshaller constructors with
16 /// the same generic interface.
18 //===----------------------------------------------------------------------===//
20 #ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
21 #define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
23 #include "clang/ASTMatchers/ASTMatchers.h"
24 #include "clang/ASTMatchers/Dynamic/Diagnostics.h"
25 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
26 #include "clang/Basic/LLVM.h"
27 #include "llvm/ADT/STLExtras.h"
31 namespace ast_matchers {
36 /// \brief Helper template class to just from argument type to the right is/get
37 /// functions in VariantValue.
38 /// Used to verify and extract the matcher arguments below.
39 template <class T> struct ArgTypeTraits;
40 template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
43 template <> struct ArgTypeTraits<std::string> {
44 static bool is(const VariantValue &Value) { return Value.isString(); }
45 static const std::string &get(const VariantValue &Value) {
46 return Value.getString();
48 static ArgKind getKind() {
49 return ArgKind(ArgKind::AK_String);
54 struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
57 template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
58 static bool is(const VariantValue &Value) {
59 return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
61 static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
62 return Value.getMatcher().getTypedMatcher<T>();
64 static ArgKind getKind() {
65 return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
69 template <> struct ArgTypeTraits<unsigned> {
70 static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
71 static unsigned get(const VariantValue &Value) {
72 return Value.getUnsigned();
74 static ArgKind getKind() {
75 return ArgKind(ArgKind::AK_Unsigned);
79 template <> struct ArgTypeTraits<attr::Kind> {
81 static attr::Kind getAttrKind(llvm::StringRef AttrKind) {
82 return llvm::StringSwitch<attr::Kind>(AttrKind)
83 #define ATTR(X) .Case("attr::" #X, attr:: X)
84 #include "clang/Basic/AttrList.inc"
85 .Default(attr::Kind(-1));
88 static bool is(const VariantValue &Value) {
89 return Value.isString() &&
90 getAttrKind(Value.getString()) != attr::Kind(-1);
92 static attr::Kind get(const VariantValue &Value) {
93 return getAttrKind(Value.getString());
95 static ArgKind getKind() {
96 return ArgKind(ArgKind::AK_String);
100 /// \brief Matcher descriptor interface.
102 /// Provides a \c create() method that constructs the matcher from the provided
103 /// arguments, and various other methods for type introspection.
104 class MatcherDescriptor {
106 virtual ~MatcherDescriptor() {}
107 virtual VariantMatcher create(SourceRange NameRange,
108 ArrayRef<ParserValue> Args,
109 Diagnostics *Error) const = 0;
111 /// Returns whether the matcher is variadic. Variadic matchers can take any
112 /// number of arguments, but they must be of the same type.
113 virtual bool isVariadic() const = 0;
115 /// Returns the number of arguments accepted by the matcher if not variadic.
116 virtual unsigned getNumArgs() const = 0;
118 /// Given that the matcher is being converted to type \p ThisKind, append the
119 /// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
120 // FIXME: We should provide the ability to constrain the output of this
121 // function based on the types of other matcher arguments.
122 virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
123 std::vector<ArgKind> &ArgKinds) const = 0;
125 /// Returns whether this matcher is convertible to the given type. If it is
126 /// so convertible, store in *Specificity a value corresponding to the
127 /// "specificity" of the converted matcher to the given context, and in
128 /// *LeastDerivedKind the least derived matcher kind which would result in the
129 /// same matcher overload. Zero specificity indicates that this conversion
130 /// would produce a trivial matcher that will either always or never match.
131 /// Such matchers are excluded from code completion results.
132 virtual bool isConvertibleTo(
133 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
134 ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
136 /// Returns whether the matcher will, given a matcher of any type T, yield a
137 /// matcher of type T.
138 virtual bool isPolymorphic() const { return false; }
141 inline bool isRetKindConvertibleTo(
142 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
143 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
144 ast_type_traits::ASTNodeKind *LeastDerivedKind) {
145 for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
146 if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
147 if (LeastDerivedKind)
148 *LeastDerivedKind = NodeKind;
155 /// \brief Simple callback implementation. Marshaller and function are provided.
157 /// This class wraps a function of arbitrary signature and a marshaller
158 /// function into a MatcherDescriptor.
159 /// The marshaller is in charge of taking the VariantValue arguments, checking
160 /// their types, unpacking them and calling the underlying function.
161 class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
163 typedef VariantMatcher (*MarshallerType)(void (*Func)(),
164 StringRef MatcherName,
165 SourceRange NameRange,
166 ArrayRef<ParserValue> Args,
169 /// \param Marshaller Function to unpack the arguments and call \c Func
170 /// \param Func Matcher construct function. This is the function that
171 /// compile-time matcher expressions would use to create the matcher.
172 /// \param RetKinds The list of matcher types to which the matcher is
174 /// \param ArgKinds The types of the arguments this matcher takes.
175 FixedArgCountMatcherDescriptor(
176 MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
177 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
178 ArrayRef<ArgKind> ArgKinds)
179 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
180 RetKinds(RetKinds.begin(), RetKinds.end()),
181 ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
183 VariantMatcher create(SourceRange NameRange,
184 ArrayRef<ParserValue> Args,
185 Diagnostics *Error) const override {
186 return Marshaller(Func, MatcherName, NameRange, Args, Error);
189 bool isVariadic() const override { return false; }
190 unsigned getNumArgs() const override { return ArgKinds.size(); }
191 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
192 std::vector<ArgKind> &Kinds) const override {
193 Kinds.push_back(ArgKinds[ArgNo]);
195 bool isConvertibleTo(
196 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
197 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
198 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
203 const MarshallerType Marshaller;
204 void (* const Func)();
205 const std::string MatcherName;
206 const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
207 const std::vector<ArgKind> ArgKinds;
210 /// \brief Helper methods to extract and merge all possible typed matchers
211 /// out of the polymorphic object.
212 template <class PolyMatcher>
213 static void mergePolyMatchers(const PolyMatcher &Poly,
214 std::vector<DynTypedMatcher> &Out,
215 ast_matchers::internal::EmptyTypeList) {}
217 template <class PolyMatcher, class TypeList>
218 static void mergePolyMatchers(const PolyMatcher &Poly,
219 std::vector<DynTypedMatcher> &Out, TypeList) {
220 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
221 mergePolyMatchers(Poly, Out, typename TypeList::tail());
224 /// \brief Convert the return values of the functions into a VariantMatcher.
226 /// There are 2 cases right now: The return value is a Matcher<T> or is a
227 /// polymorphic matcher. For the former, we just construct the VariantMatcher.
228 /// For the latter, we instantiate all the possible Matcher<T> of the poly
230 static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
231 return VariantMatcher::SingleMatcher(Matcher);
234 template <typename T>
235 static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
236 typename T::ReturnTypes * =
238 std::vector<DynTypedMatcher> Matchers;
239 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
240 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
244 template <typename T>
245 inline void buildReturnTypeVectorFromTypeList(
246 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
248 ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
249 buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
254 buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
255 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
257 template <typename T>
258 struct BuildReturnTypeVector {
259 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
260 buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
264 template <typename T>
265 struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T> > {
266 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
267 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
271 template <typename T>
272 struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T> > {
273 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
274 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
278 /// \brief Variadic marshaller function.
279 template <typename ResultT, typename ArgT,
280 ResultT (*Func)(ArrayRef<const ArgT *>)>
282 variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
283 ArrayRef<ParserValue> Args, Diagnostics *Error) {
284 ArgT **InnerArgs = new ArgT *[Args.size()]();
286 bool HasError = false;
287 for (size_t i = 0, e = Args.size(); i != e; ++i) {
288 typedef ArgTypeTraits<ArgT> ArgTraits;
289 const ParserValue &Arg = Args[i];
290 const VariantValue &Value = Arg.Value;
291 if (!ArgTraits::is(Value)) {
292 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
293 << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
297 InnerArgs[i] = new ArgT(ArgTraits::get(Value));
302 Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs,
306 for (size_t i = 0, e = Args.size(); i != e; ++i) {
313 /// \brief Matcher descriptor for variadic functions.
315 /// This class simply wraps a VariadicFunction with the right signature to export
316 /// it as a MatcherDescriptor.
317 /// This allows us to have one implementation of the interface for as many free
318 /// functions as we want, reducing the number of symbols and size of the
320 class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
322 typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
323 SourceRange NameRange,
324 ArrayRef<ParserValue> Args,
327 template <typename ResultT, typename ArgT,
328 ResultT (*F)(ArrayRef<const ArgT *>)>
329 VariadicFuncMatcherDescriptor(llvm::VariadicFunction<ResultT, ArgT, F> Func,
330 StringRef MatcherName)
331 : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
332 MatcherName(MatcherName.str()),
333 ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
334 BuildReturnTypeVector<ResultT>::build(RetKinds);
337 VariantMatcher create(SourceRange NameRange,
338 ArrayRef<ParserValue> Args,
339 Diagnostics *Error) const override {
340 return Func(MatcherName, NameRange, Args, Error);
343 bool isVariadic() const override { return true; }
344 unsigned getNumArgs() const override { return 0; }
345 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
346 std::vector<ArgKind> &Kinds) const override {
347 Kinds.push_back(ArgsKind);
349 bool isConvertibleTo(
350 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
351 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
352 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
358 const std::string MatcherName;
359 std::vector<ast_type_traits::ASTNodeKind> RetKinds;
360 const ArgKind ArgsKind;
363 /// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
364 class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
366 template <typename BaseT, typename DerivedT>
367 DynCastAllOfMatcherDescriptor(
368 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
369 StringRef MatcherName)
370 : VariadicFuncMatcherDescriptor(Func, MatcherName),
371 DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
375 isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
376 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
377 // If Kind is not a base of DerivedKind, either DerivedKind is a base of
378 // Kind (in which case the match will always succeed) or Kind and
379 // DerivedKind are unrelated (in which case it will always fail), so set
381 if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
383 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
394 const ast_type_traits::ASTNodeKind DerivedKind;
397 /// \brief Helper macros to check the arguments on all marshaller functions.
398 #define CHECK_ARG_COUNT(count) \
399 if (Args.size() != count) { \
400 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \
401 << count << Args.size(); \
402 return VariantMatcher(); \
405 #define CHECK_ARG_TYPE(index, type) \
406 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \
407 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
408 << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
409 << Args[index].Value.getTypeAsString(); \
410 return VariantMatcher(); \
414 /// \brief 0-arg marshaller function.
415 template <typename ReturnType>
416 static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
417 SourceRange NameRange,
418 ArrayRef<ParserValue> Args,
419 Diagnostics *Error) {
420 typedef ReturnType (*FuncType)();
422 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
425 /// \brief 1-arg marshaller function.
426 template <typename ReturnType, typename ArgType1>
427 static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
428 SourceRange NameRange,
429 ArrayRef<ParserValue> Args,
430 Diagnostics *Error) {
431 typedef ReturnType (*FuncType)(ArgType1);
433 CHECK_ARG_TYPE(0, ArgType1);
434 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
435 ArgTypeTraits<ArgType1>::get(Args[0].Value)));
438 /// \brief 2-arg marshaller function.
439 template <typename ReturnType, typename ArgType1, typename ArgType2>
440 static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
441 SourceRange NameRange,
442 ArrayRef<ParserValue> Args,
443 Diagnostics *Error) {
444 typedef ReturnType (*FuncType)(ArgType1, ArgType2);
446 CHECK_ARG_TYPE(0, ArgType1);
447 CHECK_ARG_TYPE(1, ArgType2);
448 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
449 ArgTypeTraits<ArgType1>::get(Args[0].Value),
450 ArgTypeTraits<ArgType2>::get(Args[1].Value)));
453 #undef CHECK_ARG_COUNT
454 #undef CHECK_ARG_TYPE
456 /// \brief Helper class used to collect all the possible overloads of an
457 /// argument adaptative matcher function.
458 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
459 typename FromTypes, typename ToTypes>
460 class AdaptativeOverloadCollector {
462 AdaptativeOverloadCollector(StringRef Name,
463 std::vector<MatcherDescriptor *> &Out)
464 : Name(Name), Out(Out) {
465 collect(FromTypes());
469 typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc<
470 ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc;
472 /// \brief End case for the recursion
473 static void collect(ast_matchers::internal::EmptyTypeList) {}
475 /// \brief Recursive case. Get the overload for the head of the list, and
476 /// recurse to the tail.
477 template <typename FromTypeList>
478 inline void collect(FromTypeList);
481 std::vector<MatcherDescriptor *> &Out;
484 /// \brief MatcherDescriptor that wraps multiple "overloads" of the same
487 /// It will try every overload and generate appropriate errors for when none or
488 /// more than one overloads match the arguments.
489 class OverloadedMatcherDescriptor : public MatcherDescriptor {
491 OverloadedMatcherDescriptor(ArrayRef<MatcherDescriptor *> Callbacks)
492 : Overloads(Callbacks.begin(), Callbacks.end()) {}
494 ~OverloadedMatcherDescriptor() override {}
496 VariantMatcher create(SourceRange NameRange,
497 ArrayRef<ParserValue> Args,
498 Diagnostics *Error) const override {
499 std::vector<VariantMatcher> Constructed;
500 Diagnostics::OverloadContext Ctx(Error);
501 for (const auto &O : Overloads) {
502 VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
503 if (!SubMatcher.isNull()) {
504 Constructed.push_back(SubMatcher);
508 if (Constructed.empty()) return VariantMatcher(); // No overload matched.
509 // We ignore the errors if any matcher succeeded.
511 if (Constructed.size() > 1) {
512 // More than one constructed. It is ambiguous.
513 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
514 return VariantMatcher();
516 return Constructed[0];
519 bool isVariadic() const override {
520 bool Overload0Variadic = Overloads[0]->isVariadic();
522 for (const auto &O : Overloads) {
523 assert(Overload0Variadic == O->isVariadic());
526 return Overload0Variadic;
529 unsigned getNumArgs() const override {
530 unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
532 for (const auto &O : Overloads) {
533 assert(Overload0NumArgs == O->getNumArgs());
536 return Overload0NumArgs;
539 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
540 std::vector<ArgKind> &Kinds) const override {
541 for (const auto &O : Overloads) {
542 if (O->isConvertibleTo(ThisKind))
543 O->getArgKinds(ThisKind, ArgNo, Kinds);
547 bool isConvertibleTo(
548 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
549 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
550 for (const auto &O : Overloads) {
551 if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
558 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
561 /// \brief Variadic operator marshaller function.
562 class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
564 typedef DynTypedMatcher::VariadicOperator VarOp;
565 VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
566 VarOp Op, StringRef MatcherName)
567 : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
568 MatcherName(MatcherName) {}
570 VariantMatcher create(SourceRange NameRange,
571 ArrayRef<ParserValue> Args,
572 Diagnostics *Error) const override {
573 if (Args.size() < MinCount || MaxCount < Args.size()) {
574 const std::string MaxStr =
575 (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str();
576 Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
577 << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
578 return VariantMatcher();
581 std::vector<VariantMatcher> InnerArgs;
582 for (size_t i = 0, e = Args.size(); i != e; ++i) {
583 const ParserValue &Arg = Args[i];
584 const VariantValue &Value = Arg.Value;
585 if (!Value.isMatcher()) {
586 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
587 << (i + 1) << "Matcher<>" << Value.getTypeAsString();
588 return VariantMatcher();
590 InnerArgs.push_back(Value.getMatcher());
592 return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
595 bool isVariadic() const override { return true; }
596 unsigned getNumArgs() const override { return 0; }
597 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
598 std::vector<ArgKind> &Kinds) const override {
599 Kinds.push_back(ThisKind);
601 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
602 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
605 if (LeastDerivedKind)
606 *LeastDerivedKind = Kind;
609 bool isPolymorphic() const override { return true; }
612 const unsigned MinCount;
613 const unsigned MaxCount;
615 const StringRef MatcherName;
618 /// Helper functions to select the appropriate marshaller functions.
619 /// They detect the number of arguments, arguments types and return type.
621 /// \brief 0-arg overload
622 template <typename ReturnType>
623 MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(),
624 StringRef MatcherName) {
625 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
626 BuildReturnTypeVector<ReturnType>::build(RetTypes);
627 return new FixedArgCountMatcherDescriptor(
628 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
629 MatcherName, RetTypes, None);
632 /// \brief 1-arg overload
633 template <typename ReturnType, typename ArgType1>
634 MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1),
635 StringRef MatcherName) {
636 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
637 BuildReturnTypeVector<ReturnType>::build(RetTypes);
638 ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
639 return new FixedArgCountMatcherDescriptor(
640 matcherMarshall1<ReturnType, ArgType1>,
641 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
644 /// \brief 2-arg overload
645 template <typename ReturnType, typename ArgType1, typename ArgType2>
646 MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
647 StringRef MatcherName) {
648 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
649 BuildReturnTypeVector<ReturnType>::build(RetTypes);
650 ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
651 ArgTypeTraits<ArgType2>::getKind() };
652 return new FixedArgCountMatcherDescriptor(
653 matcherMarshall2<ReturnType, ArgType1, ArgType2>,
654 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
657 /// \brief Variadic overload.
658 template <typename ResultT, typename ArgT,
659 ResultT (*Func)(ArrayRef<const ArgT *>)>
661 makeMatcherAutoMarshall(llvm::VariadicFunction<ResultT, ArgT, Func> VarFunc,
662 StringRef MatcherName) {
663 return new VariadicFuncMatcherDescriptor(VarFunc, MatcherName);
666 /// \brief Overload for VariadicDynCastAllOfMatchers.
668 /// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
669 /// completion results for that type of matcher.
670 template <typename BaseT, typename DerivedT>
672 makeMatcherAutoMarshall(ast_matchers::internal::VariadicDynCastAllOfMatcher<
673 BaseT, DerivedT> VarFunc,
674 StringRef MatcherName) {
675 return new DynCastAllOfMatcherDescriptor(VarFunc, MatcherName);
678 /// \brief Argument adaptative overload.
679 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
680 typename FromTypes, typename ToTypes>
682 makeMatcherAutoMarshall(ast_matchers::internal::ArgumentAdaptingMatcherFunc<
683 ArgumentAdapterT, FromTypes, ToTypes>,
684 StringRef MatcherName) {
685 std::vector<MatcherDescriptor *> Overloads;
686 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
688 return new OverloadedMatcherDescriptor(Overloads);
691 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
692 typename FromTypes, typename ToTypes>
693 template <typename FromTypeList>
694 inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
695 ToTypes>::collect(FromTypeList) {
696 Out.push_back(makeMatcherAutoMarshall(
697 &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
698 collect(typename FromTypeList::tail());
701 /// \brief Variadic operator overload.
702 template <unsigned MinCount, unsigned MaxCount>
704 makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc<
705 MinCount, MaxCount> Func,
706 StringRef MatcherName) {
707 return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Op,
711 } // namespace internal
712 } // namespace dynamic
713 } // namespace ast_matchers
716 #endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H