xref: /freebsd-src/contrib/llvm-project/clang/lib/ASTMatchers/ASTMatchersInternal.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
10b57cec5SDimitry Andric //===- ASTMatchersInternal.cpp - Structural query framework ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  Implements the base layer of the matcher framework.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/ASTMatchers/ASTMatchersInternal.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTTypeTraits.h"
160b57cec5SDimitry Andric #include "clang/AST/Decl.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
185ffd83dbSDimitry Andric #include "clang/AST/ParentMapContext.h"
190b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h"
200b57cec5SDimitry Andric #include "clang/ASTMatchers/ASTMatchers.h"
210b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
225ffd83dbSDimitry Andric #include "clang/Lex/Lexer.h"
230b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
240b57cec5SDimitry Andric #include "llvm/ADT/IntrusiveRefCntPtr.h"
250b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
260b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
270b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
280b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
290b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
300b57cec5SDimitry Andric #include "llvm/Support/ManagedStatic.h"
315ffd83dbSDimitry Andric #include "llvm/Support/Regex.h"
325ffd83dbSDimitry Andric #include "llvm/Support/WithColor.h"
330b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
340b57cec5SDimitry Andric #include <algorithm>
350b57cec5SDimitry Andric #include <cassert>
360b57cec5SDimitry Andric #include <cstddef>
37bdd1243dSDimitry Andric #include <optional>
380b57cec5SDimitry Andric #include <string>
390b57cec5SDimitry Andric #include <utility>
400b57cec5SDimitry Andric #include <vector>
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric namespace clang {
430b57cec5SDimitry Andric namespace ast_matchers {
440b57cec5SDimitry Andric 
AST_MATCHER_P(ObjCMessageExpr,hasAnySelectorMatcher,std::vector<std::string>,Matches)450b57cec5SDimitry Andric AST_MATCHER_P(ObjCMessageExpr, hasAnySelectorMatcher, std::vector<std::string>,
460b57cec5SDimitry Andric               Matches) {
475ffd83dbSDimitry Andric   return llvm::is_contained(Matches, Node.getSelector().getAsString());
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric namespace internal {
510b57cec5SDimitry Andric 
52e8d8bef9SDimitry Andric static bool notUnaryOperator(const DynTypedNode &DynNode,
53e8d8bef9SDimitry Andric                              ASTMatchFinder *Finder,
545ffd83dbSDimitry Andric                              BoundNodesTreeBuilder *Builder,
550b57cec5SDimitry Andric                              ArrayRef<DynTypedMatcher> InnerMatchers);
560b57cec5SDimitry Andric 
57e8d8bef9SDimitry Andric static bool allOfVariadicOperator(const DynTypedNode &DynNode,
58e8d8bef9SDimitry Andric                                   ASTMatchFinder *Finder,
595ffd83dbSDimitry Andric                                   BoundNodesTreeBuilder *Builder,
605ffd83dbSDimitry Andric                                   ArrayRef<DynTypedMatcher> InnerMatchers);
615ffd83dbSDimitry Andric 
62e8d8bef9SDimitry Andric static bool eachOfVariadicOperator(const DynTypedNode &DynNode,
63e8d8bef9SDimitry Andric                                    ASTMatchFinder *Finder,
645ffd83dbSDimitry Andric                                    BoundNodesTreeBuilder *Builder,
655ffd83dbSDimitry Andric                                    ArrayRef<DynTypedMatcher> InnerMatchers);
665ffd83dbSDimitry Andric 
67e8d8bef9SDimitry Andric static bool anyOfVariadicOperator(const DynTypedNode &DynNode,
68e8d8bef9SDimitry Andric                                   ASTMatchFinder *Finder,
695ffd83dbSDimitry Andric                                   BoundNodesTreeBuilder *Builder,
705ffd83dbSDimitry Andric                                   ArrayRef<DynTypedMatcher> InnerMatchers);
715ffd83dbSDimitry Andric 
72e8d8bef9SDimitry Andric static bool optionallyVariadicOperator(const DynTypedNode &DynNode,
730b57cec5SDimitry Andric                                        ASTMatchFinder *Finder,
740b57cec5SDimitry Andric                                        BoundNodesTreeBuilder *Builder,
750b57cec5SDimitry Andric                                        ArrayRef<DynTypedMatcher> InnerMatchers);
760b57cec5SDimitry Andric 
matchesAnyBase(const CXXRecordDecl & Node,const Matcher<CXXBaseSpecifier> & BaseSpecMatcher,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder)775ffd83dbSDimitry Andric bool matchesAnyBase(const CXXRecordDecl &Node,
785ffd83dbSDimitry Andric                     const Matcher<CXXBaseSpecifier> &BaseSpecMatcher,
795ffd83dbSDimitry Andric                     ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) {
805ffd83dbSDimitry Andric   if (!Node.hasDefinition())
815ffd83dbSDimitry Andric     return false;
820b57cec5SDimitry Andric 
835ffd83dbSDimitry Andric   CXXBasePaths Paths;
845ffd83dbSDimitry Andric   Paths.setOrigin(&Node);
850b57cec5SDimitry Andric 
865ffd83dbSDimitry Andric   const auto basePredicate =
875ffd83dbSDimitry Andric       [Finder, Builder, &BaseSpecMatcher](const CXXBaseSpecifier *BaseSpec,
885ffd83dbSDimitry Andric                                           CXXBasePath &IgnoredParam) {
895ffd83dbSDimitry Andric         BoundNodesTreeBuilder Result(*Builder);
905f757f3fSDimitry Andric         if (BaseSpecMatcher.matches(*BaseSpec, Finder, &Result)) {
915ffd83dbSDimitry Andric           *Builder = std::move(Result);
925ffd83dbSDimitry Andric           return true;
935ffd83dbSDimitry Andric         }
945ffd83dbSDimitry Andric         return false;
955ffd83dbSDimitry Andric       };
965ffd83dbSDimitry Andric 
975ffd83dbSDimitry Andric   return Node.lookupInBases(basePredicate, Paths,
985ffd83dbSDimitry Andric                             /*LookupInDependent =*/true);
995ffd83dbSDimitry Andric }
100480093f4SDimitry Andric 
visitMatches(Visitor * ResultVisitor)1010b57cec5SDimitry Andric void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
1020b57cec5SDimitry Andric   if (Bindings.empty())
1030b57cec5SDimitry Andric     Bindings.push_back(BoundNodesMap());
1040b57cec5SDimitry Andric   for (BoundNodesMap &Binding : Bindings) {
1050b57cec5SDimitry Andric     ResultVisitor->visitMatch(BoundNodes(Binding));
1060b57cec5SDimitry Andric   }
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric namespace {
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric using VariadicOperatorFunction = bool (*)(
1125ffd83dbSDimitry Andric     const DynTypedNode &DynNode, ASTMatchFinder *Finder,
1130b57cec5SDimitry Andric     BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric template <VariadicOperatorFunction Func>
1160b57cec5SDimitry Andric class VariadicMatcher : public DynMatcherInterface {
1170b57cec5SDimitry Andric public:
VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)1180b57cec5SDimitry Andric   VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)
1190b57cec5SDimitry Andric       : InnerMatchers(std::move(InnerMatchers)) {}
1200b57cec5SDimitry Andric 
dynMatches(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const1215ffd83dbSDimitry Andric   bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
1220b57cec5SDimitry Andric                   BoundNodesTreeBuilder *Builder) const override {
1230b57cec5SDimitry Andric     return Func(DynNode, Finder, Builder, InnerMatchers);
1240b57cec5SDimitry Andric   }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric private:
1270b57cec5SDimitry Andric   std::vector<DynTypedMatcher> InnerMatchers;
1280b57cec5SDimitry Andric };
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric class IdDynMatcher : public DynMatcherInterface {
1310b57cec5SDimitry Andric public:
IdDynMatcher(StringRef ID,IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)1320b57cec5SDimitry Andric   IdDynMatcher(StringRef ID,
1330b57cec5SDimitry Andric                IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
1340b57cec5SDimitry Andric       : ID(ID), InnerMatcher(std::move(InnerMatcher)) {}
1350b57cec5SDimitry Andric 
dynMatches(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const1365ffd83dbSDimitry Andric   bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
1370b57cec5SDimitry Andric                   BoundNodesTreeBuilder *Builder) const override {
1380b57cec5SDimitry Andric     bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder);
1390b57cec5SDimitry Andric     if (Result) Builder->setBinding(ID, DynNode);
1400b57cec5SDimitry Andric     return Result;
1410b57cec5SDimitry Andric   }
1420b57cec5SDimitry Andric 
TraversalKind() const143bdd1243dSDimitry Andric   std::optional<clang::TraversalKind> TraversalKind() const override {
144480093f4SDimitry Andric     return InnerMatcher->TraversalKind();
145480093f4SDimitry Andric   }
146480093f4SDimitry Andric 
1470b57cec5SDimitry Andric private:
1480b57cec5SDimitry Andric   const std::string ID;
1490b57cec5SDimitry Andric   const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
1500b57cec5SDimitry Andric };
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric /// A matcher that always returns true.
1530b57cec5SDimitry Andric class TrueMatcherImpl : public DynMatcherInterface {
1540b57cec5SDimitry Andric public:
155e8d8bef9SDimitry Andric   TrueMatcherImpl() = default;
1560b57cec5SDimitry Andric 
dynMatches(const DynTypedNode &,ASTMatchFinder *,BoundNodesTreeBuilder *) const1575ffd83dbSDimitry Andric   bool dynMatches(const DynTypedNode &, ASTMatchFinder *,
1580b57cec5SDimitry Andric                   BoundNodesTreeBuilder *) const override {
1590b57cec5SDimitry Andric     return true;
1600b57cec5SDimitry Andric   }
1610b57cec5SDimitry Andric };
1620b57cec5SDimitry Andric 
1635ffd83dbSDimitry Andric /// A matcher that specifies a particular \c TraversalKind.
1645ffd83dbSDimitry Andric ///
1655ffd83dbSDimitry Andric /// The kind provided to the constructor overrides any kind that may be
1665ffd83dbSDimitry Andric /// specified by the `InnerMatcher`.
1675ffd83dbSDimitry Andric class DynTraversalMatcherImpl : public DynMatcherInterface {
1685ffd83dbSDimitry Andric public:
DynTraversalMatcherImpl(clang::TraversalKind TK,IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)1695ffd83dbSDimitry Andric   explicit DynTraversalMatcherImpl(
1705ffd83dbSDimitry Andric       clang::TraversalKind TK,
1715ffd83dbSDimitry Andric       IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
1725ffd83dbSDimitry Andric       : TK(TK), InnerMatcher(std::move(InnerMatcher)) {}
1735ffd83dbSDimitry Andric 
dynMatches(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const1745ffd83dbSDimitry Andric   bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
1755ffd83dbSDimitry Andric                   BoundNodesTreeBuilder *Builder) const override {
1765ffd83dbSDimitry Andric     return this->InnerMatcher->dynMatches(DynNode, Finder, Builder);
1775ffd83dbSDimitry Andric   }
1785ffd83dbSDimitry Andric 
TraversalKind() const179bdd1243dSDimitry Andric   std::optional<clang::TraversalKind> TraversalKind() const override {
1805ffd83dbSDimitry Andric     return TK;
1815ffd83dbSDimitry Andric   }
1825ffd83dbSDimitry Andric 
1835ffd83dbSDimitry Andric private:
1845ffd83dbSDimitry Andric   clang::TraversalKind TK;
1855ffd83dbSDimitry Andric   IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
1865ffd83dbSDimitry Andric };
1875ffd83dbSDimitry Andric 
1880b57cec5SDimitry Andric } // namespace
1890b57cec5SDimitry Andric 
isTraversalIgnoringImplicitNodes() const190e8d8bef9SDimitry Andric bool ASTMatchFinder::isTraversalIgnoringImplicitNodes() const {
191e8d8bef9SDimitry Andric   return getASTContext().getParentMapContext().getTraversalKind() ==
192e8d8bef9SDimitry Andric          TK_IgnoreUnlessSpelledInSource;
193e8d8bef9SDimitry Andric }
1940b57cec5SDimitry Andric 
1955ffd83dbSDimitry Andric DynTypedMatcher
constructVariadic(DynTypedMatcher::VariadicOperator Op,ASTNodeKind SupportedKind,std::vector<DynTypedMatcher> InnerMatchers)1965ffd83dbSDimitry Andric DynTypedMatcher::constructVariadic(DynTypedMatcher::VariadicOperator Op,
1975ffd83dbSDimitry Andric                                    ASTNodeKind SupportedKind,
1980b57cec5SDimitry Andric                                    std::vector<DynTypedMatcher> InnerMatchers) {
1990b57cec5SDimitry Andric   assert(!InnerMatchers.empty() && "Array must not be empty.");
2000b57cec5SDimitry Andric   assert(llvm::all_of(InnerMatchers,
2010b57cec5SDimitry Andric                       [SupportedKind](const DynTypedMatcher &M) {
2020b57cec5SDimitry Andric                         return M.canConvertTo(SupportedKind);
2030b57cec5SDimitry Andric                       }) &&
2040b57cec5SDimitry Andric          "InnerMatchers must be convertible to SupportedKind!");
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   // We must relax the restrict kind here.
2070b57cec5SDimitry Andric   // The different operators might deal differently with a mismatch.
2080b57cec5SDimitry Andric   // Make it the same as SupportedKind, since that is the broadest type we are
2090b57cec5SDimitry Andric   // allowed to accept.
2100b57cec5SDimitry Andric   auto RestrictKind = SupportedKind;
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric   switch (Op) {
2130b57cec5SDimitry Andric   case VO_AllOf:
2140b57cec5SDimitry Andric     // In the case of allOf() we must pass all the checks, so making
2150b57cec5SDimitry Andric     // RestrictKind the most restrictive can save us time. This way we reject
2160b57cec5SDimitry Andric     // invalid types earlier and we can elide the kind checks inside the
2170b57cec5SDimitry Andric     // matcher.
2180b57cec5SDimitry Andric     for (auto &IM : InnerMatchers) {
2195ffd83dbSDimitry Andric       RestrictKind =
2205ffd83dbSDimitry Andric           ASTNodeKind::getMostDerivedType(RestrictKind, IM.RestrictKind);
2210b57cec5SDimitry Andric     }
2220b57cec5SDimitry Andric     return DynTypedMatcher(
2230b57cec5SDimitry Andric         SupportedKind, RestrictKind,
224e8d8bef9SDimitry Andric         new VariadicMatcher<allOfVariadicOperator>(std::move(InnerMatchers)));
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   case VO_AnyOf:
2270b57cec5SDimitry Andric     return DynTypedMatcher(
2280b57cec5SDimitry Andric         SupportedKind, RestrictKind,
229e8d8bef9SDimitry Andric         new VariadicMatcher<anyOfVariadicOperator>(std::move(InnerMatchers)));
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric   case VO_EachOf:
2320b57cec5SDimitry Andric     return DynTypedMatcher(
2330b57cec5SDimitry Andric         SupportedKind, RestrictKind,
234e8d8bef9SDimitry Andric         new VariadicMatcher<eachOfVariadicOperator>(std::move(InnerMatchers)));
2350b57cec5SDimitry Andric 
236480093f4SDimitry Andric   case VO_Optionally:
237480093f4SDimitry Andric     return DynTypedMatcher(SupportedKind, RestrictKind,
238e8d8bef9SDimitry Andric                            new VariadicMatcher<optionallyVariadicOperator>(
239480093f4SDimitry Andric                                std::move(InnerMatchers)));
240480093f4SDimitry Andric 
2410b57cec5SDimitry Andric   case VO_UnaryNot:
2420b57cec5SDimitry Andric     // FIXME: Implement the Not operator to take a single matcher instead of a
2430b57cec5SDimitry Andric     // vector.
2440b57cec5SDimitry Andric     return DynTypedMatcher(
2450b57cec5SDimitry Andric         SupportedKind, RestrictKind,
246e8d8bef9SDimitry Andric         new VariadicMatcher<notUnaryOperator>(std::move(InnerMatchers)));
2470b57cec5SDimitry Andric   }
2480b57cec5SDimitry Andric   llvm_unreachable("Invalid Op value.");
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric 
2515ffd83dbSDimitry Andric DynTypedMatcher
constructRestrictedWrapper(const DynTypedMatcher & InnerMatcher,ASTNodeKind RestrictKind)2525ffd83dbSDimitry Andric DynTypedMatcher::constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
2535ffd83dbSDimitry Andric                                             ASTNodeKind RestrictKind) {
254480093f4SDimitry Andric   DynTypedMatcher Copy = InnerMatcher;
255480093f4SDimitry Andric   Copy.RestrictKind = RestrictKind;
256480093f4SDimitry Andric   return Copy;
257480093f4SDimitry Andric }
258480093f4SDimitry Andric 
withTraversalKind(TraversalKind TK)259e8d8bef9SDimitry Andric DynTypedMatcher DynTypedMatcher::withTraversalKind(TraversalKind TK) {
2600b57cec5SDimitry Andric   auto Copy = *this;
2615ffd83dbSDimitry Andric   Copy.Implementation =
2625ffd83dbSDimitry Andric       new DynTraversalMatcherImpl(TK, std::move(Copy.Implementation));
2630b57cec5SDimitry Andric   return Copy;
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric 
trueMatcher(ASTNodeKind NodeKind)2665ffd83dbSDimitry Andric DynTypedMatcher DynTypedMatcher::trueMatcher(ASTNodeKind NodeKind) {
267e8d8bef9SDimitry Andric   // We only ever need one instance of TrueMatcherImpl, so we create a static
268e8d8bef9SDimitry Andric   // instance and reuse it to reduce the overhead of the matcher and increase
269e8d8bef9SDimitry Andric   // the chance of cache hits.
270e8d8bef9SDimitry Andric   static const llvm::IntrusiveRefCntPtr<TrueMatcherImpl> Instance =
271e8d8bef9SDimitry Andric       new TrueMatcherImpl();
272e8d8bef9SDimitry Andric   return DynTypedMatcher(NodeKind, NodeKind, Instance);
2735ffd83dbSDimitry Andric }
2745ffd83dbSDimitry Andric 
canMatchNodesOfKind(ASTNodeKind Kind) const2755ffd83dbSDimitry Andric bool DynTypedMatcher::canMatchNodesOfKind(ASTNodeKind Kind) const {
2765ffd83dbSDimitry Andric   return RestrictKind.isBaseOf(Kind);
2775ffd83dbSDimitry Andric }
2785ffd83dbSDimitry Andric 
dynCastTo(const ASTNodeKind Kind) const2795ffd83dbSDimitry Andric DynTypedMatcher DynTypedMatcher::dynCastTo(const ASTNodeKind Kind) const {
2805ffd83dbSDimitry Andric   auto Copy = *this;
2815ffd83dbSDimitry Andric   Copy.SupportedKind = Kind;
2825ffd83dbSDimitry Andric   Copy.RestrictKind = ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
2835ffd83dbSDimitry Andric   return Copy;
2845ffd83dbSDimitry Andric }
2855ffd83dbSDimitry Andric 
matches(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const2865ffd83dbSDimitry Andric bool DynTypedMatcher::matches(const DynTypedNode &DynNode,
2870b57cec5SDimitry Andric                               ASTMatchFinder *Finder,
2880b57cec5SDimitry Andric                               BoundNodesTreeBuilder *Builder) const {
289480093f4SDimitry Andric   TraversalKindScope RAII(Finder->getASTContext(),
290480093f4SDimitry Andric                           Implementation->TraversalKind());
291480093f4SDimitry Andric 
292e8d8bef9SDimitry Andric   if (Finder->isTraversalIgnoringImplicitNodes() &&
293e8d8bef9SDimitry Andric       Finder->IsMatchingInASTNodeNotSpelledInSource())
294e8d8bef9SDimitry Andric     return false;
295e8d8bef9SDimitry Andric 
296e8d8bef9SDimitry Andric   if (!Finder->isTraversalIgnoringImplicitNodes() &&
297e8d8bef9SDimitry Andric       Finder->IsMatchingInASTNodeNotAsIs())
298e8d8bef9SDimitry Andric     return false;
299e8d8bef9SDimitry Andric 
3005ffd83dbSDimitry Andric   auto N =
3015ffd83dbSDimitry Andric       Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);
302480093f4SDimitry Andric 
303480093f4SDimitry Andric   if (RestrictKind.isBaseOf(N.getNodeKind()) &&
304480093f4SDimitry Andric       Implementation->dynMatches(N, Finder, Builder)) {
3050b57cec5SDimitry Andric     return true;
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric   // Delete all bindings when a matcher does not match.
3080b57cec5SDimitry Andric   // This prevents unexpected exposure of bound nodes in unmatches
3090b57cec5SDimitry Andric   // branches of the match tree.
3100b57cec5SDimitry Andric   Builder->removeBindings([](const BoundNodesMap &) { return true; });
3110b57cec5SDimitry Andric   return false;
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
matchesNoKindCheck(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder) const3145ffd83dbSDimitry Andric bool DynTypedMatcher::matchesNoKindCheck(const DynTypedNode &DynNode,
3155ffd83dbSDimitry Andric                                          ASTMatchFinder *Finder,
3160b57cec5SDimitry Andric                                          BoundNodesTreeBuilder *Builder) const {
317480093f4SDimitry Andric   TraversalKindScope raii(Finder->getASTContext(),
318480093f4SDimitry Andric                           Implementation->TraversalKind());
319480093f4SDimitry Andric 
320e8d8bef9SDimitry Andric   if (Finder->isTraversalIgnoringImplicitNodes() &&
321e8d8bef9SDimitry Andric       Finder->IsMatchingInASTNodeNotSpelledInSource())
322e8d8bef9SDimitry Andric     return false;
323e8d8bef9SDimitry Andric 
324e8d8bef9SDimitry Andric   if (!Finder->isTraversalIgnoringImplicitNodes() &&
325e8d8bef9SDimitry Andric       Finder->IsMatchingInASTNodeNotAsIs())
326e8d8bef9SDimitry Andric     return false;
327e8d8bef9SDimitry Andric 
3285ffd83dbSDimitry Andric   auto N =
3295ffd83dbSDimitry Andric       Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);
330480093f4SDimitry Andric 
331480093f4SDimitry Andric   assert(RestrictKind.isBaseOf(N.getNodeKind()));
332480093f4SDimitry Andric   if (Implementation->dynMatches(N, Finder, Builder)) {
3330b57cec5SDimitry Andric     return true;
3340b57cec5SDimitry Andric   }
3350b57cec5SDimitry Andric   // Delete all bindings when a matcher does not match.
3360b57cec5SDimitry Andric   // This prevents unexpected exposure of bound nodes in unmatches
3370b57cec5SDimitry Andric   // branches of the match tree.
3380b57cec5SDimitry Andric   Builder->removeBindings([](const BoundNodesMap &) { return true; });
3390b57cec5SDimitry Andric   return false;
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric 
tryBind(StringRef ID) const342bdd1243dSDimitry Andric std::optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {
343bdd1243dSDimitry Andric   if (!AllowBind)
344bdd1243dSDimitry Andric     return std::nullopt;
3450b57cec5SDimitry Andric   auto Result = *this;
3460b57cec5SDimitry Andric   Result.Implementation =
3470b57cec5SDimitry Andric       new IdDynMatcher(ID, std::move(Result.Implementation));
3480b57cec5SDimitry Andric   return std::move(Result);
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric 
canConvertTo(ASTNodeKind To) const3515ffd83dbSDimitry Andric bool DynTypedMatcher::canConvertTo(ASTNodeKind To) const {
3520b57cec5SDimitry Andric   const auto From = getSupportedKind();
3535ffd83dbSDimitry Andric   auto QualKind = ASTNodeKind::getFromNodeKind<QualType>();
3545ffd83dbSDimitry Andric   auto TypeKind = ASTNodeKind::getFromNodeKind<Type>();
3550b57cec5SDimitry Andric   /// Mimic the implicit conversions of Matcher<>.
3560b57cec5SDimitry Andric   /// - From Matcher<Type> to Matcher<QualType>
3570b57cec5SDimitry Andric   if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;
3580b57cec5SDimitry Andric   /// - From Matcher<Base> to Matcher<Derived>
3590b57cec5SDimitry Andric   return From.isBaseOf(To);
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
addMatch(const BoundNodesTreeBuilder & Other)3620b57cec5SDimitry Andric void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
3630b57cec5SDimitry Andric   Bindings.append(Other.Bindings.begin(), Other.Bindings.end());
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
notUnaryOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)366e8d8bef9SDimitry Andric static bool notUnaryOperator(const DynTypedNode &DynNode,
367e8d8bef9SDimitry Andric                              ASTMatchFinder *Finder,
3685ffd83dbSDimitry Andric                              BoundNodesTreeBuilder *Builder,
3690b57cec5SDimitry Andric                              ArrayRef<DynTypedMatcher> InnerMatchers) {
3700b57cec5SDimitry Andric   if (InnerMatchers.size() != 1)
3710b57cec5SDimitry Andric     return false;
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric   // The 'unless' matcher will always discard the result:
3740b57cec5SDimitry Andric   // If the inner matcher doesn't match, unless returns true,
3750b57cec5SDimitry Andric   // but the inner matcher cannot have bound anything.
3760b57cec5SDimitry Andric   // If the inner matcher matches, the result is false, and
3770b57cec5SDimitry Andric   // any possible binding will be discarded.
3780b57cec5SDimitry Andric   // We still need to hand in all the bound nodes up to this
3790b57cec5SDimitry Andric   // point so the inner matcher can depend on bound nodes,
3800b57cec5SDimitry Andric   // and we need to actively discard the bound nodes, otherwise
3810b57cec5SDimitry Andric   // the inner matcher will reset the bound nodes if it doesn't
3820b57cec5SDimitry Andric   // match, but this would be inversed by 'unless'.
3830b57cec5SDimitry Andric   BoundNodesTreeBuilder Discard(*Builder);
3840b57cec5SDimitry Andric   return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric 
allOfVariadicOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)387e8d8bef9SDimitry Andric static bool allOfVariadicOperator(const DynTypedNode &DynNode,
388e8d8bef9SDimitry Andric                                   ASTMatchFinder *Finder,
3890b57cec5SDimitry Andric                                   BoundNodesTreeBuilder *Builder,
3900b57cec5SDimitry Andric                                   ArrayRef<DynTypedMatcher> InnerMatchers) {
3910b57cec5SDimitry Andric   // allOf leads to one matcher for each alternative in the first
3920b57cec5SDimitry Andric   // matcher combined with each alternative in the second matcher.
3930b57cec5SDimitry Andric   // Thus, we can reuse the same Builder.
3945ffd83dbSDimitry Andric   return llvm::all_of(InnerMatchers, [&](const DynTypedMatcher &InnerMatcher) {
3955ffd83dbSDimitry Andric     return InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder);
3965ffd83dbSDimitry Andric   });
3970b57cec5SDimitry Andric }
3980b57cec5SDimitry Andric 
eachOfVariadicOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)399e8d8bef9SDimitry Andric static bool eachOfVariadicOperator(const DynTypedNode &DynNode,
400e8d8bef9SDimitry Andric                                    ASTMatchFinder *Finder,
4010b57cec5SDimitry Andric                                    BoundNodesTreeBuilder *Builder,
4020b57cec5SDimitry Andric                                    ArrayRef<DynTypedMatcher> InnerMatchers) {
4030b57cec5SDimitry Andric   BoundNodesTreeBuilder Result;
4040b57cec5SDimitry Andric   bool Matched = false;
4050b57cec5SDimitry Andric   for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
4060b57cec5SDimitry Andric     BoundNodesTreeBuilder BuilderInner(*Builder);
4070b57cec5SDimitry Andric     if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) {
4080b57cec5SDimitry Andric       Matched = true;
4090b57cec5SDimitry Andric       Result.addMatch(BuilderInner);
4100b57cec5SDimitry Andric     }
4110b57cec5SDimitry Andric   }
4120b57cec5SDimitry Andric   *Builder = std::move(Result);
4130b57cec5SDimitry Andric   return Matched;
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
anyOfVariadicOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)416e8d8bef9SDimitry Andric static bool anyOfVariadicOperator(const DynTypedNode &DynNode,
417e8d8bef9SDimitry Andric                                   ASTMatchFinder *Finder,
4180b57cec5SDimitry Andric                                   BoundNodesTreeBuilder *Builder,
4190b57cec5SDimitry Andric                                   ArrayRef<DynTypedMatcher> InnerMatchers) {
4200b57cec5SDimitry Andric   for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
4210b57cec5SDimitry Andric     BoundNodesTreeBuilder Result = *Builder;
4220b57cec5SDimitry Andric     if (InnerMatcher.matches(DynNode, Finder, &Result)) {
4230b57cec5SDimitry Andric       *Builder = std::move(Result);
4240b57cec5SDimitry Andric       return true;
4250b57cec5SDimitry Andric     }
4260b57cec5SDimitry Andric   }
4270b57cec5SDimitry Andric   return false;
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric 
430e8d8bef9SDimitry Andric static bool
optionallyVariadicOperator(const DynTypedNode & DynNode,ASTMatchFinder * Finder,BoundNodesTreeBuilder * Builder,ArrayRef<DynTypedMatcher> InnerMatchers)431e8d8bef9SDimitry Andric optionallyVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
432480093f4SDimitry Andric                            BoundNodesTreeBuilder *Builder,
433480093f4SDimitry Andric                            ArrayRef<DynTypedMatcher> InnerMatchers) {
4345ffd83dbSDimitry Andric   if (InnerMatchers.size() != 1)
4355ffd83dbSDimitry Andric     return false;
4365ffd83dbSDimitry Andric 
4375ffd83dbSDimitry Andric   BoundNodesTreeBuilder Result(*Builder);
4385ffd83dbSDimitry Andric   if (InnerMatchers[0].matches(DynNode, Finder, &Result))
439480093f4SDimitry Andric     *Builder = std::move(Result);
440480093f4SDimitry Andric   return true;
441480093f4SDimitry Andric }
442480093f4SDimitry Andric 
4430b57cec5SDimitry Andric inline static
vectorFromRefs(ArrayRef<const StringRef * > NameRefs)4440b57cec5SDimitry Andric std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) {
4450b57cec5SDimitry Andric   std::vector<std::string> Names;
4465ffd83dbSDimitry Andric   Names.reserve(NameRefs.size());
4470b57cec5SDimitry Andric   for (auto *Name : NameRefs)
4480b57cec5SDimitry Andric     Names.emplace_back(*Name);
4490b57cec5SDimitry Andric   return Names;
4500b57cec5SDimitry Andric }
4510b57cec5SDimitry Andric 
hasAnyNameFunc(ArrayRef<const StringRef * > NameRefs)4520b57cec5SDimitry Andric Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs) {
4535ffd83dbSDimitry Andric   return internal::Matcher<NamedDecl>(
4545ffd83dbSDimitry Andric       new internal::HasNameMatcher(vectorFromRefs(NameRefs)));
4550b57cec5SDimitry Andric }
4560b57cec5SDimitry Andric 
hasAnySelectorFunc(ArrayRef<const StringRef * > NameRefs)4570b57cec5SDimitry Andric Matcher<ObjCMessageExpr> hasAnySelectorFunc(
4580b57cec5SDimitry Andric     ArrayRef<const StringRef *> NameRefs) {
4590b57cec5SDimitry Andric   return hasAnySelectorMatcher(vectorFromRefs(NameRefs));
4600b57cec5SDimitry Andric }
4610b57cec5SDimitry Andric 
hasAnyOperatorNameFunc(ArrayRef<const StringRef * > NameRefs)4625ffd83dbSDimitry Andric HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {
4635ffd83dbSDimitry Andric   return HasOpNameMatcher(vectorFromRefs(NameRefs));
4645ffd83dbSDimitry Andric }
4655ffd83dbSDimitry Andric 
4665ffd83dbSDimitry Andric HasOverloadOpNameMatcher
hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef * > NameRefs)4675ffd83dbSDimitry Andric hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {
4685ffd83dbSDimitry Andric   return HasOverloadOpNameMatcher(vectorFromRefs(NameRefs));
4695ffd83dbSDimitry Andric }
4705ffd83dbSDimitry Andric 
HasNameMatcher(std::vector<std::string> N)4710b57cec5SDimitry Andric HasNameMatcher::HasNameMatcher(std::vector<std::string> N)
472349cc55cSDimitry Andric     : UseUnqualifiedMatch(
473349cc55cSDimitry Andric           llvm::all_of(N, [](StringRef Name) { return !Name.contains("::"); })),
4740b57cec5SDimitry Andric       Names(std::move(N)) {
4750b57cec5SDimitry Andric #ifndef NDEBUG
4760b57cec5SDimitry Andric   for (StringRef Name : Names)
4770b57cec5SDimitry Andric     assert(!Name.empty());
4780b57cec5SDimitry Andric #endif
4790b57cec5SDimitry Andric }
4800b57cec5SDimitry Andric 
consumeNameSuffix(StringRef & FullName,StringRef Suffix)4810b57cec5SDimitry Andric static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {
4820b57cec5SDimitry Andric   StringRef Name = FullName;
4835f757f3fSDimitry Andric   if (!Name.ends_with(Suffix))
4840b57cec5SDimitry Andric     return false;
4850b57cec5SDimitry Andric   Name = Name.drop_back(Suffix.size());
4860b57cec5SDimitry Andric   if (!Name.empty()) {
4875f757f3fSDimitry Andric     if (!Name.ends_with("::"))
4880b57cec5SDimitry Andric       return false;
4890b57cec5SDimitry Andric     Name = Name.drop_back(2);
4900b57cec5SDimitry Andric   }
4910b57cec5SDimitry Andric   FullName = Name;
4920b57cec5SDimitry Andric   return true;
4930b57cec5SDimitry Andric }
4940b57cec5SDimitry Andric 
getNodeName(const NamedDecl & Node,llvm::SmallString<128> & Scratch)4950b57cec5SDimitry Andric static StringRef getNodeName(const NamedDecl &Node,
4960b57cec5SDimitry Andric                              llvm::SmallString<128> &Scratch) {
4970b57cec5SDimitry Andric   // Simple name.
4980b57cec5SDimitry Andric   if (Node.getIdentifier())
4990b57cec5SDimitry Andric     return Node.getName();
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric   if (Node.getDeclName()) {
5020b57cec5SDimitry Andric     // Name needs to be constructed.
5030b57cec5SDimitry Andric     Scratch.clear();
5040b57cec5SDimitry Andric     llvm::raw_svector_ostream OS(Scratch);
5050b57cec5SDimitry Andric     Node.printName(OS);
5060b57cec5SDimitry Andric     return OS.str();
5070b57cec5SDimitry Andric   }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric   return "(anonymous)";
5100b57cec5SDimitry Andric }
5110b57cec5SDimitry Andric 
getNodeName(const RecordDecl & Node,llvm::SmallString<128> & Scratch)5120b57cec5SDimitry Andric static StringRef getNodeName(const RecordDecl &Node,
5130b57cec5SDimitry Andric                              llvm::SmallString<128> &Scratch) {
5140b57cec5SDimitry Andric   if (Node.getIdentifier()) {
5150b57cec5SDimitry Andric     return Node.getName();
5160b57cec5SDimitry Andric   }
5170b57cec5SDimitry Andric   Scratch.clear();
5180b57cec5SDimitry Andric   return ("(anonymous " + Node.getKindName() + ")").toStringRef(Scratch);
5190b57cec5SDimitry Andric }
5200b57cec5SDimitry Andric 
getNodeName(const NamespaceDecl & Node,llvm::SmallString<128> & Scratch)5210b57cec5SDimitry Andric static StringRef getNodeName(const NamespaceDecl &Node,
5220b57cec5SDimitry Andric                              llvm::SmallString<128> &Scratch) {
5230b57cec5SDimitry Andric   return Node.isAnonymousNamespace() ? "(anonymous namespace)" : Node.getName();
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric namespace {
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric class PatternSet {
5290b57cec5SDimitry Andric public:
PatternSet(ArrayRef<std::string> Names)5300b57cec5SDimitry Andric   PatternSet(ArrayRef<std::string> Names) {
5315ffd83dbSDimitry Andric     Patterns.reserve(Names.size());
5320b57cec5SDimitry Andric     for (StringRef Name : Names)
5335f757f3fSDimitry Andric       Patterns.push_back({Name, Name.starts_with("::")});
5340b57cec5SDimitry Andric   }
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric   /// Consumes the name suffix from each pattern in the set and removes the ones
5370b57cec5SDimitry Andric   /// that didn't match.
5380b57cec5SDimitry Andric   /// Return true if there are still any patterns left.
consumeNameSuffix(StringRef NodeName,bool CanSkip)5390b57cec5SDimitry Andric   bool consumeNameSuffix(StringRef NodeName, bool CanSkip) {
5400b57cec5SDimitry Andric     for (size_t I = 0; I < Patterns.size();) {
5410b57cec5SDimitry Andric       if (::clang::ast_matchers::internal::consumeNameSuffix(Patterns[I].P,
5420b57cec5SDimitry Andric                                                              NodeName) ||
5430b57cec5SDimitry Andric           CanSkip) {
5440b57cec5SDimitry Andric         ++I;
5450b57cec5SDimitry Andric       } else {
5460b57cec5SDimitry Andric         Patterns.erase(Patterns.begin() + I);
5470b57cec5SDimitry Andric       }
5480b57cec5SDimitry Andric     }
5490b57cec5SDimitry Andric     return !Patterns.empty();
5500b57cec5SDimitry Andric   }
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric   /// Check if any of the patterns are a match.
5530b57cec5SDimitry Andric   /// A match will be a pattern that was fully consumed, that also matches the
5540b57cec5SDimitry Andric   /// 'fully qualified' requirement.
foundMatch(bool AllowFullyQualified) const5550b57cec5SDimitry Andric   bool foundMatch(bool AllowFullyQualified) const {
5565ffd83dbSDimitry Andric     return llvm::any_of(Patterns, [&](const Pattern &Pattern) {
5575ffd83dbSDimitry Andric       return Pattern.P.empty() &&
5585ffd83dbSDimitry Andric              (AllowFullyQualified || !Pattern.IsFullyQualified);
5595ffd83dbSDimitry Andric     });
5600b57cec5SDimitry Andric   }
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric private:
5630b57cec5SDimitry Andric   struct Pattern {
5640b57cec5SDimitry Andric     StringRef P;
5650b57cec5SDimitry Andric     bool IsFullyQualified;
5660b57cec5SDimitry Andric   };
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   llvm::SmallVector<Pattern, 8> Patterns;
5690b57cec5SDimitry Andric };
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric } // namespace
5720b57cec5SDimitry Andric 
matchesNodeUnqualified(const NamedDecl & Node) const5730b57cec5SDimitry Andric bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
5740b57cec5SDimitry Andric   assert(UseUnqualifiedMatch);
5750b57cec5SDimitry Andric   llvm::SmallString<128> Scratch;
5760b57cec5SDimitry Andric   StringRef NodeName = getNodeName(Node, Scratch);
5770b57cec5SDimitry Andric   return llvm::any_of(Names, [&](StringRef Name) {
5780b57cec5SDimitry Andric     return consumeNameSuffix(Name, NodeName) && Name.empty();
5790b57cec5SDimitry Andric   });
5800b57cec5SDimitry Andric }
5810b57cec5SDimitry Andric 
matchesNodeFullFast(const NamedDecl & Node) const5820b57cec5SDimitry Andric bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const {
5830b57cec5SDimitry Andric   PatternSet Patterns(Names);
5840b57cec5SDimitry Andric   llvm::SmallString<128> Scratch;
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric   // This function is copied and adapted from NamedDecl::printQualifiedName()
5870b57cec5SDimitry Andric   // By matching each part individually we optimize in a couple of ways:
5880b57cec5SDimitry Andric   //  - We can exit early on the first failure.
5890b57cec5SDimitry Andric   //  - We can skip inline/anonymous namespaces without another pass.
5900b57cec5SDimitry Andric   //  - We print one name at a time, reducing the chance of overflowing the
5910b57cec5SDimitry Andric   //    inlined space of the SmallString.
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric   // First, match the name.
5940b57cec5SDimitry Andric   if (!Patterns.consumeNameSuffix(getNodeName(Node, Scratch),
5950b57cec5SDimitry Andric                                   /*CanSkip=*/false))
5960b57cec5SDimitry Andric     return false;
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric   // Try to match each declaration context.
5990b57cec5SDimitry Andric   // We are allowed to skip anonymous and inline namespaces if they don't match.
6000b57cec5SDimitry Andric   const DeclContext *Ctx = Node.getDeclContext();
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   if (Ctx->isFunctionOrMethod())
6030b57cec5SDimitry Andric     return Patterns.foundMatch(/*AllowFullyQualified=*/false);
6040b57cec5SDimitry Andric 
60547395794SDimitry Andric   for (; Ctx; Ctx = Ctx->getParent()) {
60647395794SDimitry Andric     // Linkage Spec can just be ignored
60747395794SDimitry Andric     // FIXME: Any other DeclContext kinds that can be safely disregarded
60847395794SDimitry Andric     if (isa<LinkageSpecDecl>(Ctx))
60947395794SDimitry Andric       continue;
61047395794SDimitry Andric     if (!isa<NamedDecl>(Ctx))
61147395794SDimitry Andric       break;
6120b57cec5SDimitry Andric     if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
6130b57cec5SDimitry Andric       return true;
6140b57cec5SDimitry Andric 
6150b57cec5SDimitry Andric     if (const auto *ND = dyn_cast<NamespaceDecl>(Ctx)) {
6160b57cec5SDimitry Andric       // If it matches (or we can skip it), continue.
6170b57cec5SDimitry Andric       if (Patterns.consumeNameSuffix(getNodeName(*ND, Scratch),
6180b57cec5SDimitry Andric                                      /*CanSkip=*/ND->isAnonymousNamespace() ||
6190b57cec5SDimitry Andric                                          ND->isInline()))
6200b57cec5SDimitry Andric         continue;
6210b57cec5SDimitry Andric       return false;
6220b57cec5SDimitry Andric     }
6230b57cec5SDimitry Andric     if (const auto *RD = dyn_cast<RecordDecl>(Ctx)) {
6240b57cec5SDimitry Andric       if (!isa<ClassTemplateSpecializationDecl>(Ctx)) {
6250b57cec5SDimitry Andric         if (Patterns.consumeNameSuffix(getNodeName(*RD, Scratch),
6260b57cec5SDimitry Andric                                        /*CanSkip=*/false))
6270b57cec5SDimitry Andric           continue;
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric         return false;
6300b57cec5SDimitry Andric       }
6310b57cec5SDimitry Andric     }
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric     // We don't know how to deal with this DeclContext.
6340b57cec5SDimitry Andric     // Fallback to the slow version of the code.
6350b57cec5SDimitry Andric     return matchesNodeFullSlow(Node);
6360b57cec5SDimitry Andric   }
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric   return Patterns.foundMatch(/*AllowFullyQualified=*/true);
6390b57cec5SDimitry Andric }
6400b57cec5SDimitry Andric 
matchesNodeFullSlow(const NamedDecl & Node) const6410b57cec5SDimitry Andric bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const {
6420b57cec5SDimitry Andric   const bool SkipUnwrittenCases[] = {false, true};
6430b57cec5SDimitry Andric   for (bool SkipUnwritten : SkipUnwrittenCases) {
6440b57cec5SDimitry Andric     llvm::SmallString<128> NodeName = StringRef("::");
6450b57cec5SDimitry Andric     llvm::raw_svector_ostream OS(NodeName);
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric     PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy();
648e8d8bef9SDimitry Andric     Policy.SuppressUnwrittenScope = SkipUnwritten;
649e8d8bef9SDimitry Andric     Policy.SuppressInlineNamespace = SkipUnwritten;
6500b57cec5SDimitry Andric     Node.printQualifiedName(OS, Policy);
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric     const StringRef FullName = OS.str();
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric     for (const StringRef Pattern : Names) {
6555f757f3fSDimitry Andric       if (Pattern.starts_with("::")) {
6560b57cec5SDimitry Andric         if (FullName == Pattern)
6570b57cec5SDimitry Andric           return true;
6585f757f3fSDimitry Andric       } else if (FullName.ends_with(Pattern) &&
6595f757f3fSDimitry Andric                  FullName.drop_back(Pattern.size()).ends_with("::")) {
6600b57cec5SDimitry Andric         return true;
6610b57cec5SDimitry Andric       }
6620b57cec5SDimitry Andric     }
6630b57cec5SDimitry Andric   }
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   return false;
6660b57cec5SDimitry Andric }
6670b57cec5SDimitry Andric 
matchesNode(const NamedDecl & Node) const6680b57cec5SDimitry Andric bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
6690b57cec5SDimitry Andric   assert(matchesNodeFullFast(Node) == matchesNodeFullSlow(Node));
6700b57cec5SDimitry Andric   if (UseUnqualifiedMatch) {
6710b57cec5SDimitry Andric     assert(matchesNodeUnqualified(Node) == matchesNodeFullFast(Node));
6720b57cec5SDimitry Andric     return matchesNodeUnqualified(Node);
6730b57cec5SDimitry Andric   }
6740b57cec5SDimitry Andric   return matchesNodeFullFast(Node);
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric 
6775ffd83dbSDimitry Andric // Checks whether \p Loc points to a token with source text of \p TokenText.
isTokenAtLoc(const SourceManager & SM,const LangOptions & LangOpts,StringRef Text,SourceLocation Loc)6785ffd83dbSDimitry Andric static bool isTokenAtLoc(const SourceManager &SM, const LangOptions &LangOpts,
6795ffd83dbSDimitry Andric                          StringRef Text, SourceLocation Loc) {
6805ffd83dbSDimitry Andric   llvm::SmallString<16> Buffer;
6815ffd83dbSDimitry Andric   bool Invalid = false;
6825ffd83dbSDimitry Andric   // Since `Loc` may point into an expansion buffer, which has no corresponding
6835ffd83dbSDimitry Andric   // source, we need to look at the spelling location to read the actual source.
6845ffd83dbSDimitry Andric   StringRef TokenText = Lexer::getSpelling(SM.getSpellingLoc(Loc), Buffer, SM,
6855ffd83dbSDimitry Andric                                            LangOpts, &Invalid);
6865ffd83dbSDimitry Andric   return !Invalid && Text == TokenText;
6875ffd83dbSDimitry Andric }
6885ffd83dbSDimitry Andric 
689bdd1243dSDimitry Andric std::optional<SourceLocation>
getExpansionLocOfMacro(StringRef MacroName,SourceLocation Loc,const ASTContext & Context)6905ffd83dbSDimitry Andric getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
6915ffd83dbSDimitry Andric                        const ASTContext &Context) {
6925ffd83dbSDimitry Andric   auto &SM = Context.getSourceManager();
6935ffd83dbSDimitry Andric   const LangOptions &LangOpts = Context.getLangOpts();
6945ffd83dbSDimitry Andric   while (Loc.isMacroID()) {
6955ffd83dbSDimitry Andric     SrcMgr::ExpansionInfo Expansion =
6965ffd83dbSDimitry Andric         SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();
6975ffd83dbSDimitry Andric     if (Expansion.isMacroArgExpansion())
6985ffd83dbSDimitry Andric       // Check macro argument for an expansion of the given macro. For example,
6995ffd83dbSDimitry Andric       // `F(G(3))`, where `MacroName` is `G`.
700bdd1243dSDimitry Andric       if (std::optional<SourceLocation> ArgLoc = getExpansionLocOfMacro(
7015ffd83dbSDimitry Andric               MacroName, Expansion.getSpellingLoc(), Context))
7025ffd83dbSDimitry Andric         return ArgLoc;
7035ffd83dbSDimitry Andric     Loc = Expansion.getExpansionLocStart();
7045ffd83dbSDimitry Andric     if (isTokenAtLoc(SM, LangOpts, MacroName, Loc))
7055ffd83dbSDimitry Andric       return Loc;
7065ffd83dbSDimitry Andric   }
707bdd1243dSDimitry Andric   return std::nullopt;
7085ffd83dbSDimitry Andric }
7095ffd83dbSDimitry Andric 
createAndVerifyRegex(StringRef Regex,llvm::Regex::RegexFlags Flags,StringRef MatcherID)7105ffd83dbSDimitry Andric std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
7115ffd83dbSDimitry Andric                                                   llvm::Regex::RegexFlags Flags,
7125ffd83dbSDimitry Andric                                                   StringRef MatcherID) {
7135ffd83dbSDimitry Andric   assert(!Regex.empty() && "Empty regex string");
7145ffd83dbSDimitry Andric   auto SharedRegex = std::make_shared<llvm::Regex>(Regex, Flags);
7155ffd83dbSDimitry Andric   std::string Error;
7165ffd83dbSDimitry Andric   if (!SharedRegex->isValid(Error)) {
7175ffd83dbSDimitry Andric     llvm::WithColor::error()
7185ffd83dbSDimitry Andric         << "building matcher '" << MatcherID << "': " << Error << "\n";
7195ffd83dbSDimitry Andric     llvm::WithColor::note() << " input was '" << Regex << "'\n";
7205ffd83dbSDimitry Andric   }
7215ffd83dbSDimitry Andric   return SharedRegex;
7225ffd83dbSDimitry Andric }
7230b57cec5SDimitry Andric } // end namespace internal
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAutoreleasePoolStmt>
7260b57cec5SDimitry Andric     autoreleasePoolStmt;
7270b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
7280b57cec5SDimitry Andric     translationUnitDecl;
7290b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
7300b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
7310b57cec5SDimitry Andric     typedefNameDecl;
7320b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
7330b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
7340b57cec5SDimitry Andric     typeAliasTemplateDecl;
7350b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<Decl> decl;
736d409305fSDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, DecompositionDecl> decompositionDecl;
737fe6060f1SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, BindingDecl> bindingDecl;
7380b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
7390b57cec5SDimitry Andric     linkageSpecDecl;
7400b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
7410b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
7420b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
7430b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
7440b57cec5SDimitry Andric     namespaceAliasDecl;
7450b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
7460b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> cxxRecordDecl;
7470b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
7480b57cec5SDimitry Andric     classTemplateDecl;
7490b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl,
7500b57cec5SDimitry Andric                                             ClassTemplateSpecializationDecl>
7510b57cec5SDimitry Andric     classTemplateSpecializationDecl;
7520b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<
7530b57cec5SDimitry Andric     Decl, ClassTemplatePartialSpecializationDecl>
7540b57cec5SDimitry Andric     classTemplatePartialSpecializationDecl;
7550b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
7560b57cec5SDimitry Andric     declaratorDecl;
7570b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
7580b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
7590b57cec5SDimitry Andric     accessSpecDecl;
760fe6060f1SDimitry Andric const internal::VariadicAllOfMatcher<CXXBaseSpecifier> cxxBaseSpecifier;
7610b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
7620b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
763e8d8bef9SDimitry Andric const internal::VariadicAllOfMatcher<TemplateArgumentLoc> templateArgumentLoc;
7640b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<TemplateName> templateName;
7650b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, NonTypeTemplateParmDecl>
7660b57cec5SDimitry Andric     nonTypeTemplateParmDecl;
7670b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
7680b57cec5SDimitry Andric     templateTypeParmDecl;
769e8d8bef9SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTemplateParmDecl>
770e8d8bef9SDimitry Andric     templateTemplateParmDecl;
771e8d8bef9SDimitry Andric 
772349cc55cSDimitry Andric const internal::VariadicAllOfMatcher<LambdaCapture> lambdaCapture;
7730b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<QualType> qualType;
7740b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<Type> type;
7750b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
776349cc55cSDimitry Andric 
777349cc55cSDimitry Andric const internal::VariadicDynCastAllOfMatcher<TypeLoc, QualifiedTypeLoc>
778349cc55cSDimitry Andric     qualifiedTypeLoc;
779349cc55cSDimitry Andric const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>
780349cc55cSDimitry Andric     pointerTypeLoc;
781349cc55cSDimitry Andric const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
782349cc55cSDimitry Andric     referenceTypeLoc;
783349cc55cSDimitry Andric const internal::VariadicDynCastAllOfMatcher<TypeLoc,
784349cc55cSDimitry Andric                                             TemplateSpecializationTypeLoc>
785349cc55cSDimitry Andric     templateSpecializationTypeLoc;
786349cc55cSDimitry Andric const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
787349cc55cSDimitry Andric     elaboratedTypeLoc;
788349cc55cSDimitry Andric 
7890b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>
7900b57cec5SDimitry Andric     unaryExprOrTypeTraitExpr;
7910b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
7920b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
7930b57cec5SDimitry Andric     cxxConstructorDecl;
7940b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
7950b57cec5SDimitry Andric     cxxDestructorDecl;
7960b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
7970b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
7980b57cec5SDimitry Andric     enumConstantDecl;
7995ffd83dbSDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;
8000b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
8010b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
8020b57cec5SDimitry Andric     cxxConversionDecl;
80306c3fb27SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ConceptDecl> conceptDecl;
8040b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
8050b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
8060b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>
8070b57cec5SDimitry Andric     indirectFieldDecl;
8080b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
8090b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
8100b57cec5SDimitry Andric     functionTemplateDecl;
8110b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
8120b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<Stmt> stmt;
8130b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
8140b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
8150b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>
8160b57cec5SDimitry Andric     unresolvedMemberExpr;
8170b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDependentScopeMemberExpr>
8180b57cec5SDimitry Andric     cxxDependentScopeMemberExpr;
8190b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
8200b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
8210b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
8220b57cec5SDimitry Andric     cxxMemberCallExpr;
8230b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
8240b57cec5SDimitry Andric     objcMessageExpr;
8250b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
8260b57cec5SDimitry Andric     objcInterfaceDecl;
8270b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
8280b57cec5SDimitry Andric     objcImplementationDecl;
8290b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
8300b57cec5SDimitry Andric     objcProtocolDecl;
8310b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
8320b57cec5SDimitry Andric     objcCategoryDecl;
8330b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
8340b57cec5SDimitry Andric     objcCategoryImplDecl;
8350b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
8360b57cec5SDimitry Andric     objcMethodDecl;
8370b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>
8380b57cec5SDimitry Andric     blockDecl;
8390b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl;
8400b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
8410b57cec5SDimitry Andric     objcPropertyDecl;
8420b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
8430b57cec5SDimitry Andric     objcThrowStmt;
8440b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> objcTryStmt;
8450b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
8460b57cec5SDimitry Andric     objcCatchStmt;
8470b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
8480b57cec5SDimitry Andric     objcFinallyStmt;
8490b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
8500b57cec5SDimitry Andric     exprWithCleanups;
8510b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
8520b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStdInitializerListExpr>
8530b57cec5SDimitry Andric     cxxStdInitializerListExpr;
8540b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
8550b57cec5SDimitry Andric     implicitValueInitExpr;
8560b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;
8570b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
8580b57cec5SDimitry Andric     substNonTypeTemplateParmExpr;
8590b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
860fe6060f1SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, UsingEnumDecl> usingEnumDecl;
8610b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
8620b57cec5SDimitry Andric     usingDirectiveDecl;
8630b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
8640b57cec5SDimitry Andric     unresolvedLookupExpr;
8650b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl>
8660b57cec5SDimitry Andric     unresolvedUsingValueDecl;
8670b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>
8680b57cec5SDimitry Andric     unresolvedUsingTypenameDecl;
8690b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr> constantExpr;
8700b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
8710b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
8720b57cec5SDimitry Andric     cxxConstructExpr;
8730b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXUnresolvedConstructExpr>
8740b57cec5SDimitry Andric     cxxUnresolvedConstructExpr;
8750b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
8760b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
8770b57cec5SDimitry Andric     cxxBindTemporaryExpr;
8780b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr>
8790b57cec5SDimitry Andric     materializeTemporaryExpr;
8800b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
8810b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
8825ffd83dbSDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNoexceptExpr>
8835ffd83dbSDimitry Andric     cxxNoexceptExpr;
8840b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
8850b57cec5SDimitry Andric     arraySubscriptExpr;
88606c3fb27SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ArrayInitIndexExpr>
88706c3fb27SDimitry Andric     arrayInitIndexExpr;
88806c3fb27SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ArrayInitLoopExpr>
88906c3fb27SDimitry Andric     arrayInitLoopExpr;
8900b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
8910b57cec5SDimitry Andric     cxxDefaultArgExpr;
8920b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
8930b57cec5SDimitry Andric     cxxOperatorCallExpr;
894e8d8bef9SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXRewrittenBinaryOperator>
895e8d8bef9SDimitry Andric     cxxRewrittenBinaryOperator;
896*7a6dacacSDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr> cxxFoldExpr;
8970b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
8980b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
8990b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr> objcIvarRefExpr;
9000b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, BlockExpr> blockExpr;
9010b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
9020b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
9030b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
9040b57cec5SDimitry Andric     cxxForRangeStmt;
9050b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
9060b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
9070b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
9080b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
909fe6060f1SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CoreturnStmt> coreturnStmt;
9100b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
9110b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
9120b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
9130b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;
9140b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
9150b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
9160b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
9170b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
9180b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
91906c3fb27SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CoroutineBodyStmt>
92006c3fb27SDimitry Andric     coroutineBodyStmt;
9210b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
9220b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
9230b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
9240b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
9250b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
9260b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
9270b57cec5SDimitry Andric     cxxBoolLiteral;
9280b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral;
92981ad6265SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCStringLiteral> objcStringLiteral;
9300b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
9310b57cec5SDimitry Andric     characterLiteral;
9320b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
9330b57cec5SDimitry Andric     integerLiteral;
9340b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral;
9350b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral> imaginaryLiteral;
9365ffd83dbSDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, FixedPointLiteral>
9375ffd83dbSDimitry Andric     fixedPointLiteral;
9380b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
9390b57cec5SDimitry Andric     userDefinedLiteral;
9400b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
9410b57cec5SDimitry Andric     compoundLiteralExpr;
9420b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
9430b57cec5SDimitry Andric     cxxNullPtrLiteralExpr;
9440b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> chooseExpr;
9455f757f3fSDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ConvertVectorExpr>
9465f757f3fSDimitry Andric     convertVectorExpr;
947fe6060f1SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CoawaitExpr>
948fe6060f1SDimitry Andric     coawaitExpr;
949fe6060f1SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr>
950fe6060f1SDimitry Andric     dependentCoawaitExpr;
951fe6060f1SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr>
952fe6060f1SDimitry Andric     coyieldExpr;
9530b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
954e8d8bef9SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, GenericSelectionExpr>
955e8d8bef9SDimitry Andric     genericSelectionExpr;
9560b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
9570b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
9580b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
9590b57cec5SDimitry Andric     binaryOperator;
960e8d8bef9SDimitry Andric const internal::MapAnyOfMatcher<BinaryOperator, CXXOperatorCallExpr,
961e8d8bef9SDimitry Andric                                 CXXRewrittenBinaryOperator>
962e8d8bef9SDimitry Andric     binaryOperation;
963fe6060f1SDimitry Andric const internal::MapAnyOfMatcher<CallExpr, CXXConstructExpr> invocation;
9640b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator;
9650b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
9660b57cec5SDimitry Andric     conditionalOperator;
9670b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryConditionalOperator>
9680b57cec5SDimitry Andric     binaryConditionalOperator;
9690b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
9700b57cec5SDimitry Andric     opaqueValueExpr;
9710b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
9720b57cec5SDimitry Andric     staticAssertDecl;
9730b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
9740b57cec5SDimitry Andric     cxxReinterpretCastExpr;
9750b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
9760b57cec5SDimitry Andric     cxxStaticCastExpr;
9770b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
9780b57cec5SDimitry Andric     cxxDynamicCastExpr;
9790b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
9800b57cec5SDimitry Andric     cxxConstCastExpr;
9810b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
9820b57cec5SDimitry Andric     cStyleCastExpr;
9830b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
9840b57cec5SDimitry Andric     explicitCastExpr;
9850b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
9860b57cec5SDimitry Andric     implicitCastExpr;
9870b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
9880b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
9890b57cec5SDimitry Andric     cxxFunctionalCastExpr;
9900b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
9910b57cec5SDimitry Andric     cxxTemporaryObjectExpr;
9920b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
9930b57cec5SDimitry Andric     predefinedExpr;
9940b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
9950b57cec5SDimitry Andric     designatedInitExpr;
9960b57cec5SDimitry Andric const internal::VariadicOperatorMatcherFunc<
9970b57cec5SDimitry Andric     2, std::numeric_limits<unsigned>::max()>
9980b57cec5SDimitry Andric     eachOf = {internal::DynTypedMatcher::VO_EachOf};
9990b57cec5SDimitry Andric const internal::VariadicOperatorMatcherFunc<
10000b57cec5SDimitry Andric     2, std::numeric_limits<unsigned>::max()>
10010b57cec5SDimitry Andric     anyOf = {internal::DynTypedMatcher::VO_AnyOf};
10020b57cec5SDimitry Andric const internal::VariadicOperatorMatcherFunc<
10030b57cec5SDimitry Andric     2, std::numeric_limits<unsigned>::max()>
10040b57cec5SDimitry Andric     allOf = {internal::DynTypedMatcher::VO_AllOf};
10055ffd83dbSDimitry Andric const internal::VariadicOperatorMatcherFunc<1, 1> optionally = {
10065ffd83dbSDimitry Andric     internal::DynTypedMatcher::VO_Optionally};
10070b57cec5SDimitry Andric const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
10080b57cec5SDimitry Andric                                  internal::hasAnyNameFunc>
10090b57cec5SDimitry Andric     hasAnyName = {};
10105ffd83dbSDimitry Andric 
10115ffd83dbSDimitry Andric const internal::VariadicFunction<internal::HasOpNameMatcher, StringRef,
10125ffd83dbSDimitry Andric                                  internal::hasAnyOperatorNameFunc>
10135ffd83dbSDimitry Andric     hasAnyOperatorName = {};
10145ffd83dbSDimitry Andric const internal::VariadicFunction<internal::HasOverloadOpNameMatcher, StringRef,
10155ffd83dbSDimitry Andric                                  internal::hasAnyOverloadedOperatorNameFunc>
10165ffd83dbSDimitry Andric     hasAnyOverloadedOperatorName = {};
10170b57cec5SDimitry Andric const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, StringRef,
10180b57cec5SDimitry Andric                                  internal::hasAnySelectorFunc>
10190b57cec5SDimitry Andric     hasAnySelector = {};
10200b57cec5SDimitry Andric const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has = {};
10210b57cec5SDimitry Andric const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
10220b57cec5SDimitry Andric     hasDescendant = {};
10230b57cec5SDimitry Andric const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> forEach =
10240b57cec5SDimitry Andric     {};
10250b57cec5SDimitry Andric const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
10260b57cec5SDimitry Andric     forEachDescendant = {};
10270b57cec5SDimitry Andric const internal::ArgumentAdaptingMatcherFunc<
10280b57cec5SDimitry Andric     internal::HasParentMatcher,
1029349cc55cSDimitry Andric     internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
1030349cc55cSDimitry Andric     internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
10310b57cec5SDimitry Andric     hasParent = {};
10320b57cec5SDimitry Andric const internal::ArgumentAdaptingMatcherFunc<
10330b57cec5SDimitry Andric     internal::HasAncestorMatcher,
1034349cc55cSDimitry Andric     internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
1035349cc55cSDimitry Andric     internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
10360b57cec5SDimitry Andric     hasAncestor = {};
10370b57cec5SDimitry Andric const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
10380b57cec5SDimitry Andric     internal::DynTypedMatcher::VO_UnaryNot};
10390b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
10400b57cec5SDimitry Andric const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
10410b57cec5SDimitry Andric     nestedNameSpecifierLoc;
1042349cc55cSDimitry Andric const internal::VariadicAllOfMatcher<Attr> attr;
10430b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
10440b57cec5SDimitry Andric     cudaKernelCallExpr;
10450b57cec5SDimitry Andric const AstTypeMatcher<BuiltinType> builtinType;
10460b57cec5SDimitry Andric const AstTypeMatcher<ArrayType> arrayType;
10470b57cec5SDimitry Andric const AstTypeMatcher<ComplexType> complexType;
10480b57cec5SDimitry Andric const AstTypeMatcher<ConstantArrayType> constantArrayType;
10495ffd83dbSDimitry Andric const AstTypeMatcher<DeducedTemplateSpecializationType>
10505ffd83dbSDimitry Andric     deducedTemplateSpecializationType;
10510b57cec5SDimitry Andric const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
10525f757f3fSDimitry Andric const AstTypeMatcher<DependentSizedExtVectorType> dependentSizedExtVectorType;
10530b57cec5SDimitry Andric const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
10540b57cec5SDimitry Andric const AstTypeMatcher<VariableArrayType> variableArrayType;
10550b57cec5SDimitry Andric const AstTypeMatcher<AtomicType> atomicType;
10560b57cec5SDimitry Andric const AstTypeMatcher<AutoType> autoType;
10570b57cec5SDimitry Andric const AstTypeMatcher<DecltypeType> decltypeType;
10580b57cec5SDimitry Andric const AstTypeMatcher<FunctionType> functionType;
10590b57cec5SDimitry Andric const AstTypeMatcher<FunctionProtoType> functionProtoType;
10600b57cec5SDimitry Andric const AstTypeMatcher<ParenType> parenType;
10610b57cec5SDimitry Andric const AstTypeMatcher<BlockPointerType> blockPointerType;
10625f757f3fSDimitry Andric const AstTypeMatcher<MacroQualifiedType> macroQualifiedType;
10630b57cec5SDimitry Andric const AstTypeMatcher<MemberPointerType> memberPointerType;
10640b57cec5SDimitry Andric const AstTypeMatcher<PointerType> pointerType;
10650b57cec5SDimitry Andric const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
10660b57cec5SDimitry Andric const AstTypeMatcher<ReferenceType> referenceType;
10670b57cec5SDimitry Andric const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
10680b57cec5SDimitry Andric const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
10690b57cec5SDimitry Andric const AstTypeMatcher<TypedefType> typedefType;
10700b57cec5SDimitry Andric const AstTypeMatcher<EnumType> enumType;
10710b57cec5SDimitry Andric const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType;
10720b57cec5SDimitry Andric const AstTypeMatcher<UnaryTransformType> unaryTransformType;
10730b57cec5SDimitry Andric const AstTypeMatcher<RecordType> recordType;
10740b57cec5SDimitry Andric const AstTypeMatcher<TagType> tagType;
10750b57cec5SDimitry Andric const AstTypeMatcher<ElaboratedType> elaboratedType;
10760eae32dcSDimitry Andric const AstTypeMatcher<UsingType> usingType;
10770b57cec5SDimitry Andric const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
10780b57cec5SDimitry Andric const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
10790b57cec5SDimitry Andric const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
10800b57cec5SDimitry Andric const AstTypeMatcher<DecayedType> decayedType;
10810b57cec5SDimitry Andric AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasElementType,
10820b57cec5SDimitry Andric                                  AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
10830b57cec5SDimitry Andric                                                                  ComplexType));
10840b57cec5SDimitry Andric AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasValueType,
10850b57cec5SDimitry Andric                                  AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
10860b57cec5SDimitry Andric AST_TYPELOC_TRAVERSE_MATCHER_DEF(
10870b57cec5SDimitry Andric     pointee,
10880b57cec5SDimitry Andric     AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
10890b57cec5SDimitry Andric                                     PointerType, ReferenceType));
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>
10920b57cec5SDimitry Andric     ompExecutableDirective;
10930b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
10940b57cec5SDimitry Andric     ompDefaultClause;
10950b57cec5SDimitry Andric const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>
10960b57cec5SDimitry Andric     cxxDeductionGuideDecl;
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric } // end namespace ast_matchers
10990b57cec5SDimitry Andric } // end namespace clang
1100