https://github.com/hach-que created https://github.com/llvm/llvm-project/pull/86228
This adds a 'refersToPack' AST matcher, which can be used to match against template arguments that are inside parameter packs. The inner matcher is evaluated against each argument in the parameter pack, such that given: ```cpp template<typename T, typename... Params> class A {}; A<int, double> a; A<double, int> b; A<double, int, long> c; ``` The matcher `classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToPack(refersToType(...))))` would evaluate the `refersToType` against: - For `a`, the `double` template argument. - For `b`, the `int` template argument. - For `c`, the `int` template argument, then the `long` template argument. If the inner matcher matches against any argument of the parameter pack, then `refersToPack` matches. >From e298ea2437dfdd3d44e7d53ef2a5e41bf17bd329 Mon Sep 17 00:00:00 2001 From: June Rhodes <jrhodes@redpoint.games> Date: Fri, 22 Mar 2024 12:51:40 +1100 Subject: [PATCH] Add 'refersToPack' AST matcher --- clang/include/clang/ASTMatchers/ASTMatchers.h | 29 +++++++++++++++++++ clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 + 2 files changed, 30 insertions(+) diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 2f71053d030f68..df30d4c85c22c6 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1151,6 +1151,35 @@ AST_MATCHER_P(TemplateArgument, refersToDeclaration, return false; } +/// Matches template arguments within a pack template argument; the inner +/// matcher is compared against each argument of the parameter pack. +/// +/// Given +/// \code +/// template<typename T, typename... Params> class A {}; +/// A<int, double> a; +/// A<double, int> b; +/// \endcode +/// +/// \endcode +/// classTemplateSpecializationDecl(hasAnyTemplateArgument( +/// refersToPack(refersToType(asString("double"))))) +/// matches the specialization \c A<int, double> +/// but does not match the specialization \c A<double, int> +AST_MATCHER_P(TemplateArgument, refersToPack, + internal::Matcher<TemplateArgument>, InnerMatcher) { + if (Node.getKind() == TemplateArgument::Pack) { + for (const TemplateArgument &Arg : Node.pack_elements()) { + BoundNodesTreeBuilder Result(*Builder); + if (InnerMatcher.matches(Arg, Finder, &Result)) { + *Builder = std::move(Result); + return true; + } + } + } + return false; +} + /// Matches a sugar TemplateArgument that refers to a certain expression. /// /// Given diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 2c75e6beb74301..732d49e850288a 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -551,6 +551,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(referenceType); REGISTER_MATCHER(referenceTypeLoc); REGISTER_MATCHER(refersToDeclaration); + REGISTER_MATCHER(refersToPack); REGISTER_MATCHER(refersToIntegralType); REGISTER_MATCHER(refersToTemplate); REGISTER_MATCHER(refersToType); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits