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