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