1 //===--- ASTMatchFinder.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 an algorithm to efficiently search for matches on AST nodes. 10 // Uses memoization to support recursive matches like HasDescendant. 11 // 12 // The general idea is to visit all AST nodes with a RecursiveASTVisitor, 13 // calling the Matches(...) method of each matcher we are running on each 14 // AST node. The matcher can recurse via the ASTMatchFinder interface. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "clang/ASTMatchers/ASTMatchFinder.h" 19 #include "clang/AST/ASTConsumer.h" 20 #include "clang/AST/ASTContext.h" 21 #include "clang/AST/RecursiveASTVisitor.h" 22 #include "llvm/ADT/DenseMap.h" 23 #include "llvm/ADT/StringMap.h" 24 #include "llvm/Support/Timer.h" 25 #include <deque> 26 #include <memory> 27 #include <set> 28 29 namespace clang { 30 namespace ast_matchers { 31 namespace internal { 32 namespace { 33 34 typedef MatchFinder::MatchCallback MatchCallback; 35 36 // The maximum number of memoization entries to store. 37 // 10k has been experimentally found to give a good trade-off 38 // of performance vs. memory consumption by running matcher 39 // that match on every statement over a very large codebase. 40 // 41 // FIXME: Do some performance optimization in general and 42 // revisit this number; also, put up micro-benchmarks that we can 43 // optimize this on. 44 static const unsigned MaxMemoizationEntries = 10000; 45 46 enum class MatchType { 47 Ancestors, 48 49 Descendants, 50 Child, 51 }; 52 53 // We use memoization to avoid running the same matcher on the same 54 // AST node twice. This struct is the key for looking up match 55 // result. It consists of an ID of the MatcherInterface (for 56 // identifying the matcher), a pointer to the AST node and the 57 // bound nodes before the matcher was executed. 58 // 59 // We currently only memoize on nodes whose pointers identify the 60 // nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc). 61 // For \c QualType and \c TypeLoc it is possible to implement 62 // generation of keys for each type. 63 // FIXME: Benchmark whether memoization of non-pointer typed nodes 64 // provides enough benefit for the additional amount of code. 65 struct MatchKey { 66 DynTypedMatcher::MatcherIDType MatcherID; 67 DynTypedNode Node; 68 BoundNodesTreeBuilder BoundNodes; 69 TraversalKind Traversal = TK_AsIs; 70 MatchType Type; 71 72 bool operator<(const MatchKey &Other) const { 73 return std::tie(Traversal, Type, MatcherID, Node, BoundNodes) < 74 std::tie(Other.Traversal, Other.Type, Other.MatcherID, Other.Node, 75 Other.BoundNodes); 76 } 77 }; 78 79 // Used to store the result of a match and possibly bound nodes. 80 struct MemoizedMatchResult { 81 bool ResultOfMatch; 82 BoundNodesTreeBuilder Nodes; 83 }; 84 85 // A RecursiveASTVisitor that traverses all children or all descendants of 86 // a node. 87 class MatchChildASTVisitor 88 : public RecursiveASTVisitor<MatchChildASTVisitor> { 89 public: 90 typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase; 91 92 // Creates an AST visitor that matches 'matcher' on all children or 93 // descendants of a traversed node. max_depth is the maximum depth 94 // to traverse: use 1 for matching the children and INT_MAX for 95 // matching the descendants. 96 MatchChildASTVisitor(const DynTypedMatcher *Matcher, ASTMatchFinder *Finder, 97 BoundNodesTreeBuilder *Builder, int MaxDepth, 98 bool IgnoreImplicitChildren, 99 ASTMatchFinder::BindKind Bind) 100 : Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0), 101 MaxDepth(MaxDepth), IgnoreImplicitChildren(IgnoreImplicitChildren), 102 Bind(Bind), Matches(false) {} 103 104 // Returns true if a match is found in the subtree rooted at the 105 // given AST node. This is done via a set of mutually recursive 106 // functions. Here's how the recursion is done (the *wildcard can 107 // actually be Decl, Stmt, or Type): 108 // 109 // - Traverse(node) calls BaseTraverse(node) when it needs 110 // to visit the descendants of node. 111 // - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node)) 112 // Traverse*(c) for each child c of 'node'. 113 // - Traverse*(c) in turn calls Traverse(c), completing the 114 // recursion. 115 bool findMatch(const DynTypedNode &DynNode) { 116 reset(); 117 if (const Decl *D = DynNode.get<Decl>()) 118 traverse(*D); 119 else if (const Stmt *S = DynNode.get<Stmt>()) 120 traverse(*S); 121 else if (const NestedNameSpecifier *NNS = 122 DynNode.get<NestedNameSpecifier>()) 123 traverse(*NNS); 124 else if (const NestedNameSpecifierLoc *NNSLoc = 125 DynNode.get<NestedNameSpecifierLoc>()) 126 traverse(*NNSLoc); 127 else if (const QualType *Q = DynNode.get<QualType>()) 128 traverse(*Q); 129 else if (const TypeLoc *T = DynNode.get<TypeLoc>()) 130 traverse(*T); 131 else if (const auto *C = DynNode.get<CXXCtorInitializer>()) 132 traverse(*C); 133 else if (const TemplateArgumentLoc *TALoc = 134 DynNode.get<TemplateArgumentLoc>()) 135 traverse(*TALoc); 136 // FIXME: Add other base types after adding tests. 137 138 // It's OK to always overwrite the bound nodes, as if there was 139 // no match in this recursive branch, the result set is empty 140 // anyway. 141 *Builder = ResultBindings; 142 143 return Matches; 144 } 145 146 // The following are overriding methods from the base visitor class. 147 // They are public only to allow CRTP to work. They are *not *part 148 // of the public API of this class. 149 bool TraverseDecl(Decl *DeclNode) { 150 151 if (DeclNode && DeclNode->isImplicit() && 152 Finder->isTraversalIgnoringImplicitNodes()) 153 return baseTraverse(*DeclNode); 154 155 ScopedIncrement ScopedDepth(&CurrentDepth); 156 return (DeclNode == nullptr) || traverse(*DeclNode); 157 } 158 159 Stmt *getStmtToTraverse(Stmt *StmtNode) { 160 Stmt *StmtToTraverse = StmtNode; 161 if (auto *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) { 162 auto *LambdaNode = dyn_cast_or_null<LambdaExpr>(StmtNode); 163 if (LambdaNode && Finder->isTraversalIgnoringImplicitNodes()) 164 StmtToTraverse = LambdaNode; 165 else 166 StmtToTraverse = 167 Finder->getASTContext().getParentMapContext().traverseIgnored( 168 ExprNode); 169 } 170 return StmtToTraverse; 171 } 172 173 bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) { 174 // If we need to keep track of the depth, we can't perform data recursion. 175 if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX)) 176 Queue = nullptr; 177 178 ScopedIncrement ScopedDepth(&CurrentDepth); 179 Stmt *StmtToTraverse = getStmtToTraverse(StmtNode); 180 if (!StmtToTraverse) 181 return true; 182 183 if (IgnoreImplicitChildren && isa<CXXDefaultArgExpr>(StmtNode)) 184 return true; 185 186 if (!match(*StmtToTraverse)) 187 return false; 188 return VisitorBase::TraverseStmt(StmtToTraverse, Queue); 189 } 190 // We assume that the QualType and the contained type are on the same 191 // hierarchy level. Thus, we try to match either of them. 192 bool TraverseType(QualType TypeNode) { 193 if (TypeNode.isNull()) 194 return true; 195 ScopedIncrement ScopedDepth(&CurrentDepth); 196 // Match the Type. 197 if (!match(*TypeNode)) 198 return false; 199 // The QualType is matched inside traverse. 200 return traverse(TypeNode); 201 } 202 // We assume that the TypeLoc, contained QualType and contained Type all are 203 // on the same hierarchy level. Thus, we try to match all of them. 204 bool TraverseTypeLoc(TypeLoc TypeLocNode) { 205 if (TypeLocNode.isNull()) 206 return true; 207 ScopedIncrement ScopedDepth(&CurrentDepth); 208 // Match the Type. 209 if (!match(*TypeLocNode.getType())) 210 return false; 211 // Match the QualType. 212 if (!match(TypeLocNode.getType())) 213 return false; 214 // The TypeLoc is matched inside traverse. 215 return traverse(TypeLocNode); 216 } 217 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 218 ScopedIncrement ScopedDepth(&CurrentDepth); 219 return (NNS == nullptr) || traverse(*NNS); 220 } 221 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 222 if (!NNS) 223 return true; 224 ScopedIncrement ScopedDepth(&CurrentDepth); 225 if (!match(*NNS.getNestedNameSpecifier())) 226 return false; 227 return traverse(NNS); 228 } 229 bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) { 230 if (!CtorInit) 231 return true; 232 ScopedIncrement ScopedDepth(&CurrentDepth); 233 return traverse(*CtorInit); 234 } 235 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL) { 236 ScopedIncrement ScopedDepth(&CurrentDepth); 237 return traverse(TAL); 238 } 239 bool TraverseCXXForRangeStmt(CXXForRangeStmt *Node) { 240 if (!Finder->isTraversalIgnoringImplicitNodes()) 241 return VisitorBase::TraverseCXXForRangeStmt(Node); 242 if (!Node) 243 return true; 244 ScopedIncrement ScopedDepth(&CurrentDepth); 245 if (auto *Init = Node->getInit()) 246 if (!match(*Init)) 247 return false; 248 if (!match(*Node->getLoopVariable()) || !match(*Node->getRangeInit()) || 249 !match(*Node->getBody())) 250 return false; 251 return VisitorBase::TraverseStmt(Node->getBody()); 252 } 253 bool TraverseCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *Node) { 254 if (!Finder->isTraversalIgnoringImplicitNodes()) 255 return VisitorBase::TraverseCXXRewrittenBinaryOperator(Node); 256 if (!Node) 257 return true; 258 ScopedIncrement ScopedDepth(&CurrentDepth); 259 260 return match(*Node->getLHS()) && match(*Node->getRHS()); 261 } 262 bool TraverseLambdaExpr(LambdaExpr *Node) { 263 if (!Finder->isTraversalIgnoringImplicitNodes()) 264 return VisitorBase::TraverseLambdaExpr(Node); 265 if (!Node) 266 return true; 267 ScopedIncrement ScopedDepth(&CurrentDepth); 268 269 for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { 270 const auto *C = Node->capture_begin() + I; 271 if (!C->isExplicit()) 272 continue; 273 if (Node->isInitCapture(C) && !match(*C->getCapturedVar())) 274 return false; 275 if (!match(*Node->capture_init_begin()[I])) 276 return false; 277 } 278 279 if (const auto *TPL = Node->getTemplateParameterList()) { 280 for (const auto *TP : *TPL) { 281 if (!match(*TP)) 282 return false; 283 } 284 } 285 286 for (const auto *P : Node->getCallOperator()->parameters()) { 287 if (!match(*P)) 288 return false; 289 } 290 291 if (!match(*Node->getBody())) 292 return false; 293 294 return true; 295 } 296 297 bool shouldVisitTemplateInstantiations() const { return true; } 298 bool shouldVisitImplicitCode() const { return !IgnoreImplicitChildren; } 299 300 private: 301 // Used for updating the depth during traversal. 302 struct ScopedIncrement { 303 explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); } 304 ~ScopedIncrement() { --(*Depth); } 305 306 private: 307 int *Depth; 308 }; 309 310 // Resets the state of this object. 311 void reset() { 312 Matches = false; 313 CurrentDepth = 0; 314 } 315 316 // Forwards the call to the corresponding Traverse*() method in the 317 // base visitor class. 318 bool baseTraverse(const Decl &DeclNode) { 319 return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode)); 320 } 321 bool baseTraverse(const Stmt &StmtNode) { 322 return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode)); 323 } 324 bool baseTraverse(QualType TypeNode) { 325 return VisitorBase::TraverseType(TypeNode); 326 } 327 bool baseTraverse(TypeLoc TypeLocNode) { 328 return VisitorBase::TraverseTypeLoc(TypeLocNode); 329 } 330 bool baseTraverse(const NestedNameSpecifier &NNS) { 331 return VisitorBase::TraverseNestedNameSpecifier( 332 const_cast<NestedNameSpecifier*>(&NNS)); 333 } 334 bool baseTraverse(NestedNameSpecifierLoc NNS) { 335 return VisitorBase::TraverseNestedNameSpecifierLoc(NNS); 336 } 337 bool baseTraverse(const CXXCtorInitializer &CtorInit) { 338 return VisitorBase::TraverseConstructorInitializer( 339 const_cast<CXXCtorInitializer *>(&CtorInit)); 340 } 341 bool baseTraverse(TemplateArgumentLoc TAL) { 342 return VisitorBase::TraverseTemplateArgumentLoc(TAL); 343 } 344 345 // Sets 'Matched' to true if 'Matcher' matches 'Node' and: 346 // 0 < CurrentDepth <= MaxDepth. 347 // 348 // Returns 'true' if traversal should continue after this function 349 // returns, i.e. if no match is found or 'Bind' is 'BK_All'. 350 template <typename T> 351 bool match(const T &Node) { 352 if (CurrentDepth == 0 || CurrentDepth > MaxDepth) { 353 return true; 354 } 355 if (Bind != ASTMatchFinder::BK_All) { 356 BoundNodesTreeBuilder RecursiveBuilder(*Builder); 357 if (Matcher->matches(DynTypedNode::create(Node), Finder, 358 &RecursiveBuilder)) { 359 Matches = true; 360 ResultBindings.addMatch(RecursiveBuilder); 361 return false; // Abort as soon as a match is found. 362 } 363 } else { 364 BoundNodesTreeBuilder RecursiveBuilder(*Builder); 365 if (Matcher->matches(DynTypedNode::create(Node), Finder, 366 &RecursiveBuilder)) { 367 // After the first match the matcher succeeds. 368 Matches = true; 369 ResultBindings.addMatch(RecursiveBuilder); 370 } 371 } 372 return true; 373 } 374 375 // Traverses the subtree rooted at 'Node'; returns true if the 376 // traversal should continue after this function returns. 377 template <typename T> 378 bool traverse(const T &Node) { 379 static_assert(IsBaseType<T>::value, 380 "traverse can only be instantiated with base type"); 381 if (!match(Node)) 382 return false; 383 return baseTraverse(Node); 384 } 385 386 const DynTypedMatcher *const Matcher; 387 ASTMatchFinder *const Finder; 388 BoundNodesTreeBuilder *const Builder; 389 BoundNodesTreeBuilder ResultBindings; 390 int CurrentDepth; 391 const int MaxDepth; 392 const bool IgnoreImplicitChildren; 393 const ASTMatchFinder::BindKind Bind; 394 bool Matches; 395 }; 396 397 // Controls the outermost traversal of the AST and allows to match multiple 398 // matchers. 399 class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, 400 public ASTMatchFinder { 401 public: 402 MatchASTVisitor(const MatchFinder::MatchersByType *Matchers, 403 const MatchFinder::MatchFinderOptions &Options) 404 : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {} 405 406 ~MatchASTVisitor() override { 407 if (Options.CheckProfiling) { 408 Options.CheckProfiling->Records = std::move(TimeByBucket); 409 } 410 } 411 412 void onStartOfTranslationUnit() { 413 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 414 TimeBucketRegion Timer; 415 for (MatchCallback *MC : Matchers->AllCallbacks) { 416 if (EnableCheckProfiling) 417 Timer.setBucket(&TimeByBucket[MC->getID()]); 418 MC->onStartOfTranslationUnit(); 419 } 420 } 421 422 void onEndOfTranslationUnit() { 423 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 424 TimeBucketRegion Timer; 425 for (MatchCallback *MC : Matchers->AllCallbacks) { 426 if (EnableCheckProfiling) 427 Timer.setBucket(&TimeByBucket[MC->getID()]); 428 MC->onEndOfTranslationUnit(); 429 } 430 } 431 432 void set_active_ast_context(ASTContext *NewActiveASTContext) { 433 ActiveASTContext = NewActiveASTContext; 434 } 435 436 // The following Visit*() and Traverse*() functions "override" 437 // methods in RecursiveASTVisitor. 438 439 bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) { 440 // When we see 'typedef A B', we add name 'B' to the set of names 441 // A's canonical type maps to. This is necessary for implementing 442 // isDerivedFrom(x) properly, where x can be the name of the base 443 // class or any of its aliases. 444 // 445 // In general, the is-alias-of (as defined by typedefs) relation 446 // is tree-shaped, as you can typedef a type more than once. For 447 // example, 448 // 449 // typedef A B; 450 // typedef A C; 451 // typedef C D; 452 // typedef C E; 453 // 454 // gives you 455 // 456 // A 457 // |- B 458 // `- C 459 // |- D 460 // `- E 461 // 462 // It is wrong to assume that the relation is a chain. A correct 463 // implementation of isDerivedFrom() needs to recognize that B and 464 // E are aliases, even though neither is a typedef of the other. 465 // Therefore, we cannot simply walk through one typedef chain to 466 // find out whether the type name matches. 467 const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr(); 468 const Type *CanonicalType = // root of the typedef tree 469 ActiveASTContext->getCanonicalType(TypeNode); 470 TypeAliases[CanonicalType].insert(DeclNode); 471 return true; 472 } 473 474 bool VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { 475 const ObjCInterfaceDecl *InterfaceDecl = CAD->getClassInterface(); 476 CompatibleAliases[InterfaceDecl].insert(CAD); 477 return true; 478 } 479 480 bool TraverseDecl(Decl *DeclNode); 481 bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr); 482 bool TraverseType(QualType TypeNode); 483 bool TraverseTypeLoc(TypeLoc TypeNode); 484 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); 485 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 486 bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit); 487 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL); 488 489 bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) { 490 if (auto *RF = dyn_cast<CXXForRangeStmt>(S)) { 491 for (auto *SubStmt : RF->children()) { 492 if (SubStmt == RF->getInit() || SubStmt == RF->getLoopVarStmt() || 493 SubStmt == RF->getRangeInit() || SubStmt == RF->getBody()) { 494 TraverseStmt(SubStmt, Queue); 495 } else { 496 ASTNodeNotSpelledInSourceScope RAII(this, true); 497 TraverseStmt(SubStmt, Queue); 498 } 499 } 500 return true; 501 } else if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 502 { 503 ASTNodeNotAsIsSourceScope RAII(this, true); 504 TraverseStmt(const_cast<Expr *>(RBO->getLHS())); 505 TraverseStmt(const_cast<Expr *>(RBO->getRHS())); 506 } 507 { 508 ASTNodeNotSpelledInSourceScope RAII(this, true); 509 for (auto *SubStmt : RBO->children()) { 510 TraverseStmt(SubStmt); 511 } 512 } 513 return true; 514 } else if (auto *LE = dyn_cast<LambdaExpr>(S)) { 515 for (auto I : llvm::zip(LE->captures(), LE->capture_inits())) { 516 auto C = std::get<0>(I); 517 ASTNodeNotSpelledInSourceScope RAII( 518 this, TraversingASTNodeNotSpelledInSource || !C.isExplicit()); 519 TraverseLambdaCapture(LE, &C, std::get<1>(I)); 520 } 521 522 { 523 ASTNodeNotSpelledInSourceScope RAII(this, true); 524 TraverseDecl(LE->getLambdaClass()); 525 } 526 { 527 ASTNodeNotAsIsSourceScope RAII(this, true); 528 529 // We need to poke around to find the bits that might be explicitly 530 // written. 531 TypeLoc TL = LE->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); 532 FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>(); 533 534 if (auto *TPL = LE->getTemplateParameterList()) { 535 for (NamedDecl *D : *TPL) { 536 TraverseDecl(D); 537 } 538 if (Expr *RequiresClause = TPL->getRequiresClause()) { 539 TraverseStmt(RequiresClause); 540 } 541 } 542 543 if (LE->hasExplicitParameters()) { 544 // Visit parameters. 545 for (ParmVarDecl *Param : Proto.getParams()) 546 TraverseDecl(Param); 547 } 548 549 const auto *T = Proto.getTypePtr(); 550 for (const auto &E : T->exceptions()) 551 TraverseType(E); 552 553 if (Expr *NE = T->getNoexceptExpr()) 554 TraverseStmt(NE, Queue); 555 556 if (LE->hasExplicitResultType()) 557 TraverseTypeLoc(Proto.getReturnLoc()); 558 TraverseStmt(LE->getTrailingRequiresClause()); 559 560 TraverseStmt(LE->getBody()); 561 } 562 return true; 563 } 564 return RecursiveASTVisitor<MatchASTVisitor>::dataTraverseNode(S, Queue); 565 } 566 567 // Matches children or descendants of 'Node' with 'BaseMatcher'. 568 bool memoizedMatchesRecursively(const DynTypedNode &Node, ASTContext &Ctx, 569 const DynTypedMatcher &Matcher, 570 BoundNodesTreeBuilder *Builder, int MaxDepth, 571 BindKind Bind) { 572 // For AST-nodes that don't have an identity, we can't memoize. 573 if (!Node.getMemoizationData() || !Builder->isComparable()) 574 return matchesRecursively(Node, Matcher, Builder, MaxDepth, Bind); 575 576 MatchKey Key; 577 Key.MatcherID = Matcher.getID(); 578 Key.Node = Node; 579 // Note that we key on the bindings *before* the match. 580 Key.BoundNodes = *Builder; 581 Key.Traversal = Ctx.getParentMapContext().getTraversalKind(); 582 // Memoize result even doing a single-level match, it might be expensive. 583 Key.Type = MaxDepth == 1 ? MatchType::Child : MatchType::Descendants; 584 MemoizationMap::iterator I = ResultCache.find(Key); 585 if (I != ResultCache.end()) { 586 *Builder = I->second.Nodes; 587 return I->second.ResultOfMatch; 588 } 589 590 MemoizedMatchResult Result; 591 Result.Nodes = *Builder; 592 Result.ResultOfMatch = 593 matchesRecursively(Node, Matcher, &Result.Nodes, MaxDepth, Bind); 594 595 MemoizedMatchResult &CachedResult = ResultCache[Key]; 596 CachedResult = std::move(Result); 597 598 *Builder = CachedResult.Nodes; 599 return CachedResult.ResultOfMatch; 600 } 601 602 // Matches children or descendants of 'Node' with 'BaseMatcher'. 603 bool matchesRecursively(const DynTypedNode &Node, 604 const DynTypedMatcher &Matcher, 605 BoundNodesTreeBuilder *Builder, int MaxDepth, 606 BindKind Bind) { 607 bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 608 TraversingASTChildrenNotSpelledInSource; 609 610 bool IgnoreImplicitChildren = false; 611 612 if (isTraversalIgnoringImplicitNodes()) { 613 IgnoreImplicitChildren = true; 614 } 615 616 ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal); 617 618 MatchChildASTVisitor Visitor(&Matcher, this, Builder, MaxDepth, 619 IgnoreImplicitChildren, Bind); 620 return Visitor.findMatch(Node); 621 } 622 623 bool classIsDerivedFrom(const CXXRecordDecl *Declaration, 624 const Matcher<NamedDecl> &Base, 625 BoundNodesTreeBuilder *Builder, 626 bool Directly) override; 627 628 bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration, 629 const Matcher<NamedDecl> &Base, 630 BoundNodesTreeBuilder *Builder, 631 bool Directly) override; 632 633 // Implements ASTMatchFinder::matchesChildOf. 634 bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx, 635 const DynTypedMatcher &Matcher, 636 BoundNodesTreeBuilder *Builder, BindKind Bind) override { 637 if (ResultCache.size() > MaxMemoizationEntries) 638 ResultCache.clear(); 639 return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, 1, Bind); 640 } 641 // Implements ASTMatchFinder::matchesDescendantOf. 642 bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx, 643 const DynTypedMatcher &Matcher, 644 BoundNodesTreeBuilder *Builder, 645 BindKind Bind) override { 646 if (ResultCache.size() > MaxMemoizationEntries) 647 ResultCache.clear(); 648 return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, INT_MAX, 649 Bind); 650 } 651 // Implements ASTMatchFinder::matchesAncestorOf. 652 bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx, 653 const DynTypedMatcher &Matcher, 654 BoundNodesTreeBuilder *Builder, 655 AncestorMatchMode MatchMode) override { 656 // Reset the cache outside of the recursive call to make sure we 657 // don't invalidate any iterators. 658 if (ResultCache.size() > MaxMemoizationEntries) 659 ResultCache.clear(); 660 if (MatchMode == AncestorMatchMode::AMM_ParentOnly) 661 return matchesParentOf(Node, Matcher, Builder); 662 return matchesAnyAncestorOf(Node, Ctx, Matcher, Builder); 663 } 664 665 // Matches all registered matchers on the given node and calls the 666 // result callback for every node that matches. 667 void match(const DynTypedNode &Node) { 668 // FIXME: Improve this with a switch or a visitor pattern. 669 if (auto *N = Node.get<Decl>()) { 670 match(*N); 671 } else if (auto *N = Node.get<Stmt>()) { 672 match(*N); 673 } else if (auto *N = Node.get<Type>()) { 674 match(*N); 675 } else if (auto *N = Node.get<QualType>()) { 676 match(*N); 677 } else if (auto *N = Node.get<NestedNameSpecifier>()) { 678 match(*N); 679 } else if (auto *N = Node.get<NestedNameSpecifierLoc>()) { 680 match(*N); 681 } else if (auto *N = Node.get<TypeLoc>()) { 682 match(*N); 683 } else if (auto *N = Node.get<CXXCtorInitializer>()) { 684 match(*N); 685 } else if (auto *N = Node.get<TemplateArgumentLoc>()) { 686 match(*N); 687 } 688 } 689 690 template <typename T> void match(const T &Node) { 691 matchDispatch(&Node); 692 } 693 694 // Implements ASTMatchFinder::getASTContext. 695 ASTContext &getASTContext() const override { return *ActiveASTContext; } 696 697 bool shouldVisitTemplateInstantiations() const { return true; } 698 bool shouldVisitImplicitCode() const { return true; } 699 700 bool IsMatchingInASTNodeNotSpelledInSource() const override { 701 return TraversingASTNodeNotSpelledInSource; 702 } 703 bool isMatchingChildrenNotSpelledInSource() const override { 704 return TraversingASTChildrenNotSpelledInSource; 705 } 706 void setMatchingChildrenNotSpelledInSource(bool Set) override { 707 TraversingASTChildrenNotSpelledInSource = Set; 708 } 709 710 bool IsMatchingInASTNodeNotAsIs() const override { 711 return TraversingASTNodeNotAsIs; 712 } 713 714 bool TraverseTemplateInstantiations(ClassTemplateDecl *D) { 715 ASTNodeNotSpelledInSourceScope RAII(this, true); 716 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 717 D); 718 } 719 720 bool TraverseTemplateInstantiations(VarTemplateDecl *D) { 721 ASTNodeNotSpelledInSourceScope RAII(this, true); 722 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 723 D); 724 } 725 726 bool TraverseTemplateInstantiations(FunctionTemplateDecl *D) { 727 ASTNodeNotSpelledInSourceScope RAII(this, true); 728 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 729 D); 730 } 731 732 private: 733 bool TraversingASTNodeNotSpelledInSource = false; 734 bool TraversingASTNodeNotAsIs = false; 735 bool TraversingASTChildrenNotSpelledInSource = false; 736 737 struct ASTNodeNotSpelledInSourceScope { 738 ASTNodeNotSpelledInSourceScope(MatchASTVisitor *V, bool B) 739 : MV(V), MB(V->TraversingASTNodeNotSpelledInSource) { 740 V->TraversingASTNodeNotSpelledInSource = B; 741 } 742 ~ASTNodeNotSpelledInSourceScope() { 743 MV->TraversingASTNodeNotSpelledInSource = MB; 744 } 745 746 private: 747 MatchASTVisitor *MV; 748 bool MB; 749 }; 750 751 struct ASTNodeNotAsIsSourceScope { 752 ASTNodeNotAsIsSourceScope(MatchASTVisitor *V, bool B) 753 : MV(V), MB(V->TraversingASTNodeNotAsIs) { 754 V->TraversingASTNodeNotAsIs = B; 755 } 756 ~ASTNodeNotAsIsSourceScope() { MV->TraversingASTNodeNotAsIs = MB; } 757 758 private: 759 MatchASTVisitor *MV; 760 bool MB; 761 }; 762 763 class TimeBucketRegion { 764 public: 765 TimeBucketRegion() : Bucket(nullptr) {} 766 ~TimeBucketRegion() { setBucket(nullptr); } 767 768 /// Start timing for \p NewBucket. 769 /// 770 /// If there was a bucket already set, it will finish the timing for that 771 /// other bucket. 772 /// \p NewBucket will be timed until the next call to \c setBucket() or 773 /// until the \c TimeBucketRegion is destroyed. 774 /// If \p NewBucket is the same as the currently timed bucket, this call 775 /// does nothing. 776 void setBucket(llvm::TimeRecord *NewBucket) { 777 if (Bucket != NewBucket) { 778 auto Now = llvm::TimeRecord::getCurrentTime(true); 779 if (Bucket) 780 *Bucket += Now; 781 if (NewBucket) 782 *NewBucket -= Now; 783 Bucket = NewBucket; 784 } 785 } 786 787 private: 788 llvm::TimeRecord *Bucket; 789 }; 790 791 /// Runs all the \p Matchers on \p Node. 792 /// 793 /// Used by \c matchDispatch() below. 794 template <typename T, typename MC> 795 void matchWithoutFilter(const T &Node, const MC &Matchers) { 796 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 797 TimeBucketRegion Timer; 798 for (const auto &MP : Matchers) { 799 if (EnableCheckProfiling) 800 Timer.setBucket(&TimeByBucket[MP.second->getID()]); 801 BoundNodesTreeBuilder Builder; 802 if (MP.first.matches(Node, this, &Builder)) { 803 MatchVisitor Visitor(ActiveASTContext, MP.second); 804 Builder.visitMatches(&Visitor); 805 } 806 } 807 } 808 809 void matchWithFilter(const DynTypedNode &DynNode) { 810 auto Kind = DynNode.getNodeKind(); 811 auto it = MatcherFiltersMap.find(Kind); 812 const auto &Filter = 813 it != MatcherFiltersMap.end() ? it->second : getFilterForKind(Kind); 814 815 if (Filter.empty()) 816 return; 817 818 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 819 TimeBucketRegion Timer; 820 auto &Matchers = this->Matchers->DeclOrStmt; 821 for (unsigned short I : Filter) { 822 auto &MP = Matchers[I]; 823 if (EnableCheckProfiling) 824 Timer.setBucket(&TimeByBucket[MP.second->getID()]); 825 BoundNodesTreeBuilder Builder; 826 if (MP.first.matches(DynNode, this, &Builder)) { 827 MatchVisitor Visitor(ActiveASTContext, MP.second); 828 Builder.visitMatches(&Visitor); 829 } 830 } 831 } 832 833 const std::vector<unsigned short> &getFilterForKind(ASTNodeKind Kind) { 834 auto &Filter = MatcherFiltersMap[Kind]; 835 auto &Matchers = this->Matchers->DeclOrStmt; 836 assert((Matchers.size() < USHRT_MAX) && "Too many matchers."); 837 for (unsigned I = 0, E = Matchers.size(); I != E; ++I) { 838 if (Matchers[I].first.canMatchNodesOfKind(Kind)) { 839 Filter.push_back(I); 840 } 841 } 842 return Filter; 843 } 844 845 /// @{ 846 /// Overloads to pair the different node types to their matchers. 847 void matchDispatch(const Decl *Node) { 848 return matchWithFilter(DynTypedNode::create(*Node)); 849 } 850 void matchDispatch(const Stmt *Node) { 851 return matchWithFilter(DynTypedNode::create(*Node)); 852 } 853 854 void matchDispatch(const Type *Node) { 855 matchWithoutFilter(QualType(Node, 0), Matchers->Type); 856 } 857 void matchDispatch(const TypeLoc *Node) { 858 matchWithoutFilter(*Node, Matchers->TypeLoc); 859 } 860 void matchDispatch(const QualType *Node) { 861 matchWithoutFilter(*Node, Matchers->Type); 862 } 863 void matchDispatch(const NestedNameSpecifier *Node) { 864 matchWithoutFilter(*Node, Matchers->NestedNameSpecifier); 865 } 866 void matchDispatch(const NestedNameSpecifierLoc *Node) { 867 matchWithoutFilter(*Node, Matchers->NestedNameSpecifierLoc); 868 } 869 void matchDispatch(const CXXCtorInitializer *Node) { 870 matchWithoutFilter(*Node, Matchers->CtorInit); 871 } 872 void matchDispatch(const TemplateArgumentLoc *Node) { 873 matchWithoutFilter(*Node, Matchers->TemplateArgumentLoc); 874 } 875 void matchDispatch(const void *) { /* Do nothing. */ } 876 /// @} 877 878 // Returns whether a direct parent of \p Node matches \p Matcher. 879 // Unlike matchesAnyAncestorOf there's no memoization: it doesn't save much. 880 bool matchesParentOf(const DynTypedNode &Node, const DynTypedMatcher &Matcher, 881 BoundNodesTreeBuilder *Builder) { 882 for (const auto &Parent : ActiveASTContext->getParents(Node)) { 883 BoundNodesTreeBuilder BuilderCopy = *Builder; 884 if (Matcher.matches(Parent, this, &BuilderCopy)) { 885 *Builder = std::move(BuilderCopy); 886 return true; 887 } 888 } 889 return false; 890 } 891 892 // Returns whether an ancestor of \p Node matches \p Matcher. 893 // 894 // The order of matching (which can lead to different nodes being bound in 895 // case there are multiple matches) is breadth first search. 896 // 897 // To allow memoization in the very common case of having deeply nested 898 // expressions inside a template function, we first walk up the AST, memoizing 899 // the result of the match along the way, as long as there is only a single 900 // parent. 901 // 902 // Once there are multiple parents, the breadth first search order does not 903 // allow simple memoization on the ancestors. Thus, we only memoize as long 904 // as there is a single parent. 905 // 906 // We avoid a recursive implementation to prevent excessive stack use on 907 // very deep ASTs (similarly to RecursiveASTVisitor's data recursion). 908 bool matchesAnyAncestorOf(DynTypedNode Node, ASTContext &Ctx, 909 const DynTypedMatcher &Matcher, 910 BoundNodesTreeBuilder *Builder) { 911 912 // Memoization keys that can be updated with the result. 913 // These are the memoizable nodes in the chain of unique parents, which 914 // terminates when a node has multiple parents, or matches, or is the root. 915 std::vector<MatchKey> Keys; 916 // When returning, update the memoization cache. 917 auto Finish = [&](bool Matched) { 918 for (const auto &Key : Keys) { 919 MemoizedMatchResult &CachedResult = ResultCache[Key]; 920 CachedResult.ResultOfMatch = Matched; 921 CachedResult.Nodes = *Builder; 922 } 923 return Matched; 924 }; 925 926 // Loop while there's a single parent and we want to attempt memoization. 927 DynTypedNodeList Parents{ArrayRef<DynTypedNode>()}; // after loop: size != 1 928 for (;;) { 929 // A cache key only makes sense if memoization is possible. 930 if (Builder->isComparable()) { 931 Keys.emplace_back(); 932 Keys.back().MatcherID = Matcher.getID(); 933 Keys.back().Node = Node; 934 Keys.back().BoundNodes = *Builder; 935 Keys.back().Traversal = Ctx.getParentMapContext().getTraversalKind(); 936 Keys.back().Type = MatchType::Ancestors; 937 938 // Check the cache. 939 MemoizationMap::iterator I = ResultCache.find(Keys.back()); 940 if (I != ResultCache.end()) { 941 Keys.pop_back(); // Don't populate the cache for the matching node! 942 *Builder = I->second.Nodes; 943 return Finish(I->second.ResultOfMatch); 944 } 945 } 946 947 Parents = ActiveASTContext->getParents(Node); 948 // Either no parents or multiple parents: leave chain+memoize mode and 949 // enter bfs+forgetful mode. 950 if (Parents.size() != 1) 951 break; 952 953 // Check the next parent. 954 Node = *Parents.begin(); 955 BoundNodesTreeBuilder BuilderCopy = *Builder; 956 if (Matcher.matches(Node, this, &BuilderCopy)) { 957 *Builder = std::move(BuilderCopy); 958 return Finish(true); 959 } 960 } 961 // We reached the end of the chain. 962 963 if (Parents.empty()) { 964 // Nodes may have no parents if: 965 // a) the node is the TranslationUnitDecl 966 // b) we have a limited traversal scope that excludes the parent edges 967 // c) there is a bug in the AST, and the node is not reachable 968 // Usually the traversal scope is the whole AST, which precludes b. 969 // Bugs are common enough that it's worthwhile asserting when we can. 970 #ifndef NDEBUG 971 if (!Node.get<TranslationUnitDecl>() && 972 /* Traversal scope is full AST if any of the bounds are the TU */ 973 llvm::any_of(ActiveASTContext->getTraversalScope(), [](Decl *D) { 974 return D->getKind() == Decl::TranslationUnit; 975 })) { 976 llvm::errs() << "Tried to match orphan node:\n"; 977 Node.dump(llvm::errs(), *ActiveASTContext); 978 llvm_unreachable("Parent map should be complete!"); 979 } 980 #endif 981 } else { 982 assert(Parents.size() > 1); 983 // BFS starting from the parents not yet considered. 984 // Memoization of newly visited nodes is not possible (but we still update 985 // results for the elements in the chain we found above). 986 std::deque<DynTypedNode> Queue(Parents.begin(), Parents.end()); 987 llvm::DenseSet<const void *> Visited; 988 while (!Queue.empty()) { 989 BoundNodesTreeBuilder BuilderCopy = *Builder; 990 if (Matcher.matches(Queue.front(), this, &BuilderCopy)) { 991 *Builder = std::move(BuilderCopy); 992 return Finish(true); 993 } 994 for (const auto &Parent : ActiveASTContext->getParents(Queue.front())) { 995 // Make sure we do not visit the same node twice. 996 // Otherwise, we'll visit the common ancestors as often as there 997 // are splits on the way down. 998 if (Visited.insert(Parent.getMemoizationData()).second) 999 Queue.push_back(Parent); 1000 } 1001 Queue.pop_front(); 1002 } 1003 } 1004 return Finish(false); 1005 } 1006 1007 // Implements a BoundNodesTree::Visitor that calls a MatchCallback with 1008 // the aggregated bound nodes for each match. 1009 class MatchVisitor : public BoundNodesTreeBuilder::Visitor { 1010 public: 1011 MatchVisitor(ASTContext* Context, 1012 MatchFinder::MatchCallback* Callback) 1013 : Context(Context), 1014 Callback(Callback) {} 1015 1016 void visitMatch(const BoundNodes& BoundNodesView) override { 1017 Callback->run(MatchFinder::MatchResult(BoundNodesView, Context)); 1018 } 1019 1020 private: 1021 ASTContext* Context; 1022 MatchFinder::MatchCallback* Callback; 1023 }; 1024 1025 // Returns true if 'TypeNode' has an alias that matches the given matcher. 1026 bool typeHasMatchingAlias(const Type *TypeNode, 1027 const Matcher<NamedDecl> &Matcher, 1028 BoundNodesTreeBuilder *Builder) { 1029 const Type *const CanonicalType = 1030 ActiveASTContext->getCanonicalType(TypeNode); 1031 auto Aliases = TypeAliases.find(CanonicalType); 1032 if (Aliases == TypeAliases.end()) 1033 return false; 1034 for (const TypedefNameDecl *Alias : Aliases->second) { 1035 BoundNodesTreeBuilder Result(*Builder); 1036 if (Matcher.matches(*Alias, this, &Result)) { 1037 *Builder = std::move(Result); 1038 return true; 1039 } 1040 } 1041 return false; 1042 } 1043 1044 bool 1045 objcClassHasMatchingCompatibilityAlias(const ObjCInterfaceDecl *InterfaceDecl, 1046 const Matcher<NamedDecl> &Matcher, 1047 BoundNodesTreeBuilder *Builder) { 1048 auto Aliases = CompatibleAliases.find(InterfaceDecl); 1049 if (Aliases == CompatibleAliases.end()) 1050 return false; 1051 for (const ObjCCompatibleAliasDecl *Alias : Aliases->second) { 1052 BoundNodesTreeBuilder Result(*Builder); 1053 if (Matcher.matches(*Alias, this, &Result)) { 1054 *Builder = std::move(Result); 1055 return true; 1056 } 1057 } 1058 return false; 1059 } 1060 1061 /// Bucket to record map. 1062 /// 1063 /// Used to get the appropriate bucket for each matcher. 1064 llvm::StringMap<llvm::TimeRecord> TimeByBucket; 1065 1066 const MatchFinder::MatchersByType *Matchers; 1067 1068 /// Filtered list of matcher indices for each matcher kind. 1069 /// 1070 /// \c Decl and \c Stmt toplevel matchers usually apply to a specific node 1071 /// kind (and derived kinds) so it is a waste to try every matcher on every 1072 /// node. 1073 /// We precalculate a list of matchers that pass the toplevel restrict check. 1074 llvm::DenseMap<ASTNodeKind, std::vector<unsigned short>> MatcherFiltersMap; 1075 1076 const MatchFinder::MatchFinderOptions &Options; 1077 ASTContext *ActiveASTContext; 1078 1079 // Maps a canonical type to its TypedefDecls. 1080 llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases; 1081 1082 // Maps an Objective-C interface to its ObjCCompatibleAliasDecls. 1083 llvm::DenseMap<const ObjCInterfaceDecl *, 1084 llvm::SmallPtrSet<const ObjCCompatibleAliasDecl *, 2>> 1085 CompatibleAliases; 1086 1087 // Maps (matcher, node) -> the match result for memoization. 1088 typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap; 1089 MemoizationMap ResultCache; 1090 }; 1091 1092 static CXXRecordDecl * 1093 getAsCXXRecordDeclOrPrimaryTemplate(const Type *TypeNode) { 1094 if (auto *RD = TypeNode->getAsCXXRecordDecl()) 1095 return RD; 1096 1097 // Find the innermost TemplateSpecializationType that isn't an alias template. 1098 auto *TemplateType = TypeNode->getAs<TemplateSpecializationType>(); 1099 while (TemplateType && TemplateType->isTypeAlias()) 1100 TemplateType = 1101 TemplateType->getAliasedType()->getAs<TemplateSpecializationType>(); 1102 1103 // If this is the name of a (dependent) template specialization, use the 1104 // definition of the template, even though it might be specialized later. 1105 if (TemplateType) 1106 if (auto *ClassTemplate = dyn_cast_or_null<ClassTemplateDecl>( 1107 TemplateType->getTemplateName().getAsTemplateDecl())) 1108 return ClassTemplate->getTemplatedDecl(); 1109 1110 return nullptr; 1111 } 1112 1113 // Returns true if the given C++ class is directly or indirectly derived 1114 // from a base type with the given name. A class is not considered to be 1115 // derived from itself. 1116 bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration, 1117 const Matcher<NamedDecl> &Base, 1118 BoundNodesTreeBuilder *Builder, 1119 bool Directly) { 1120 if (!Declaration->hasDefinition()) 1121 return false; 1122 for (const auto &It : Declaration->bases()) { 1123 const Type *TypeNode = It.getType().getTypePtr(); 1124 1125 if (typeHasMatchingAlias(TypeNode, Base, Builder)) 1126 return true; 1127 1128 // FIXME: Going to the primary template here isn't really correct, but 1129 // unfortunately we accept a Decl matcher for the base class not a Type 1130 // matcher, so it's the best thing we can do with our current interface. 1131 CXXRecordDecl *ClassDecl = getAsCXXRecordDeclOrPrimaryTemplate(TypeNode); 1132 if (!ClassDecl) 1133 continue; 1134 if (ClassDecl == Declaration) { 1135 // This can happen for recursive template definitions. 1136 continue; 1137 } 1138 BoundNodesTreeBuilder Result(*Builder); 1139 if (Base.matches(*ClassDecl, this, &Result)) { 1140 *Builder = std::move(Result); 1141 return true; 1142 } 1143 if (!Directly && classIsDerivedFrom(ClassDecl, Base, Builder, Directly)) 1144 return true; 1145 } 1146 return false; 1147 } 1148 1149 // Returns true if the given Objective-C class is directly or indirectly 1150 // derived from a matching base class. A class is not considered to be derived 1151 // from itself. 1152 bool MatchASTVisitor::objcClassIsDerivedFrom( 1153 const ObjCInterfaceDecl *Declaration, const Matcher<NamedDecl> &Base, 1154 BoundNodesTreeBuilder *Builder, bool Directly) { 1155 // Check if any of the superclasses of the class match. 1156 for (const ObjCInterfaceDecl *ClassDecl = Declaration->getSuperClass(); 1157 ClassDecl != nullptr; ClassDecl = ClassDecl->getSuperClass()) { 1158 // Check if there are any matching compatibility aliases. 1159 if (objcClassHasMatchingCompatibilityAlias(ClassDecl, Base, Builder)) 1160 return true; 1161 1162 // Check if there are any matching type aliases. 1163 const Type *TypeNode = ClassDecl->getTypeForDecl(); 1164 if (typeHasMatchingAlias(TypeNode, Base, Builder)) 1165 return true; 1166 1167 if (Base.matches(*ClassDecl, this, Builder)) 1168 return true; 1169 1170 // Not `return false` as a temporary workaround for PR43879. 1171 if (Directly) 1172 break; 1173 } 1174 1175 return false; 1176 } 1177 1178 bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) { 1179 if (!DeclNode) { 1180 return true; 1181 } 1182 1183 bool ScopedTraversal = 1184 TraversingASTNodeNotSpelledInSource || DeclNode->isImplicit(); 1185 bool ScopedChildren = TraversingASTChildrenNotSpelledInSource; 1186 1187 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(DeclNode)) { 1188 auto SK = CTSD->getSpecializationKind(); 1189 if (SK == TSK_ExplicitInstantiationDeclaration || 1190 SK == TSK_ExplicitInstantiationDefinition) 1191 ScopedChildren = true; 1192 } else if (const auto *FD = dyn_cast<FunctionDecl>(DeclNode)) { 1193 if (FD->isDefaulted()) 1194 ScopedChildren = true; 1195 if (FD->isTemplateInstantiation()) 1196 ScopedTraversal = true; 1197 } 1198 1199 ASTNodeNotSpelledInSourceScope RAII1(this, ScopedTraversal); 1200 ASTChildrenNotSpelledInSourceScope RAII2(this, ScopedChildren); 1201 1202 match(*DeclNode); 1203 return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode); 1204 } 1205 1206 bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) { 1207 if (!StmtNode) { 1208 return true; 1209 } 1210 bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 1211 TraversingASTChildrenNotSpelledInSource; 1212 1213 ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal); 1214 match(*StmtNode); 1215 return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode, Queue); 1216 } 1217 1218 bool MatchASTVisitor::TraverseType(QualType TypeNode) { 1219 match(TypeNode); 1220 return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode); 1221 } 1222 1223 bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) { 1224 // The RecursiveASTVisitor only visits types if they're not within TypeLocs. 1225 // We still want to find those types via matchers, so we match them here. Note 1226 // that the TypeLocs are structurally a shadow-hierarchy to the expressed 1227 // type, so we visit all involved parts of a compound type when matching on 1228 // each TypeLoc. 1229 match(TypeLocNode); 1230 match(TypeLocNode.getType()); 1231 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode); 1232 } 1233 1234 bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 1235 match(*NNS); 1236 return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS); 1237 } 1238 1239 bool MatchASTVisitor::TraverseNestedNameSpecifierLoc( 1240 NestedNameSpecifierLoc NNS) { 1241 if (!NNS) 1242 return true; 1243 1244 match(NNS); 1245 1246 // We only match the nested name specifier here (as opposed to traversing it) 1247 // because the traversal is already done in the parallel "Loc"-hierarchy. 1248 if (NNS.hasQualifier()) 1249 match(*NNS.getNestedNameSpecifier()); 1250 return 1251 RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS); 1252 } 1253 1254 bool MatchASTVisitor::TraverseConstructorInitializer( 1255 CXXCtorInitializer *CtorInit) { 1256 if (!CtorInit) 1257 return true; 1258 1259 bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 1260 TraversingASTChildrenNotSpelledInSource; 1261 1262 if (!CtorInit->isWritten()) 1263 ScopedTraversal = true; 1264 1265 ASTNodeNotSpelledInSourceScope RAII1(this, ScopedTraversal); 1266 1267 match(*CtorInit); 1268 1269 return RecursiveASTVisitor<MatchASTVisitor>::TraverseConstructorInitializer( 1270 CtorInit); 1271 } 1272 1273 bool MatchASTVisitor::TraverseTemplateArgumentLoc(TemplateArgumentLoc Loc) { 1274 match(Loc); 1275 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateArgumentLoc(Loc); 1276 } 1277 1278 class MatchASTConsumer : public ASTConsumer { 1279 public: 1280 MatchASTConsumer(MatchFinder *Finder, 1281 MatchFinder::ParsingDoneTestCallback *ParsingDone) 1282 : Finder(Finder), ParsingDone(ParsingDone) {} 1283 1284 private: 1285 void HandleTranslationUnit(ASTContext &Context) override { 1286 if (ParsingDone != nullptr) { 1287 ParsingDone->run(); 1288 } 1289 Finder->matchAST(Context); 1290 } 1291 1292 MatchFinder *Finder; 1293 MatchFinder::ParsingDoneTestCallback *ParsingDone; 1294 }; 1295 1296 } // end namespace 1297 } // end namespace internal 1298 1299 MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes, 1300 ASTContext *Context) 1301 : Nodes(Nodes), Context(Context), 1302 SourceManager(&Context->getSourceManager()) {} 1303 1304 MatchFinder::MatchCallback::~MatchCallback() {} 1305 MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {} 1306 1307 MatchFinder::MatchFinder(MatchFinderOptions Options) 1308 : Options(std::move(Options)), ParsingDone(nullptr) {} 1309 1310 MatchFinder::~MatchFinder() {} 1311 1312 void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch, 1313 MatchCallback *Action) { 1314 Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 1315 Matchers.AllCallbacks.insert(Action); 1316 } 1317 1318 void MatchFinder::addMatcher(const TypeMatcher &NodeMatch, 1319 MatchCallback *Action) { 1320 Matchers.Type.emplace_back(NodeMatch, Action); 1321 Matchers.AllCallbacks.insert(Action); 1322 } 1323 1324 void MatchFinder::addMatcher(const StatementMatcher &NodeMatch, 1325 MatchCallback *Action) { 1326 Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 1327 Matchers.AllCallbacks.insert(Action); 1328 } 1329 1330 void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch, 1331 MatchCallback *Action) { 1332 Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action); 1333 Matchers.AllCallbacks.insert(Action); 1334 } 1335 1336 void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch, 1337 MatchCallback *Action) { 1338 Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action); 1339 Matchers.AllCallbacks.insert(Action); 1340 } 1341 1342 void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch, 1343 MatchCallback *Action) { 1344 Matchers.TypeLoc.emplace_back(NodeMatch, Action); 1345 Matchers.AllCallbacks.insert(Action); 1346 } 1347 1348 void MatchFinder::addMatcher(const CXXCtorInitializerMatcher &NodeMatch, 1349 MatchCallback *Action) { 1350 Matchers.CtorInit.emplace_back(NodeMatch, Action); 1351 Matchers.AllCallbacks.insert(Action); 1352 } 1353 1354 void MatchFinder::addMatcher(const TemplateArgumentLocMatcher &NodeMatch, 1355 MatchCallback *Action) { 1356 Matchers.TemplateArgumentLoc.emplace_back(NodeMatch, Action); 1357 Matchers.AllCallbacks.insert(Action); 1358 } 1359 1360 bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, 1361 MatchCallback *Action) { 1362 if (NodeMatch.canConvertTo<Decl>()) { 1363 addMatcher(NodeMatch.convertTo<Decl>(), Action); 1364 return true; 1365 } else if (NodeMatch.canConvertTo<QualType>()) { 1366 addMatcher(NodeMatch.convertTo<QualType>(), Action); 1367 return true; 1368 } else if (NodeMatch.canConvertTo<Stmt>()) { 1369 addMatcher(NodeMatch.convertTo<Stmt>(), Action); 1370 return true; 1371 } else if (NodeMatch.canConvertTo<NestedNameSpecifier>()) { 1372 addMatcher(NodeMatch.convertTo<NestedNameSpecifier>(), Action); 1373 return true; 1374 } else if (NodeMatch.canConvertTo<NestedNameSpecifierLoc>()) { 1375 addMatcher(NodeMatch.convertTo<NestedNameSpecifierLoc>(), Action); 1376 return true; 1377 } else if (NodeMatch.canConvertTo<TypeLoc>()) { 1378 addMatcher(NodeMatch.convertTo<TypeLoc>(), Action); 1379 return true; 1380 } else if (NodeMatch.canConvertTo<CXXCtorInitializer>()) { 1381 addMatcher(NodeMatch.convertTo<CXXCtorInitializer>(), Action); 1382 return true; 1383 } else if (NodeMatch.canConvertTo<TemplateArgumentLoc>()) { 1384 addMatcher(NodeMatch.convertTo<TemplateArgumentLoc>(), Action); 1385 return true; 1386 } 1387 return false; 1388 } 1389 1390 std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() { 1391 return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone); 1392 } 1393 1394 void MatchFinder::match(const clang::DynTypedNode &Node, ASTContext &Context) { 1395 internal::MatchASTVisitor Visitor(&Matchers, Options); 1396 Visitor.set_active_ast_context(&Context); 1397 Visitor.match(Node); 1398 } 1399 1400 void MatchFinder::matchAST(ASTContext &Context) { 1401 internal::MatchASTVisitor Visitor(&Matchers, Options); 1402 Visitor.set_active_ast_context(&Context); 1403 Visitor.onStartOfTranslationUnit(); 1404 Visitor.TraverseAST(Context); 1405 Visitor.onEndOfTranslationUnit(); 1406 } 1407 1408 void MatchFinder::registerTestCallbackAfterParsing( 1409 MatchFinder::ParsingDoneTestCallback *NewParsingDone) { 1410 ParsingDone = NewParsingDone; 1411 } 1412 1413 StringRef MatchFinder::MatchCallback::getID() const { return "<unknown>"; } 1414 1415 } // end namespace ast_matchers 1416 } // end namespace clang 1417