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