1 //===- Marshallers.h - Generic matcher function marshallers -----*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// Functions templates and classes to wrap matcher construct functions.
12 /// A collection of template function and classes that provide a generic
13 /// marshalling layer on top of matcher construct functions.
14 /// These are used by the registry to export all marshaller constructors with
15 /// the same generic interface.
17 //===----------------------------------------------------------------------===//
19 #ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
20 #define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
22 #include "clang/AST/ASTTypeTraits.h"
23 #include "clang/AST/OperationKinds.h"
24 #include "clang/ASTMatchers/ASTMatchersInternal.h"
25 #include "clang/ASTMatchers/Dynamic/Diagnostics.h"
26 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
27 #include "clang/Basic/AttrKinds.h"
28 #include "clang/Basic/LLVM.h"
29 #include "clang/Basic/OpenMPKinds.h"
30 #include "llvm/ADT/ArrayRef.h"
31 #include "llvm/ADT/None.h"
32 #include "llvm/ADT/STLExtras.h"
33 #include "llvm/ADT/StringRef.h"
34 #include "llvm/ADT/StringSwitch.h"
35 #include "llvm/ADT/Twine.h"
46 namespace ast_matchers {
50 /// Helper template class to just from argument type to the right is/get
51 /// functions in VariantValue.
52 /// Used to verify and extract the matcher arguments below.
53 template <class T> struct ArgTypeTraits;
54 template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
57 template <> struct ArgTypeTraits<std::string> {
58 static bool is(const VariantValue &Value) { return Value.isString(); }
60 static const std::string &get(const VariantValue &Value) {
61 return Value.getString();
64 static ArgKind getKind() {
65 return ArgKind(ArgKind::AK_String);
70 struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
73 template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> {
74 static bool is(const VariantValue &Value) {
75 return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
78 static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
79 return Value.getMatcher().getTypedMatcher<T>();
82 static ArgKind getKind() {
83 return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
87 template <> struct ArgTypeTraits<bool> {
88 static bool is(const VariantValue &Value) { return Value.isBoolean(); }
90 static bool get(const VariantValue &Value) {
91 return Value.getBoolean();
94 static ArgKind getKind() {
95 return ArgKind(ArgKind::AK_Boolean);
99 template <> struct ArgTypeTraits<double> {
100 static bool is(const VariantValue &Value) { return Value.isDouble(); }
102 static double get(const VariantValue &Value) {
103 return Value.getDouble();
106 static ArgKind getKind() {
107 return ArgKind(ArgKind::AK_Double);
111 template <> struct ArgTypeTraits<unsigned> {
112 static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
114 static unsigned get(const VariantValue &Value) {
115 return Value.getUnsigned();
118 static ArgKind getKind() {
119 return ArgKind(ArgKind::AK_Unsigned);
123 template <> struct ArgTypeTraits<attr::Kind> {
125 static Optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) {
126 return llvm::StringSwitch<Optional<attr::Kind>>(AttrKind)
127 #define ATTR(X) .Case("attr::" #X, attr:: X)
128 #include "clang/Basic/AttrList.inc"
129 .Default(llvm::None);
133 static bool is(const VariantValue &Value) {
134 return Value.isString() && getAttrKind(Value.getString());
137 static attr::Kind get(const VariantValue &Value) {
138 return *getAttrKind(Value.getString());
141 static ArgKind getKind() {
142 return ArgKind(ArgKind::AK_String);
146 template <> struct ArgTypeTraits<CastKind> {
148 static Optional<CastKind> getCastKind(llvm::StringRef AttrKind) {
149 return llvm::StringSwitch<Optional<CastKind>>(AttrKind)
150 #define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
151 #include "clang/AST/OperationKinds.def"
152 .Default(llvm::None);
156 static bool is(const VariantValue &Value) {
157 return Value.isString() && getCastKind(Value.getString());
160 static CastKind get(const VariantValue &Value) {
161 return *getCastKind(Value.getString());
164 static ArgKind getKind() {
165 return ArgKind(ArgKind::AK_String);
169 template <> struct ArgTypeTraits<OpenMPClauseKind> {
171 static Optional<OpenMPClauseKind> getClauseKind(llvm::StringRef ClauseKind) {
172 return llvm::StringSwitch<Optional<OpenMPClauseKind>>(ClauseKind)
173 #define OPENMP_CLAUSE(TextualSpelling, Class) \
174 .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling)
175 #include "clang/Basic/OpenMPKinds.def"
176 .Default(llvm::None);
180 static bool is(const VariantValue &Value) {
181 return Value.isString() && getClauseKind(Value.getString());
184 static OpenMPClauseKind get(const VariantValue &Value) {
185 return *getClauseKind(Value.getString());
188 static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }
191 /// Matcher descriptor interface.
193 /// Provides a \c create() method that constructs the matcher from the provided
194 /// arguments, and various other methods for type introspection.
195 class MatcherDescriptor {
197 virtual ~MatcherDescriptor() = default;
199 virtual VariantMatcher create(SourceRange NameRange,
200 ArrayRef<ParserValue> Args,
201 Diagnostics *Error) const = 0;
203 /// Returns whether the matcher is variadic. Variadic matchers can take any
204 /// number of arguments, but they must be of the same type.
205 virtual bool isVariadic() const = 0;
207 /// Returns the number of arguments accepted by the matcher if not variadic.
208 virtual unsigned getNumArgs() const = 0;
210 /// Given that the matcher is being converted to type \p ThisKind, append the
211 /// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
212 // FIXME: We should provide the ability to constrain the output of this
213 // function based on the types of other matcher arguments.
214 virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
215 std::vector<ArgKind> &ArgKinds) const = 0;
217 /// Returns whether this matcher is convertible to the given type. If it is
218 /// so convertible, store in *Specificity a value corresponding to the
219 /// "specificity" of the converted matcher to the given context, and in
220 /// *LeastDerivedKind the least derived matcher kind which would result in the
221 /// same matcher overload. Zero specificity indicates that this conversion
222 /// would produce a trivial matcher that will either always or never match.
223 /// Such matchers are excluded from code completion results.
224 virtual bool isConvertibleTo(
225 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
226 ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
228 /// Returns whether the matcher will, given a matcher of any type T, yield a
229 /// matcher of type T.
230 virtual bool isPolymorphic() const { return false; }
233 inline bool isRetKindConvertibleTo(
234 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
235 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
236 ast_type_traits::ASTNodeKind *LeastDerivedKind) {
237 for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
238 if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
239 if (LeastDerivedKind)
240 *LeastDerivedKind = NodeKind;
247 /// Simple callback implementation. Marshaller and function are provided.
249 /// This class wraps a function of arbitrary signature and a marshaller
250 /// function into a MatcherDescriptor.
251 /// The marshaller is in charge of taking the VariantValue arguments, checking
252 /// their types, unpacking them and calling the underlying function.
253 class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
255 using MarshallerType = VariantMatcher (*)(void (*Func)(),
256 StringRef MatcherName,
257 SourceRange NameRange,
258 ArrayRef<ParserValue> Args,
261 /// \param Marshaller Function to unpack the arguments and call \c Func
262 /// \param Func Matcher construct function. This is the function that
263 /// compile-time matcher expressions would use to create the matcher.
264 /// \param RetKinds The list of matcher types to which the matcher is
266 /// \param ArgKinds The types of the arguments this matcher takes.
267 FixedArgCountMatcherDescriptor(
268 MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
269 ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
270 ArrayRef<ArgKind> ArgKinds)
271 : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
272 RetKinds(RetKinds.begin(), RetKinds.end()),
273 ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
275 VariantMatcher create(SourceRange NameRange,
276 ArrayRef<ParserValue> Args,
277 Diagnostics *Error) const override {
278 return Marshaller(Func, MatcherName, NameRange, Args, Error);
281 bool isVariadic() const override { return false; }
282 unsigned getNumArgs() const override { return ArgKinds.size(); }
284 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
285 std::vector<ArgKind> &Kinds) const override {
286 Kinds.push_back(ArgKinds[ArgNo]);
289 bool isConvertibleTo(
290 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
291 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
292 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
297 const MarshallerType Marshaller;
298 void (* const Func)();
299 const std::string MatcherName;
300 const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
301 const std::vector<ArgKind> ArgKinds;
304 /// Helper methods to extract and merge all possible typed matchers
305 /// out of the polymorphic object.
306 template <class PolyMatcher>
307 static void mergePolyMatchers(const PolyMatcher &Poly,
308 std::vector<DynTypedMatcher> &Out,
309 ast_matchers::internal::EmptyTypeList) {}
311 template <class PolyMatcher, class TypeList>
312 static void mergePolyMatchers(const PolyMatcher &Poly,
313 std::vector<DynTypedMatcher> &Out, TypeList) {
314 Out.push_back(ast_matchers::internal::Matcher<typename TypeList::head>(Poly));
315 mergePolyMatchers(Poly, Out, typename TypeList::tail());
318 /// Convert the return values of the functions into a VariantMatcher.
320 /// There are 2 cases right now: The return value is a Matcher<T> or is a
321 /// polymorphic matcher. For the former, we just construct the VariantMatcher.
322 /// For the latter, we instantiate all the possible Matcher<T> of the poly
324 static VariantMatcher outvalueToVariantMatcher(const DynTypedMatcher &Matcher) {
325 return VariantMatcher::SingleMatcher(Matcher);
328 template <typename T>
329 static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
330 typename T::ReturnTypes * =
332 std::vector<DynTypedMatcher> Matchers;
333 mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
334 VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
338 template <typename T>
339 inline void buildReturnTypeVectorFromTypeList(
340 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
342 ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
343 buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
348 buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
349 std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
351 template <typename T>
352 struct BuildReturnTypeVector {
353 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
354 buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
358 template <typename T>
359 struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> {
360 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
361 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
365 template <typename T>
366 struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> {
367 static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
368 RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
372 /// Variadic marshaller function.
373 template <typename ResultT, typename ArgT,
374 ResultT (*Func)(ArrayRef<const ArgT *>)>
376 variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
377 ArrayRef<ParserValue> Args, Diagnostics *Error) {
378 ArgT **InnerArgs = new ArgT *[Args.size()]();
380 bool HasError = false;
381 for (size_t i = 0, e = Args.size(); i != e; ++i) {
382 using ArgTraits = ArgTypeTraits<ArgT>;
384 const ParserValue &Arg = Args[i];
385 const VariantValue &Value = Arg.Value;
386 if (!ArgTraits::is(Value)) {
387 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
388 << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
392 InnerArgs[i] = new ArgT(ArgTraits::get(Value));
397 Out = outvalueToVariantMatcher(Func(llvm::makeArrayRef(InnerArgs,
401 for (size_t i = 0, e = Args.size(); i != e; ++i) {
408 /// Matcher descriptor for variadic functions.
410 /// This class simply wraps a VariadicFunction with the right signature to export
411 /// it as a MatcherDescriptor.
412 /// This allows us to have one implementation of the interface for as many free
413 /// functions as we want, reducing the number of symbols and size of the
415 class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
417 using RunFunc = VariantMatcher (*)(StringRef MatcherName,
418 SourceRange NameRange,
419 ArrayRef<ParserValue> Args,
422 template <typename ResultT, typename ArgT,
423 ResultT (*F)(ArrayRef<const ArgT *>)>
424 VariadicFuncMatcherDescriptor(
425 ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func,
426 StringRef MatcherName)
427 : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
428 MatcherName(MatcherName.str()),
429 ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
430 BuildReturnTypeVector<ResultT>::build(RetKinds);
433 VariantMatcher create(SourceRange NameRange,
434 ArrayRef<ParserValue> Args,
435 Diagnostics *Error) const override {
436 return Func(MatcherName, NameRange, Args, Error);
439 bool isVariadic() const override { return true; }
440 unsigned getNumArgs() const override { return 0; }
442 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
443 std::vector<ArgKind> &Kinds) const override {
444 Kinds.push_back(ArgsKind);
447 bool isConvertibleTo(
448 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
449 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
450 return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
456 const std::string MatcherName;
457 std::vector<ast_type_traits::ASTNodeKind> RetKinds;
458 const ArgKind ArgsKind;
461 /// Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
462 class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
464 template <typename BaseT, typename DerivedT>
465 DynCastAllOfMatcherDescriptor(
466 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
467 StringRef MatcherName)
468 : VariadicFuncMatcherDescriptor(Func, MatcherName),
469 DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
473 isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
474 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
475 // If Kind is not a base of DerivedKind, either DerivedKind is a base of
476 // Kind (in which case the match will always succeed) or Kind and
477 // DerivedKind are unrelated (in which case it will always fail), so set
479 if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
481 if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
492 const ast_type_traits::ASTNodeKind DerivedKind;
495 /// Helper macros to check the arguments on all marshaller functions.
496 #define CHECK_ARG_COUNT(count) \
497 if (Args.size() != count) { \
498 Error->addError(NameRange, Error->ET_RegistryWrongArgCount) \
499 << count << Args.size(); \
500 return VariantMatcher(); \
503 #define CHECK_ARG_TYPE(index, type) \
504 if (!ArgTypeTraits<type>::is(Args[index].Value)) { \
505 Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType) \
506 << (index + 1) << ArgTypeTraits<type>::getKind().asString() \
507 << Args[index].Value.getTypeAsString(); \
508 return VariantMatcher(); \
511 /// 0-arg marshaller function.
512 template <typename ReturnType>
513 static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
514 SourceRange NameRange,
515 ArrayRef<ParserValue> Args,
516 Diagnostics *Error) {
517 using FuncType = ReturnType (*)();
519 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
522 /// 1-arg marshaller function.
523 template <typename ReturnType, typename ArgType1>
524 static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
525 SourceRange NameRange,
526 ArrayRef<ParserValue> Args,
527 Diagnostics *Error) {
528 using FuncType = ReturnType (*)(ArgType1);
530 CHECK_ARG_TYPE(0, ArgType1);
531 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
532 ArgTypeTraits<ArgType1>::get(Args[0].Value)));
535 /// 2-arg marshaller function.
536 template <typename ReturnType, typename ArgType1, typename ArgType2>
537 static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
538 SourceRange NameRange,
539 ArrayRef<ParserValue> Args,
540 Diagnostics *Error) {
541 using FuncType = ReturnType (*)(ArgType1, ArgType2);
543 CHECK_ARG_TYPE(0, ArgType1);
544 CHECK_ARG_TYPE(1, ArgType2);
545 return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
546 ArgTypeTraits<ArgType1>::get(Args[0].Value),
547 ArgTypeTraits<ArgType2>::get(Args[1].Value)));
550 #undef CHECK_ARG_COUNT
551 #undef CHECK_ARG_TYPE
553 /// Helper class used to collect all the possible overloads of an
554 /// argument adaptative matcher function.
555 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
556 typename FromTypes, typename ToTypes>
557 class AdaptativeOverloadCollector {
559 AdaptativeOverloadCollector(
560 StringRef Name, std::vector<std::unique_ptr<MatcherDescriptor>> &Out)
561 : Name(Name), Out(Out) {
562 collect(FromTypes());
566 using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc<
567 ArgumentAdapterT, FromTypes, ToTypes>;
569 /// End case for the recursion
570 static void collect(ast_matchers::internal::EmptyTypeList) {}
572 /// Recursive case. Get the overload for the head of the list, and
573 /// recurse to the tail.
574 template <typename FromTypeList>
575 inline void collect(FromTypeList);
578 std::vector<std::unique_ptr<MatcherDescriptor>> &Out;
581 /// MatcherDescriptor that wraps multiple "overloads" of the same
584 /// It will try every overload and generate appropriate errors for when none or
585 /// more than one overloads match the arguments.
586 class OverloadedMatcherDescriptor : public MatcherDescriptor {
588 OverloadedMatcherDescriptor(
589 MutableArrayRef<std::unique_ptr<MatcherDescriptor>> Callbacks)
590 : Overloads(std::make_move_iterator(Callbacks.begin()),
591 std::make_move_iterator(Callbacks.end())) {}
593 ~OverloadedMatcherDescriptor() override = default;
595 VariantMatcher create(SourceRange NameRange,
596 ArrayRef<ParserValue> Args,
597 Diagnostics *Error) const override {
598 std::vector<VariantMatcher> Constructed;
599 Diagnostics::OverloadContext Ctx(Error);
600 for (const auto &O : Overloads) {
601 VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
602 if (!SubMatcher.isNull()) {
603 Constructed.push_back(SubMatcher);
607 if (Constructed.empty()) return VariantMatcher(); // No overload matched.
608 // We ignore the errors if any matcher succeeded.
610 if (Constructed.size() > 1) {
611 // More than one constructed. It is ambiguous.
612 Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload);
613 return VariantMatcher();
615 return Constructed[0];
618 bool isVariadic() const override {
619 bool Overload0Variadic = Overloads[0]->isVariadic();
621 for (const auto &O : Overloads) {
622 assert(Overload0Variadic == O->isVariadic());
625 return Overload0Variadic;
628 unsigned getNumArgs() const override {
629 unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
631 for (const auto &O : Overloads) {
632 assert(Overload0NumArgs == O->getNumArgs());
635 return Overload0NumArgs;
638 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
639 std::vector<ArgKind> &Kinds) const override {
640 for (const auto &O : Overloads) {
641 if (O->isConvertibleTo(ThisKind))
642 O->getArgKinds(ThisKind, ArgNo, Kinds);
646 bool isConvertibleTo(
647 ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
648 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
649 for (const auto &O : Overloads) {
650 if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
657 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
660 /// Variadic operator marshaller function.
661 class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
663 using VarOp = DynTypedMatcher::VariadicOperator;
665 VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
666 VarOp Op, StringRef MatcherName)
667 : MinCount(MinCount), MaxCount(MaxCount), Op(Op),
668 MatcherName(MatcherName) {}
670 VariantMatcher create(SourceRange NameRange,
671 ArrayRef<ParserValue> Args,
672 Diagnostics *Error) const override {
673 if (Args.size() < MinCount || MaxCount < Args.size()) {
674 const std::string MaxStr =
675 (MaxCount == std::numeric_limits<unsigned>::max() ? ""
678 Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
679 << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
680 return VariantMatcher();
683 std::vector<VariantMatcher> InnerArgs;
684 for (size_t i = 0, e = Args.size(); i != e; ++i) {
685 const ParserValue &Arg = Args[i];
686 const VariantValue &Value = Arg.Value;
687 if (!Value.isMatcher()) {
688 Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
689 << (i + 1) << "Matcher<>" << Value.getTypeAsString();
690 return VariantMatcher();
692 InnerArgs.push_back(Value.getMatcher());
694 return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs));
697 bool isVariadic() const override { return true; }
698 unsigned getNumArgs() const override { return 0; }
700 void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
701 std::vector<ArgKind> &Kinds) const override {
702 Kinds.push_back(ThisKind);
705 bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
706 ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
709 if (LeastDerivedKind)
710 *LeastDerivedKind = Kind;
714 bool isPolymorphic() const override { return true; }
717 const unsigned MinCount;
718 const unsigned MaxCount;
720 const StringRef MatcherName;
723 /// Helper functions to select the appropriate marshaller functions.
724 /// They detect the number of arguments, arguments types and return type.
727 template <typename ReturnType>
728 std::unique_ptr<MatcherDescriptor>
729 makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {
730 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
731 BuildReturnTypeVector<ReturnType>::build(RetTypes);
732 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
733 matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
734 MatcherName, RetTypes, None);
738 template <typename ReturnType, typename ArgType1>
739 std::unique_ptr<MatcherDescriptor>
740 makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) {
741 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
742 BuildReturnTypeVector<ReturnType>::build(RetTypes);
743 ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
744 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
745 matcherMarshall1<ReturnType, ArgType1>,
746 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
750 template <typename ReturnType, typename ArgType1, typename ArgType2>
751 std::unique_ptr<MatcherDescriptor>
752 makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
753 StringRef MatcherName) {
754 std::vector<ast_type_traits::ASTNodeKind> RetTypes;
755 BuildReturnTypeVector<ReturnType>::build(RetTypes);
756 ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
757 ArgTypeTraits<ArgType2>::getKind() };
758 return llvm::make_unique<FixedArgCountMatcherDescriptor>(
759 matcherMarshall2<ReturnType, ArgType1, ArgType2>,
760 reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
763 /// Variadic overload.
764 template <typename ResultT, typename ArgT,
765 ResultT (*Func)(ArrayRef<const ArgT *>)>
766 std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
767 ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc,
768 StringRef MatcherName) {
769 return llvm::make_unique<VariadicFuncMatcherDescriptor>(VarFunc, MatcherName);
772 /// Overload for VariadicDynCastAllOfMatchers.
774 /// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
775 /// completion results for that type of matcher.
776 template <typename BaseT, typename DerivedT>
777 std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
778 ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT>
780 StringRef MatcherName) {
781 return llvm::make_unique<DynCastAllOfMatcherDescriptor>(VarFunc, MatcherName);
784 /// Argument adaptative overload.
785 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
786 typename FromTypes, typename ToTypes>
787 std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
788 ast_matchers::internal::ArgumentAdaptingMatcherFunc<ArgumentAdapterT,
790 StringRef MatcherName) {
791 std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
792 AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
794 return llvm::make_unique<OverloadedMatcherDescriptor>(Overloads);
797 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
798 typename FromTypes, typename ToTypes>
799 template <typename FromTypeList>
800 inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
801 ToTypes>::collect(FromTypeList) {
802 Out.push_back(makeMatcherAutoMarshall(
803 &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
804 collect(typename FromTypeList::tail());
807 /// Variadic operator overload.
808 template <unsigned MinCount, unsigned MaxCount>
809 std::unique_ptr<MatcherDescriptor> makeMatcherAutoMarshall(
810 ast_matchers::internal::VariadicOperatorMatcherFunc<MinCount, MaxCount>
812 StringRef MatcherName) {
813 return llvm::make_unique<VariadicOperatorMatcherDescriptor>(
814 MinCount, MaxCount, Func.Op, MatcherName);
817 } // namespace internal
818 } // namespace dynamic
819 } // namespace ast_matchers
822 #endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H