1137 lines · cpp
1//===- ASTMatchersInternal.cpp - Structural query framework ---------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Implements the base layer of the matcher framework.10//11//===----------------------------------------------------------------------===//12 13#include "clang/ASTMatchers/ASTMatchersInternal.h"14#include "clang/AST/ASTContext.h"15#include "clang/AST/ASTTypeTraits.h"16#include "clang/AST/Decl.h"17#include "clang/AST/DeclTemplate.h"18#include "clang/AST/ExprConcepts.h"19#include "clang/AST/ParentMapContext.h"20#include "clang/AST/PrettyPrinter.h"21#include "clang/ASTMatchers/ASTMatchers.h"22#include "clang/Basic/LLVM.h"23#include "clang/Lex/Lexer.h"24#include "llvm/ADT/ArrayRef.h"25#include "llvm/ADT/DenseSet.h"26#include "llvm/ADT/IntrusiveRefCntPtr.h"27#include "llvm/ADT/SmallString.h"28#include "llvm/ADT/SmallVector.h"29#include "llvm/ADT/StringRef.h"30#include "llvm/Support/ErrorHandling.h"31#include "llvm/Support/Regex.h"32#include "llvm/Support/WithColor.h"33#include "llvm/Support/raw_ostream.h"34#include <cassert>35#include <cstddef>36#include <optional>37#include <string>38#include <utility>39#include <vector>40 41namespace clang {42namespace ast_matchers {43 44AST_MATCHER_P(ObjCMessageExpr, hasAnySelectorMatcher, std::vector<std::string>,45 Matches) {46 return llvm::is_contained(Matches, Node.getSelector().getAsString());47}48 49namespace internal {50 51static bool notUnaryOperator(const DynTypedNode &DynNode,52 ASTMatchFinder *Finder,53 BoundNodesTreeBuilder *Builder,54 ArrayRef<DynTypedMatcher> InnerMatchers);55 56static bool allOfVariadicOperator(const DynTypedNode &DynNode,57 ASTMatchFinder *Finder,58 BoundNodesTreeBuilder *Builder,59 ArrayRef<DynTypedMatcher> InnerMatchers);60 61static bool eachOfVariadicOperator(const DynTypedNode &DynNode,62 ASTMatchFinder *Finder,63 BoundNodesTreeBuilder *Builder,64 ArrayRef<DynTypedMatcher> InnerMatchers);65 66static bool anyOfVariadicOperator(const DynTypedNode &DynNode,67 ASTMatchFinder *Finder,68 BoundNodesTreeBuilder *Builder,69 ArrayRef<DynTypedMatcher> InnerMatchers);70 71static bool optionallyVariadicOperator(const DynTypedNode &DynNode,72 ASTMatchFinder *Finder,73 BoundNodesTreeBuilder *Builder,74 ArrayRef<DynTypedMatcher> InnerMatchers);75 76bool matchesAnyBase(const CXXRecordDecl &Node,77 const Matcher<CXXBaseSpecifier> &BaseSpecMatcher,78 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) {79 if (!Node.hasDefinition())80 return false;81 82 CXXBasePaths Paths;83 Paths.setOrigin(&Node);84 85 const auto basePredicate =86 [Finder, Builder, &BaseSpecMatcher](const CXXBaseSpecifier *BaseSpec,87 CXXBasePath &IgnoredParam) {88 BoundNodesTreeBuilder Result(*Builder);89 if (BaseSpecMatcher.matches(*BaseSpec, Finder, &Result)) {90 *Builder = std::move(Result);91 return true;92 }93 return false;94 };95 96 return Node.lookupInBases(basePredicate, Paths,97 /*LookupInDependent =*/true);98}99 100void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {101 if (Bindings.empty())102 Bindings.push_back(BoundNodesMap());103 for (BoundNodesMap &Binding : Bindings) {104 ResultVisitor->visitMatch(BoundNodes(Binding));105 }106}107 108namespace {109 110using VariadicOperatorFunction = bool (*)(111 const DynTypedNode &DynNode, ASTMatchFinder *Finder,112 BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);113 114template <VariadicOperatorFunction Func>115class VariadicMatcher : public DynMatcherInterface {116public:117 VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)118 : InnerMatchers(std::move(InnerMatchers)) {}119 120 bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,121 BoundNodesTreeBuilder *Builder) const override {122 return Func(DynNode, Finder, Builder, InnerMatchers);123 }124 125private:126 std::vector<DynTypedMatcher> InnerMatchers;127};128 129class IdDynMatcher : public DynMatcherInterface {130public:131 IdDynMatcher(StringRef ID,132 IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)133 : ID(ID), InnerMatcher(std::move(InnerMatcher)) {}134 135 bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,136 BoundNodesTreeBuilder *Builder) const override {137 bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder);138 if (Result) Builder->setBinding(ID, DynNode);139 return Result;140 }141 142 std::optional<clang::TraversalKind> TraversalKind() const override {143 return InnerMatcher->TraversalKind();144 }145 146private:147 const std::string ID;148 const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;149};150 151/// A matcher that always returns true.152class TrueMatcherImpl : public DynMatcherInterface {153public:154 TrueMatcherImpl() = default;155 156 bool dynMatches(const DynTypedNode &, ASTMatchFinder *,157 BoundNodesTreeBuilder *) const override {158 return true;159 }160};161 162/// A matcher that specifies a particular \c TraversalKind.163///164/// The kind provided to the constructor overrides any kind that may be165/// specified by the `InnerMatcher`.166class DynTraversalMatcherImpl : public DynMatcherInterface {167public:168 explicit DynTraversalMatcherImpl(169 clang::TraversalKind TK,170 IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)171 : TK(TK), InnerMatcher(std::move(InnerMatcher)) {}172 173 bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,174 BoundNodesTreeBuilder *Builder) const override {175 return this->InnerMatcher->dynMatches(DynNode, Finder, Builder);176 }177 178 std::optional<clang::TraversalKind> TraversalKind() const override {179 return TK;180 }181 182private:183 clang::TraversalKind TK;184 IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;185};186 187} // namespace188 189bool ASTMatchFinder::isTraversalIgnoringImplicitNodes() const {190 return getASTContext().getParentMapContext().getTraversalKind() ==191 TK_IgnoreUnlessSpelledInSource;192}193 194DynTypedMatcher195DynTypedMatcher::constructVariadic(DynTypedMatcher::VariadicOperator Op,196 ASTNodeKind SupportedKind,197 std::vector<DynTypedMatcher> InnerMatchers) {198 assert(!InnerMatchers.empty() && "Array must not be empty.");199 assert(llvm::all_of(InnerMatchers,200 [SupportedKind](const DynTypedMatcher &M) {201 return M.canConvertTo(SupportedKind);202 }) &&203 "InnerMatchers must be convertible to SupportedKind!");204 205 // We must relax the restrict kind here.206 // The different operators might deal differently with a mismatch.207 // Make it the same as SupportedKind, since that is the broadest type we are208 // allowed to accept.209 auto RestrictKind = SupportedKind;210 211 switch (Op) {212 case VO_AllOf:213 // In the case of allOf() we must pass all the checks, so making214 // RestrictKind the most restrictive can save us time. This way we reject215 // invalid types earlier and we can elide the kind checks inside the216 // matcher.217 for (auto &IM : InnerMatchers) {218 RestrictKind =219 ASTNodeKind::getMostDerivedType(RestrictKind, IM.RestrictKind);220 }221 return DynTypedMatcher(222 SupportedKind, RestrictKind,223 new VariadicMatcher<allOfVariadicOperator>(std::move(InnerMatchers)));224 225 case VO_AnyOf:226 return DynTypedMatcher(227 SupportedKind, RestrictKind,228 new VariadicMatcher<anyOfVariadicOperator>(std::move(InnerMatchers)));229 230 case VO_EachOf:231 return DynTypedMatcher(232 SupportedKind, RestrictKind,233 new VariadicMatcher<eachOfVariadicOperator>(std::move(InnerMatchers)));234 235 case VO_Optionally:236 return DynTypedMatcher(SupportedKind, RestrictKind,237 new VariadicMatcher<optionallyVariadicOperator>(238 std::move(InnerMatchers)));239 240 case VO_UnaryNot:241 // FIXME: Implement the Not operator to take a single matcher instead of a242 // vector.243 return DynTypedMatcher(244 SupportedKind, RestrictKind,245 new VariadicMatcher<notUnaryOperator>(std::move(InnerMatchers)));246 }247 llvm_unreachable("Invalid Op value.");248}249 250DynTypedMatcher251DynTypedMatcher::constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,252 ASTNodeKind RestrictKind) {253 DynTypedMatcher Copy = InnerMatcher;254 Copy.RestrictKind = RestrictKind;255 return Copy;256}257 258DynTypedMatcher DynTypedMatcher::withTraversalKind(TraversalKind TK) {259 auto Copy = *this;260 Copy.Implementation =261 new DynTraversalMatcherImpl(TK, std::move(Copy.Implementation));262 return Copy;263}264 265DynTypedMatcher DynTypedMatcher::trueMatcher(ASTNodeKind NodeKind) {266 // We only ever need one instance of TrueMatcherImpl, so we create a static267 // instance and reuse it to reduce the overhead of the matcher and increase268 // the chance of cache hits.269 static const llvm::IntrusiveRefCntPtr<TrueMatcherImpl> Instance =270 new TrueMatcherImpl();271 return DynTypedMatcher(NodeKind, NodeKind, Instance);272}273 274bool DynTypedMatcher::canMatchNodesOfKind(ASTNodeKind Kind) const {275 return RestrictKind.isBaseOf(Kind);276}277 278DynTypedMatcher DynTypedMatcher::dynCastTo(const ASTNodeKind Kind) const {279 auto Copy = *this;280 Copy.SupportedKind = Kind;281 Copy.RestrictKind = ASTNodeKind::getMostDerivedType(Kind, RestrictKind);282 return Copy;283}284 285bool DynTypedMatcher::matches(const DynTypedNode &DynNode,286 ASTMatchFinder *Finder,287 BoundNodesTreeBuilder *Builder) const {288 TraversalKindScope RAII(Finder->getASTContext(),289 Implementation->TraversalKind());290 291 if (Finder->isTraversalIgnoringImplicitNodes() &&292 Finder->IsMatchingInASTNodeNotSpelledInSource())293 return false;294 295 if (!Finder->isTraversalIgnoringImplicitNodes() &&296 Finder->IsMatchingInASTNodeNotAsIs())297 return false;298 299 auto N =300 Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);301 302 if (RestrictKind.isBaseOf(N.getNodeKind()) &&303 Implementation->dynMatches(N, Finder, Builder)) {304 return true;305 }306 // Delete all bindings when a matcher does not match.307 // This prevents unexpected exposure of bound nodes in unmatches308 // branches of the match tree.309 Builder->removeBindings([](const BoundNodesMap &) { return true; });310 return false;311}312 313bool DynTypedMatcher::matchesNoKindCheck(const DynTypedNode &DynNode,314 ASTMatchFinder *Finder,315 BoundNodesTreeBuilder *Builder) const {316 TraversalKindScope raii(Finder->getASTContext(),317 Implementation->TraversalKind());318 319 if (Finder->isTraversalIgnoringImplicitNodes() &&320 Finder->IsMatchingInASTNodeNotSpelledInSource())321 return false;322 323 if (!Finder->isTraversalIgnoringImplicitNodes() &&324 Finder->IsMatchingInASTNodeNotAsIs())325 return false;326 327 auto N =328 Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);329 330 assert(RestrictKind.isBaseOf(N.getNodeKind()));331 if (Implementation->dynMatches(N, Finder, Builder)) {332 return true;333 }334 // Delete all bindings when a matcher does not match.335 // This prevents unexpected exposure of bound nodes in unmatches336 // branches of the match tree.337 Builder->removeBindings([](const BoundNodesMap &) { return true; });338 return false;339}340 341std::optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {342 if (!AllowBind)343 return std::nullopt;344 auto Result = *this;345 Result.Implementation =346 new IdDynMatcher(ID, std::move(Result.Implementation));347 return std::move(Result);348}349 350bool DynTypedMatcher::canConvertTo(ASTNodeKind To) const {351 const auto From = getSupportedKind();352 auto QualKind = ASTNodeKind::getFromNodeKind<QualType>();353 auto TypeKind = ASTNodeKind::getFromNodeKind<Type>();354 /// Mimic the implicit conversions of Matcher<>.355 /// - From Matcher<Type> to Matcher<QualType>356 if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;357 /// - From Matcher<Base> to Matcher<Derived>358 return From.isBaseOf(To);359}360 361void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {362 Bindings.append(Other.Bindings.begin(), Other.Bindings.end());363}364 365static bool notUnaryOperator(const DynTypedNode &DynNode,366 ASTMatchFinder *Finder,367 BoundNodesTreeBuilder *Builder,368 ArrayRef<DynTypedMatcher> InnerMatchers) {369 if (InnerMatchers.size() != 1)370 return false;371 372 // The 'unless' matcher will always discard the result:373 // If the inner matcher doesn't match, unless returns true,374 // but the inner matcher cannot have bound anything.375 // If the inner matcher matches, the result is false, and376 // any possible binding will be discarded.377 // We still need to hand in all the bound nodes up to this378 // point so the inner matcher can depend on bound nodes,379 // and we need to actively discard the bound nodes, otherwise380 // the inner matcher will reset the bound nodes if it doesn't381 // match, but this would be inversed by 'unless'.382 BoundNodesTreeBuilder Discard(*Builder);383 return !InnerMatchers[0].matches(DynNode, Finder, &Discard);384}385 386static bool allOfVariadicOperator(const DynTypedNode &DynNode,387 ASTMatchFinder *Finder,388 BoundNodesTreeBuilder *Builder,389 ArrayRef<DynTypedMatcher> InnerMatchers) {390 // allOf leads to one matcher for each alternative in the first391 // matcher combined with each alternative in the second matcher.392 // Thus, we can reuse the same Builder.393 return llvm::all_of(InnerMatchers, [&](const DynTypedMatcher &InnerMatcher) {394 return InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder);395 });396}397 398static bool eachOfVariadicOperator(const DynTypedNode &DynNode,399 ASTMatchFinder *Finder,400 BoundNodesTreeBuilder *Builder,401 ArrayRef<DynTypedMatcher> InnerMatchers) {402 BoundNodesTreeBuilder Result;403 bool Matched = false;404 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {405 BoundNodesTreeBuilder BuilderInner(*Builder);406 if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) {407 Matched = true;408 Result.addMatch(BuilderInner);409 }410 }411 *Builder = std::move(Result);412 return Matched;413}414 415static bool anyOfVariadicOperator(const DynTypedNode &DynNode,416 ASTMatchFinder *Finder,417 BoundNodesTreeBuilder *Builder,418 ArrayRef<DynTypedMatcher> InnerMatchers) {419 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {420 BoundNodesTreeBuilder Result = *Builder;421 if (InnerMatcher.matches(DynNode, Finder, &Result)) {422 *Builder = std::move(Result);423 return true;424 }425 }426 return false;427}428 429static bool430optionallyVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,431 BoundNodesTreeBuilder *Builder,432 ArrayRef<DynTypedMatcher> InnerMatchers) {433 if (InnerMatchers.size() != 1)434 return false;435 436 BoundNodesTreeBuilder Result(*Builder);437 if (InnerMatchers[0].matches(DynNode, Finder, &Result))438 *Builder = std::move(Result);439 return true;440}441 442inline static443std::vector<std::string> vectorFromRefs(ArrayRef<const StringRef *> NameRefs) {444 std::vector<std::string> Names;445 Names.reserve(NameRefs.size());446 for (auto *Name : NameRefs)447 Names.emplace_back(*Name);448 return Names;449}450 451Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs) {452 return internal::Matcher<NamedDecl>(453 new internal::HasNameMatcher(vectorFromRefs(NameRefs)));454}455 456Matcher<ObjCMessageExpr> hasAnySelectorFunc(457 ArrayRef<const StringRef *> NameRefs) {458 return hasAnySelectorMatcher(vectorFromRefs(NameRefs));459}460 461HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {462 return HasOpNameMatcher(vectorFromRefs(NameRefs));463}464 465HasOverloadOpNameMatcher466hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs) {467 return HasOverloadOpNameMatcher(vectorFromRefs(NameRefs));468}469 470HasNameMatcher::HasNameMatcher(std::vector<std::string> N)471 : UseUnqualifiedMatch(472 llvm::all_of(N, [](StringRef Name) { return !Name.contains("::"); })),473 Names(std::move(N)) {474#ifndef NDEBUG475 for (StringRef Name : Names)476 assert(!Name.empty());477#endif478}479 480static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {481 StringRef Name = FullName;482 if (!Name.ends_with(Suffix))483 return false;484 Name = Name.drop_back(Suffix.size());485 if (!Name.empty()) {486 if (!Name.ends_with("::"))487 return false;488 Name = Name.drop_back(2);489 }490 FullName = Name;491 return true;492}493 494static StringRef getNodeName(const NamedDecl &Node,495 llvm::SmallString<128> &Scratch) {496 // Simple name.497 if (Node.getIdentifier())498 return Node.getName();499 500 if (Node.getDeclName()) {501 // Name needs to be constructed.502 Scratch.clear();503 llvm::raw_svector_ostream OS(Scratch);504 Node.printName(OS);505 return OS.str();506 }507 508 return "(anonymous)";509}510 511static StringRef getNodeName(const RecordDecl &Node,512 llvm::SmallString<128> &Scratch) {513 if (Node.getIdentifier()) {514 return Node.getName();515 }516 Scratch.clear();517 return ("(anonymous " + Node.getKindName() + ")").toStringRef(Scratch);518}519 520static StringRef getNodeName(const NamespaceDecl &Node,521 llvm::SmallString<128> &Scratch) {522 return Node.isAnonymousNamespace() ? "(anonymous namespace)" : Node.getName();523}524 525namespace {526 527class PatternSet {528public:529 PatternSet(ArrayRef<std::string> Names) {530 Patterns.reserve(Names.size());531 for (StringRef Name : Names)532 Patterns.push_back({Name, Name.starts_with("::")});533 }534 535 /// Consumes the name suffix from each pattern in the set and removes the ones536 /// that didn't match.537 /// Return true if there are still any patterns left.538 bool consumeNameSuffix(StringRef NodeName, bool CanSkip) {539 if (CanSkip) {540 // If we can skip the node, then we need to handle the case where a541 // skipped node has the same name as its parent.542 // namespace a { inline namespace a { class A; } }543 // cxxRecordDecl(hasName("::a::A"))544 // To do this, any patterns that match should be duplicated in our set,545 // one of them with the tail removed.546 for (size_t I = 0, E = Patterns.size(); I != E; ++I) {547 StringRef Pattern = Patterns[I].P;548 if (ast_matchers::internal::consumeNameSuffix(Patterns[I].P, NodeName))549 Patterns.push_back({Pattern, Patterns[I].IsFullyQualified});550 }551 } else {552 llvm::erase_if(Patterns, [&NodeName](auto &Pattern) {553 return !::clang::ast_matchers::internal::consumeNameSuffix(Pattern.P,554 NodeName);555 });556 }557 return !Patterns.empty();558 }559 560 /// Check if any of the patterns are a match.561 /// A match will be a pattern that was fully consumed, that also matches the562 /// 'fully qualified' requirement.563 bool foundMatch(bool AllowFullyQualified) const {564 return llvm::any_of(Patterns, [&](const Pattern &Pattern) {565 return Pattern.P.empty() &&566 (AllowFullyQualified || !Pattern.IsFullyQualified);567 });568 }569 570private:571 struct Pattern {572 StringRef P;573 bool IsFullyQualified;574 };575 576 llvm::SmallVector<Pattern, 8> Patterns;577};578 579} // namespace580 581bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {582 assert(UseUnqualifiedMatch);583 llvm::SmallString<128> Scratch;584 StringRef NodeName = getNodeName(Node, Scratch);585 return llvm::any_of(Names, [&](StringRef Name) {586 return consumeNameSuffix(Name, NodeName) && Name.empty();587 });588}589 590bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const {591 PatternSet Patterns(Names);592 llvm::SmallString<128> Scratch;593 594 // This function is copied and adapted from NamedDecl::printQualifiedName()595 // By matching each part individually we optimize in a couple of ways:596 // - We can exit early on the first failure.597 // - We can skip inline/anonymous namespaces without another pass.598 // - We print one name at a time, reducing the chance of overflowing the599 // inlined space of the SmallString.600 601 // First, match the name.602 if (!Patterns.consumeNameSuffix(getNodeName(Node, Scratch),603 /*CanSkip=*/false))604 return false;605 606 // Try to match each declaration context.607 // We are allowed to skip anonymous and inline namespaces if they don't match.608 const DeclContext *Ctx = Node.getDeclContext();609 610 if (Ctx->isFunctionOrMethod())611 return Patterns.foundMatch(/*AllowFullyQualified=*/false);612 613 for (; Ctx; Ctx = Ctx->getParent()) {614 // Linkage Spec can just be ignored615 // FIXME: Any other DeclContext kinds that can be safely disregarded616 if (isa<LinkageSpecDecl>(Ctx))617 continue;618 if (!isa<NamedDecl>(Ctx))619 break;620 if (Patterns.foundMatch(/*AllowFullyQualified=*/false))621 return true;622 623 if (const auto *ND = dyn_cast<NamespaceDecl>(Ctx)) {624 // If it matches (or we can skip it), continue.625 if (Patterns.consumeNameSuffix(getNodeName(*ND, Scratch),626 /*CanSkip=*/ND->isAnonymousNamespace() ||627 ND->isInline()))628 continue;629 return false;630 }631 if (const auto *RD = dyn_cast<RecordDecl>(Ctx)) {632 if (!isa<ClassTemplateSpecializationDecl>(Ctx)) {633 if (Patterns.consumeNameSuffix(getNodeName(*RD, Scratch),634 /*CanSkip=*/false))635 continue;636 637 return false;638 }639 }640 641 // We don't know how to deal with this DeclContext.642 // Fallback to the slow version of the code.643 return matchesNodeFullSlow(Node);644 }645 646 return Patterns.foundMatch(/*AllowFullyQualified=*/true);647}648 649bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const {650 const bool SkipUnwrittenCases[] = {false, true};651 for (bool SkipUnwritten : SkipUnwrittenCases) {652 llvm::SmallString<128> NodeName = StringRef("::");653 llvm::raw_svector_ostream OS(NodeName);654 655 PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy();656 Policy.SuppressUnwrittenScope = SkipUnwritten;657 Policy.SuppressInlineNamespace =658 SkipUnwritten ? PrintingPolicy::SuppressInlineNamespaceMode::All659 : PrintingPolicy::SuppressInlineNamespaceMode::None;660 Node.printQualifiedName(OS, Policy);661 662 const StringRef FullName = OS.str();663 664 for (const StringRef Pattern : Names) {665 if (Pattern.starts_with("::")) {666 if (FullName == Pattern)667 return true;668 } else if (FullName.ends_with(Pattern) &&669 FullName.drop_back(Pattern.size()).ends_with("::")) {670 return true;671 }672 }673 }674 675 return false;676}677 678bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {679 assert(matchesNodeFullFast(Node) == matchesNodeFullSlow(Node));680 if (UseUnqualifiedMatch) {681 assert(matchesNodeUnqualified(Node) == matchesNodeFullFast(Node));682 return matchesNodeUnqualified(Node);683 }684 return matchesNodeFullFast(Node);685}686 687// Checks whether \p Loc points to a token with source text of \p TokenText.688static bool isTokenAtLoc(const SourceManager &SM, const LangOptions &LangOpts,689 StringRef Text, SourceLocation Loc) {690 llvm::SmallString<16> Buffer;691 bool Invalid = false;692 // Since `Loc` may point into an expansion buffer, which has no corresponding693 // source, we need to look at the spelling location to read the actual source.694 StringRef TokenText = Lexer::getSpelling(SM.getSpellingLoc(Loc), Buffer, SM,695 LangOpts, &Invalid);696 return !Invalid && Text == TokenText;697}698 699static std::optional<SourceLocation> getExpansionLocOfMacroRecursive(700 StringRef MacroName, SourceLocation Loc, const ASTContext &Context,701 llvm::DenseSet<SourceLocation> &CheckedLocations) {702 auto &SM = Context.getSourceManager();703 const LangOptions &LangOpts = Context.getLangOpts();704 while (Loc.isMacroID()) {705 if (CheckedLocations.count(Loc))706 return std::nullopt;707 CheckedLocations.insert(Loc);708 SrcMgr::ExpansionInfo Expansion =709 SM.getSLocEntry(SM.getFileID(Loc)).getExpansion();710 if (Expansion.isMacroArgExpansion()) {711 // Check macro argument for an expansion of the given macro. For example,712 // `F(G(3))`, where `MacroName` is `G`.713 if (std::optional<SourceLocation> ArgLoc =714 getExpansionLocOfMacroRecursive(MacroName,715 Expansion.getSpellingLoc(),716 Context, CheckedLocations)) {717 return ArgLoc;718 }719 }720 Loc = Expansion.getExpansionLocStart();721 if (isTokenAtLoc(SM, LangOpts, MacroName, Loc))722 return Loc;723 }724 return std::nullopt;725}726 727std::optional<SourceLocation>728getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,729 const ASTContext &Context) {730 llvm::DenseSet<SourceLocation> CheckedLocations;731 return getExpansionLocOfMacroRecursive(MacroName, Loc, Context,732 CheckedLocations);733}734 735std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,736 llvm::Regex::RegexFlags Flags,737 StringRef MatcherID) {738 assert(!Regex.empty() && "Empty regex string");739 auto SharedRegex = std::make_shared<llvm::Regex>(Regex, Flags);740 std::string Error;741 if (!SharedRegex->isValid(Error)) {742 llvm::WithColor::error()743 << "building matcher '" << MatcherID << "': " << Error << "\n";744 llvm::WithColor::note() << " input was '" << Regex << "'\n";745 }746 return SharedRegex;747}748} // end namespace internal749 750const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAutoreleasePoolStmt>751 autoreleasePoolStmt;752const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>753 translationUnitDecl;754const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;755const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>756 typedefNameDecl;757const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;758const internal::VariadicDynCastAllOfMatcher<Decl, UsingShadowDecl>759 usingShadowDecl;760const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>761 typeAliasTemplateDecl;762const internal::VariadicAllOfMatcher<Decl> decl;763const internal::VariadicDynCastAllOfMatcher<Decl, DecompositionDecl> decompositionDecl;764const internal::VariadicDynCastAllOfMatcher<Decl, BindingDecl> bindingDecl;765const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>766 linkageSpecDecl;767const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;768const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;769const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;770const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>771 namespaceAliasDecl;772const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;773const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> cxxRecordDecl;774const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>775 classTemplateDecl;776const internal::VariadicDynCastAllOfMatcher<Decl,777 ClassTemplateSpecializationDecl>778 classTemplateSpecializationDecl;779const internal::VariadicDynCastAllOfMatcher<780 Decl, ClassTemplatePartialSpecializationDecl>781 classTemplatePartialSpecializationDecl;782const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>783 declaratorDecl;784const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;785const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>786 accessSpecDecl;787const internal::VariadicAllOfMatcher<CXXBaseSpecifier> cxxBaseSpecifier;788const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;789const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;790const internal::VariadicAllOfMatcher<TemplateArgumentLoc> templateArgumentLoc;791const internal::VariadicAllOfMatcher<TemplateName> templateName;792const internal::VariadicDynCastAllOfMatcher<Decl, NonTypeTemplateParmDecl>793 nonTypeTemplateParmDecl;794const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>795 templateTypeParmDecl;796const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTemplateParmDecl>797 templateTemplateParmDecl;798 799const internal::VariadicAllOfMatcher<LambdaCapture> lambdaCapture;800const internal::VariadicAllOfMatcher<QualType> qualType;801const internal::VariadicAllOfMatcher<Type> type;802const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;803 804const internal::VariadicDynCastAllOfMatcher<TypeLoc, QualifiedTypeLoc>805 qualifiedTypeLoc;806const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>807 pointerTypeLoc;808const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>809 referenceTypeLoc;810const internal::VariadicDynCastAllOfMatcher<TypeLoc, ArrayTypeLoc> arrayTypeLoc;811const internal::VariadicDynCastAllOfMatcher<TypeLoc,812 TemplateSpecializationTypeLoc>813 templateSpecializationTypeLoc;814 815const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>816 unaryExprOrTypeTraitExpr;817const internal::VariadicDynCastAllOfMatcher<Decl, ExportDecl> exportDecl;818const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;819const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>820 cxxConstructorDecl;821const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>822 cxxDestructorDecl;823const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;824const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>825 enumConstantDecl;826const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;827const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;828const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>829 cxxConversionDecl;830const internal::VariadicDynCastAllOfMatcher<Decl, ConceptDecl> conceptDecl;831const internal::VariadicDynCastAllOfMatcher<Expr, RequiresExpr> requiresExpr;832const internal::VariadicDynCastAllOfMatcher<Decl, RequiresExprBodyDecl>833 requiresExprBodyDecl;834const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;835const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;836const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>837 indirectFieldDecl;838const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;839const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>840 functionTemplateDecl;841const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;842const internal::VariadicAllOfMatcher<Stmt> stmt;843const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;844const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;845const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedMemberExpr>846 unresolvedMemberExpr;847const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDependentScopeMemberExpr>848 cxxDependentScopeMemberExpr;849const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;850const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;851const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>852 cxxMemberCallExpr;853const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>854 objcMessageExpr;855const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>856 objcInterfaceDecl;857const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>858 objcImplementationDecl;859const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>860 objcProtocolDecl;861const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>862 objcCategoryDecl;863const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>864 objcCategoryImplDecl;865const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>866 objcMethodDecl;867const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>868 blockDecl;869const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl;870const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>871 objcPropertyDecl;872const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>873 objcThrowStmt;874const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> objcTryStmt;875const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>876 objcCatchStmt;877const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>878 objcFinallyStmt;879const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>880 exprWithCleanups;881const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;882const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStdInitializerListExpr>883 cxxStdInitializerListExpr;884const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>885 implicitValueInitExpr;886const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;887const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>888 substNonTypeTemplateParmExpr;889const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;890const internal::VariadicDynCastAllOfMatcher<Decl, UsingEnumDecl> usingEnumDecl;891const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>892 usingDirectiveDecl;893const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>894 unresolvedLookupExpr;895const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl>896 unresolvedUsingValueDecl;897const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>898 unresolvedUsingTypenameDecl;899const internal::VariadicDynCastAllOfMatcher<Stmt, ConstantExpr> constantExpr;900const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;901const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>902 cxxConstructExpr;903const internal::VariadicDynCastAllOfMatcher<Stmt, CXXUnresolvedConstructExpr>904 cxxUnresolvedConstructExpr;905const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;906const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>907 cxxBindTemporaryExpr;908const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr>909 materializeTemporaryExpr;910const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;911const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;912const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNoexceptExpr>913 cxxNoexceptExpr;914const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>915 arraySubscriptExpr;916const internal::VariadicDynCastAllOfMatcher<Stmt, ArrayInitIndexExpr>917 arrayInitIndexExpr;918const internal::VariadicDynCastAllOfMatcher<Stmt, ArrayInitLoopExpr>919 arrayInitLoopExpr;920const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>921 cxxDefaultArgExpr;922const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>923 cxxOperatorCallExpr;924const internal::VariadicDynCastAllOfMatcher<Stmt, CXXRewrittenBinaryOperator>925 cxxRewrittenBinaryOperator;926const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr> cxxFoldExpr;927const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;928const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;929const internal::VariadicDynCastAllOfMatcher<Stmt, DependentScopeDeclRefExpr>930 dependentScopeDeclRefExpr;931const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCIvarRefExpr> objcIvarRefExpr;932const internal::VariadicDynCastAllOfMatcher<Stmt, BlockExpr> blockExpr;933const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;934const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;935const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>936 cxxForRangeStmt;937const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;938const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;939const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;940const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;941const internal::VariadicDynCastAllOfMatcher<Stmt, CoreturnStmt> coreturnStmt;942const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;943const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;944const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;945const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;946const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;947const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;948const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;949const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;950const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;951const internal::VariadicDynCastAllOfMatcher<Stmt, CoroutineBodyStmt>952 coroutineBodyStmt;953const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;954const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;955const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;956const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;957const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;958const internal::VariadicDynCastAllOfMatcher<Decl, FileScopeAsmDecl>959 fileScopeAsmDecl;960const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>961 cxxBoolLiteral;962const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral;963const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCStringLiteral> objcStringLiteral;964const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>965 characterLiteral;966const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>967 integerLiteral;968const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral;969const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral> imaginaryLiteral;970const internal::VariadicDynCastAllOfMatcher<Stmt, FixedPointLiteral>971 fixedPointLiteral;972const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>973 userDefinedLiteral;974const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>975 compoundLiteralExpr;976const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>977 cxxNullPtrLiteralExpr;978const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> chooseExpr;979const internal::VariadicDynCastAllOfMatcher<Stmt, ConvertVectorExpr>980 convertVectorExpr;981const internal::VariadicDynCastAllOfMatcher<Stmt, CoawaitExpr>982 coawaitExpr;983const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr>984 dependentCoawaitExpr;985const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr>986 coyieldExpr;987const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;988const internal::VariadicDynCastAllOfMatcher<Stmt, GenericSelectionExpr>989 genericSelectionExpr;990const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;991const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;992const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>993 binaryOperator;994const internal::MapAnyOfMatcher<BinaryOperator, CXXOperatorCallExpr,995 CXXRewrittenBinaryOperator>996 binaryOperation;997const internal::MapAnyOfMatcher<CallExpr, CXXConstructExpr> invocation;998const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator;999const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>1000 conditionalOperator;1001const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryConditionalOperator>1002 binaryConditionalOperator;1003const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>1004 opaqueValueExpr;1005const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>1006 staticAssertDecl;1007const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>1008 cxxReinterpretCastExpr;1009const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>1010 cxxStaticCastExpr;1011const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>1012 cxxDynamicCastExpr;1013const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>1014 cxxConstCastExpr;1015const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNamedCastExpr>1016 cxxNamedCastExpr;1017const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>1018 cStyleCastExpr;1019const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>1020 explicitCastExpr;1021const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>1022 implicitCastExpr;1023const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;1024const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>1025 cxxFunctionalCastExpr;1026const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>1027 cxxTemporaryObjectExpr;1028const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>1029 predefinedExpr;1030const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>1031 designatedInitExpr;1032const internal::VariadicOperatorMatcherFunc<1033 2, std::numeric_limits<unsigned>::max()>1034 eachOf = {internal::DynTypedMatcher::VO_EachOf};1035const internal::VariadicOperatorMatcherFunc<1036 2, std::numeric_limits<unsigned>::max()>1037 anyOf = {internal::DynTypedMatcher::VO_AnyOf};1038const internal::VariadicOperatorMatcherFunc<1039 2, std::numeric_limits<unsigned>::max()>1040 allOf = {internal::DynTypedMatcher::VO_AllOf};1041const internal::VariadicOperatorMatcherFunc<1, 1> optionally = {1042 internal::DynTypedMatcher::VO_Optionally};1043const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,1044 internal::hasAnyNameFunc>1045 hasAnyName = {};1046 1047const internal::VariadicFunction<internal::HasOpNameMatcher, StringRef,1048 internal::hasAnyOperatorNameFunc>1049 hasAnyOperatorName = {};1050const internal::VariadicFunction<internal::HasOverloadOpNameMatcher, StringRef,1051 internal::hasAnyOverloadedOperatorNameFunc>1052 hasAnyOverloadedOperatorName = {};1053const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, StringRef,1054 internal::hasAnySelectorFunc>1055 hasAnySelector = {};1056const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has = {};1057const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>1058 hasDescendant = {};1059const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> forEach =1060 {};1061const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>1062 forEachDescendant = {};1063const internal::ArgumentAdaptingMatcherFunc<1064 internal::HasParentMatcher,1065 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,1066 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>1067 hasParent = {};1068const internal::ArgumentAdaptingMatcherFunc<1069 internal::HasAncestorMatcher,1070 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,1071 internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>1072 hasAncestor = {};1073const internal::VariadicOperatorMatcherFunc<1, 1> unless = {1074 internal::DynTypedMatcher::VO_UnaryNot};1075const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;1076const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>1077 nestedNameSpecifierLoc;1078const internal::VariadicAllOfMatcher<Attr> attr;1079const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>1080 cudaKernelCallExpr;1081const AstTypeMatcher<BuiltinType> builtinType;1082const AstTypeMatcher<ArrayType> arrayType;1083const AstTypeMatcher<ComplexType> complexType;1084const AstTypeMatcher<ConstantArrayType> constantArrayType;1085const AstTypeMatcher<DeducedTemplateSpecializationType>1086 deducedTemplateSpecializationType;1087const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;1088const AstTypeMatcher<DependentSizedExtVectorType> dependentSizedExtVectorType;1089const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;1090const AstTypeMatcher<VariableArrayType> variableArrayType;1091const AstTypeMatcher<AtomicType> atomicType;1092const AstTypeMatcher<AutoType> autoType;1093const AstTypeMatcher<DecltypeType> decltypeType;1094const AstTypeMatcher<FunctionType> functionType;1095const AstTypeMatcher<FunctionProtoType> functionProtoType;1096const AstTypeMatcher<ParenType> parenType;1097const AstTypeMatcher<BlockPointerType> blockPointerType;1098const AstTypeMatcher<MacroQualifiedType> macroQualifiedType;1099const AstTypeMatcher<MemberPointerType> memberPointerType;1100const AstTypeMatcher<PointerType> pointerType;1101const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;1102const AstTypeMatcher<ReferenceType> referenceType;1103const AstTypeMatcher<LValueReferenceType> lValueReferenceType;1104const AstTypeMatcher<RValueReferenceType> rValueReferenceType;1105const AstTypeMatcher<TypedefType> typedefType;1106const AstTypeMatcher<EnumType> enumType;1107const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType;1108const AstTypeMatcher<UnaryTransformType> unaryTransformType;1109const AstTypeMatcher<RecordType> recordType;1110const AstTypeMatcher<TagType> tagType;1111const AstTypeMatcher<UsingType> usingType;1112const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;1113const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;1114const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;1115const AstTypeMatcher<DecayedType> decayedType;1116const AstTypeMatcher<DependentNameType> dependentNameType;1117AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasElementType,1118 AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,1119 ComplexType));1120AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasValueType,1121 AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));1122AST_TYPELOC_TRAVERSE_MATCHER_DEF(1123 pointee,1124 AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,1125 PointerType, ReferenceType,1126 ObjCObjectPointerType));1127 1128const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>1129 ompExecutableDirective;1130const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>1131 ompDefaultClause;1132const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>1133 cxxDeductionGuideDecl;1134 1135} // end namespace ast_matchers1136} // end namespace clang1137