Coverage Report

Created: 2021-09-21 08:58

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