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