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