clang  10.0.0svn
ASTMatchFinder.cpp
Go to the documentation of this file.
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 
19 #include "clang/AST/ASTConsumer.h"
20 #include "clang/AST/ASTContext.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 // We use memoization to avoid running the same matcher on the same
47 // AST node twice. This struct is the key for looking up match
48 // result. It consists of an ID of the MatcherInterface (for
49 // identifying the matcher), a pointer to the AST node and the
50 // bound nodes before the matcher was executed.
51 //
52 // We currently only memoize on nodes whose pointers identify the
53 // nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc).
54 // For \c QualType and \c TypeLoc it is possible to implement
55 // generation of keys for each type.
56 // FIXME: Benchmark whether memoization of non-pointer typed nodes
57 // provides enough benefit for the additional amount of code.
58 struct MatchKey {
59  DynTypedMatcher::MatcherIDType MatcherID;
61  BoundNodesTreeBuilder BoundNodes;
62 
63  bool operator<(const MatchKey &Other) const {
64  return std::tie(MatcherID, Node, BoundNodes) <
65  std::tie(Other.MatcherID, Other.Node, Other.BoundNodes);
66  }
67 };
68 
69 // Used to store the result of a match and possibly bound nodes.
70 struct MemoizedMatchResult {
72  BoundNodesTreeBuilder Nodes;
73 };
74 
75 // A RecursiveASTVisitor that traverses all children or all descendants of
76 // a node.
77 class MatchChildASTVisitor
78  : public RecursiveASTVisitor<MatchChildASTVisitor> {
79 public:
80  typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase;
81 
82  // Creates an AST visitor that matches 'matcher' on all children or
83  // descendants of a traversed node. max_depth is the maximum depth
84  // to traverse: use 1 for matching the children and INT_MAX for
85  // matching the descendants.
86  MatchChildASTVisitor(const DynTypedMatcher *Matcher, ASTMatchFinder *Finder,
87  BoundNodesTreeBuilder *Builder, int MaxDepth,
89  ASTMatchFinder::BindKind Bind)
90  : Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0),
91  MaxDepth(MaxDepth), Traversal(Traversal), Bind(Bind), Matches(false) {}
92 
93  // Returns true if a match is found in the subtree rooted at the
94  // given AST node. This is done via a set of mutually recursive
95  // functions. Here's how the recursion is done (the *wildcard can
96  // actually be Decl, Stmt, or Type):
97  //
98  // - Traverse(node) calls BaseTraverse(node) when it needs
99  // to visit the descendants of node.
100  // - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node))
101  // Traverse*(c) for each child c of 'node'.
102  // - Traverse*(c) in turn calls Traverse(c), completing the
103  // recursion.
104  bool findMatch(const ast_type_traits::DynTypedNode &DynNode) {
105  reset();
106  if (const Decl *D = DynNode.get<Decl>())
107  traverse(*D);
108  else if (const Stmt *S = DynNode.get<Stmt>())
109  traverse(*S);
110  else if (const NestedNameSpecifier *NNS =
111  DynNode.get<NestedNameSpecifier>())
112  traverse(*NNS);
113  else if (const NestedNameSpecifierLoc *NNSLoc =
114  DynNode.get<NestedNameSpecifierLoc>())
115  traverse(*NNSLoc);
116  else if (const QualType *Q = DynNode.get<QualType>())
117  traverse(*Q);
118  else if (const TypeLoc *T = DynNode.get<TypeLoc>())
119  traverse(*T);
120  else if (const auto *C = DynNode.get<CXXCtorInitializer>())
121  traverse(*C);
122  // FIXME: Add other base types after adding tests.
123 
124  // It's OK to always overwrite the bound nodes, as if there was
125  // no match in this recursive branch, the result set is empty
126  // anyway.
127  *Builder = ResultBindings;
128 
129  return Matches;
130  }
131 
132  // The following are overriding methods from the base visitor class.
133  // They are public only to allow CRTP to work. They are *not *part
134  // of the public API of this class.
135  bool TraverseDecl(Decl *DeclNode) {
136  ScopedIncrement ScopedDepth(&CurrentDepth);
137  return (DeclNode == nullptr) || traverse(*DeclNode);
138  }
139  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) {
140  // If we need to keep track of the depth, we can't perform data recursion.
141  if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX))
142  Queue = nullptr;
143 
144  ScopedIncrement ScopedDepth(&CurrentDepth);
145  Stmt *StmtToTraverse = StmtNode;
146  if (Traversal ==
148  if (Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode))
149  StmtToTraverse = ExprNode->IgnoreParenImpCasts();
150  }
151  if (!StmtToTraverse)
152  return true;
153  if (!match(*StmtToTraverse))
154  return false;
155  return VisitorBase::TraverseStmt(StmtToTraverse, Queue);
156  }
157  // We assume that the QualType and the contained type are on the same
158  // hierarchy level. Thus, we try to match either of them.
159  bool TraverseType(QualType TypeNode) {
160  if (TypeNode.isNull())
161  return true;
162  ScopedIncrement ScopedDepth(&CurrentDepth);
163  // Match the Type.
164  if (!match(*TypeNode))
165  return false;
166  // The QualType is matched inside traverse.
167  return traverse(TypeNode);
168  }
169  // We assume that the TypeLoc, contained QualType and contained Type all are
170  // on the same hierarchy level. Thus, we try to match all of them.
171  bool TraverseTypeLoc(TypeLoc TypeLocNode) {
172  if (TypeLocNode.isNull())
173  return true;
174  ScopedIncrement ScopedDepth(&CurrentDepth);
175  // Match the Type.
176  if (!match(*TypeLocNode.getType()))
177  return false;
178  // Match the QualType.
179  if (!match(TypeLocNode.getType()))
180  return false;
181  // The TypeLoc is matched inside traverse.
182  return traverse(TypeLocNode);
183  }
184  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
185  ScopedIncrement ScopedDepth(&CurrentDepth);
186  return (NNS == nullptr) || traverse(*NNS);
187  }
188  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
189  if (!NNS)
190  return true;
191  ScopedIncrement ScopedDepth(&CurrentDepth);
192  if (!match(*NNS.getNestedNameSpecifier()))
193  return false;
194  return traverse(NNS);
195  }
196  bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) {
197  if (!CtorInit)
198  return true;
199  ScopedIncrement ScopedDepth(&CurrentDepth);
200  return traverse(*CtorInit);
201  }
202 
203  bool shouldVisitTemplateInstantiations() const { return true; }
204  bool shouldVisitImplicitCode() const { return true; }
205 
206 private:
207  // Used for updating the depth during traversal.
208  struct ScopedIncrement {
209  explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); }
210  ~ScopedIncrement() { --(*Depth); }
211 
212  private:
213  int *Depth;
214  };
215 
216  // Resets the state of this object.
217  void reset() {
218  Matches = false;
219  CurrentDepth = 0;
220  }
221 
222  // Forwards the call to the corresponding Traverse*() method in the
223  // base visitor class.
224  bool baseTraverse(const Decl &DeclNode) {
225  return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode));
226  }
227  bool baseTraverse(const Stmt &StmtNode) {
228  return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode));
229  }
230  bool baseTraverse(QualType TypeNode) {
231  return VisitorBase::TraverseType(TypeNode);
232  }
233  bool baseTraverse(TypeLoc TypeLocNode) {
234  return VisitorBase::TraverseTypeLoc(TypeLocNode);
235  }
236  bool baseTraverse(const NestedNameSpecifier &NNS) {
237  return VisitorBase::TraverseNestedNameSpecifier(
238  const_cast<NestedNameSpecifier*>(&NNS));
239  }
240  bool baseTraverse(NestedNameSpecifierLoc NNS) {
241  return VisitorBase::TraverseNestedNameSpecifierLoc(NNS);
242  }
243  bool baseTraverse(const CXXCtorInitializer &CtorInit) {
244  return VisitorBase::TraverseConstructorInitializer(
245  const_cast<CXXCtorInitializer *>(&CtorInit));
246  }
247 
248  // Sets 'Matched' to true if 'Matcher' matches 'Node' and:
249  // 0 < CurrentDepth <= MaxDepth.
250  //
251  // Returns 'true' if traversal should continue after this function
252  // returns, i.e. if no match is found or 'Bind' is 'BK_All'.
253  template <typename T>
254  bool match(const T &Node) {
255  if (CurrentDepth == 0 || CurrentDepth > MaxDepth) {
256  return true;
257  }
258  if (Bind != ASTMatchFinder::BK_All) {
259  BoundNodesTreeBuilder RecursiveBuilder(*Builder);
260  if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
261  &RecursiveBuilder)) {
262  Matches = true;
263  ResultBindings.addMatch(RecursiveBuilder);
264  return false; // Abort as soon as a match is found.
265  }
266  } else {
267  BoundNodesTreeBuilder RecursiveBuilder(*Builder);
268  if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
269  &RecursiveBuilder)) {
270  // After the first match the matcher succeeds.
271  Matches = true;
272  ResultBindings.addMatch(RecursiveBuilder);
273  }
274  }
275  return true;
276  }
277 
278  // Traverses the subtree rooted at 'Node'; returns true if the
279  // traversal should continue after this function returns.
280  template <typename T>
281  bool traverse(const T &Node) {
282  static_assert(IsBaseType<T>::value,
283  "traverse can only be instantiated with base type");
284  if (!match(Node))
285  return false;
286  return baseTraverse(Node);
287  }
288 
289  const DynTypedMatcher *const Matcher;
290  ASTMatchFinder *const Finder;
291  BoundNodesTreeBuilder *const Builder;
292  BoundNodesTreeBuilder ResultBindings;
293  int CurrentDepth;
294  const int MaxDepth;
295  const ast_type_traits::TraversalKind Traversal;
296  const ASTMatchFinder::BindKind Bind;
297  bool Matches;
298 };
299 
300 // Controls the outermost traversal of the AST and allows to match multiple
301 // matchers.
302 class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
303  public ASTMatchFinder {
304 public:
305  MatchASTVisitor(const MatchFinder::MatchersByType *Matchers,
306  const MatchFinder::MatchFinderOptions &Options)
307  : Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {}
308 
309  ~MatchASTVisitor() override {
310  if (Options.CheckProfiling) {
311  Options.CheckProfiling->Records = std::move(TimeByBucket);
312  }
313  }
314 
315  void onStartOfTranslationUnit() {
316  const bool EnableCheckProfiling = Options.CheckProfiling.hasValue();
317  TimeBucketRegion Timer;
318  for (MatchCallback *MC : Matchers->AllCallbacks) {
319  if (EnableCheckProfiling)
320  Timer.setBucket(&TimeByBucket[MC->getID()]);
321  MC->onStartOfTranslationUnit();
322  }
323  }
324 
325  void onEndOfTranslationUnit() {
326  const bool EnableCheckProfiling = Options.CheckProfiling.hasValue();
327  TimeBucketRegion Timer;
328  for (MatchCallback *MC : Matchers->AllCallbacks) {
329  if (EnableCheckProfiling)
330  Timer.setBucket(&TimeByBucket[MC->getID()]);
331  MC->onEndOfTranslationUnit();
332  }
333  }
334 
335  void set_active_ast_context(ASTContext *NewActiveASTContext) {
336  ActiveASTContext = NewActiveASTContext;
337  }
338 
339  // The following Visit*() and Traverse*() functions "override"
340  // methods in RecursiveASTVisitor.
341 
342  bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) {
343  // When we see 'typedef A B', we add name 'B' to the set of names
344  // A's canonical type maps to. This is necessary for implementing
345  // isDerivedFrom(x) properly, where x can be the name of the base
346  // class or any of its aliases.
347  //
348  // In general, the is-alias-of (as defined by typedefs) relation
349  // is tree-shaped, as you can typedef a type more than once. For
350  // example,
351  //
352  // typedef A B;
353  // typedef A C;
354  // typedef C D;
355  // typedef C E;
356  //
357  // gives you
358  //
359  // A
360  // |- B
361  // `- C
362  // |- D
363  // `- E
364  //
365  // It is wrong to assume that the relation is a chain. A correct
366  // implementation of isDerivedFrom() needs to recognize that B and
367  // E are aliases, even though neither is a typedef of the other.
368  // Therefore, we cannot simply walk through one typedef chain to
369  // find out whether the type name matches.
370  const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr();
371  const Type *CanonicalType = // root of the typedef tree
372  ActiveASTContext->getCanonicalType(TypeNode);
373  TypeAliases[CanonicalType].insert(DeclNode);
374  return true;
375  }
376 
377  bool VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
378  const ObjCInterfaceDecl *InterfaceDecl = CAD->getClassInterface();
379  CompatibleAliases[InterfaceDecl].insert(CAD);
380  return true;
381  }
382 
383  bool TraverseDecl(Decl *DeclNode);
384  bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr);
385  bool TraverseType(QualType TypeNode);
386  bool TraverseTypeLoc(TypeLoc TypeNode);
387  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
388  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
389  bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);
390 
391  // Matches children or descendants of 'Node' with 'BaseMatcher'.
392  bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
393  const DynTypedMatcher &Matcher,
394  BoundNodesTreeBuilder *Builder, int MaxDepth,
396  BindKind Bind) {
397  // For AST-nodes that don't have an identity, we can't memoize.
398  if (!Node.getMemoizationData() || !Builder->isComparable())
399  return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal,
400  Bind);
401 
402  MatchKey Key;
403  Key.MatcherID = Matcher.getID();
404  Key.Node = Node;
405  // Note that we key on the bindings *before* the match.
406  Key.BoundNodes = *Builder;
407 
408  MemoizationMap::iterator I = ResultCache.find(Key);
409  if (I != ResultCache.end()) {
410  *Builder = I->second.Nodes;
411  return I->second.ResultOfMatch;
412  }
413 
414  MemoizedMatchResult Result;
415  Result.Nodes = *Builder;
416  Result.ResultOfMatch = matchesRecursively(Node, Matcher, &Result.Nodes,
417  MaxDepth, Traversal, Bind);
418 
419  MemoizedMatchResult &CachedResult = ResultCache[Key];
420  CachedResult = std::move(Result);
421 
422  *Builder = CachedResult.Nodes;
423  return CachedResult.ResultOfMatch;
424  }
425 
426  // Matches children or descendants of 'Node' with 'BaseMatcher'.
427  bool matchesRecursively(const ast_type_traits::DynTypedNode &Node,
428  const DynTypedMatcher &Matcher,
429  BoundNodesTreeBuilder *Builder, int MaxDepth,
431  BindKind Bind) {
432  MatchChildASTVisitor Visitor(
433  &Matcher, this, Builder, MaxDepth, Traversal, Bind);
434  return Visitor.findMatch(Node);
435  }
436 
437  bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
438  const Matcher<NamedDecl> &Base,
439  BoundNodesTreeBuilder *Builder,
440  bool Directly) override;
441 
442  bool objcClassIsDerivedFrom(const ObjCInterfaceDecl *Declaration,
443  const Matcher<NamedDecl> &Base,
444  BoundNodesTreeBuilder *Builder,
445  bool Directly) override;
446 
447  // Implements ASTMatchFinder::matchesChildOf.
448  bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
449  const DynTypedMatcher &Matcher,
450  BoundNodesTreeBuilder *Builder,
452  BindKind Bind) override {
453  if (ResultCache.size() > MaxMemoizationEntries)
454  ResultCache.clear();
455  return memoizedMatchesRecursively(Node, Matcher, Builder, 1, Traversal,
456  Bind);
457  }
458  // Implements ASTMatchFinder::matchesDescendantOf.
459  bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
460  const DynTypedMatcher &Matcher,
461  BoundNodesTreeBuilder *Builder,
462  BindKind Bind) override {
463  if (ResultCache.size() > MaxMemoizationEntries)
464  ResultCache.clear();
465  return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX,
467  Bind);
468  }
469  // Implements ASTMatchFinder::matchesAncestorOf.
470  bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
471  const DynTypedMatcher &Matcher,
472  BoundNodesTreeBuilder *Builder,
473  AncestorMatchMode MatchMode) override {
474  // Reset the cache outside of the recursive call to make sure we
475  // don't invalidate any iterators.
476  if (ResultCache.size() > MaxMemoizationEntries)
477  ResultCache.clear();
478  return memoizedMatchesAncestorOfRecursively(Node, Matcher, Builder,
479  MatchMode);
480  }
481 
482  // Matches all registered matchers on the given node and calls the
483  // result callback for every node that matches.
484  void match(const ast_type_traits::DynTypedNode &Node) {
485  // FIXME: Improve this with a switch or a visitor pattern.
486  if (auto *N = Node.get<Decl>()) {
487  match(*N);
488  } else if (auto *N = Node.get<Stmt>()) {
489  match(*N);
490  } else if (auto *N = Node.get<Type>()) {
491  match(*N);
492  } else if (auto *N = Node.get<QualType>()) {
493  match(*N);
494  } else if (auto *N = Node.get<NestedNameSpecifier>()) {
495  match(*N);
496  } else if (auto *N = Node.get<NestedNameSpecifierLoc>()) {
497  match(*N);
498  } else if (auto *N = Node.get<TypeLoc>()) {
499  match(*N);
500  } else if (auto *N = Node.get<CXXCtorInitializer>()) {
501  match(*N);
502  }
503  }
504 
505  template <typename T> void match(const T &Node) {
506  matchDispatch(&Node);
507  }
508 
509  // Implements ASTMatchFinder::getASTContext.
510  ASTContext &getASTContext() const override { return *ActiveASTContext; }
511 
512  bool shouldVisitTemplateInstantiations() const { return true; }
513  bool shouldVisitImplicitCode() const { return true; }
514 
515 private:
516  class TimeBucketRegion {
517  public:
518  TimeBucketRegion() : Bucket(nullptr) {}
519  ~TimeBucketRegion() { setBucket(nullptr); }
520 
521  /// Start timing for \p NewBucket.
522  ///
523  /// If there was a bucket already set, it will finish the timing for that
524  /// other bucket.
525  /// \p NewBucket will be timed until the next call to \c setBucket() or
526  /// until the \c TimeBucketRegion is destroyed.
527  /// If \p NewBucket is the same as the currently timed bucket, this call
528  /// does nothing.
529  void setBucket(llvm::TimeRecord *NewBucket) {
530  if (Bucket != NewBucket) {
531  auto Now = llvm::TimeRecord::getCurrentTime(true);
532  if (Bucket)
533  *Bucket += Now;
534  if (NewBucket)
535  *NewBucket -= Now;
536  Bucket = NewBucket;
537  }
538  }
539 
540  private:
541  llvm::TimeRecord *Bucket;
542  };
543 
544  /// Runs all the \p Matchers on \p Node.
545  ///
546  /// Used by \c matchDispatch() below.
547  template <typename T, typename MC>
548  void matchWithoutFilter(const T &Node, const MC &Matchers) {
549  const bool EnableCheckProfiling = Options.CheckProfiling.hasValue();
550  TimeBucketRegion Timer;
551  for (const auto &MP : Matchers) {
552  if (EnableCheckProfiling)
553  Timer.setBucket(&TimeByBucket[MP.second->getID()]);
554  BoundNodesTreeBuilder Builder;
555  if (MP.first.matches(Node, this, &Builder)) {
556  MatchVisitor Visitor(ActiveASTContext, MP.second);
557  Builder.visitMatches(&Visitor);
558  }
559  }
560  }
561 
562  void matchWithFilter(const ast_type_traits::DynTypedNode &DynNode) {
563  auto Kind = DynNode.getNodeKind();
564  auto it = MatcherFiltersMap.find(Kind);
565  const auto &Filter =
566  it != MatcherFiltersMap.end() ? it->second : getFilterForKind(Kind);
567 
568  if (Filter.empty())
569  return;
570 
571  const bool EnableCheckProfiling = Options.CheckProfiling.hasValue();
572  TimeBucketRegion Timer;
573  auto &Matchers = this->Matchers->DeclOrStmt;
574  for (unsigned short I : Filter) {
575  auto &MP = Matchers[I];
576  if (EnableCheckProfiling)
577  Timer.setBucket(&TimeByBucket[MP.second->getID()]);
578  BoundNodesTreeBuilder Builder;
579  if (MP.first.matchesNoKindCheck(DynNode, this, &Builder)) {
580  MatchVisitor Visitor(ActiveASTContext, MP.second);
581  Builder.visitMatches(&Visitor);
582  }
583  }
584  }
585 
586  const std::vector<unsigned short> &
587  getFilterForKind(ast_type_traits::ASTNodeKind Kind) {
588  auto &Filter = MatcherFiltersMap[Kind];
589  auto &Matchers = this->Matchers->DeclOrStmt;
590  assert((Matchers.size() < USHRT_MAX) && "Too many matchers.");
591  for (unsigned I = 0, E = Matchers.size(); I != E; ++I) {
592  if (Matchers[I].first.canMatchNodesOfKind(Kind)) {
593  Filter.push_back(I);
594  }
595  }
596  return Filter;
597  }
598 
599  /// @{
600  /// Overloads to pair the different node types to their matchers.
601  void matchDispatch(const Decl *Node) {
602  return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node));
603  }
604  void matchDispatch(const Stmt *Node) {
605  return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node));
606  }
607 
608  void matchDispatch(const Type *Node) {
609  matchWithoutFilter(QualType(Node, 0), Matchers->Type);
610  }
611  void matchDispatch(const TypeLoc *Node) {
612  matchWithoutFilter(*Node, Matchers->TypeLoc);
613  }
614  void matchDispatch(const QualType *Node) {
615  matchWithoutFilter(*Node, Matchers->Type);
616  }
617  void matchDispatch(const NestedNameSpecifier *Node) {
618  matchWithoutFilter(*Node, Matchers->NestedNameSpecifier);
619  }
620  void matchDispatch(const NestedNameSpecifierLoc *Node) {
621  matchWithoutFilter(*Node, Matchers->NestedNameSpecifierLoc);
622  }
623  void matchDispatch(const CXXCtorInitializer *Node) {
624  matchWithoutFilter(*Node, Matchers->CtorInit);
625  }
626  void matchDispatch(const void *) { /* Do nothing. */ }
627  /// @}
628 
629  // Returns whether an ancestor of \p Node matches \p Matcher.
630  //
631  // The order of matching ((which can lead to different nodes being bound in
632  // case there are multiple matches) is breadth first search.
633  //
634  // To allow memoization in the very common case of having deeply nested
635  // expressions inside a template function, we first walk up the AST, memoizing
636  // the result of the match along the way, as long as there is only a single
637  // parent.
638  //
639  // Once there are multiple parents, the breadth first search order does not
640  // allow simple memoization on the ancestors. Thus, we only memoize as long
641  // as there is a single parent.
642  bool memoizedMatchesAncestorOfRecursively(
643  const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher,
644  BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) {
645  // For AST-nodes that don't have an identity, we can't memoize.
646  if (!Builder->isComparable())
647  return matchesAncestorOfRecursively(Node, Matcher, Builder, MatchMode);
648 
649  MatchKey Key;
650  Key.MatcherID = Matcher.getID();
651  Key.Node = Node;
652  Key.BoundNodes = *Builder;
653 
654  // Note that we cannot use insert and reuse the iterator, as recursive
655  // calls to match might invalidate the result cache iterators.
656  MemoizationMap::iterator I = ResultCache.find(Key);
657  if (I != ResultCache.end()) {
658  *Builder = I->second.Nodes;
659  return I->second.ResultOfMatch;
660  }
661 
662  MemoizedMatchResult Result;
663  Result.Nodes = *Builder;
664  Result.ResultOfMatch =
665  matchesAncestorOfRecursively(Node, Matcher, &Result.Nodes, MatchMode);
666 
667  MemoizedMatchResult &CachedResult = ResultCache[Key];
668  CachedResult = std::move(Result);
669 
670  *Builder = CachedResult.Nodes;
671  return CachedResult.ResultOfMatch;
672  }
673 
674  bool matchesAncestorOfRecursively(const ast_type_traits::DynTypedNode &Node,
675  const DynTypedMatcher &Matcher,
676  BoundNodesTreeBuilder *Builder,
677  AncestorMatchMode MatchMode) {
678  const auto &Parents = ActiveASTContext->getParents(Node);
679  if (Parents.empty()) {
680  // Nodes may have no parents if:
681  // a) the node is the TranslationUnitDecl
682  // b) we have a limited traversal scope that excludes the parent edges
683  // c) there is a bug in the AST, and the node is not reachable
684  // Usually the traversal scope is the whole AST, which precludes b.
685  // Bugs are common enough that it's worthwhile asserting when we can.
686 #ifndef NDEBUG
687  if (!Node.get<TranslationUnitDecl>() &&
688  /* Traversal scope is full AST if any of the bounds are the TU */
689  llvm::any_of(ActiveASTContext->getTraversalScope(), [](Decl *D) {
690  return D->getKind() == Decl::TranslationUnit;
691  })) {
692  llvm::errs() << "Tried to match orphan node:\n";
693  Node.dump(llvm::errs(), ActiveASTContext->getSourceManager());
694  llvm_unreachable("Parent map should be complete!");
695  }
696 #endif
697  return false;
698  }
699  if (Parents.size() == 1) {
700  // Only one parent - do recursive memoization.
701  const ast_type_traits::DynTypedNode Parent = Parents[0];
702  BoundNodesTreeBuilder BuilderCopy = *Builder;
703  if (Matcher.matches(Parent, this, &BuilderCopy)) {
704  *Builder = std::move(BuilderCopy);
705  return true;
706  }
707  if (MatchMode != ASTMatchFinder::AMM_ParentOnly) {
708  return memoizedMatchesAncestorOfRecursively(Parent, Matcher, Builder,
709  MatchMode);
710  // Once we get back from the recursive call, the result will be the
711  // same as the parent's result.
712  }
713  } else {
714  // Multiple parents - BFS over the rest of the nodes.
716  std::deque<ast_type_traits::DynTypedNode> Queue(Parents.begin(),
717  Parents.end());
718  while (!Queue.empty()) {
719  BoundNodesTreeBuilder BuilderCopy = *Builder;
720  if (Matcher.matches(Queue.front(), this, &BuilderCopy)) {
721  *Builder = std::move(BuilderCopy);
722  return true;
723  }
724  if (MatchMode != ASTMatchFinder::AMM_ParentOnly) {
725  for (const auto &Parent :
726  ActiveASTContext->getParents(Queue.front())) {
727  // Make sure we do not visit the same node twice.
728  // Otherwise, we'll visit the common ancestors as often as there
729  // are splits on the way down.
730  if (Visited.insert(Parent.getMemoizationData()).second)
731  Queue.push_back(Parent);
732  }
733  }
734  Queue.pop_front();
735  }
736  }
737  return false;
738  }
739 
740  // Implements a BoundNodesTree::Visitor that calls a MatchCallback with
741  // the aggregated bound nodes for each match.
742  class MatchVisitor : public BoundNodesTreeBuilder::Visitor {
743  public:
744  MatchVisitor(ASTContext* Context,
745  MatchFinder::MatchCallback* Callback)
746  : Context(Context),
747  Callback(Callback) {}
748 
749  void visitMatch(const BoundNodes& BoundNodesView) override {
750  Callback->run(MatchFinder::MatchResult(BoundNodesView, Context));
751  }
752 
753  private:
754  ASTContext* Context;
755  MatchFinder::MatchCallback* Callback;
756  };
757 
758  // Returns true if 'TypeNode' has an alias that matches the given matcher.
759  bool typeHasMatchingAlias(const Type *TypeNode,
760  const Matcher<NamedDecl> &Matcher,
761  BoundNodesTreeBuilder *Builder) {
762  const Type *const CanonicalType =
763  ActiveASTContext->getCanonicalType(TypeNode);
764  auto Aliases = TypeAliases.find(CanonicalType);
765  if (Aliases == TypeAliases.end())
766  return false;
767  for (const TypedefNameDecl *Alias : Aliases->second) {
768  BoundNodesTreeBuilder Result(*Builder);
769  if (Matcher.matches(*Alias, this, &Result)) {
770  *Builder = std::move(Result);
771  return true;
772  }
773  }
774  return false;
775  }
776 
777  bool
778  objcClassHasMatchingCompatibilityAlias(const ObjCInterfaceDecl *InterfaceDecl,
779  const Matcher<NamedDecl> &Matcher,
780  BoundNodesTreeBuilder *Builder) {
781  auto Aliases = CompatibleAliases.find(InterfaceDecl);
782  if (Aliases == CompatibleAliases.end())
783  return false;
784  for (const ObjCCompatibleAliasDecl *Alias : Aliases->second) {
785  BoundNodesTreeBuilder Result(*Builder);
786  if (Matcher.matches(*Alias, this, &Result)) {
787  *Builder = std::move(Result);
788  return true;
789  }
790  }
791  return false;
792  }
793 
794  /// Bucket to record map.
795  ///
796  /// Used to get the appropriate bucket for each matcher.
797  llvm::StringMap<llvm::TimeRecord> TimeByBucket;
798 
799  const MatchFinder::MatchersByType *Matchers;
800 
801  /// Filtered list of matcher indices for each matcher kind.
802  ///
803  /// \c Decl and \c Stmt toplevel matchers usually apply to a specific node
804  /// kind (and derived kinds) so it is a waste to try every matcher on every
805  /// node.
806  /// We precalculate a list of matchers that pass the toplevel restrict check.
807  /// This also allows us to skip the restrict check at matching time. See
808  /// use \c matchesNoKindCheck() above.
809  llvm::DenseMap<ast_type_traits::ASTNodeKind, std::vector<unsigned short>>
810  MatcherFiltersMap;
811 
812  const MatchFinder::MatchFinderOptions &Options;
813  ASTContext *ActiveASTContext;
814 
815  // Maps a canonical type to its TypedefDecls.
816  llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases;
817 
818  // Maps an Objective-C interface to its ObjCCompatibleAliasDecls.
819  llvm::DenseMap<const ObjCInterfaceDecl *,
820  llvm::SmallPtrSet<const ObjCCompatibleAliasDecl *, 2>>
821  CompatibleAliases;
822 
823  // Maps (matcher, node) -> the match result for memoization.
824  typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap;
825  MemoizationMap ResultCache;
826 };
827 
828 static CXXRecordDecl *
829 getAsCXXRecordDeclOrPrimaryTemplate(const Type *TypeNode) {
830  if (auto *RD = TypeNode->getAsCXXRecordDecl())
831  return RD;
832 
833  // Find the innermost TemplateSpecializationType that isn't an alias template.
834  auto *TemplateType = TypeNode->getAs<TemplateSpecializationType>();
835  while (TemplateType && TemplateType->isTypeAlias())
836  TemplateType =
837  TemplateType->getAliasedType()->getAs<TemplateSpecializationType>();
838 
839  // If this is the name of a (dependent) template specialization, use the
840  // definition of the template, even though it might be specialized later.
841  if (TemplateType)
842  if (auto *ClassTemplate = dyn_cast_or_null<ClassTemplateDecl>(
843  TemplateType->getTemplateName().getAsTemplateDecl()))
844  return ClassTemplate->getTemplatedDecl();
845 
846  return nullptr;
847 }
848 
849 // Returns true if the given C++ class is directly or indirectly derived
850 // from a base type with the given name. A class is not considered to be
851 // derived from itself.
852 bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration,
853  const Matcher<NamedDecl> &Base,
854  BoundNodesTreeBuilder *Builder,
855  bool Directly) {
856  if (!Declaration->hasDefinition())
857  return false;
858  for (const auto &It : Declaration->bases()) {
859  const Type *TypeNode = It.getType().getTypePtr();
860 
861  if (typeHasMatchingAlias(TypeNode, Base, Builder))
862  return true;
863 
864  // FIXME: Going to the primary template here isn't really correct, but
865  // unfortunately we accept a Decl matcher for the base class not a Type
866  // matcher, so it's the best thing we can do with our current interface.
867  CXXRecordDecl *ClassDecl = getAsCXXRecordDeclOrPrimaryTemplate(TypeNode);
868  if (!ClassDecl)
869  continue;
870  if (ClassDecl == Declaration) {
871  // This can happen for recursive template definitions; if the
872  // current declaration did not match, we can safely return false.
873  return false;
874  }
875  BoundNodesTreeBuilder Result(*Builder);
876  if (Base.matches(*ClassDecl, this, &Result)) {
877  *Builder = std::move(Result);
878  return true;
879  }
880  if (!Directly && classIsDerivedFrom(ClassDecl, Base, Builder, Directly))
881  return true;
882  }
883  return false;
884 }
885 
886 // Returns true if the given Objective-C class is directly or indirectly
887 // derived from a matching base class. A class is not considered to be derived
888 // from itself.
889 bool MatchASTVisitor::objcClassIsDerivedFrom(
890  const ObjCInterfaceDecl *Declaration, const Matcher<NamedDecl> &Base,
891  BoundNodesTreeBuilder *Builder, bool Directly) {
892  // Check if any of the superclasses of the class match.
893  for (const ObjCInterfaceDecl *ClassDecl = Declaration->getSuperClass();
894  ClassDecl != nullptr; ClassDecl = ClassDecl->getSuperClass()) {
895  // Check if there are any matching compatibility aliases.
896  if (objcClassHasMatchingCompatibilityAlias(ClassDecl, Base, Builder))
897  return true;
898 
899  // Check if there are any matching type aliases.
900  const Type *TypeNode = ClassDecl->getTypeForDecl();
901  if (typeHasMatchingAlias(TypeNode, Base, Builder))
902  return true;
903 
904  if (Base.matches(*ClassDecl, this, Builder))
905  return true;
906 
907  if (Directly)
908  return false;
909  }
910 
911  return false;
912 }
913 
914 bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
915  if (!DeclNode) {
916  return true;
917  }
918  match(*DeclNode);
920 }
921 
922 bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) {
923  if (!StmtNode) {
924  return true;
925  }
926  match(*StmtNode);
928 }
929 
930 bool MatchASTVisitor::TraverseType(QualType TypeNode) {
931  match(TypeNode);
933 }
934 
935 bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {
936  // The RecursiveASTVisitor only visits types if they're not within TypeLocs.
937  // We still want to find those types via matchers, so we match them here. Note
938  // that the TypeLocs are structurally a shadow-hierarchy to the expressed
939  // type, so we visit all involved parts of a compound type when matching on
940  // each TypeLoc.
941  match(TypeLocNode);
942  match(TypeLocNode.getType());
944 }
945 
946 bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
947  match(*NNS);
949 }
950 
951 bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
952  NestedNameSpecifierLoc NNS) {
953  if (!NNS)
954  return true;
955 
956  match(NNS);
957 
958  // We only match the nested name specifier here (as opposed to traversing it)
959  // because the traversal is already done in the parallel "Loc"-hierarchy.
960  if (NNS.hasQualifier())
961  match(*NNS.getNestedNameSpecifier());
962  return
964 }
965 
966 bool MatchASTVisitor::TraverseConstructorInitializer(
967  CXXCtorInitializer *CtorInit) {
968  if (!CtorInit)
969  return true;
970 
971  match(*CtorInit);
972 
974  CtorInit);
975 }
976 
977 class MatchASTConsumer : public ASTConsumer {
978 public:
979  MatchASTConsumer(MatchFinder *Finder,
980  MatchFinder::ParsingDoneTestCallback *ParsingDone)
981  : Finder(Finder), ParsingDone(ParsingDone) {}
982 
983 private:
984  void HandleTranslationUnit(ASTContext &Context) override {
985  if (ParsingDone != nullptr) {
986  ParsingDone->run();
987  }
988  Finder->matchAST(Context);
989  }
990 
991  MatchFinder *Finder;
992  MatchFinder::ParsingDoneTestCallback *ParsingDone;
993 };
994 
995 } // end namespace
996 } // end namespace internal
997 
999  ASTContext *Context)
1000  : Nodes(Nodes), Context(Context),
1001  SourceManager(&Context->getSourceManager()) {}
1002 
1005 
1007  : Options(std::move(Options)), ParsingDone(nullptr) {}
1008 
1010 
1012  MatchCallback *Action) {
1013  Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);
1014  Matchers.AllCallbacks.insert(Action);
1015 }
1016 
1017 void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
1018  MatchCallback *Action) {
1019  Matchers.Type.emplace_back(NodeMatch, Action);
1020  Matchers.AllCallbacks.insert(Action);
1021 }
1022 
1024  MatchCallback *Action) {
1025  Matchers.DeclOrStmt.emplace_back(NodeMatch, Action);
1026  Matchers.AllCallbacks.insert(Action);
1027 }
1028 
1030  MatchCallback *Action) {
1031  Matchers.NestedNameSpecifier.emplace_back(NodeMatch, Action);
1032  Matchers.AllCallbacks.insert(Action);
1033 }
1034 
1036  MatchCallback *Action) {
1037  Matchers.NestedNameSpecifierLoc.emplace_back(NodeMatch, Action);
1038  Matchers.AllCallbacks.insert(Action);
1039 }
1040 
1042  MatchCallback *Action) {
1043  Matchers.TypeLoc.emplace_back(NodeMatch, Action);
1044  Matchers.AllCallbacks.insert(Action);
1045 }
1046 
1048  MatchCallback *Action) {
1049  Matchers.CtorInit.emplace_back(NodeMatch, Action);
1050  Matchers.AllCallbacks.insert(Action);
1051 }
1052 
1053 bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
1054  MatchCallback *Action) {
1055  if (NodeMatch.canConvertTo<Decl>()) {
1056  addMatcher(NodeMatch.convertTo<Decl>(), Action);
1057  return true;
1058  } else if (NodeMatch.canConvertTo<QualType>()) {
1059  addMatcher(NodeMatch.convertTo<QualType>(), Action);
1060  return true;
1061  } else if (NodeMatch.canConvertTo<Stmt>()) {
1062  addMatcher(NodeMatch.convertTo<Stmt>(), Action);
1063  return true;
1064  } else if (NodeMatch.canConvertTo<NestedNameSpecifier>()) {
1065  addMatcher(NodeMatch.convertTo<NestedNameSpecifier>(), Action);
1066  return true;
1067  } else if (NodeMatch.canConvertTo<NestedNameSpecifierLoc>()) {
1068  addMatcher(NodeMatch.convertTo<NestedNameSpecifierLoc>(), Action);
1069  return true;
1070  } else if (NodeMatch.canConvertTo<TypeLoc>()) {
1071  addMatcher(NodeMatch.convertTo<TypeLoc>(), Action);
1072  return true;
1073  } else if (NodeMatch.canConvertTo<CXXCtorInitializer>()) {
1074  addMatcher(NodeMatch.convertTo<CXXCtorInitializer>(), Action);
1075  return true;
1076  }
1077  return false;
1078 }
1079 
1080 std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() {
1081  return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone);
1082 }
1083 
1085  ASTContext &Context) {
1086  internal::MatchASTVisitor Visitor(&Matchers, Options);
1087  Visitor.set_active_ast_context(&Context);
1088  Visitor.match(Node);
1089 }
1090 
1092  internal::MatchASTVisitor Visitor(&Matchers, Options);
1093  Visitor.set_active_ast_context(&Context);
1094  Visitor.onStartOfTranslationUnit();
1095  Visitor.TraverseAST(Context);
1096  Visitor.onEndOfTranslationUnit();
1097 }
1098 
1100  MatchFinder::ParsingDoneTestCallback *NewParsingDone) {
1101  ParsingDone = NewParsingDone;
1102 }
1103 
1104 StringRef MatchFinder::MatchCallback::getID() const { return "<unknown>"; }
1105 
1106 } // end namespace ast_matchers
1107 } // end namespace clang
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
Definition: Type.h:643
internal::Matcher< NestedNameSpecifier > NestedNameSpecifierMatcher
Definition: ASTMatchers.h:141
Stmt - This represents one statement.
Definition: Stmt.h:66
internal::Matcher< Stmt > StatementMatcher
Definition: ASTMatchers.h:138
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
MatchFinder::MatchResult MatchResult
llvm::SmallPtrSet< MatchCallback *, 16 > AllCallbacks
All the callbacks in one container to simplify iteration.
Called when parsing is finished. Intended for testing only.
MatchFinder(MatchFinderOptions Options=MatchFinderOptions())
internal::Matcher< QualType > TypeMatcher
Definition: ASTMatchers.h:139
BoundNodesTreeBuilder Nodes
bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument&#39;s dynamic ty...
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:56
void match(const T &Node, ASTContext &Context)
Calls the registered callbacks on all matches on the given Node.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
A C++ nested-name-specifier augmented with source location information.
Will traverse all child nodes.
Definition: ASTTypeTraits.h:45
Definition: Format.h:2392
void addMatcher(const DeclarationMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.
std::vector< std::pair< CXXCtorInitializerMatcher, MatchCallback * > > CtorInit
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
DynTypedMatcher::MatcherIDType MatcherID
NodeId Parent
Definition: ASTDiff.cpp:191
bool TraverseConstructorInitializer(CXXCtorInitializer *Init)
Recursively visit a constructor initializer.
Will not traverse implicit casts and parentheses.
Definition: ASTTypeTraits.h:49
int Depth
Definition: ASTDiff.cpp:190
void registerTestCallbackAfterParsing(ParsingDoneTestCallback *ParsingDone)
Registers a callback to notify the end of parsing.
MatchResult(const BoundNodes &Nodes, clang::ASTContext *Context)
std::unique_ptr< clang::ASTConsumer > newASTConsumer()
Creates a clang ASTConsumer that finds all matches.
#define USHRT_MAX
Definition: limits.h:55
Maps string IDs to AST nodes matched by parts of a matcher.
Definition: ASTMatchers.h:103
bool ResultOfMatch
llvm::cl::opt< std::string > Filter
Kind
virtual StringRef getID() const
An id used to group the matchers.
bool TraverseTypeLoc(TypeLoc TL)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Recursively visit a C++ nested-name-specifier with location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void matchAST(ASTContext &Context)
Finds all matches in the given AST.
std::vector< std::pair< NestedNameSpecifierLocMatcher, MatchCallback * > > NestedNameSpecifierLoc
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument&#39;s dy...
std::vector< std::pair< internal::DynTypedMatcher, MatchCallback * > > DeclOrStmt
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool TraverseType(QualType T)
Recursively visit a type, by dispatching to Traverse*Type() based on the argument&#39;s getTypeClass() pr...
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
std::vector< std::pair< NestedNameSpecifierMatcher, MatchCallback * > > NestedNameSpecifier
std::vector< std::pair< TypeMatcher, MatchCallback * > > Type
BoundNodesTreeBuilder BoundNodes
ast_type_traits::DynTypedNode DynTypedNode
ast_type_traits::DynTypedNode Node
Optional< types::ID > Type
Dataflow Directional Tag Classes.
internal::Matcher< CXXCtorInitializer > CXXCtorInitializerMatcher
Definition: ASTMatchers.h:143
A dynamically typed AST node container.
std::vector< std::pair< TypeLocMatcher, MatchCallback * > > TypeLoc
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2137
TraversalKind
Defines how we descend a level in the AST when we pass through expressions.
Definition: ASTTypeTraits.h:43
bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS)
Recursively visit a C++ nested-name-specifier.
#define INT_MAX
Definition: limits.h:46
internal::Matcher< NestedNameSpecifierLoc > NestedNameSpecifierLocMatcher
Definition: ASTMatchers.h:142
internal::Matcher< TypeLoc > TypeLocMatcher
Definition: ASTMatchers.h:140
Called when the Match registered for it was successfully found in the AST.
This class handles loading and caching of source files into memory.
internal::Matcher< Decl > DeclarationMatcher
Types of matchers for the top-level classes in the AST class hierarchy.
Definition: ASTMatchers.h:137
bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, MatchCallback *Action)
Adds a matcher to execute when running over the AST.