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 enum class MatchType { 47 Ancestors, 48 49 Descendants, 50 Child, 51 }; 52 53 // We use memoization to avoid running the same matcher on the same 54 // AST node twice. This struct is the key for looking up match 55 // result. It consists of an ID of the MatcherInterface (for 56 // identifying the matcher), a pointer to the AST node and the 57 // bound nodes before the matcher was executed. 58 // 59 // We currently only memoize on nodes whose pointers identify the 60 // nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc). 61 // For \c QualType and \c TypeLoc it is possible to implement 62 // generation of keys for each type. 63 // FIXME: Benchmark whether memoization of non-pointer typed nodes 64 // provides enough benefit for the additional amount of code. 65 struct MatchKey { 66 DynTypedMatcher::MatcherIDType MatcherID; 67 DynTypedNode Node; 68 BoundNodesTreeBuilder BoundNodes; 69 TraversalKind Traversal = TK_AsIs; 70 MatchType Type; 71 72 bool operator<(const MatchKey &Other) const { 73 return std::tie(Traversal, Type, MatcherID, Node, BoundNodes) < 74 std::tie(Other.Traversal, Other.Type, Other.MatcherID, Other.Node, 75 Other.BoundNodes); 76 } 77 }; 78 79 // Used to store the result of a match and possibly bound nodes. 80 struct MemoizedMatchResult { 81 bool ResultOfMatch; 82 BoundNodesTreeBuilder Nodes; 83 }; 84 85 // A RecursiveASTVisitor that traverses all children or all descendants of 86 // a node. 87 class MatchChildASTVisitor 88 : public RecursiveASTVisitor<MatchChildASTVisitor> { 89 public: 90 typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase; 91 92 // Creates an AST visitor that matches 'matcher' on all children or 93 // descendants of a traversed node. max_depth is the maximum depth 94 // to traverse: use 1 for matching the children and INT_MAX for 95 // matching the descendants. 96 MatchChildASTVisitor(const DynTypedMatcher *Matcher, ASTMatchFinder *Finder, 97 BoundNodesTreeBuilder *Builder, int MaxDepth, 98 TraversalKind Traversal, bool IgnoreImplicitChildren, 99 ASTMatchFinder::BindKind Bind) 100 : Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0), 101 MaxDepth(MaxDepth), Traversal(Traversal), 102 IgnoreImplicitChildren(IgnoreImplicitChildren), Bind(Bind), 103 Matches(false) {} 104 105 // Returns true if a match is found in the subtree rooted at the 106 // given AST node. This is done via a set of mutually recursive 107 // functions. Here's how the recursion is done (the *wildcard can 108 // actually be Decl, Stmt, or Type): 109 // 110 // - Traverse(node) calls BaseTraverse(node) when it needs 111 // to visit the descendants of node. 112 // - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node)) 113 // Traverse*(c) for each child c of 'node'. 114 // - Traverse*(c) in turn calls Traverse(c), completing the 115 // recursion. 116 bool findMatch(const DynTypedNode &DynNode) { 117 reset(); 118 if (const Decl *D = DynNode.get<Decl>()) 119 traverse(*D); 120 else if (const Stmt *S = DynNode.get<Stmt>()) 121 traverse(*S); 122 else if (const NestedNameSpecifier *NNS = 123 DynNode.get<NestedNameSpecifier>()) 124 traverse(*NNS); 125 else if (const NestedNameSpecifierLoc *NNSLoc = 126 DynNode.get<NestedNameSpecifierLoc>()) 127 traverse(*NNSLoc); 128 else if (const QualType *Q = DynNode.get<QualType>()) 129 traverse(*Q); 130 else if (const TypeLoc *T = DynNode.get<TypeLoc>()) 131 traverse(*T); 132 else if (const auto *C = DynNode.get<CXXCtorInitializer>()) 133 traverse(*C); 134 else if (const TemplateArgumentLoc *TALoc = 135 DynNode.get<TemplateArgumentLoc>()) 136 traverse(*TALoc); 137 // FIXME: Add other base types after adding tests. 138 139 // It's OK to always overwrite the bound nodes, as if there was 140 // no match in this recursive branch, the result set is empty 141 // anyway. 142 *Builder = ResultBindings; 143 144 return Matches; 145 } 146 147 // The following are overriding methods from the base visitor class. 148 // They are public only to allow CRTP to work. They are *not *part 149 // of the public API of this class. 150 bool TraverseDecl(Decl *DeclNode) { 151 152 if (DeclNode && DeclNode->isImplicit() && 153 Finder->isTraversalIgnoringImplicitNodes()) 154 return baseTraverse(*DeclNode); 155 156 ScopedIncrement ScopedDepth(&CurrentDepth); 157 return (DeclNode == nullptr) || traverse(*DeclNode); 158 } 159 160 Stmt *getStmtToTraverse(Stmt *StmtNode) { 161 Stmt *StmtToTraverse = StmtNode; 162 if (auto *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) { 163 auto *LambdaNode = dyn_cast_or_null<LambdaExpr>(StmtNode); 164 if (LambdaNode && Finder->isTraversalIgnoringImplicitNodes()) 165 StmtToTraverse = LambdaNode; 166 else 167 StmtToTraverse = 168 Finder->getASTContext().getParentMapContext().traverseIgnored( 169 ExprNode); 170 } 171 if (Traversal == TraversalKind::TK_IgnoreImplicitCastsAndParentheses) { 172 if (Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) 173 StmtToTraverse = ExprNode->IgnoreParenImpCasts(); 174 } 175 return StmtToTraverse; 176 } 177 178 bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) { 179 // If we need to keep track of the depth, we can't perform data recursion. 180 if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX)) 181 Queue = nullptr; 182 183 ScopedIncrement ScopedDepth(&CurrentDepth); 184 Stmt *StmtToTraverse = getStmtToTraverse(StmtNode); 185 if (!StmtToTraverse) 186 return true; 187 188 if (IgnoreImplicitChildren && isa<CXXDefaultArgExpr>(StmtNode)) 189 return true; 190 191 if (!match(*StmtToTraverse)) 192 return false; 193 return VisitorBase::TraverseStmt(StmtToTraverse, Queue); 194 } 195 // We assume that the QualType and the contained type are on the same 196 // hierarchy level. Thus, we try to match either of them. 197 bool TraverseType(QualType TypeNode) { 198 if (TypeNode.isNull()) 199 return true; 200 ScopedIncrement ScopedDepth(&CurrentDepth); 201 // Match the Type. 202 if (!match(*TypeNode)) 203 return false; 204 // The QualType is matched inside traverse. 205 return traverse(TypeNode); 206 } 207 // We assume that the TypeLoc, contained QualType and contained Type all are 208 // on the same hierarchy level. Thus, we try to match all of them. 209 bool TraverseTypeLoc(TypeLoc TypeLocNode) { 210 if (TypeLocNode.isNull()) 211 return true; 212 ScopedIncrement ScopedDepth(&CurrentDepth); 213 // Match the Type. 214 if (!match(*TypeLocNode.getType())) 215 return false; 216 // Match the QualType. 217 if (!match(TypeLocNode.getType())) 218 return false; 219 // The TypeLoc is matched inside traverse. 220 return traverse(TypeLocNode); 221 } 222 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 223 ScopedIncrement ScopedDepth(&CurrentDepth); 224 return (NNS == nullptr) || traverse(*NNS); 225 } 226 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 227 if (!NNS) 228 return true; 229 ScopedIncrement ScopedDepth(&CurrentDepth); 230 if (!match(*NNS.getNestedNameSpecifier())) 231 return false; 232 return traverse(NNS); 233 } 234 bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) { 235 if (!CtorInit) 236 return true; 237 ScopedIncrement ScopedDepth(&CurrentDepth); 238 return traverse(*CtorInit); 239 } 240 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL) { 241 ScopedIncrement ScopedDepth(&CurrentDepth); 242 return traverse(TAL); 243 } 244 bool TraverseLambdaExpr(LambdaExpr *Node) { 245 if (!Finder->isTraversalIgnoringImplicitNodes()) 246 return VisitorBase::TraverseLambdaExpr(Node); 247 if (!Node) 248 return true; 249 ScopedIncrement ScopedDepth(&CurrentDepth); 250 251 for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { 252 const auto *C = Node->capture_begin() + I; 253 if (!C->isExplicit()) 254 continue; 255 if (Node->isInitCapture(C) && !match(*C->getCapturedVar())) 256 return false; 257 if (!match(*Node->capture_init_begin()[I])) 258 return false; 259 } 260 261 if (const auto *TPL = Node->getTemplateParameterList()) { 262 for (const auto *TP : *TPL) { 263 if (!match(*TP)) 264 return false; 265 } 266 } 267 268 for (const auto *P : Node->getCallOperator()->parameters()) { 269 if (!match(*P)) 270 return false; 271 } 272 273 if (!match(*Node->getBody())) 274 return false; 275 276 return true; 277 } 278 279 bool shouldVisitTemplateInstantiations() const { return true; } 280 bool shouldVisitImplicitCode() const { return !IgnoreImplicitChildren; } 281 282 private: 283 // Used for updating the depth during traversal. 284 struct ScopedIncrement { 285 explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); } 286 ~ScopedIncrement() { --(*Depth); } 287 288 private: 289 int *Depth; 290 }; 291 292 // Resets the state of this object. 293 void reset() { 294 Matches = false; 295 CurrentDepth = 0; 296 } 297 298 // Forwards the call to the corresponding Traverse*() method in the 299 // base visitor class. 300 bool baseTraverse(const Decl &DeclNode) { 301 return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode)); 302 } 303 bool baseTraverse(const Stmt &StmtNode) { 304 return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode)); 305 } 306 bool baseTraverse(QualType TypeNode) { 307 return VisitorBase::TraverseType(TypeNode); 308 } 309 bool baseTraverse(TypeLoc TypeLocNode) { 310 return VisitorBase::TraverseTypeLoc(TypeLocNode); 311 } 312 bool baseTraverse(const NestedNameSpecifier &NNS) { 313 return VisitorBase::TraverseNestedNameSpecifier( 314 const_cast<NestedNameSpecifier*>(&NNS)); 315 } 316 bool baseTraverse(NestedNameSpecifierLoc NNS) { 317 return VisitorBase::TraverseNestedNameSpecifierLoc(NNS); 318 } 319 bool baseTraverse(const CXXCtorInitializer &CtorInit) { 320 return VisitorBase::TraverseConstructorInitializer( 321 const_cast<CXXCtorInitializer *>(&CtorInit)); 322 } 323 bool baseTraverse(TemplateArgumentLoc TAL) { 324 return VisitorBase::TraverseTemplateArgumentLoc(TAL); 325 } 326 327 // Sets 'Matched' to true if 'Matcher' matches 'Node' and: 328 // 0 < CurrentDepth <= MaxDepth. 329 // 330 // Returns 'true' if traversal should continue after this function 331 // returns, i.e. if no match is found or 'Bind' is 'BK_All'. 332 template <typename T> 333 bool match(const T &Node) { 334 if (CurrentDepth == 0 || CurrentDepth > MaxDepth) { 335 return true; 336 } 337 if (Bind != ASTMatchFinder::BK_All) { 338 BoundNodesTreeBuilder RecursiveBuilder(*Builder); 339 if (Matcher->matches(DynTypedNode::create(Node), Finder, 340 &RecursiveBuilder)) { 341 Matches = true; 342 ResultBindings.addMatch(RecursiveBuilder); 343 return false; // Abort as soon as a match is found. 344 } 345 } else { 346 BoundNodesTreeBuilder RecursiveBuilder(*Builder); 347 if (Matcher->matches(DynTypedNode::create(Node), Finder, 348 &RecursiveBuilder)) { 349 // After the first match the matcher succeeds. 350 Matches = true; 351 ResultBindings.addMatch(RecursiveBuilder); 352 } 353 } 354 return true; 355 } 356 357 // Traverses the subtree rooted at 'Node'; returns true if the 358 // traversal should continue after this function returns. 359 template <typename T> 360 bool traverse(const T &Node) { 361 static_assert(IsBaseType<T>::value, 362 "traverse can only be instantiated with base type"); 363 if (!match(Node)) 364 return false; 365 return baseTraverse(Node); 366 } 367 368 const DynTypedMatcher *const Matcher; 369 ASTMatchFinder *const Finder; 370 BoundNodesTreeBuilder *const Builder; 371 BoundNodesTreeBuilder ResultBindings; 372 int CurrentDepth; 373 const int MaxDepth; 374 const TraversalKind Traversal; 375 const bool IgnoreImplicitChildren; 376 const ASTMatchFinder::BindKind Bind; 377 bool Matches; 378 }; 379 380 // Controls the outermost traversal of the AST and allows to match multiple 381 // matchers. 382 class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, 383 public ASTMatchFinder { 384 public: 385 MatchASTVisitor(const MatchFinder::MatchersByType *Matchers, 386 const MatchFinder::MatchFinderOptions &Options) 387 : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {} 388 389 ~MatchASTVisitor() override { 390 if (Options.CheckProfiling) { 391 Options.CheckProfiling->Records = std::move(TimeByBucket); 392 } 393 } 394 395 void onStartOfTranslationUnit() { 396 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 397 TimeBucketRegion Timer; 398 for (MatchCallback *MC : Matchers->AllCallbacks) { 399 if (EnableCheckProfiling) 400 Timer.setBucket(&TimeByBucket[MC->getID()]); 401 MC->onStartOfTranslationUnit(); 402 } 403 } 404 405 void onEndOfTranslationUnit() { 406 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 407 TimeBucketRegion Timer; 408 for (MatchCallback *MC : Matchers->AllCallbacks) { 409 if (EnableCheckProfiling) 410 Timer.setBucket(&TimeByBucket[MC->getID()]); 411 MC->onEndOfTranslationUnit(); 412 } 413 } 414 415 void set_active_ast_context(ASTContext *NewActiveASTContext) { 416 ActiveASTContext = NewActiveASTContext; 417 } 418 419 // The following Visit*() and Traverse*() functions "override" 420 // methods in RecursiveASTVisitor. 421 422 bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) { 423 // When we see 'typedef A B', we add name 'B' to the set of names 424 // A's canonical type maps to. This is necessary for implementing 425 // isDerivedFrom(x) properly, where x can be the name of the base 426 // class or any of its aliases. 427 // 428 // In general, the is-alias-of (as defined by typedefs) relation 429 // is tree-shaped, as you can typedef a type more than once. For 430 // example, 431 // 432 // typedef A B; 433 // typedef A C; 434 // typedef C D; 435 // typedef C E; 436 // 437 // gives you 438 // 439 // A 440 // |- B 441 // `- C 442 // |- D 443 // `- E 444 // 445 // It is wrong to assume that the relation is a chain. A correct 446 // implementation of isDerivedFrom() needs to recognize that B and 447 // E are aliases, even though neither is a typedef of the other. 448 // Therefore, we cannot simply walk through one typedef chain to 449 // find out whether the type name matches. 450 const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr(); 451 const Type *CanonicalType = // root of the typedef tree 452 ActiveASTContext->getCanonicalType(TypeNode); 453 TypeAliases[CanonicalType].insert(DeclNode); 454 return true; 455 } 456 457 bool VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { 458 const ObjCInterfaceDecl *InterfaceDecl = CAD->getClassInterface(); 459 CompatibleAliases[InterfaceDecl].insert(CAD); 460 return true; 461 } 462 463 bool TraverseDecl(Decl *DeclNode); 464 bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr); 465 bool TraverseType(QualType TypeNode); 466 bool TraverseTypeLoc(TypeLoc TypeNode); 467 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); 468 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 469 bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit); 470 bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL); 471 472 // Matches children or descendants of 'Node' with 'BaseMatcher'. 473 bool memoizedMatchesRecursively(const DynTypedNode &Node, ASTContext &Ctx, 474 const DynTypedMatcher &Matcher, 475 BoundNodesTreeBuilder *Builder, int MaxDepth, 476 TraversalKind Traversal, BindKind Bind) { 477 // For AST-nodes that don't have an identity, we can't memoize. 478 if (!Node.getMemoizationData() || !Builder->isComparable()) 479 return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal, 480 Bind); 481 482 MatchKey Key; 483 Key.MatcherID = Matcher.getID(); 484 Key.Node = Node; 485 // Note that we key on the bindings *before* the match. 486 Key.BoundNodes = *Builder; 487 Key.Traversal = Ctx.getParentMapContext().getTraversalKind(); 488 // Memoize result even doing a single-level match, it might be expensive. 489 Key.Type = MaxDepth == 1 ? MatchType::Child : MatchType::Descendants; 490 MemoizationMap::iterator I = ResultCache.find(Key); 491 if (I != ResultCache.end()) { 492 *Builder = I->second.Nodes; 493 return I->second.ResultOfMatch; 494 } 495 496 MemoizedMatchResult Result; 497 Result.Nodes = *Builder; 498 Result.ResultOfMatch = matchesRecursively(Node, Matcher, &Result.Nodes, 499 MaxDepth, Traversal, Bind); 500 501 MemoizedMatchResult &CachedResult = ResultCache[Key]; 502 CachedResult = std::move(Result); 503 504 *Builder = CachedResult.Nodes; 505 return CachedResult.ResultOfMatch; 506 } 507 508 // Matches children or descendants of 'Node' with 'BaseMatcher'. 509 bool matchesRecursively(const DynTypedNode &Node, 510 const DynTypedMatcher &Matcher, 511 BoundNodesTreeBuilder *Builder, int MaxDepth, 512 TraversalKind Traversal, BindKind Bind) { 513 bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 514 TraversingASTChildrenNotSpelledInSource; 515 516 bool IgnoreImplicitChildren = false; 517 518 if (isTraversalIgnoringImplicitNodes()) { 519 IgnoreImplicitChildren = true; 520 if (Node.get<CXXForRangeStmt>()) 521 ScopedTraversal = true; 522 } 523 524 ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal); 525 526 MatchChildASTVisitor Visitor(&Matcher, this, Builder, MaxDepth, Traversal, 527 IgnoreImplicitChildren, Bind); 528 return Visitor.findMatch(Node); 529 } 530 531 bool classIsDerivedFrom(const CXXRecordDecl *Declaration, 532 const Matcher<NamedDecl> &Base, 533 BoundNodesTreeBuilder *Builder, 534 bool Directly) override; 535 536 bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration, 537 const Matcher<NamedDecl> &Base, 538 BoundNodesTreeBuilder *Builder, 539 bool Directly) override; 540 541 // Implements ASTMatchFinder::matchesChildOf. 542 bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx, 543 const DynTypedMatcher &Matcher, 544 BoundNodesTreeBuilder *Builder, TraversalKind Traversal, 545 BindKind Bind) override { 546 if (ResultCache.size() > MaxMemoizationEntries) 547 ResultCache.clear(); 548 return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, 1, Traversal, 549 Bind); 550 } 551 // Implements ASTMatchFinder::matchesDescendantOf. 552 bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx, 553 const DynTypedMatcher &Matcher, 554 BoundNodesTreeBuilder *Builder, 555 BindKind Bind) override { 556 if (ResultCache.size() > MaxMemoizationEntries) 557 ResultCache.clear(); 558 return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, INT_MAX, 559 TraversalKind::TK_AsIs, Bind); 560 } 561 // Implements ASTMatchFinder::matchesAncestorOf. 562 bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx, 563 const DynTypedMatcher &Matcher, 564 BoundNodesTreeBuilder *Builder, 565 AncestorMatchMode MatchMode) override { 566 // Reset the cache outside of the recursive call to make sure we 567 // don't invalidate any iterators. 568 if (ResultCache.size() > MaxMemoizationEntries) 569 ResultCache.clear(); 570 if (MatchMode == AncestorMatchMode::AMM_ParentOnly) 571 return matchesParentOf(Node, Matcher, Builder); 572 return matchesAnyAncestorOf(Node, Ctx, Matcher, Builder); 573 } 574 575 // Matches all registered matchers on the given node and calls the 576 // result callback for every node that matches. 577 void match(const DynTypedNode &Node) { 578 // FIXME: Improve this with a switch or a visitor pattern. 579 if (auto *N = Node.get<Decl>()) { 580 match(*N); 581 } else if (auto *N = Node.get<Stmt>()) { 582 match(*N); 583 } else if (auto *N = Node.get<Type>()) { 584 match(*N); 585 } else if (auto *N = Node.get<QualType>()) { 586 match(*N); 587 } else if (auto *N = Node.get<NestedNameSpecifier>()) { 588 match(*N); 589 } else if (auto *N = Node.get<NestedNameSpecifierLoc>()) { 590 match(*N); 591 } else if (auto *N = Node.get<TypeLoc>()) { 592 match(*N); 593 } else if (auto *N = Node.get<CXXCtorInitializer>()) { 594 match(*N); 595 } else if (auto *N = Node.get<TemplateArgumentLoc>()) { 596 match(*N); 597 } 598 } 599 600 template <typename T> void match(const T &Node) { 601 matchDispatch(&Node); 602 } 603 604 // Implements ASTMatchFinder::getASTContext. 605 ASTContext &getASTContext() const override { return *ActiveASTContext; } 606 607 bool shouldVisitTemplateInstantiations() const { return true; } 608 bool shouldVisitImplicitCode() const { return true; } 609 610 bool IsMatchingInASTNodeNotSpelledInSource() const override { 611 return TraversingASTNodeNotSpelledInSource; 612 } 613 614 bool TraverseTemplateInstantiations(ClassTemplateDecl *D) { 615 ASTNodeNotSpelledInSourceScope RAII(this, true); 616 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 617 D); 618 } 619 620 bool TraverseTemplateInstantiations(VarTemplateDecl *D) { 621 ASTNodeNotSpelledInSourceScope RAII(this, true); 622 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 623 D); 624 } 625 626 bool TraverseTemplateInstantiations(FunctionTemplateDecl *D) { 627 ASTNodeNotSpelledInSourceScope RAII(this, true); 628 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateInstantiations( 629 D); 630 } 631 632 private: 633 bool TraversingASTNodeNotSpelledInSource = false; 634 bool TraversingASTChildrenNotSpelledInSource = false; 635 636 struct ASTNodeNotSpelledInSourceScope { 637 ASTNodeNotSpelledInSourceScope(MatchASTVisitor *V, bool B) 638 : MV(V), MB(V->TraversingASTNodeNotSpelledInSource) { 639 V->TraversingASTNodeNotSpelledInSource = B; 640 } 641 ~ASTNodeNotSpelledInSourceScope() { 642 MV->TraversingASTNodeNotSpelledInSource = MB; 643 } 644 645 private: 646 MatchASTVisitor *MV; 647 bool MB; 648 }; 649 650 struct ASTChildrenNotSpelledInSource { 651 ASTChildrenNotSpelledInSource(MatchASTVisitor *V, bool B) 652 : MV(V), MB(V->TraversingASTChildrenNotSpelledInSource) { 653 V->TraversingASTChildrenNotSpelledInSource = B; 654 } 655 ~ASTChildrenNotSpelledInSource() { 656 MV->TraversingASTChildrenNotSpelledInSource = MB; 657 } 658 659 private: 660 MatchASTVisitor *MV; 661 bool MB; 662 }; 663 664 class TimeBucketRegion { 665 public: 666 TimeBucketRegion() : Bucket(nullptr) {} 667 ~TimeBucketRegion() { setBucket(nullptr); } 668 669 /// Start timing for \p NewBucket. 670 /// 671 /// If there was a bucket already set, it will finish the timing for that 672 /// other bucket. 673 /// \p NewBucket will be timed until the next call to \c setBucket() or 674 /// until the \c TimeBucketRegion is destroyed. 675 /// If \p NewBucket is the same as the currently timed bucket, this call 676 /// does nothing. 677 void setBucket(llvm::TimeRecord *NewBucket) { 678 if (Bucket != NewBucket) { 679 auto Now = llvm::TimeRecord::getCurrentTime(true); 680 if (Bucket) 681 *Bucket += Now; 682 if (NewBucket) 683 *NewBucket -= Now; 684 Bucket = NewBucket; 685 } 686 } 687 688 private: 689 llvm::TimeRecord *Bucket; 690 }; 691 692 /// Runs all the \p Matchers on \p Node. 693 /// 694 /// Used by \c matchDispatch() below. 695 template <typename T, typename MC> 696 void matchWithoutFilter(const T &Node, const MC &Matchers) { 697 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 698 TimeBucketRegion Timer; 699 for (const auto &MP : Matchers) { 700 if (EnableCheckProfiling) 701 Timer.setBucket(&TimeByBucket[MP.second->getID()]); 702 BoundNodesTreeBuilder Builder; 703 if (MP.first.matches(Node, this, &Builder)) { 704 MatchVisitor Visitor(ActiveASTContext, MP.second); 705 Builder.visitMatches(&Visitor); 706 } 707 } 708 } 709 710 void matchWithFilter(const DynTypedNode &DynNode) { 711 auto Kind = DynNode.getNodeKind(); 712 auto it = MatcherFiltersMap.find(Kind); 713 const auto &Filter = 714 it != MatcherFiltersMap.end() ? it->second : getFilterForKind(Kind); 715 716 if (Filter.empty()) 717 return; 718 719 const bool EnableCheckProfiling = Options.CheckProfiling.hasValue(); 720 TimeBucketRegion Timer; 721 auto &Matchers = this->Matchers->DeclOrStmt; 722 for (unsigned short I : Filter) { 723 auto &MP = Matchers[I]; 724 if (EnableCheckProfiling) 725 Timer.setBucket(&TimeByBucket[MP.second->getID()]); 726 BoundNodesTreeBuilder Builder; 727 if (MP.first.matches(DynNode, this, &Builder)) { 728 MatchVisitor Visitor(ActiveASTContext, MP.second); 729 Builder.visitMatches(&Visitor); 730 } 731 } 732 } 733 734 const std::vector<unsigned short> &getFilterForKind(ASTNodeKind Kind) { 735 auto &Filter = MatcherFiltersMap[Kind]; 736 auto &Matchers = this->Matchers->DeclOrStmt; 737 assert((Matchers.size() < USHRT_MAX) && "Too many matchers."); 738 for (unsigned I = 0, E = Matchers.size(); I != E; ++I) { 739 if (Matchers[I].first.canMatchNodesOfKind(Kind)) { 740 Filter.push_back(I); 741 } 742 } 743 return Filter; 744 } 745 746 /// @{ 747 /// Overloads to pair the different node types to their matchers. 748 void matchDispatch(const Decl *Node) { 749 return matchWithFilter(DynTypedNode::create(*Node)); 750 } 751 void matchDispatch(const Stmt *Node) { 752 return matchWithFilter(DynTypedNode::create(*Node)); 753 } 754 755 void matchDispatch(const Type *Node) { 756 matchWithoutFilter(QualType(Node, 0), Matchers->Type); 757 } 758 void matchDispatch(const TypeLoc *Node) { 759 matchWithoutFilter(*Node, Matchers->TypeLoc); 760 } 761 void matchDispatch(const QualType *Node) { 762 matchWithoutFilter(*Node, Matchers->Type); 763 } 764 void matchDispatch(const NestedNameSpecifier *Node) { 765 matchWithoutFilter(*Node, Matchers->NestedNameSpecifier); 766 } 767 void matchDispatch(const NestedNameSpecifierLoc *Node) { 768 matchWithoutFilter(*Node, Matchers->NestedNameSpecifierLoc); 769 } 770 void matchDispatch(const CXXCtorInitializer *Node) { 771 matchWithoutFilter(*Node, Matchers->CtorInit); 772 } 773 void matchDispatch(const TemplateArgumentLoc *Node) { 774 matchWithoutFilter(*Node, Matchers->TemplateArgumentLoc); 775 } 776 void matchDispatch(const void *) { /* Do nothing. */ } 777 /// @} 778 779 // Returns whether a direct parent of \p Node matches \p Matcher. 780 // Unlike matchesAnyAncestorOf there's no memoization: it doesn't save much. 781 bool matchesParentOf(const DynTypedNode &Node, const DynTypedMatcher &Matcher, 782 BoundNodesTreeBuilder *Builder) { 783 for (const auto &Parent : ActiveASTContext->getParents(Node)) { 784 BoundNodesTreeBuilder BuilderCopy = *Builder; 785 if (Matcher.matches(Parent, this, &BuilderCopy)) { 786 *Builder = std::move(BuilderCopy); 787 return true; 788 } 789 } 790 return false; 791 } 792 793 // Returns whether an ancestor of \p Node matches \p Matcher. 794 // 795 // The order of matching (which can lead to different nodes being bound in 796 // case there are multiple matches) is breadth first search. 797 // 798 // To allow memoization in the very common case of having deeply nested 799 // expressions inside a template function, we first walk up the AST, memoizing 800 // the result of the match along the way, as long as there is only a single 801 // parent. 802 // 803 // Once there are multiple parents, the breadth first search order does not 804 // allow simple memoization on the ancestors. Thus, we only memoize as long 805 // as there is a single parent. 806 // 807 // We avoid a recursive implementation to prevent excessive stack use on 808 // very deep ASTs (similarly to RecursiveASTVisitor's data recursion). 809 bool matchesAnyAncestorOf(DynTypedNode Node, ASTContext &Ctx, 810 const DynTypedMatcher &Matcher, 811 BoundNodesTreeBuilder *Builder) { 812 813 // Memoization keys that can be updated with the result. 814 // These are the memoizable nodes in the chain of unique parents, which 815 // terminates when a node has multiple parents, or matches, or is the root. 816 std::vector<MatchKey> Keys; 817 // When returning, update the memoization cache. 818 auto Finish = [&](bool Matched) { 819 for (const auto &Key : Keys) { 820 MemoizedMatchResult &CachedResult = ResultCache[Key]; 821 CachedResult.ResultOfMatch = Matched; 822 CachedResult.Nodes = *Builder; 823 } 824 return Matched; 825 }; 826 827 // Loop while there's a single parent and we want to attempt memoization. 828 DynTypedNodeList Parents{ArrayRef<DynTypedNode>()}; // after loop: size != 1 829 for (;;) { 830 // A cache key only makes sense if memoization is possible. 831 if (Builder->isComparable()) { 832 Keys.emplace_back(); 833 Keys.back().MatcherID = Matcher.getID(); 834 Keys.back().Node = Node; 835 Keys.back().BoundNodes = *Builder; 836 Keys.back().Traversal = Ctx.getParentMapContext().getTraversalKind(); 837 Keys.back().Type = MatchType::Ancestors; 838 839 // Check the cache. 840 MemoizationMap::iterator I = ResultCache.find(Keys.back()); 841 if (I != ResultCache.end()) { 842 Keys.pop_back(); // Don't populate the cache for the matching node! 843 *Builder = I->second.Nodes; 844 return Finish(I->second.ResultOfMatch); 845 } 846 } 847 848 Parents = ActiveASTContext->getParents(Node); 849 // Either no parents or multiple parents: leave chain+memoize mode and 850 // enter bfs+forgetful mode. 851 if (Parents.size() != 1) 852 break; 853 854 // Check the next parent. 855 Node = *Parents.begin(); 856 BoundNodesTreeBuilder BuilderCopy = *Builder; 857 if (Matcher.matches(Node, this, &BuilderCopy)) { 858 *Builder = std::move(BuilderCopy); 859 return Finish(true); 860 } 861 } 862 // We reached the end of the chain. 863 864 if (Parents.empty()) { 865 // Nodes may have no parents if: 866 // a) the node is the TranslationUnitDecl 867 // b) we have a limited traversal scope that excludes the parent edges 868 // c) there is a bug in the AST, and the node is not reachable 869 // Usually the traversal scope is the whole AST, which precludes b. 870 // Bugs are common enough that it's worthwhile asserting when we can. 871 #ifndef NDEBUG 872 if (!Node.get<TranslationUnitDecl>() && 873 /* Traversal scope is full AST if any of the bounds are the TU */ 874 llvm::any_of(ActiveASTContext->getTraversalScope(), [](Decl *D) { 875 return D->getKind() == Decl::TranslationUnit; 876 })) { 877 llvm::errs() << "Tried to match orphan node:\n"; 878 Node.dump(llvm::errs(), *ActiveASTContext); 879 llvm_unreachable("Parent map should be complete!"); 880 } 881 #endif 882 } else { 883 assert(Parents.size() > 1); 884 // BFS starting from the parents not yet considered. 885 // Memoization of newly visited nodes is not possible (but we still update 886 // results for the elements in the chain we found above). 887 std::deque<DynTypedNode> Queue(Parents.begin(), Parents.end()); 888 llvm::DenseSet<const void *> Visited; 889 while (!Queue.empty()) { 890 BoundNodesTreeBuilder BuilderCopy = *Builder; 891 if (Matcher.matches(Queue.front(), this, &BuilderCopy)) { 892 *Builder = std::move(BuilderCopy); 893 return Finish(true); 894 } 895 for (const auto &Parent : ActiveASTContext->getParents(Queue.front())) { 896 // Make sure we do not visit the same node twice. 897 // Otherwise, we'll visit the common ancestors as often as there 898 // are splits on the way down. 899 if (Visited.insert(Parent.getMemoizationData()).second) 900 Queue.push_back(Parent); 901 } 902 Queue.pop_front(); 903 } 904 } 905 return Finish(false); 906 } 907 908 // Implements a BoundNodesTree::Visitor that calls a MatchCallback with 909 // the aggregated bound nodes for each match. 910 class MatchVisitor : public BoundNodesTreeBuilder::Visitor { 911 public: 912 MatchVisitor(ASTContext* Context, 913 MatchFinder::MatchCallback* Callback) 914 : Context(Context), 915 Callback(Callback) {} 916 917 void visitMatch(const BoundNodes& BoundNodesView) override { 918 Callback->run(MatchFinder::MatchResult(BoundNodesView, Context)); 919 } 920 921 private: 922 ASTContext* Context; 923 MatchFinder::MatchCallback* Callback; 924 }; 925 926 // Returns true if 'TypeNode' has an alias that matches the given matcher. 927 bool typeHasMatchingAlias(const Type *TypeNode, 928 const Matcher<NamedDecl> &Matcher, 929 BoundNodesTreeBuilder *Builder) { 930 const Type *const CanonicalType = 931 ActiveASTContext->getCanonicalType(TypeNode); 932 auto Aliases = TypeAliases.find(CanonicalType); 933 if (Aliases == TypeAliases.end()) 934 return false; 935 for (const TypedefNameDecl *Alias : Aliases->second) { 936 BoundNodesTreeBuilder Result(*Builder); 937 if (Matcher.matches(*Alias, this, &Result)) { 938 *Builder = std::move(Result); 939 return true; 940 } 941 } 942 return false; 943 } 944 945 bool 946 objcClassHasMatchingCompatibilityAlias(const ObjCInterfaceDecl *InterfaceDecl, 947 const Matcher<NamedDecl> &Matcher, 948 BoundNodesTreeBuilder *Builder) { 949 auto Aliases = CompatibleAliases.find(InterfaceDecl); 950 if (Aliases == CompatibleAliases.end()) 951 return false; 952 for (const ObjCCompatibleAliasDecl *Alias : Aliases->second) { 953 BoundNodesTreeBuilder Result(*Builder); 954 if (Matcher.matches(*Alias, this, &Result)) { 955 *Builder = std::move(Result); 956 return true; 957 } 958 } 959 return false; 960 } 961 962 /// Bucket to record map. 963 /// 964 /// Used to get the appropriate bucket for each matcher. 965 llvm::StringMap<llvm::TimeRecord> TimeByBucket; 966 967 const MatchFinder::MatchersByType *Matchers; 968 969 /// Filtered list of matcher indices for each matcher kind. 970 /// 971 /// \c Decl and \c Stmt toplevel matchers usually apply to a specific node 972 /// kind (and derived kinds) so it is a waste to try every matcher on every 973 /// node. 974 /// We precalculate a list of matchers that pass the toplevel restrict check. 975 llvm::DenseMap<ASTNodeKind, std::vector<unsigned short>> MatcherFiltersMap; 976 977 const MatchFinder::MatchFinderOptions &Options; 978 ASTContext *ActiveASTContext; 979 980 // Maps a canonical type to its TypedefDecls. 981 llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases; 982 983 // Maps an Objective-C interface to its ObjCCompatibleAliasDecls. 984 llvm::DenseMap<const ObjCInterfaceDecl *, 985 llvm::SmallPtrSet<const ObjCCompatibleAliasDecl *, 2>> 986 CompatibleAliases; 987 988 // Maps (matcher, node) -> the match result for memoization. 989 typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap; 990 MemoizationMap ResultCache; 991 }; 992 993 static CXXRecordDecl * 994 getAsCXXRecordDeclOrPrimaryTemplate(const Type *TypeNode) { 995 if (auto *RD = TypeNode->getAsCXXRecordDecl()) 996 return RD; 997 998 // Find the innermost TemplateSpecializationType that isn't an alias template. 999 auto *TemplateType = TypeNode->getAs<TemplateSpecializationType>(); 1000 while (TemplateType && TemplateType->isTypeAlias()) 1001 TemplateType = 1002 TemplateType->getAliasedType()->getAs<TemplateSpecializationType>(); 1003 1004 // If this is the name of a (dependent) template specialization, use the 1005 // definition of the template, even though it might be specialized later. 1006 if (TemplateType) 1007 if (auto *ClassTemplate = dyn_cast_or_null<ClassTemplateDecl>( 1008 TemplateType->getTemplateName().getAsTemplateDecl())) 1009 return ClassTemplate->getTemplatedDecl(); 1010 1011 return nullptr; 1012 } 1013 1014 // Returns true if the given C++ class is directly or indirectly derived 1015 // from a base type with the given name. A class is not considered to be 1016 // derived from itself. 1017 bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration, 1018 const Matcher<NamedDecl> &Base, 1019 BoundNodesTreeBuilder *Builder, 1020 bool Directly) { 1021 if (!Declaration->hasDefinition()) 1022 return false; 1023 for (const auto &It : Declaration->bases()) { 1024 const Type *TypeNode = It.getType().getTypePtr(); 1025 1026 if (typeHasMatchingAlias(TypeNode, Base, Builder)) 1027 return true; 1028 1029 // FIXME: Going to the primary template here isn't really correct, but 1030 // unfortunately we accept a Decl matcher for the base class not a Type 1031 // matcher, so it's the best thing we can do with our current interface. 1032 CXXRecordDecl *ClassDecl = getAsCXXRecordDeclOrPrimaryTemplate(TypeNode); 1033 if (!ClassDecl) 1034 continue; 1035 if (ClassDecl == Declaration) { 1036 // This can happen for recursive template definitions. 1037 continue; 1038 } 1039 BoundNodesTreeBuilder Result(*Builder); 1040 if (Base.matches(*ClassDecl, this, &Result)) { 1041 *Builder = std::move(Result); 1042 return true; 1043 } 1044 if (!Directly && classIsDerivedFrom(ClassDecl, Base, Builder, Directly)) 1045 return true; 1046 } 1047 return false; 1048 } 1049 1050 // Returns true if the given Objective-C class is directly or indirectly 1051 // derived from a matching base class. A class is not considered to be derived 1052 // from itself. 1053 bool MatchASTVisitor::objcClassIsDerivedFrom( 1054 const ObjCInterfaceDecl *Declaration, const Matcher<NamedDecl> &Base, 1055 BoundNodesTreeBuilder *Builder, bool Directly) { 1056 // Check if any of the superclasses of the class match. 1057 for (const ObjCInterfaceDecl *ClassDecl = Declaration->getSuperClass(); 1058 ClassDecl != nullptr; ClassDecl = ClassDecl->getSuperClass()) { 1059 // Check if there are any matching compatibility aliases. 1060 if (objcClassHasMatchingCompatibilityAlias(ClassDecl, Base, Builder)) 1061 return true; 1062 1063 // Check if there are any matching type aliases. 1064 const Type *TypeNode = ClassDecl->getTypeForDecl(); 1065 if (typeHasMatchingAlias(TypeNode, Base, Builder)) 1066 return true; 1067 1068 if (Base.matches(*ClassDecl, this, Builder)) 1069 return true; 1070 1071 // Not `return false` as a temporary workaround for PR43879. 1072 if (Directly) 1073 break; 1074 } 1075 1076 return false; 1077 } 1078 1079 bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) { 1080 if (!DeclNode) { 1081 return true; 1082 } 1083 1084 bool ScopedTraversal = 1085 TraversingASTNodeNotSpelledInSource || DeclNode->isImplicit(); 1086 bool ScopedChildren = TraversingASTChildrenNotSpelledInSource; 1087 1088 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(DeclNode)) { 1089 auto SK = CTSD->getSpecializationKind(); 1090 if (SK == TSK_ExplicitInstantiationDeclaration || 1091 SK == TSK_ExplicitInstantiationDefinition) 1092 ScopedChildren = true; 1093 } else if (const auto *FD = dyn_cast<FunctionDecl>(DeclNode)) { 1094 if (FD->isDefaulted()) 1095 ScopedChildren = true; 1096 } 1097 1098 ASTNodeNotSpelledInSourceScope RAII1(this, ScopedTraversal); 1099 ASTChildrenNotSpelledInSource RAII2(this, ScopedChildren); 1100 1101 match(*DeclNode); 1102 return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode); 1103 } 1104 1105 bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) { 1106 if (!StmtNode) { 1107 return true; 1108 } 1109 bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 1110 TraversingASTChildrenNotSpelledInSource; 1111 1112 ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal); 1113 match(*StmtNode); 1114 return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode, Queue); 1115 } 1116 1117 bool MatchASTVisitor::TraverseType(QualType TypeNode) { 1118 match(TypeNode); 1119 return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode); 1120 } 1121 1122 bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) { 1123 // The RecursiveASTVisitor only visits types if they're not within TypeLocs. 1124 // We still want to find those types via matchers, so we match them here. Note 1125 // that the TypeLocs are structurally a shadow-hierarchy to the expressed 1126 // type, so we visit all involved parts of a compound type when matching on 1127 // each TypeLoc. 1128 match(TypeLocNode); 1129 match(TypeLocNode.getType()); 1130 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode); 1131 } 1132 1133 bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { 1134 match(*NNS); 1135 return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS); 1136 } 1137 1138 bool MatchASTVisitor::TraverseNestedNameSpecifierLoc( 1139 NestedNameSpecifierLoc NNS) { 1140 if (!NNS) 1141 return true; 1142 1143 match(NNS); 1144 1145 // We only match the nested name specifier here (as opposed to traversing it) 1146 // because the traversal is already done in the parallel "Loc"-hierarchy. 1147 if (NNS.hasQualifier()) 1148 match(*NNS.getNestedNameSpecifier()); 1149 return 1150 RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS); 1151 } 1152 1153 bool MatchASTVisitor::TraverseConstructorInitializer( 1154 CXXCtorInitializer *CtorInit) { 1155 if (!CtorInit) 1156 return true; 1157 1158 bool ScopedTraversal = TraversingASTNodeNotSpelledInSource || 1159 TraversingASTChildrenNotSpelledInSource; 1160 1161 if (!CtorInit->isWritten()) 1162 ScopedTraversal = true; 1163 1164 ASTNodeNotSpelledInSourceScope RAII1(this, ScopedTraversal); 1165 1166 match(*CtorInit); 1167 1168 return RecursiveASTVisitor<MatchASTVisitor>::TraverseConstructorInitializer( 1169 CtorInit); 1170 } 1171 1172 bool MatchASTVisitor::TraverseTemplateArgumentLoc(TemplateArgumentLoc Loc) { 1173 match(Loc); 1174 return RecursiveASTVisitor<MatchASTVisitor>::TraverseTemplateArgumentLoc(Loc); 1175 } 1176 1177 class MatchASTConsumer : public ASTConsumer { 1178 public: 1179 MatchASTConsumer(MatchFinder *Finder, 1180 MatchFinder::ParsingDoneTestCallback *ParsingDone) 1181 : Finder(Finder), ParsingDone(ParsingDone) {} 1182 1183 private: 1184 void HandleTranslationUnit(ASTContext &Context) override { 1185 if (ParsingDone != nullptr) { 1186 ParsingDone->run(); 1187 } 1188 Finder->matchAST(Context); 1189 } 1190 1191 MatchFinder *Finder; 1192 MatchFinder::ParsingDoneTestCallback *ParsingDone; 1193 }; 1194 1195 } // end namespace 1196 } // end namespace internal 1197 1198 MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes, 1199 ASTContext *Context) 1200 : Nodes(Nodes), Context(Context), 1201 SourceManager(&Context->getSourceManager()) {} 1202 1203 MatchFinder::MatchCallback::~MatchCallback() {} 1204 MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {} 1205 1206 MatchFinder::MatchFinder(MatchFinderOptions Options) 1207 : Options(std::move(Options)), ParsingDone(nullptr) {} 1208 1209 MatchFinder::~MatchFinder() {} 1210 1211 void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch, 1212 MatchCallback *Action) { 1213 Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 1214 Matchers.AllCallbacks.insert(Action); 1215 } 1216 1217 void MatchFinder::addMatcher(const TypeMatcher &NodeMatch, 1218 MatchCallback *Action) { 1219 Matchers.Type.emplace_back(NodeMatch, Action); 1220 Matchers.AllCallbacks.insert(Action); 1221 } 1222 1223 void MatchFinder::addMatcher(const StatementMatcher &NodeMatch, 1224 MatchCallback *Action) { 1225 Matchers.DeclOrStmt.emplace_back(NodeMatch, Action); 1226 Matchers.AllCallbacks.insert(Action); 1227 } 1228 1229 void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch, 1230 MatchCallback *Action) { 1231 Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action); 1232 Matchers.AllCallbacks.insert(Action); 1233 } 1234 1235 void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch, 1236 MatchCallback *Action) { 1237 Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action); 1238 Matchers.AllCallbacks.insert(Action); 1239 } 1240 1241 void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch, 1242 MatchCallback *Action) { 1243 Matchers.TypeLoc.emplace_back(NodeMatch, Action); 1244 Matchers.AllCallbacks.insert(Action); 1245 } 1246 1247 void MatchFinder::addMatcher(const CXXCtorInitializerMatcher &NodeMatch, 1248 MatchCallback *Action) { 1249 Matchers.CtorInit.emplace_back(NodeMatch, Action); 1250 Matchers.AllCallbacks.insert(Action); 1251 } 1252 1253 void MatchFinder::addMatcher(const TemplateArgumentLocMatcher &NodeMatch, 1254 MatchCallback *Action) { 1255 Matchers.TemplateArgumentLoc.emplace_back(NodeMatch, Action); 1256 Matchers.AllCallbacks.insert(Action); 1257 } 1258 1259 bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, 1260 MatchCallback *Action) { 1261 if (NodeMatch.canConvertTo<Decl>()) { 1262 addMatcher(NodeMatch.convertTo<Decl>(), Action); 1263 return true; 1264 } else if (NodeMatch.canConvertTo<QualType>()) { 1265 addMatcher(NodeMatch.convertTo<QualType>(), Action); 1266 return true; 1267 } else if (NodeMatch.canConvertTo<Stmt>()) { 1268 addMatcher(NodeMatch.convertTo<Stmt>(), Action); 1269 return true; 1270 } else if (NodeMatch.canConvertTo<NestedNameSpecifier>()) { 1271 addMatcher(NodeMatch.convertTo<NestedNameSpecifier>(), Action); 1272 return true; 1273 } else if (NodeMatch.canConvertTo<NestedNameSpecifierLoc>()) { 1274 addMatcher(NodeMatch.convertTo<NestedNameSpecifierLoc>(), Action); 1275 return true; 1276 } else if (NodeMatch.canConvertTo<TypeLoc>()) { 1277 addMatcher(NodeMatch.convertTo<TypeLoc>(), Action); 1278 return true; 1279 } else if (NodeMatch.canConvertTo<CXXCtorInitializer>()) { 1280 addMatcher(NodeMatch.convertTo<CXXCtorInitializer>(), Action); 1281 return true; 1282 } else if (NodeMatch.canConvertTo<TemplateArgumentLoc>()) { 1283 addMatcher(NodeMatch.convertTo<TemplateArgumentLoc>(), Action); 1284 return true; 1285 } 1286 return false; 1287 } 1288 1289 std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() { 1290 return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone); 1291 } 1292 1293 void MatchFinder::match(const clang::DynTypedNode &Node, ASTContext &Context) { 1294 internal::MatchASTVisitor Visitor(&Matchers, Options); 1295 Visitor.set_active_ast_context(&Context); 1296 Visitor.match(Node); 1297 } 1298 1299 void MatchFinder::matchAST(ASTContext &Context) { 1300 internal::MatchASTVisitor Visitor(&Matchers, Options); 1301 Visitor.set_active_ast_context(&Context); 1302 Visitor.onStartOfTranslationUnit(); 1303 Visitor.TraverseAST(Context); 1304 Visitor.onEndOfTranslationUnit(); 1305 } 1306 1307 void MatchFinder::registerTestCallbackAfterParsing( 1308 MatchFinder::ParsingDoneTestCallback *NewParsingDone) { 1309 ParsingDone = NewParsingDone; 1310 } 1311 1312 StringRef MatchFinder::MatchCallback::getID() const { return "<unknown>"; } 1313 1314 } // end namespace ast_matchers 1315 } // end namespace clang 1316