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