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