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