1 //===--- ASTMatchFinder.cpp - Structural query framework ------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Implements an algorithm to efficiently search for matches on AST nodes. 11 // Uses memoization to support recursive matches like HasDescendant. 12 // 13 // The general idea is to visit all AST nodes with a RecursiveASTVisitor, 14 // calling the Matches(...) method of each matcher we are running on each 15 // AST node. The matcher can recurse via the ASTMatchFinder interface. 16 // 17 //===----------------------------------------------------------------------===// 18 19 #include "clang/ASTMatchers/ASTMatchFinder.h" 20 #include "clang/AST/ASTConsumer.h" 21 #include "clang/AST/ASTContext.h" 22 #include "clang/AST/RecursiveASTVisitor.h" 23 #include "llvm/ADT/DenseMap.h" 24 #include "llvm/ADT/StringMap.h" 25 #include "llvm/Support/Timer.h" 26 #include <deque> 27 #include <memory> 28 #include <set> 29 30 namespace clang { 31 namespace ast_matchers { 32 namespace internal { 33 namespace { 34 35 typedef MatchFinder::MatchCallback MatchCallback; 36 37 // The maximum number of memoization entries to store. 38 // 10k has been experimentally found to give a good trade-off 39 // of performance vs. memory consumption by running matcher 40 // that match on every statement over a very large codebase. 41 // 42 // FIXME: Do some performance optimization in general and 43 // revisit this number; also, put up micro-benchmarks that we can 44 // optimize this on. 45 static const unsigned MaxMemoizationEntries = 10000; 46 47 // We use memoization to avoid running the same matcher on the same 48 // AST node twice. This struct is the key for looking up match 49 // result. It consists of an ID of the MatcherInterface (for 50 // identifying the matcher), a pointer to the AST node and the 51 // bound nodes before the matcher was executed. 52 // 53 // We currently only memoize on nodes whose pointers identify the 54 // nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc). 55 // For \c QualType and \c TypeLoc it is possible to implement 56 // generation of keys for each type. 57 // FIXME: Benchmark whether memoization of non-pointer typed nodes 58 // provides enough benefit for the additional amount of code. 59 struct MatchKey { 60 DynTypedMatcher::MatcherIDType MatcherID; 61 ast_type_traits::DynTypedNode Node; 62 BoundNodesTreeBuilder BoundNodes; 63 64 bool operator<(const MatchKey &Other) const { 65 return std::tie(MatcherID, Node, BoundNodes) < 66 std::tie(Other.MatcherID, Other.Node, Other.BoundNodes); 67 } 68 }; 69 70 // Used to store the result of a match and possibly bound nodes. 71 struct MemoizedMatchResult { 72 bool ResultOfMatch; 73 BoundNodesTreeBuilder Nodes; 74 }; 75 76 // A RecursiveASTVisitor that traverses all children or all descendants of 77 // a node. 78 class MatchChildASTVisitor 79 : public RecursiveASTVisitor<MatchChildASTVisitor> { 80 public: 81 typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase; 82 83 // Creates an AST visitor that matches 'matcher' on all children or 84 // descendants of a traversed node. max_depth is the maximum depth 85 // to traverse: use 1 for matching the children and INT_MAX for 86 // matching the descendants. 87 MatchChildASTVisitor(const DynTypedMatcher *Matcher, 88 ASTMatchFinder *Finder, 89 BoundNodesTreeBuilder *Builder, 90 int MaxDepth, 91 ASTMatchFinder::TraversalKind Traversal, 92 ASTMatchFinder::BindKind Bind) 93 : Matcher(Matcher), 94 Finder(Finder), 95 Builder(Builder), 96 CurrentDepth(0), 97 MaxDepth(MaxDepth), 98 Traversal(Traversal), 99 Bind(Bind), 100 Matches(false) {} 101 102 // Returns true if a match is found in the subtree rooted at the 103 // given AST node. This is done via a set of mutually recursive 104 // functions. Here's how the recursion is done (the *wildcard can 105 // actually be Decl, Stmt, or Type): 106 // 107 // - Traverse(node) calls BaseTraverse(node) when it needs 108 // to visit the descendants of node. 109 // - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node)) 110 // Traverse*(c) for each child c of 'node'. 111 // - Traverse*(c) in turn calls Traverse(c), completing the 112 // recursion. 113 bool findMatch(const ast_type_traits::DynTypedNode &DynNode) { 114 reset(); 115 if (const Decl *D = DynNode.get<Decl>()) 116 traverse(*D); 117 else if (const Stmt *S = DynNode.get<Stmt>()) 118 traverse(*S); 119 else if (const NestedNameSpecifier *NNS = 120 DynNode.get<NestedNameSpecifier>()) 121 traverse(*NNS); 122 else if (const NestedNameSpecifierLoc *NNSLoc = 123 DynNode.get<NestedNameSpecifierLoc>()) 124 traverse(*NNSLoc); 125 else if (const QualType *Q = DynNode.get<QualType>()) 126 traverse(*Q); 127 else if (const TypeLoc *T = DynNode.get<TypeLoc>()) 128 traverse(*T); 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 bool TraverseStmt(Stmt *StmtNode) { 147 ScopedIncrement ScopedDepth(&CurrentDepth); 148 const Stmt *StmtToTraverse = StmtNode; 149 if (Traversal == 150 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) { 151 const Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode); 152 if (ExprNode) { 153 StmtToTraverse = ExprNode->IgnoreParenImpCasts(); 154 } 155 } 156 return (StmtToTraverse == nullptr) || traverse(*StmtToTraverse); 157 } 158 // We assume that the QualType and the contained type are on the same 159 // hierarchy level. Thus, we try to match either of them. 160 bool TraverseType(QualType TypeNode) { 161 if (TypeNode.isNull()) 162 return true; 163 ScopedIncrement ScopedDepth(&CurrentDepth); 164 // Match the Type. 165 if (!match(*TypeNode)) 166 return false; 167 // The QualType is matched inside traverse. 168 return traverse(TypeNode); 169 } 170 // We assume that the TypeLoc, contained QualType and contained Type all are 171 // on the same hierarchy level. Thus, we try to match all of them. 172 bool TraverseTypeLoc(TypeLoc TypeLocNode) { 173 if (TypeLocNode.isNull()) 174 return true; 175 ScopedIncrement ScopedDepth(&CurrentDepth); 176 // Match the Type. 177 if (!match(*TypeLocNode.getType())) 178 return false; 179 // Match the QualType. 180 if (!match(TypeLocNode.getType())) 181 return false; 182 // The TypeLoc is matched inside traverse. 183 return traverse(TypeLocNode); 184 } 185 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 186 ScopedIncrement ScopedDepth(&CurrentDepth); 187 return (NNS == nullptr) || traverse(*NNS); 188 } 189 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 190 if (!NNS) 191 return true; 192 ScopedIncrement ScopedDepth(&CurrentDepth); 193 if (!match(*NNS.getNestedNameSpecifier())) 194 return false; 195 return traverse(NNS); 196 } 197 198 bool shouldVisitTemplateInstantiations() const { return true; } 199 bool shouldVisitImplicitCode() const { return true; } 200 // Disables data recursion. We intercept Traverse* methods in the RAV, which 201 // are not triggered during data recursion. 202 bool shouldUseDataRecursionFor(clang::Stmt *S) const { return false; } 203 204 private: 205 // Used for updating the depth during traversal. 206 struct ScopedIncrement { 207 explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); } 208 ~ScopedIncrement() { --(*Depth); } 209 210 private: 211 int *Depth; 212 }; 213 214 // Resets the state of this object. 215 void reset() { 216 Matches = false; 217 CurrentDepth = 0; 218 } 219 220 // Forwards the call to the corresponding Traverse*() method in the 221 // base visitor class. 222 bool baseTraverse(const Decl &DeclNode) { 223 return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode)); 224 } 225 bool baseTraverse(const Stmt &StmtNode) { 226 return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode)); 227 } 228 bool baseTraverse(QualType TypeNode) { 229 return VisitorBase::TraverseType(TypeNode); 230 } 231 bool baseTraverse(TypeLoc TypeLocNode) { 232 return VisitorBase::TraverseTypeLoc(TypeLocNode); 233 } 234 bool baseTraverse(const NestedNameSpecifier &NNS) { 235 return VisitorBase::TraverseNestedNameSpecifier( 236 const_cast<NestedNameSpecifier*>(&NNS)); 237 } 238 bool baseTraverse(NestedNameSpecifierLoc NNS) { 239 return VisitorBase::TraverseNestedNameSpecifierLoc(NNS); 240 } 241 242 // Sets 'Matched' to true if 'Matcher' matches 'Node' and: 243 // 0 < CurrentDepth <= MaxDepth. 244 // 245 // Returns 'true' if traversal should continue after this function 246 // returns, i.e. if no match is found or 'Bind' is 'BK_All'. 247 template <typename T> 248 bool match(const T &Node) { 249 if (CurrentDepth == 0 || CurrentDepth > MaxDepth) { 250 return true; 251 } 252 if (Bind != ASTMatchFinder::BK_All) { 253 BoundNodesTreeBuilder RecursiveBuilder(*Builder); 254 if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder, 255 &RecursiveBuilder)) { 256 Matches = true; 257 ResultBindings.addMatch(RecursiveBuilder); 258 return false; // Abort as soon as a match is found. 259 } 260 } else { 261 BoundNodesTreeBuilder RecursiveBuilder(*Builder); 262 if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder, 263 &RecursiveBuilder)) { 264 // After the first match the matcher succeeds. 265 Matches = true; 266 ResultBindings.addMatch(RecursiveBuilder); 267 } 268 } 269 return true; 270 } 271 272 // Traverses the subtree rooted at 'Node'; returns true if the 273 // traversal should continue after this function returns. 274 template <typename T> 275 bool traverse(const T &Node) { 276 static_assert(IsBaseType<T>::value, 277 "traverse can only be instantiated with base type"); 278 if (!match(Node)) 279 return false; 280 return baseTraverse(Node); 281 } 282 283 const DynTypedMatcher *const Matcher; 284 ASTMatchFinder *const Finder; 285 BoundNodesTreeBuilder *const Builder; 286 BoundNodesTreeBuilder ResultBindings; 287 int CurrentDepth; 288 const int MaxDepth; 289 const ASTMatchFinder::TraversalKind Traversal; 290 const ASTMatchFinder::BindKind Bind; 291 bool Matches; 292 }; 293 294 // Controls the outermost traversal of the AST and allows to match multiple 295 // matchers. 296 class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, 297 public ASTMatchFinder { 298 public: 299 MatchASTVisitor(const MatchFinder::MatchersByType *Matchers, 300 const MatchFinder::MatchFinderOptions &Options) 301 : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {} 302 303 ~MatchASTVisitor() override { 304 if (Options.CheckProfiling) { 305 Options.CheckProfiling->Records = std::move(TimeByBucket); 306 } 307 } 308 309 void onStartOfTranslationUnit() { 310 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 311 TimeBucketRegion Timer; 312 for (MatchCallback *MC : Matchers->AllCallbacks) { 313 if (EnableCheckProfiling) 314 Timer.setBucket(&TimeByBucket[MC->getID()]); 315 MC->onStartOfTranslationUnit(); 316 } 317 } 318 319 void onEndOfTranslationUnit() { 320 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 321 TimeBucketRegion Timer; 322 for (MatchCallback *MC : Matchers->AllCallbacks) { 323 if (EnableCheckProfiling) 324 Timer.setBucket(&TimeByBucket[MC->getID()]); 325 MC->onEndOfTranslationUnit(); 326 } 327 } 328 329 void set_active_ast_context(ASTContext *NewActiveASTContext) { 330 ActiveASTContext = NewActiveASTContext; 331 } 332 333 // The following Visit*() and Traverse*() functions "override" 334 // methods in RecursiveASTVisitor. 335 336 bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) { 337 // When we see 'typedef A B', we add name 'B' to the set of names 338 // A's canonical type maps to. This is necessary for implementing 339 // isDerivedFrom(x) properly, where x can be the name of the base 340 // class or any of its aliases. 341 // 342 // In general, the is-alias-of (as defined by typedefs) relation 343 // is tree-shaped, as you can typedef a type more than once. For 344 // example, 345 // 346 // typedef A B; 347 // typedef A C; 348 // typedef C D; 349 // typedef C E; 350 // 351 // gives you 352 // 353 // A 354 // |- B 355 // `- C 356 // |- D 357 // `- E 358 // 359 // It is wrong to assume that the relation is a chain. A correct 360 // implementation of isDerivedFrom() needs to recognize that B and 361 // E are aliases, even though neither is a typedef of the other. 362 // Therefore, we cannot simply walk through one typedef chain to 363 // find out whether the type name matches. 364 const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr(); 365 const Type *CanonicalType = // root of the typedef tree 366 ActiveASTContext->getCanonicalType(TypeNode); 367 TypeAliases[CanonicalType].insert(DeclNode); 368 return true; 369 } 370 371 bool TraverseDecl(Decl *DeclNode); 372 bool TraverseStmt(Stmt *StmtNode); 373 bool TraverseType(QualType TypeNode); 374 bool TraverseTypeLoc(TypeLoc TypeNode); 375 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); 376 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 377 378 // Matches children or descendants of 'Node' with 'BaseMatcher'. 379 bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node, 380 const DynTypedMatcher &Matcher, 381 BoundNodesTreeBuilder *Builder, int MaxDepth, 382 TraversalKind Traversal, BindKind Bind) { 383 // For AST-nodes that don't have an identity, we can't memoize. 384 if (!Node.getMemoizationData() || !Builder->isComparable()) 385 return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal, 386 Bind); 387 388 MatchKey Key; 389 Key.MatcherID = Matcher.getID(); 390 Key.Node = Node; 391 // Note that we key on the bindings *before* the match. 392 Key.BoundNodes = *Builder; 393 394 MemoizationMap::iterator I = ResultCache.find(Key); 395 if (I != ResultCache.end()) { 396 *Builder = I->second.Nodes; 397 return I->second.ResultOfMatch; 398 } 399 400 MemoizedMatchResult Result; 401 Result.Nodes = *Builder; 402 Result.ResultOfMatch = matchesRecursively(Node, Matcher, &Result.Nodes, 403 MaxDepth, Traversal, Bind); 404 405 MemoizedMatchResult &CachedResult = ResultCache[Key]; 406 CachedResult = std::move(Result); 407 408 *Builder = CachedResult.Nodes; 409 return CachedResult.ResultOfMatch; 410 } 411 412 // Matches children or descendants of 'Node' with 'BaseMatcher'. 413 bool matchesRecursively(const ast_type_traits::DynTypedNode &Node, 414 const DynTypedMatcher &Matcher, 415 BoundNodesTreeBuilder *Builder, int MaxDepth, 416 TraversalKind Traversal, BindKind Bind) { 417 MatchChildASTVisitor Visitor( 418 &Matcher, this, Builder, MaxDepth, Traversal, Bind); 419 return Visitor.findMatch(Node); 420 } 421 422 bool classIsDerivedFrom(const CXXRecordDecl *Declaration, 423 const Matcher<NamedDecl> &Base, 424 BoundNodesTreeBuilder *Builder) override; 425 426 // Implements ASTMatchFinder::matchesChildOf. 427 bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, 428 const DynTypedMatcher &Matcher, 429 BoundNodesTreeBuilder *Builder, 430 TraversalKind Traversal, 431 BindKind Bind) override { 432 if (ResultCache.size() > MaxMemoizationEntries) 433 ResultCache.clear(); 434 return memoizedMatchesRecursively(Node, Matcher, Builder, 1, Traversal, 435 Bind); 436 } 437 // Implements ASTMatchFinder::matchesDescendantOf. 438 bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, 439 const DynTypedMatcher &Matcher, 440 BoundNodesTreeBuilder *Builder, 441 BindKind Bind) override { 442 if (ResultCache.size() > MaxMemoizationEntries) 443 ResultCache.clear(); 444 return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX, 445 TK_AsIs, Bind); 446 } 447 // Implements ASTMatchFinder::matchesAncestorOf. 448 bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node, 449 const DynTypedMatcher &Matcher, 450 BoundNodesTreeBuilder *Builder, 451 AncestorMatchMode MatchMode) override { 452 // Reset the cache outside of the recursive call to make sure we 453 // don't invalidate any iterators. 454 if (ResultCache.size() > MaxMemoizationEntries) 455 ResultCache.clear(); 456 return memoizedMatchesAncestorOfRecursively(Node, Matcher, Builder, 457 MatchMode); 458 } 459 460 // Matches all registered matchers on the given node and calls the 461 // result callback for every node that matches. 462 void match(const ast_type_traits::DynTypedNode &Node) { 463 // FIXME: Improve this with a switch or a visitor pattern. 464 if (auto *N = Node.get<Decl>()) { 465 match(*N); 466 } else if (auto *N = Node.get<Stmt>()) { 467 match(*N); 468 } else if (auto *N = Node.get<Type>()) { 469 match(*N); 470 } else if (auto *N = Node.get<QualType>()) { 471 match(*N); 472 } else if (auto *N = Node.get<NestedNameSpecifier>()) { 473 match(*N); 474 } else if (auto *N = Node.get<NestedNameSpecifierLoc>()) { 475 match(*N); 476 } else if (auto *N = Node.get<TypeLoc>()) { 477 match(*N); 478 } 479 } 480 481 template <typename T> void match(const T &Node) { 482 matchDispatch(&Node); 483 } 484 485 // Implements ASTMatchFinder::getASTContext. 486 ASTContext &getASTContext() const override { return *ActiveASTContext; } 487 488 bool shouldVisitTemplateInstantiations() const { return true; } 489 bool shouldVisitImplicitCode() const { return true; } 490 // Disables data recursion. We intercept Traverse* methods in the RAV, which 491 // are not triggered during data recursion. 492 bool shouldUseDataRecursionFor(clang::Stmt *S) const { return false; } 493 494 private: 495 class TimeBucketRegion { 496 public: 497 TimeBucketRegion() : Bucket(nullptr) {} 498 ~TimeBucketRegion() { setBucket(nullptr); } 499 500 /// \brief Start timing for \p NewBucket. 501 /// 502 /// If there was a bucket already set, it will finish the timing for that 503 /// other bucket. 504 /// \p NewBucket will be timed until the next call to \c setBucket() or 505 /// until the \c TimeBucketRegion is destroyed. 506 /// If \p NewBucket is the same as the currently timed bucket, this call 507 /// does nothing. 508 void setBucket(llvm::TimeRecord *NewBucket) { 509 if (Bucket != NewBucket) { 510 auto Now = llvm::TimeRecord::getCurrentTime(true); 511 if (Bucket) 512 *Bucket += Now; 513 if (NewBucket) 514 *NewBucket -= Now; 515 Bucket = NewBucket; 516 } 517 } 518 519 private: 520 llvm::TimeRecord *Bucket; 521 }; 522 523 /// \brief Runs all the \p Matchers on \p Node. 524 /// 525 /// Used by \c matchDispatch() below. 526 template <typename T, typename MC> 527 void matchWithoutFilter(const T &Node, const MC &Matchers) { 528 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 529 TimeBucketRegion Timer; 530 for (const auto &MP : Matchers) { 531 if (EnableCheckProfiling) 532 Timer.setBucket(&TimeByBucket[MP.second->getID()]); 533 BoundNodesTreeBuilder Builder; 534 if (MP.first.matches(Node, this, &Builder)) { 535 MatchVisitor Visitor(ActiveASTContext, MP.second); 536 Builder.visitMatches(&Visitor); 537 } 538 } 539 } 540 541 void matchWithFilter(const ast_type_traits::DynTypedNode &DynNode) { 542 auto Kind = DynNode.getNodeKind(); 543 auto it = MatcherFiltersMap.find(Kind); 544 const auto &Filter = 545 it != MatcherFiltersMap.end() ? it->second : getFilterForKind(Kind); 546 547 if (Filter.empty()) 548 return; 549 550 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 551 TimeBucketRegion Timer; 552 auto &Matchers = this->Matchers->DeclOrStmt; 553 for (unsigned short I : Filter) { 554 auto &MP = Matchers[I]; 555 if (EnableCheckProfiling) 556 Timer.setBucket(&TimeByBucket[MP.second->getID()]); 557 BoundNodesTreeBuilder Builder; 558 if (MP.first.matchesNoKindCheck(DynNode, this, &Builder)) { 559 MatchVisitor Visitor(ActiveASTContext, MP.second); 560 Builder.visitMatches(&Visitor); 561 } 562 } 563 } 564 565 const std::vector<unsigned short> & 566 getFilterForKind(ast_type_traits::ASTNodeKind Kind) { 567 auto &Filter = MatcherFiltersMap[Kind]; 568 auto &Matchers = this->Matchers->DeclOrStmt; 569 assert((Matchers.size() < USHRT_MAX) && "Too many matchers."); 570 for (unsigned I = 0, E = Matchers.size(); I != E; ++I) { 571 if (Matchers[I].first.canMatchNodesOfKind(Kind)) { 572 Filter.push_back(I); 573 } 574 } 575 return Filter; 576 } 577 578 /// @{ 579 /// \brief Overloads to pair the different node types to their matchers. 580 void matchDispatch(const Decl *Node) { 581 return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node)); 582 } 583 void matchDispatch(const Stmt *Node) { 584 return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node)); 585 } 586 587 void matchDispatch(const Type *Node) { 588 matchWithoutFilter(QualType(Node, 0), Matchers->Type); 589 } 590 void matchDispatch(const TypeLoc *Node) { 591 matchWithoutFilter(*Node, Matchers->TypeLoc); 592 } 593 void matchDispatch(const QualType *Node) { 594 matchWithoutFilter(*Node, Matchers->Type); 595 } 596 void matchDispatch(const NestedNameSpecifier *Node) { 597 matchWithoutFilter(*Node, Matchers->NestedNameSpecifier); 598 } 599 void matchDispatch(const NestedNameSpecifierLoc *Node) { 600 matchWithoutFilter(*Node, Matchers->NestedNameSpecifierLoc); 601 } 602 void matchDispatch(const void *) { /* Do nothing. */ } 603 /// @} 604 605 // Returns whether an ancestor of \p Node matches \p Matcher. 606 // 607 // The order of matching ((which can lead to different nodes being bound in 608 // case there are multiple matches) is breadth first search. 609 // 610 // To allow memoization in the very common case of having deeply nested 611 // expressions inside a template function, we first walk up the AST, memoizing 612 // the result of the match along the way, as long as there is only a single 613 // parent. 614 // 615 // Once there are multiple parents, the breadth first search order does not 616 // allow simple memoization on the ancestors. Thus, we only memoize as long 617 // as there is a single parent. 618 bool memoizedMatchesAncestorOfRecursively( 619 const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher, 620 BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) { 621 if (Node.get<TranslationUnitDecl>() == 622 ActiveASTContext->getTranslationUnitDecl()) 623 return false; 624 625 MatchKey Key; 626 Key.MatcherID = Matcher.getID(); 627 Key.Node = Node; 628 Key.BoundNodes = *Builder; 629 630 // Note that we cannot use insert and reuse the iterator, as recursive 631 // calls to match might invalidate the result cache iterators. 632 MemoizationMap::iterator I = ResultCache.find(Key); 633 if (I != ResultCache.end()) { 634 *Builder = I->second.Nodes; 635 return I->second.ResultOfMatch; 636 } 637 638 MemoizedMatchResult Result; 639 Result.ResultOfMatch = false; 640 Result.Nodes = *Builder; 641 642 const auto &Parents = ActiveASTContext->getParents(Node); 643 assert(!Parents.empty() && "Found node that is not in the parent map."); 644 if (Parents.size() == 1) { 645 // Only one parent - do recursive memoization. 646 const ast_type_traits::DynTypedNode Parent = Parents[0]; 647 if (Matcher.matches(Parent, this, &Result.Nodes)) { 648 Result.ResultOfMatch = true; 649 } else if (MatchMode != ASTMatchFinder::AMM_ParentOnly) { 650 // Reset the results to not include the bound nodes from the failed 651 // match above. 652 Result.Nodes = *Builder; 653 Result.ResultOfMatch = memoizedMatchesAncestorOfRecursively( 654 Parent, Matcher, &Result.Nodes, MatchMode); 655 // Once we get back from the recursive call, the result will be the 656 // same as the parent's result. 657 } 658 } else { 659 // Multiple parents - BFS over the rest of the nodes. 660 llvm::DenseSet<const void *> Visited; 661 std::deque<ast_type_traits::DynTypedNode> Queue(Parents.begin(), 662 Parents.end()); 663 while (!Queue.empty()) { 664 Result.Nodes = *Builder; 665 if (Matcher.matches(Queue.front(), this, &Result.Nodes)) { 666 Result.ResultOfMatch = true; 667 break; 668 } 669 if (MatchMode != ASTMatchFinder::AMM_ParentOnly) { 670 for (const auto &Parent : 671 ActiveASTContext->getParents(Queue.front())) { 672 // Make sure we do not visit the same node twice. 673 // Otherwise, we'll visit the common ancestors as often as there 674 // are splits on the way down. 675 if (Visited.insert(Parent.getMemoizationData()).second) 676 Queue.push_back(Parent); 677 } 678 } 679 Queue.pop_front(); 680 } 681 } 682 683 MemoizedMatchResult &CachedResult = ResultCache[Key]; 684 CachedResult = std::move(Result); 685 686 *Builder = CachedResult.Nodes; 687 return CachedResult.ResultOfMatch; 688 } 689 690 // Implements a BoundNodesTree::Visitor that calls a MatchCallback with 691 // the aggregated bound nodes for each match. 692 class MatchVisitor : public BoundNodesTreeBuilder::Visitor { 693 public: 694 MatchVisitor(ASTContext* Context, 695 MatchFinder::MatchCallback* Callback) 696 : Context(Context), 697 Callback(Callback) {} 698 699 void visitMatch(const BoundNodes& BoundNodesView) override { 700 Callback->run(MatchFinder::MatchResult(BoundNodesView, Context)); 701 } 702 703 private: 704 ASTContext* Context; 705 MatchFinder::MatchCallback* Callback; 706 }; 707 708 // Returns true if 'TypeNode' has an alias that matches the given matcher. 709 bool typeHasMatchingAlias(const Type *TypeNode, 710 const Matcher<NamedDecl> Matcher, 711 BoundNodesTreeBuilder *Builder) { 712 const Type *const CanonicalType = 713 ActiveASTContext->getCanonicalType(TypeNode); 714 for (const TypedefNameDecl *Alias : TypeAliases.lookup(CanonicalType)) { 715 BoundNodesTreeBuilder Result(*Builder); 716 if (Matcher.matches(*Alias, this, &Result)) { 717 *Builder = std::move(Result); 718 return true; 719 } 720 } 721 return false; 722 } 723 724 /// \brief Bucket to record map. 725 /// 726 /// Used to get the appropriate bucket for each matcher. 727 llvm::StringMap<llvm::TimeRecord> TimeByBucket; 728 729 const MatchFinder::MatchersByType *Matchers; 730 731 /// \brief Filtered list of matcher indices for each matcher kind. 732 /// 733 /// \c Decl and \c Stmt toplevel matchers usually apply to a specific node 734 /// kind (and derived kinds) so it is a waste to try every matcher on every 735 /// node. 736 /// We precalculate a list of matchers that pass the toplevel restrict check. 737 /// This also allows us to skip the restrict check at matching time. See 738 /// use \c matchesNoKindCheck() above. 739 llvm::DenseMap<ast_type_traits::ASTNodeKind, std::vector<unsigned short>> 740 MatcherFiltersMap; 741 742 const MatchFinder::MatchFinderOptions &Options; 743 ASTContext *ActiveASTContext; 744 745 // Maps a canonical type to its TypedefDecls. 746 llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases; 747 748 // Maps (matcher, node) -> the match result for memoization. 749 typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap; 750 MemoizationMap ResultCache; 751 }; 752 753 static CXXRecordDecl *getAsCXXRecordDecl(const Type *TypeNode) { 754 // Type::getAs<...>() drills through typedefs. 755 if (TypeNode->getAs<DependentNameType>() != nullptr || 756 TypeNode->getAs<DependentTemplateSpecializationType>() != nullptr || 757 TypeNode->getAs<TemplateTypeParmType>() != nullptr) 758 // Dependent names and template TypeNode parameters will be matched when 759 // the template is instantiated. 760 return nullptr; 761 TemplateSpecializationType const *TemplateType = 762 TypeNode->getAs<TemplateSpecializationType>(); 763 if (!TemplateType) { 764 return TypeNode->getAsCXXRecordDecl(); 765 } 766 if (TemplateType->getTemplateName().isDependent()) 767 // Dependent template specializations will be matched when the 768 // template is instantiated. 769 return nullptr; 770 771 // For template specialization types which are specializing a template 772 // declaration which is an explicit or partial specialization of another 773 // template declaration, getAsCXXRecordDecl() returns the corresponding 774 // ClassTemplateSpecializationDecl. 775 // 776 // For template specialization types which are specializing a template 777 // declaration which is neither an explicit nor partial specialization of 778 // another template declaration, getAsCXXRecordDecl() returns NULL and 779 // we get the CXXRecordDecl of the templated declaration. 780 CXXRecordDecl *SpecializationDecl = TemplateType->getAsCXXRecordDecl(); 781 if (SpecializationDecl) { 782 return SpecializationDecl; 783 } 784 NamedDecl *Templated = 785 TemplateType->getTemplateName().getAsTemplateDecl()->getTemplatedDecl(); 786 if (CXXRecordDecl *TemplatedRecord = dyn_cast<CXXRecordDecl>(Templated)) { 787 return TemplatedRecord; 788 } 789 // Now it can still be that we have an alias template. 790 TypeAliasDecl *AliasDecl = dyn_cast<TypeAliasDecl>(Templated); 791 assert(AliasDecl); 792 return getAsCXXRecordDecl(AliasDecl->getUnderlyingType().getTypePtr()); 793 } 794 795 // Returns true if the given class is directly or indirectly derived 796 // from a base type with the given name. A class is not considered to be 797 // derived from itself. 798 bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration, 799 const Matcher<NamedDecl> &Base, 800 BoundNodesTreeBuilder *Builder) { 801 if (!Declaration->hasDefinition()) 802 return false; 803 for (const auto &It : Declaration->bases()) { 804 const Type *TypeNode = It.getType().getTypePtr(); 805 806 if (typeHasMatchingAlias(TypeNode, Base, Builder)) 807 return true; 808 809 CXXRecordDecl *ClassDecl = getAsCXXRecordDecl(TypeNode); 810 if (!ClassDecl) 811 continue; 812 if (ClassDecl == Declaration) { 813 // This can happen for recursive template definitions; if the 814 // current declaration did not match, we can safely return false. 815 return false; 816 } 817 BoundNodesTreeBuilder Result(*Builder); 818 if (Base.matches(*ClassDecl, this, &Result)) { 819 *Builder = std::move(Result); 820 return true; 821 } 822 if (classIsDerivedFrom(ClassDecl, Base, Builder)) 823 return true; 824 } 825 return false; 826 } 827 828 bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) { 829 if (!DeclNode) { 830 return true; 831 } 832 match(*DeclNode); 833 return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode); 834 } 835 836 bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) { 837 if (!StmtNode) { 838 return true; 839 } 840 match(*StmtNode); 841 return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode); 842 } 843 844 bool MatchASTVisitor::TraverseType(QualType TypeNode) { 845 match(TypeNode); 846 return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode); 847 } 848 849 bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) { 850 // The RecursiveASTVisitor only visits types if they're not within TypeLocs. 851 // We still want to find those types via matchers, so we match them here. Note 852 // that the TypeLocs are structurally a shadow-hierarchy to the expressed 853 // type, so we visit all involved parts of a compound type when matching on 854 // each TypeLoc. 855 match(TypeLocNode); 856 match(TypeLocNode.getType()); 857 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode); 858 } 859 860 bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 861 match(*NNS); 862 return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS); 863 } 864 865 bool MatchASTVisitor::TraverseNestedNameSpecifierLoc( 866 NestedNameSpecifierLoc NNS) { 867 if (!NNS) 868 return true; 869 870 match(NNS); 871 872 // We only match the nested name specifier here (as opposed to traversing it) 873 // because the traversal is already done in the parallel "Loc"-hierarchy. 874 if (NNS.hasQualifier()) 875 match(*NNS.getNestedNameSpecifier()); 876 return 877 RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS); 878 } 879 880 class MatchASTConsumer : public ASTConsumer { 881 public: 882 MatchASTConsumer(MatchFinder *Finder, 883 MatchFinder::ParsingDoneTestCallback *ParsingDone) 884 : Finder(Finder), ParsingDone(ParsingDone) {} 885 886 private: 887 void HandleTranslationUnit(ASTContext &Context) override { 888 if (ParsingDone != nullptr) { 889 ParsingDone->run(); 890 } 891 Finder->matchAST(Context); 892 } 893 894 MatchFinder *Finder; 895 MatchFinder::ParsingDoneTestCallback *ParsingDone; 896 }; 897 898 } // end namespace 899 } // end namespace internal 900 901 MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes, 902 ASTContext *Context) 903 : Nodes(Nodes), Context(Context), 904 SourceManager(&Context->getSourceManager()) {} 905 906 MatchFinder::MatchCallback::~MatchCallback() {} 907 MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {} 908 909 MatchFinder::MatchFinder(MatchFinderOptions Options) 910 : Options(std::move(Options)), ParsingDone(nullptr) {} 911 912 MatchFinder::~MatchFinder() {} 913 914 void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch, 915 MatchCallback *Action) { 916 Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 917 Matchers.AllCallbacks.insert(Action); 918 } 919 920 void MatchFinder::addMatcher(const TypeMatcher &NodeMatch, 921 MatchCallback *Action) { 922 Matchers.Type.emplace_back(NodeMatch, Action); 923 Matchers.AllCallbacks.insert(Action); 924 } 925 926 void MatchFinder::addMatcher(const StatementMatcher &NodeMatch, 927 MatchCallback *Action) { 928 Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 929 Matchers.AllCallbacks.insert(Action); 930 } 931 932 void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch, 933 MatchCallback *Action) { 934 Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action); 935 Matchers.AllCallbacks.insert(Action); 936 } 937 938 void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch, 939 MatchCallback *Action) { 940 Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action); 941 Matchers.AllCallbacks.insert(Action); 942 } 943 944 void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch, 945 MatchCallback *Action) { 946 Matchers.TypeLoc.emplace_back(NodeMatch, Action); 947 Matchers.AllCallbacks.insert(Action); 948 } 949 950 bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, 951 MatchCallback *Action) { 952 if (NodeMatch.canConvertTo<Decl>()) { 953 addMatcher(NodeMatch.convertTo<Decl>(), Action); 954 return true; 955 } else if (NodeMatch.canConvertTo<QualType>()) { 956 addMatcher(NodeMatch.convertTo<QualType>(), Action); 957 return true; 958 } else if (NodeMatch.canConvertTo<Stmt>()) { 959 addMatcher(NodeMatch.convertTo<Stmt>(), Action); 960 return true; 961 } else if (NodeMatch.canConvertTo<NestedNameSpecifier>()) { 962 addMatcher(NodeMatch.convertTo<NestedNameSpecifier>(), Action); 963 return true; 964 } else if (NodeMatch.canConvertTo<NestedNameSpecifierLoc>()) { 965 addMatcher(NodeMatch.convertTo<NestedNameSpecifierLoc>(), Action); 966 return true; 967 } else if (NodeMatch.canConvertTo<TypeLoc>()) { 968 addMatcher(NodeMatch.convertTo<TypeLoc>(), Action); 969 return true; 970 } 971 return false; 972 } 973 974 std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() { 975 return llvm::make_unique<internal::MatchASTConsumer>(this, ParsingDone); 976 } 977 978 void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node, 979 ASTContext &Context) { 980 internal::MatchASTVisitor Visitor(&Matchers, Options); 981 Visitor.set_active_ast_context(&Context); 982 Visitor.match(Node); 983 } 984 985 void MatchFinder::matchAST(ASTContext &Context) { 986 internal::MatchASTVisitor Visitor(&Matchers, Options); 987 Visitor.set_active_ast_context(&Context); 988 Visitor.onStartOfTranslationUnit(); 989 Visitor.TraverseDecl(Context.getTranslationUnitDecl()); 990 Visitor.onEndOfTranslationUnit(); 991 } 992 993 void MatchFinder::registerTestCallbackAfterParsing( 994 MatchFinder::ParsingDoneTestCallback *NewParsingDone) { 995 ParsingDone = NewParsingDone; 996 } 997 998 StringRef MatchFinder::MatchCallback::getID() const { return "<unknown>"; } 999 1000 } // end namespace ast_matchers 1001 } // end namespace clang 1002