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 // We use memoization to avoid running the same matcher on the same 47 // AST node twice. This struct is the key for looking up match 48 // result. It consists of an ID of the MatcherInterface (for 49 // identifying the matcher), a pointer to the AST node and the 50 // bound nodes before the matcher was executed. 51 // 52 // We currently only memoize on nodes whose pointers identify the 53 // nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc). 54 // For \c QualType and \c TypeLoc it is possible to implement 55 // generation of keys for each type. 56 // FIXME: Benchmark whether memoization of non-pointer typed nodes 57 // provides enough benefit for the additional amount of code. 58 struct MatchKey { 59 DynTypedMatcher::MatcherIDType MatcherID; 60 ast_type_traits::DynTypedNode Node; 61 BoundNodesTreeBuilder BoundNodes; 62 ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs; 63 64 bool operator<(const MatchKey &Other) const { 65 return std::tie(Traversal, MatcherID, Node, BoundNodes) < 66 std::tie(Other.Traversal, Other.MatcherID, Other.Node, 67 Other.BoundNodes); 68 } 69 }; 70 71 // Used to store the result of a match and possibly bound nodes. 72 struct MemoizedMatchResult { 73 bool ResultOfMatch; 74 BoundNodesTreeBuilder Nodes; 75 }; 76 77 // A RecursiveASTVisitor that traverses all children or all descendants of 78 // a node. 79 class MatchChildASTVisitor 80 : public RecursiveASTVisitor<MatchChildASTVisitor> { 81 public: 82 typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase; 83 84 // Creates an AST visitor that matches 'matcher' on all children or 85 // descendants of a traversed node. max_depth is the maximum depth 86 // to traverse: use 1 for matching the children and INT_MAX for 87 // matching the descendants. 88 MatchChildASTVisitor(const DynTypedMatcher *Matcher, ASTMatchFinder *Finder, 89 BoundNodesTreeBuilder *Builder, int MaxDepth, 90 ast_type_traits::TraversalKind Traversal, 91 ASTMatchFinder::BindKind Bind) 92 : Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0), 93 MaxDepth(MaxDepth), Traversal(Traversal), Bind(Bind), Matches(false) {} 94 95 // Returns true if a match is found in the subtree rooted at the 96 // given AST node. This is done via a set of mutually recursive 97 // functions. Here's how the recursion is done (the *wildcard can 98 // actually be Decl, Stmt, or Type): 99 // 100 // - Traverse(node) calls BaseTraverse(node) when it needs 101 // to visit the descendants of node. 102 // - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node)) 103 // Traverse*(c) for each child c of 'node'. 104 // - Traverse*(c) in turn calls Traverse(c), completing the 105 // recursion. 106 bool findMatch(const ast_type_traits::DynTypedNode &DynNode) { 107 reset(); 108 if (const Decl *D = DynNode.get<Decl>()) 109 traverse(*D); 110 else if (const Stmt *S = DynNode.get<Stmt>()) 111 traverse(*S); 112 else if (const NestedNameSpecifier *NNS = 113 DynNode.get<NestedNameSpecifier>()) 114 traverse(*NNS); 115 else if (const NestedNameSpecifierLoc *NNSLoc = 116 DynNode.get<NestedNameSpecifierLoc>()) 117 traverse(*NNSLoc); 118 else if (const QualType *Q = DynNode.get<QualType>()) 119 traverse(*Q); 120 else if (const TypeLoc *T = DynNode.get<TypeLoc>()) 121 traverse(*T); 122 else if (const auto *C = DynNode.get<CXXCtorInitializer>()) 123 traverse(*C); 124 // FIXME: Add other base types after adding tests. 125 126 // It's OK to always overwrite the bound nodes, as if there was 127 // no match in this recursive branch, the result set is empty 128 // anyway. 129 *Builder = ResultBindings; 130 131 return Matches; 132 } 133 134 // The following are overriding methods from the base visitor class. 135 // They are public only to allow CRTP to work. They are *not *part 136 // of the public API of this class. 137 bool TraverseDecl(Decl *DeclNode) { 138 ScopedIncrement ScopedDepth(&CurrentDepth); 139 return (DeclNode == nullptr) || traverse(*DeclNode); 140 } 141 142 Stmt *getStmtToTraverse(Stmt *StmtNode) { 143 Stmt *StmtToTraverse = StmtNode; 144 if (auto *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) { 145 auto *LambdaNode = dyn_cast_or_null<LambdaExpr>(StmtNode); 146 if (LambdaNode && 147 Finder->getASTContext().getParentMapContext().getTraversalKind() == 148 ast_type_traits::TK_IgnoreUnlessSpelledInSource) 149 StmtToTraverse = LambdaNode; 150 else 151 StmtToTraverse = 152 Finder->getASTContext().getParentMapContext().traverseIgnored( 153 ExprNode); 154 } 155 if (Traversal == 156 ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses) { 157 if (Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) 158 StmtToTraverse = ExprNode->IgnoreParenImpCasts(); 159 } 160 return StmtToTraverse; 161 } 162 163 bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) { 164 // If we need to keep track of the depth, we can't perform data recursion. 165 if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX)) 166 Queue = nullptr; 167 168 ScopedIncrement ScopedDepth(&CurrentDepth); 169 Stmt *StmtToTraverse = getStmtToTraverse(StmtNode); 170 if (!StmtToTraverse) 171 return true; 172 if (!match(*StmtToTraverse)) 173 return false; 174 return VisitorBase::TraverseStmt(StmtToTraverse, Queue); 175 } 176 // We assume that the QualType and the contained type are on the same 177 // hierarchy level. Thus, we try to match either of them. 178 bool TraverseType(QualType TypeNode) { 179 if (TypeNode.isNull()) 180 return true; 181 ScopedIncrement ScopedDepth(&CurrentDepth); 182 // Match the Type. 183 if (!match(*TypeNode)) 184 return false; 185 // The QualType is matched inside traverse. 186 return traverse(TypeNode); 187 } 188 // We assume that the TypeLoc, contained QualType and contained Type all are 189 // on the same hierarchy level. Thus, we try to match all of them. 190 bool TraverseTypeLoc(TypeLoc TypeLocNode) { 191 if (TypeLocNode.isNull()) 192 return true; 193 ScopedIncrement ScopedDepth(&CurrentDepth); 194 // Match the Type. 195 if (!match(*TypeLocNode.getType())) 196 return false; 197 // Match the QualType. 198 if (!match(TypeLocNode.getType())) 199 return false; 200 // The TypeLoc is matched inside traverse. 201 return traverse(TypeLocNode); 202 } 203 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 204 ScopedIncrement ScopedDepth(&CurrentDepth); 205 return (NNS == nullptr) || traverse(*NNS); 206 } 207 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 208 if (!NNS) 209 return true; 210 ScopedIncrement ScopedDepth(&CurrentDepth); 211 if (!match(*NNS.getNestedNameSpecifier())) 212 return false; 213 return traverse(NNS); 214 } 215 bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) { 216 if (!CtorInit) 217 return true; 218 ScopedIncrement ScopedDepth(&CurrentDepth); 219 return traverse(*CtorInit); 220 } 221 bool TraverseLambdaExpr(LambdaExpr *Node) { 222 if (Finder->getASTContext().getParentMapContext().getTraversalKind() != 223 ast_type_traits::TK_IgnoreUnlessSpelledInSource) 224 return VisitorBase::TraverseLambdaExpr(Node); 225 if (!Node) 226 return true; 227 ScopedIncrement ScopedDepth(&CurrentDepth); 228 229 for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { 230 const auto *C = Node->capture_begin() + I; 231 if (!C->isExplicit()) 232 continue; 233 if (Node->isInitCapture(C) && !match(*C->getCapturedVar())) 234 return false; 235 if (!match(*Node->capture_init_begin()[I])) 236 return false; 237 } 238 239 if (const auto *TPL = Node->getTemplateParameterList()) { 240 for (const auto *TP : *TPL) { 241 if (!match(*TP)) 242 return false; 243 } 244 } 245 246 for (const auto *P : Node->getCallOperator()->parameters()) { 247 if (!match(*P)) 248 return false; 249 } 250 251 if (!match(*Node->getBody())) 252 return false; 253 254 return true; 255 } 256 257 bool shouldVisitTemplateInstantiations() const { return true; } 258 bool shouldVisitImplicitCode() const { return true; } 259 260 private: 261 // Used for updating the depth during traversal. 262 struct ScopedIncrement { 263 explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); } 264 ~ScopedIncrement() { --(*Depth); } 265 266 private: 267 int *Depth; 268 }; 269 270 // Resets the state of this object. 271 void reset() { 272 Matches = false; 273 CurrentDepth = 0; 274 } 275 276 // Forwards the call to the corresponding Traverse*() method in the 277 // base visitor class. 278 bool baseTraverse(const Decl &DeclNode) { 279 return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode)); 280 } 281 bool baseTraverse(const Stmt &StmtNode) { 282 return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode)); 283 } 284 bool baseTraverse(QualType TypeNode) { 285 return VisitorBase::TraverseType(TypeNode); 286 } 287 bool baseTraverse(TypeLoc TypeLocNode) { 288 return VisitorBase::TraverseTypeLoc(TypeLocNode); 289 } 290 bool baseTraverse(const NestedNameSpecifier &NNS) { 291 return VisitorBase::TraverseNestedNameSpecifier( 292 const_cast<NestedNameSpecifier*>(&NNS)); 293 } 294 bool baseTraverse(NestedNameSpecifierLoc NNS) { 295 return VisitorBase::TraverseNestedNameSpecifierLoc(NNS); 296 } 297 bool baseTraverse(const CXXCtorInitializer &CtorInit) { 298 return VisitorBase::TraverseConstructorInitializer( 299 const_cast<CXXCtorInitializer *>(&CtorInit)); 300 } 301 302 // Sets 'Matched' to true if 'Matcher' matches 'Node' and: 303 // 0 < CurrentDepth <= MaxDepth. 304 // 305 // Returns 'true' if traversal should continue after this function 306 // returns, i.e. if no match is found or 'Bind' is 'BK_All'. 307 template <typename T> 308 bool match(const T &Node) { 309 if (CurrentDepth == 0 || CurrentDepth > MaxDepth) { 310 return true; 311 } 312 if (Bind != ASTMatchFinder::BK_All) { 313 BoundNodesTreeBuilder RecursiveBuilder(*Builder); 314 if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder, 315 &RecursiveBuilder)) { 316 Matches = true; 317 ResultBindings.addMatch(RecursiveBuilder); 318 return false; // Abort as soon as a match is found. 319 } 320 } else { 321 BoundNodesTreeBuilder RecursiveBuilder(*Builder); 322 if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder, 323 &RecursiveBuilder)) { 324 // After the first match the matcher succeeds. 325 Matches = true; 326 ResultBindings.addMatch(RecursiveBuilder); 327 } 328 } 329 return true; 330 } 331 332 // Traverses the subtree rooted at 'Node'; returns true if the 333 // traversal should continue after this function returns. 334 template <typename T> 335 bool traverse(const T &Node) { 336 static_assert(IsBaseType<T>::value, 337 "traverse can only be instantiated with base type"); 338 if (!match(Node)) 339 return false; 340 return baseTraverse(Node); 341 } 342 343 const DynTypedMatcher *const Matcher; 344 ASTMatchFinder *const Finder; 345 BoundNodesTreeBuilder *const Builder; 346 BoundNodesTreeBuilder ResultBindings; 347 int CurrentDepth; 348 const int MaxDepth; 349 const ast_type_traits::TraversalKind Traversal; 350 const ASTMatchFinder::BindKind Bind; 351 bool Matches; 352 }; 353 354 // Controls the outermost traversal of the AST and allows to match multiple 355 // matchers. 356 class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, 357 public ASTMatchFinder { 358 public: 359 MatchASTVisitor(const MatchFinder::MatchersByType *Matchers, 360 const MatchFinder::MatchFinderOptions &Options) 361 : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {} 362 363 ~MatchASTVisitor() override { 364 if (Options.CheckProfiling) { 365 Options.CheckProfiling->Records = std::move(TimeByBucket); 366 } 367 } 368 369 void onStartOfTranslationUnit() { 370 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 371 TimeBucketRegion Timer; 372 for (MatchCallback *MC : Matchers->AllCallbacks) { 373 if (EnableCheckProfiling) 374 Timer.setBucket(&TimeByBucket[MC->getID()]); 375 MC->onStartOfTranslationUnit(); 376 } 377 } 378 379 void onEndOfTranslationUnit() { 380 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 381 TimeBucketRegion Timer; 382 for (MatchCallback *MC : Matchers->AllCallbacks) { 383 if (EnableCheckProfiling) 384 Timer.setBucket(&TimeByBucket[MC->getID()]); 385 MC->onEndOfTranslationUnit(); 386 } 387 } 388 389 void set_active_ast_context(ASTContext *NewActiveASTContext) { 390 ActiveASTContext = NewActiveASTContext; 391 } 392 393 // The following Visit*() and Traverse*() functions "override" 394 // methods in RecursiveASTVisitor. 395 396 bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) { 397 // When we see 'typedef A B', we add name 'B' to the set of names 398 // A's canonical type maps to. This is necessary for implementing 399 // isDerivedFrom(x) properly, where x can be the name of the base 400 // class or any of its aliases. 401 // 402 // In general, the is-alias-of (as defined by typedefs) relation 403 // is tree-shaped, as you can typedef a type more than once. For 404 // example, 405 // 406 // typedef A B; 407 // typedef A C; 408 // typedef C D; 409 // typedef C E; 410 // 411 // gives you 412 // 413 // A 414 // |- B 415 // `- C 416 // |- D 417 // `- E 418 // 419 // It is wrong to assume that the relation is a chain. A correct 420 // implementation of isDerivedFrom() needs to recognize that B and 421 // E are aliases, even though neither is a typedef of the other. 422 // Therefore, we cannot simply walk through one typedef chain to 423 // find out whether the type name matches. 424 const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr(); 425 const Type *CanonicalType = // root of the typedef tree 426 ActiveASTContext->getCanonicalType(TypeNode); 427 TypeAliases[CanonicalType].insert(DeclNode); 428 return true; 429 } 430 431 bool VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { 432 const ObjCInterfaceDecl *InterfaceDecl = CAD->getClassInterface(); 433 CompatibleAliases[InterfaceDecl].insert(CAD); 434 return true; 435 } 436 437 bool TraverseDecl(Decl *DeclNode); 438 bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr); 439 bool TraverseType(QualType TypeNode); 440 bool TraverseTypeLoc(TypeLoc TypeNode); 441 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); 442 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 443 bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit); 444 445 // Matches children or descendants of 'Node' with 'BaseMatcher'. 446 bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node, 447 ASTContext &Ctx, 448 const DynTypedMatcher &Matcher, 449 BoundNodesTreeBuilder *Builder, int MaxDepth, 450 ast_type_traits::TraversalKind Traversal, 451 BindKind Bind) { 452 // For AST-nodes that don't have an identity, we can't memoize. 453 if (!Node.getMemoizationData() || !Builder->isComparable()) 454 return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal, 455 Bind); 456 457 MatchKey Key; 458 Key.MatcherID = Matcher.getID(); 459 Key.Node = Node; 460 // Note that we key on the bindings *before* the match. 461 Key.BoundNodes = *Builder; 462 Key.Traversal = Ctx.getParentMapContext().getTraversalKind(); 463 464 MemoizationMap::iterator I = ResultCache.find(Key); 465 if (I != ResultCache.end()) { 466 *Builder = I->second.Nodes; 467 return I->second.ResultOfMatch; 468 } 469 470 MemoizedMatchResult Result; 471 Result.Nodes = *Builder; 472 Result.ResultOfMatch = matchesRecursively(Node, Matcher, &Result.Nodes, 473 MaxDepth, Traversal, Bind); 474 475 MemoizedMatchResult &CachedResult = ResultCache[Key]; 476 CachedResult = std::move(Result); 477 478 *Builder = CachedResult.Nodes; 479 return CachedResult.ResultOfMatch; 480 } 481 482 // Matches children or descendants of 'Node' with 'BaseMatcher'. 483 bool matchesRecursively(const ast_type_traits::DynTypedNode &Node, 484 const DynTypedMatcher &Matcher, 485 BoundNodesTreeBuilder *Builder, int MaxDepth, 486 ast_type_traits::TraversalKind Traversal, 487 BindKind Bind) { 488 MatchChildASTVisitor Visitor( 489 &Matcher, this, Builder, MaxDepth, Traversal, Bind); 490 return Visitor.findMatch(Node); 491 } 492 493 bool classIsDerivedFrom(const CXXRecordDecl *Declaration, 494 const Matcher<NamedDecl> &Base, 495 BoundNodesTreeBuilder *Builder, 496 bool Directly) override; 497 498 bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration, 499 const Matcher<NamedDecl> &Base, 500 BoundNodesTreeBuilder *Builder, 501 bool Directly) override; 502 503 // Implements ASTMatchFinder::matchesChildOf. 504 bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, 505 ASTContext &Ctx, const DynTypedMatcher &Matcher, 506 BoundNodesTreeBuilder *Builder, 507 ast_type_traits::TraversalKind Traversal, 508 BindKind Bind) override { 509 if (ResultCache.size() > MaxMemoizationEntries) 510 ResultCache.clear(); 511 return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, 1, Traversal, 512 Bind); 513 } 514 // Implements ASTMatchFinder::matchesDescendantOf. 515 bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, 516 ASTContext &Ctx, const DynTypedMatcher &Matcher, 517 BoundNodesTreeBuilder *Builder, 518 BindKind Bind) override { 519 if (ResultCache.size() > MaxMemoizationEntries) 520 ResultCache.clear(); 521 return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, INT_MAX, 522 ast_type_traits::TraversalKind::TK_AsIs, 523 Bind); 524 } 525 // Implements ASTMatchFinder::matchesAncestorOf. 526 bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node, 527 ASTContext &Ctx, const DynTypedMatcher &Matcher, 528 BoundNodesTreeBuilder *Builder, 529 AncestorMatchMode MatchMode) override { 530 // Reset the cache outside of the recursive call to make sure we 531 // don't invalidate any iterators. 532 if (ResultCache.size() > MaxMemoizationEntries) 533 ResultCache.clear(); 534 return memoizedMatchesAncestorOfRecursively(Node, Ctx, Matcher, Builder, 535 MatchMode); 536 } 537 538 // Matches all registered matchers on the given node and calls the 539 // result callback for every node that matches. 540 void match(const ast_type_traits::DynTypedNode &Node) { 541 // FIXME: Improve this with a switch or a visitor pattern. 542 if (auto *N = Node.get<Decl>()) { 543 match(*N); 544 } else if (auto *N = Node.get<Stmt>()) { 545 match(*N); 546 } else if (auto *N = Node.get<Type>()) { 547 match(*N); 548 } else if (auto *N = Node.get<QualType>()) { 549 match(*N); 550 } else if (auto *N = Node.get<NestedNameSpecifier>()) { 551 match(*N); 552 } else if (auto *N = Node.get<NestedNameSpecifierLoc>()) { 553 match(*N); 554 } else if (auto *N = Node.get<TypeLoc>()) { 555 match(*N); 556 } else if (auto *N = Node.get<CXXCtorInitializer>()) { 557 match(*N); 558 } 559 } 560 561 template <typename T> void match(const T &Node) { 562 matchDispatch(&Node); 563 } 564 565 // Implements ASTMatchFinder::getASTContext. 566 ASTContext &getASTContext() const override { return *ActiveASTContext; } 567 568 bool shouldVisitTemplateInstantiations() const { return true; } 569 bool shouldVisitImplicitCode() const { return true; } 570 571 private: 572 class TimeBucketRegion { 573 public: 574 TimeBucketRegion() : Bucket(nullptr) {} 575 ~TimeBucketRegion() { setBucket(nullptr); } 576 577 /// Start timing for \p NewBucket. 578 /// 579 /// If there was a bucket already set, it will finish the timing for that 580 /// other bucket. 581 /// \p NewBucket will be timed until the next call to \c setBucket() or 582 /// until the \c TimeBucketRegion is destroyed. 583 /// If \p NewBucket is the same as the currently timed bucket, this call 584 /// does nothing. 585 void setBucket(llvm::TimeRecord *NewBucket) { 586 if (Bucket != NewBucket) { 587 auto Now = llvm::TimeRecord::getCurrentTime(true); 588 if (Bucket) 589 *Bucket += Now; 590 if (NewBucket) 591 *NewBucket -= Now; 592 Bucket = NewBucket; 593 } 594 } 595 596 private: 597 llvm::TimeRecord *Bucket; 598 }; 599 600 /// Runs all the \p Matchers on \p Node. 601 /// 602 /// Used by \c matchDispatch() below. 603 template <typename T, typename MC> 604 void matchWithoutFilter(const T &Node, const MC &Matchers) { 605 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 606 TimeBucketRegion Timer; 607 for (const auto &MP : Matchers) { 608 if (EnableCheckProfiling) 609 Timer.setBucket(&TimeByBucket[MP.second->getID()]); 610 BoundNodesTreeBuilder Builder; 611 if (MP.first.matches(Node, this, &Builder)) { 612 MatchVisitor Visitor(ActiveASTContext, MP.second); 613 Builder.visitMatches(&Visitor); 614 } 615 } 616 } 617 618 void matchWithFilter(const ast_type_traits::DynTypedNode &DynNode) { 619 auto Kind = DynNode.getNodeKind(); 620 auto it = MatcherFiltersMap.find(Kind); 621 const auto &Filter = 622 it != MatcherFiltersMap.end() ? it->second : getFilterForKind(Kind); 623 624 if (Filter.empty()) 625 return; 626 627 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 628 TimeBucketRegion Timer; 629 auto &Matchers = this->Matchers->DeclOrStmt; 630 for (unsigned short I : Filter) { 631 auto &MP = Matchers[I]; 632 if (EnableCheckProfiling) 633 Timer.setBucket(&TimeByBucket[MP.second->getID()]); 634 BoundNodesTreeBuilder Builder; 635 if (MP.first.matches(DynNode, this, &Builder)) { 636 MatchVisitor Visitor(ActiveASTContext, MP.second); 637 Builder.visitMatches(&Visitor); 638 } 639 } 640 } 641 642 const std::vector<unsigned short> & 643 getFilterForKind(ast_type_traits::ASTNodeKind Kind) { 644 auto &Filter = MatcherFiltersMap[Kind]; 645 auto &Matchers = this->Matchers->DeclOrStmt; 646 assert((Matchers.size() < USHRT_MAX) && "Too many matchers."); 647 for (unsigned I = 0, E = Matchers.size(); I != E; ++I) { 648 if (Matchers[I].first.canMatchNodesOfKind(Kind)) { 649 Filter.push_back(I); 650 } 651 } 652 return Filter; 653 } 654 655 /// @{ 656 /// Overloads to pair the different node types to their matchers. 657 void matchDispatch(const Decl *Node) { 658 return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node)); 659 } 660 void matchDispatch(const Stmt *Node) { 661 return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node)); 662 } 663 664 void matchDispatch(const Type *Node) { 665 matchWithoutFilter(QualType(Node, 0), Matchers->Type); 666 } 667 void matchDispatch(const TypeLoc *Node) { 668 matchWithoutFilter(*Node, Matchers->TypeLoc); 669 } 670 void matchDispatch(const QualType *Node) { 671 matchWithoutFilter(*Node, Matchers->Type); 672 } 673 void matchDispatch(const NestedNameSpecifier *Node) { 674 matchWithoutFilter(*Node, Matchers->NestedNameSpecifier); 675 } 676 void matchDispatch(const NestedNameSpecifierLoc *Node) { 677 matchWithoutFilter(*Node, Matchers->NestedNameSpecifierLoc); 678 } 679 void matchDispatch(const CXXCtorInitializer *Node) { 680 matchWithoutFilter(*Node, Matchers->CtorInit); 681 } 682 void matchDispatch(const void *) { /* Do nothing. */ } 683 /// @} 684 685 // Returns whether an ancestor of \p Node matches \p Matcher. 686 // 687 // The order of matching ((which can lead to different nodes being bound in 688 // case there are multiple matches) is breadth first search. 689 // 690 // To allow memoization in the very common case of having deeply nested 691 // expressions inside a template function, we first walk up the AST, memoizing 692 // the result of the match along the way, as long as there is only a single 693 // parent. 694 // 695 // Once there are multiple parents, the breadth first search order does not 696 // allow simple memoization on the ancestors. Thus, we only memoize as long 697 // as there is a single parent. 698 bool memoizedMatchesAncestorOfRecursively( 699 const ast_type_traits::DynTypedNode &Node, ASTContext &Ctx, 700 const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, 701 AncestorMatchMode MatchMode) { 702 // For AST-nodes that don't have an identity, we can't memoize. 703 if (!Builder->isComparable()) 704 return matchesAncestorOfRecursively(Node, Ctx, Matcher, Builder, 705 MatchMode); 706 707 MatchKey Key; 708 Key.MatcherID = Matcher.getID(); 709 Key.Node = Node; 710 Key.BoundNodes = *Builder; 711 Key.Traversal = Ctx.getParentMapContext().getTraversalKind(); 712 713 // Note that we cannot use insert and reuse the iterator, as recursive 714 // calls to match might invalidate the result cache iterators. 715 MemoizationMap::iterator I = ResultCache.find(Key); 716 if (I != ResultCache.end()) { 717 *Builder = I->second.Nodes; 718 return I->second.ResultOfMatch; 719 } 720 721 MemoizedMatchResult Result; 722 Result.Nodes = *Builder; 723 Result.ResultOfMatch = matchesAncestorOfRecursively( 724 Node, Ctx, Matcher, &Result.Nodes, MatchMode); 725 726 MemoizedMatchResult &CachedResult = ResultCache[Key]; 727 CachedResult = std::move(Result); 728 729 *Builder = CachedResult.Nodes; 730 return CachedResult.ResultOfMatch; 731 } 732 733 bool matchesAncestorOfRecursively(const ast_type_traits::DynTypedNode &Node, 734 ASTContext &Ctx, 735 const DynTypedMatcher &Matcher, 736 BoundNodesTreeBuilder *Builder, 737 AncestorMatchMode MatchMode) { 738 const auto &Parents = ActiveASTContext->getParents(Node); 739 if (Parents.empty()) { 740 // Nodes may have no parents if: 741 // a) the node is the TranslationUnitDecl 742 // b) we have a limited traversal scope that excludes the parent edges 743 // c) there is a bug in the AST, and the node is not reachable 744 // Usually the traversal scope is the whole AST, which precludes b. 745 // Bugs are common enough that it's worthwhile asserting when we can. 746 #ifndef NDEBUG 747 if (!Node.get<TranslationUnitDecl>() && 748 /* Traversal scope is full AST if any of the bounds are the TU */ 749 llvm::any_of(ActiveASTContext->getTraversalScope(), [](Decl *D) { 750 return D->getKind() == Decl::TranslationUnit; 751 })) { 752 llvm::errs() << "Tried to match orphan node:\n"; 753 Node.dump(llvm::errs(), ActiveASTContext->getSourceManager()); 754 llvm_unreachable("Parent map should be complete!"); 755 } 756 #endif 757 return false; 758 } 759 if (Parents.size() == 1) { 760 // Only one parent - do recursive memoization. 761 const ast_type_traits::DynTypedNode Parent = Parents[0]; 762 BoundNodesTreeBuilder BuilderCopy = *Builder; 763 if (Matcher.matches(Parent, this, &BuilderCopy)) { 764 *Builder = std::move(BuilderCopy); 765 return true; 766 } 767 if (MatchMode != ASTMatchFinder::AMM_ParentOnly) { 768 return memoizedMatchesAncestorOfRecursively(Parent, Ctx, Matcher, 769 Builder, MatchMode); 770 // Once we get back from the recursive call, the result will be the 771 // same as the parent's result. 772 } 773 } else { 774 // Multiple parents - BFS over the rest of the nodes. 775 llvm::DenseSet<const void *> Visited; 776 std::deque<ast_type_traits::DynTypedNode> Queue(Parents.begin(), 777 Parents.end()); 778 while (!Queue.empty()) { 779 BoundNodesTreeBuilder BuilderCopy = *Builder; 780 if (Matcher.matches(Queue.front(), this, &BuilderCopy)) { 781 *Builder = std::move(BuilderCopy); 782 return true; 783 } 784 if (MatchMode != ASTMatchFinder::AMM_ParentOnly) { 785 for (const auto &Parent : 786 ActiveASTContext->getParents(Queue.front())) { 787 // Make sure we do not visit the same node twice. 788 // Otherwise, we'll visit the common ancestors as often as there 789 // are splits on the way down. 790 if (Visited.insert(Parent.getMemoizationData()).second) 791 Queue.push_back(Parent); 792 } 793 } 794 Queue.pop_front(); 795 } 796 } 797 return false; 798 } 799 800 // Implements a BoundNodesTree::Visitor that calls a MatchCallback with 801 // the aggregated bound nodes for each match. 802 class MatchVisitor : public BoundNodesTreeBuilder::Visitor { 803 public: 804 MatchVisitor(ASTContext* Context, 805 MatchFinder::MatchCallback* Callback) 806 : Context(Context), 807 Callback(Callback) {} 808 809 void visitMatch(const BoundNodes& BoundNodesView) override { 810 Callback->run(MatchFinder::MatchResult(BoundNodesView, Context)); 811 } 812 813 private: 814 ASTContext* Context; 815 MatchFinder::MatchCallback* Callback; 816 }; 817 818 // Returns true if 'TypeNode' has an alias that matches the given matcher. 819 bool typeHasMatchingAlias(const Type *TypeNode, 820 const Matcher<NamedDecl> &Matcher, 821 BoundNodesTreeBuilder *Builder) { 822 const Type *const CanonicalType = 823 ActiveASTContext->getCanonicalType(TypeNode); 824 auto Aliases = TypeAliases.find(CanonicalType); 825 if (Aliases == TypeAliases.end()) 826 return false; 827 for (const TypedefNameDecl *Alias : Aliases->second) { 828 BoundNodesTreeBuilder Result(*Builder); 829 if (Matcher.matches(*Alias, this, &Result)) { 830 *Builder = std::move(Result); 831 return true; 832 } 833 } 834 return false; 835 } 836 837 bool 838 objcClassHasMatchingCompatibilityAlias(const ObjCInterfaceDecl *InterfaceDecl, 839 const Matcher<NamedDecl> &Matcher, 840 BoundNodesTreeBuilder *Builder) { 841 auto Aliases = CompatibleAliases.find(InterfaceDecl); 842 if (Aliases == CompatibleAliases.end()) 843 return false; 844 for (const ObjCCompatibleAliasDecl *Alias : Aliases->second) { 845 BoundNodesTreeBuilder Result(*Builder); 846 if (Matcher.matches(*Alias, this, &Result)) { 847 *Builder = std::move(Result); 848 return true; 849 } 850 } 851 return false; 852 } 853 854 /// Bucket to record map. 855 /// 856 /// Used to get the appropriate bucket for each matcher. 857 llvm::StringMap<llvm::TimeRecord> TimeByBucket; 858 859 const MatchFinder::MatchersByType *Matchers; 860 861 /// Filtered list of matcher indices for each matcher kind. 862 /// 863 /// \c Decl and \c Stmt toplevel matchers usually apply to a specific node 864 /// kind (and derived kinds) so it is a waste to try every matcher on every 865 /// node. 866 /// We precalculate a list of matchers that pass the toplevel restrict check. 867 llvm::DenseMap<ast_type_traits::ASTNodeKind, std::vector<unsigned short>> 868 MatcherFiltersMap; 869 870 const MatchFinder::MatchFinderOptions &Options; 871 ASTContext *ActiveASTContext; 872 873 // Maps a canonical type to its TypedefDecls. 874 llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases; 875 876 // Maps an Objective-C interface to its ObjCCompatibleAliasDecls. 877 llvm::DenseMap<const ObjCInterfaceDecl *, 878 llvm::SmallPtrSet<const ObjCCompatibleAliasDecl *, 2>> 879 CompatibleAliases; 880 881 // Maps (matcher, node) -> the match result for memoization. 882 typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap; 883 MemoizationMap ResultCache; 884 }; 885 886 static CXXRecordDecl * 887 getAsCXXRecordDeclOrPrimaryTemplate(const Type *TypeNode) { 888 if (auto *RD = TypeNode->getAsCXXRecordDecl()) 889 return RD; 890 891 // Find the innermost TemplateSpecializationType that isn't an alias template. 892 auto *TemplateType = TypeNode->getAs<TemplateSpecializationType>(); 893 while (TemplateType && TemplateType->isTypeAlias()) 894 TemplateType = 895 TemplateType->getAliasedType()->getAs<TemplateSpecializationType>(); 896 897 // If this is the name of a (dependent) template specialization, use the 898 // definition of the template, even though it might be specialized later. 899 if (TemplateType) 900 if (auto *ClassTemplate = dyn_cast_or_null<ClassTemplateDecl>( 901 TemplateType->getTemplateName().getAsTemplateDecl())) 902 return ClassTemplate->getTemplatedDecl(); 903 904 return nullptr; 905 } 906 907 // Returns true if the given C++ class is directly or indirectly derived 908 // from a base type with the given name. A class is not considered to be 909 // derived from itself. 910 bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration, 911 const Matcher<NamedDecl> &Base, 912 BoundNodesTreeBuilder *Builder, 913 bool Directly) { 914 if (!Declaration->hasDefinition()) 915 return false; 916 for (const auto &It : Declaration->bases()) { 917 const Type *TypeNode = It.getType().getTypePtr(); 918 919 if (typeHasMatchingAlias(TypeNode, Base, Builder)) 920 return true; 921 922 // FIXME: Going to the primary template here isn't really correct, but 923 // unfortunately we accept a Decl matcher for the base class not a Type 924 // matcher, so it's the best thing we can do with our current interface. 925 CXXRecordDecl *ClassDecl = getAsCXXRecordDeclOrPrimaryTemplate(TypeNode); 926 if (!ClassDecl) 927 continue; 928 if (ClassDecl == Declaration) { 929 // This can happen for recursive template definitions; if the 930 // current declaration did not match, we can safely return false. 931 return false; 932 } 933 BoundNodesTreeBuilder Result(*Builder); 934 if (Base.matches(*ClassDecl, this, &Result)) { 935 *Builder = std::move(Result); 936 return true; 937 } 938 if (!Directly && classIsDerivedFrom(ClassDecl, Base, Builder, Directly)) 939 return true; 940 } 941 return false; 942 } 943 944 // Returns true if the given Objective-C class is directly or indirectly 945 // derived from a matching base class. A class is not considered to be derived 946 // from itself. 947 bool MatchASTVisitor::objcClassIsDerivedFrom( 948 const ObjCInterfaceDecl *Declaration, const Matcher<NamedDecl> &Base, 949 BoundNodesTreeBuilder *Builder, bool Directly) { 950 // Check if any of the superclasses of the class match. 951 for (const ObjCInterfaceDecl *ClassDecl = Declaration->getSuperClass(); 952 ClassDecl != nullptr; ClassDecl = ClassDecl->getSuperClass()) { 953 // Check if there are any matching compatibility aliases. 954 if (objcClassHasMatchingCompatibilityAlias(ClassDecl, Base, Builder)) 955 return true; 956 957 // Check if there are any matching type aliases. 958 const Type *TypeNode = ClassDecl->getTypeForDecl(); 959 if (typeHasMatchingAlias(TypeNode, Base, Builder)) 960 return true; 961 962 if (Base.matches(*ClassDecl, this, Builder)) 963 return true; 964 965 // Not `return false` as a temporary workaround for PR43879. 966 if (Directly) 967 break; 968 } 969 970 return false; 971 } 972 973 bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) { 974 if (!DeclNode) { 975 return true; 976 } 977 match(*DeclNode); 978 return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode); 979 } 980 981 bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) { 982 if (!StmtNode) { 983 return true; 984 } 985 match(*StmtNode); 986 return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode, Queue); 987 } 988 989 bool MatchASTVisitor::TraverseType(QualType TypeNode) { 990 match(TypeNode); 991 return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode); 992 } 993 994 bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) { 995 // The RecursiveASTVisitor only visits types if they're not within TypeLocs. 996 // We still want to find those types via matchers, so we match them here. Note 997 // that the TypeLocs are structurally a shadow-hierarchy to the expressed 998 // type, so we visit all involved parts of a compound type when matching on 999 // each TypeLoc. 1000 match(TypeLocNode); 1001 match(TypeLocNode.getType()); 1002 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode); 1003 } 1004 1005 bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 1006 match(*NNS); 1007 return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS); 1008 } 1009 1010 bool MatchASTVisitor::TraverseNestedNameSpecifierLoc( 1011 NestedNameSpecifierLoc NNS) { 1012 if (!NNS) 1013 return true; 1014 1015 match(NNS); 1016 1017 // We only match the nested name specifier here (as opposed to traversing it) 1018 // because the traversal is already done in the parallel "Loc"-hierarchy. 1019 if (NNS.hasQualifier()) 1020 match(*NNS.getNestedNameSpecifier()); 1021 return 1022 RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS); 1023 } 1024 1025 bool MatchASTVisitor::TraverseConstructorInitializer( 1026 CXXCtorInitializer *CtorInit) { 1027 if (!CtorInit) 1028 return true; 1029 1030 match(*CtorInit); 1031 1032 return RecursiveASTVisitor<MatchASTVisitor>::TraverseConstructorInitializer( 1033 CtorInit); 1034 } 1035 1036 class MatchASTConsumer : public ASTConsumer { 1037 public: 1038 MatchASTConsumer(MatchFinder *Finder, 1039 MatchFinder::ParsingDoneTestCallback *ParsingDone) 1040 : Finder(Finder), ParsingDone(ParsingDone) {} 1041 1042 private: 1043 void HandleTranslationUnit(ASTContext &Context) override { 1044 if (ParsingDone != nullptr) { 1045 ParsingDone->run(); 1046 } 1047 Finder->matchAST(Context); 1048 } 1049 1050 MatchFinder *Finder; 1051 MatchFinder::ParsingDoneTestCallback *ParsingDone; 1052 }; 1053 1054 } // end namespace 1055 } // end namespace internal 1056 1057 MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes, 1058 ASTContext *Context) 1059 : Nodes(Nodes), Context(Context), 1060 SourceManager(&Context->getSourceManager()) {} 1061 1062 MatchFinder::MatchCallback::~MatchCallback() {} 1063 MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {} 1064 1065 MatchFinder::MatchFinder(MatchFinderOptions Options) 1066 : Options(std::move(Options)), ParsingDone(nullptr) {} 1067 1068 MatchFinder::~MatchFinder() {} 1069 1070 void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch, 1071 MatchCallback *Action) { 1072 Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 1073 Matchers.AllCallbacks.insert(Action); 1074 } 1075 1076 void MatchFinder::addMatcher(const TypeMatcher &NodeMatch, 1077 MatchCallback *Action) { 1078 Matchers.Type.emplace_back(NodeMatch, Action); 1079 Matchers.AllCallbacks.insert(Action); 1080 } 1081 1082 void MatchFinder::addMatcher(const StatementMatcher &NodeMatch, 1083 MatchCallback *Action) { 1084 Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 1085 Matchers.AllCallbacks.insert(Action); 1086 } 1087 1088 void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch, 1089 MatchCallback *Action) { 1090 Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action); 1091 Matchers.AllCallbacks.insert(Action); 1092 } 1093 1094 void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch, 1095 MatchCallback *Action) { 1096 Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action); 1097 Matchers.AllCallbacks.insert(Action); 1098 } 1099 1100 void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch, 1101 MatchCallback *Action) { 1102 Matchers.TypeLoc.emplace_back(NodeMatch, Action); 1103 Matchers.AllCallbacks.insert(Action); 1104 } 1105 1106 void MatchFinder::addMatcher(const CXXCtorInitializerMatcher &NodeMatch, 1107 MatchCallback *Action) { 1108 Matchers.CtorInit.emplace_back(NodeMatch, Action); 1109 Matchers.AllCallbacks.insert(Action); 1110 } 1111 1112 bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, 1113 MatchCallback *Action) { 1114 if (NodeMatch.canConvertTo<Decl>()) { 1115 addMatcher(NodeMatch.convertTo<Decl>(), Action); 1116 return true; 1117 } else if (NodeMatch.canConvertTo<QualType>()) { 1118 addMatcher(NodeMatch.convertTo<QualType>(), Action); 1119 return true; 1120 } else if (NodeMatch.canConvertTo<Stmt>()) { 1121 addMatcher(NodeMatch.convertTo<Stmt>(), Action); 1122 return true; 1123 } else if (NodeMatch.canConvertTo<NestedNameSpecifier>()) { 1124 addMatcher(NodeMatch.convertTo<NestedNameSpecifier>(), Action); 1125 return true; 1126 } else if (NodeMatch.canConvertTo<NestedNameSpecifierLoc>()) { 1127 addMatcher(NodeMatch.convertTo<NestedNameSpecifierLoc>(), Action); 1128 return true; 1129 } else if (NodeMatch.canConvertTo<TypeLoc>()) { 1130 addMatcher(NodeMatch.convertTo<TypeLoc>(), Action); 1131 return true; 1132 } else if (NodeMatch.canConvertTo<CXXCtorInitializer>()) { 1133 addMatcher(NodeMatch.convertTo<CXXCtorInitializer>(), Action); 1134 return true; 1135 } 1136 return false; 1137 } 1138 1139 std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() { 1140 return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone); 1141 } 1142 1143 void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node, 1144 ASTContext &Context) { 1145 internal::MatchASTVisitor Visitor(&Matchers, Options); 1146 Visitor.set_active_ast_context(&Context); 1147 Visitor.match(Node); 1148 } 1149 1150 void MatchFinder::matchAST(ASTContext &Context) { 1151 internal::MatchASTVisitor Visitor(&Matchers, Options); 1152 Visitor.set_active_ast_context(&Context); 1153 Visitor.onStartOfTranslationUnit(); 1154 Visitor.TraverseAST(Context); 1155 Visitor.onEndOfTranslationUnit(); 1156 } 1157 1158 void MatchFinder::registerTestCallbackAfterParsing( 1159 MatchFinder::ParsingDoneTestCallback *NewParsingDone) { 1160 ParsingDone = NewParsingDone; 1161 } 1162 1163 StringRef MatchFinder::MatchCallback::getID() const { return "<unknown>"; } 1164 1165 } // end namespace ast_matchers 1166 } // end namespace clang 1167