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