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