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