1//===--- ASTMatchFinder.cpp - Structural query framework ------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  Implements an algorithm to efficiently search for matches on AST nodes.
11//  Uses memoization to support recursive matches like HasDescendant.
12//
13//  The general idea is to visit all AST nodes with a RecursiveASTVisitor,
14//  calling the Matches(...) method of each matcher we are running on each
15//  AST node. The matcher can recurse via the ASTMatchFinder interface.
16//
17//===----------------------------------------------------------------------===//
18
19#include "clang/ASTMatchers/ASTMatchFinder.h"
20#include "clang/AST/ASTConsumer.h"
21#include "clang/AST/ASTContext.h"
22#include "clang/AST/RecursiveASTVisitor.h"
23#include <set>
24
25namespace clang {
26namespace ast_matchers {
27namespace internal {
28namespace {
29
30typedef MatchFinder::MatchCallback MatchCallback;
31
32/// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
33/// parents as defined by the \c RecursiveASTVisitor.
34///
35/// Note that the relationship described here is purely in terms of AST
36/// traversal - there are other relationships (for example declaration context)
37/// in the AST that are better modeled by special matchers.
38///
39/// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
40class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
41public:
42  /// \brief Maps from a node to its parent.
43  typedef llvm::DenseMap<const void*, ast_type_traits::DynTypedNode> ParentMap;
44
45  /// \brief Builds and returns the translation unit's parent map.
46  ///
47  ///  The caller takes ownership of the returned \c ParentMap.
48  static ParentMap *buildMap(TranslationUnitDecl &TU) {
49    ParentMapASTVisitor Visitor(new ParentMap);
50    Visitor.TraverseDecl(&TU);
51    return Visitor.Parents;
52  }
53
54private:
55  typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase;
56
57  ParentMapASTVisitor(ParentMap *Parents) : Parents(Parents) {}
58
59  bool shouldVisitTemplateInstantiations() const { return true; }
60  bool shouldVisitImplicitCode() const { return true; }
61
62  template <typename T>
63  bool TraverseNode(T *Node, bool (VisitorBase::*traverse)(T*)) {
64    if (Node == NULL)
65      return true;
66    if (ParentStack.size() > 0)
67      (*Parents)[Node] = ParentStack.back();
68    ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
69    bool Result = (this->*traverse)(Node);
70    ParentStack.pop_back();
71    return Result;
72  }
73
74  bool TraverseDecl(Decl *DeclNode) {
75    return TraverseNode(DeclNode, &VisitorBase::TraverseDecl);
76  }
77
78  bool TraverseStmt(Stmt *StmtNode) {
79    return TraverseNode(StmtNode, &VisitorBase::TraverseStmt);
80  }
81
82  ParentMap *Parents;
83  llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
84
85  friend class RecursiveASTVisitor<ParentMapASTVisitor>;
86};
87
88// We use memoization to avoid running the same matcher on the same
89// AST node twice.  This pair is the key for looking up match
90// result.  It consists of an ID of the MatcherInterface (for
91// identifying the matcher) and a pointer to the AST node.
92//
93// We currently only memoize on nodes whose pointers identify the
94// nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc).
95// For \c QualType and \c TypeLoc it is possible to implement
96// generation of keys for each type.
97// FIXME: Benchmark whether memoization of non-pointer typed nodes
98// provides enough benefit for the additional amount of code.
99typedef std::pair<uint64_t, const void*> UntypedMatchInput;
100
101// Used to store the result of a match and possibly bound nodes.
102struct MemoizedMatchResult {
103  bool ResultOfMatch;
104  BoundNodesTree Nodes;
105};
106
107// A RecursiveASTVisitor that traverses all children or all descendants of
108// a node.
109class MatchChildASTVisitor
110    : public RecursiveASTVisitor<MatchChildASTVisitor> {
111public:
112  typedef RecursiveASTVisitor<MatchChildASTVisitor> VisitorBase;
113
114  // Creates an AST visitor that matches 'matcher' on all children or
115  // descendants of a traversed node. max_depth is the maximum depth
116  // to traverse: use 1 for matching the children and INT_MAX for
117  // matching the descendants.
118  MatchChildASTVisitor(const DynTypedMatcher *Matcher,
119                       ASTMatchFinder *Finder,
120                       BoundNodesTreeBuilder *Builder,
121                       int MaxDepth,
122                       ASTMatchFinder::TraversalKind Traversal,
123                       ASTMatchFinder::BindKind Bind)
124      : Matcher(Matcher),
125        Finder(Finder),
126        Builder(Builder),
127        CurrentDepth(-1),
128        MaxDepth(MaxDepth),
129        Traversal(Traversal),
130        Bind(Bind),
131        Matches(false) {}
132
133  // Returns true if a match is found in the subtree rooted at the
134  // given AST node. This is done via a set of mutually recursive
135  // functions. Here's how the recursion is done (the  *wildcard can
136  // actually be Decl, Stmt, or Type):
137  //
138  //   - Traverse(node) calls BaseTraverse(node) when it needs
139  //     to visit the descendants of node.
140  //   - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node))
141  //     Traverse*(c) for each child c of 'node'.
142  //   - Traverse*(c) in turn calls Traverse(c), completing the
143  //     recursion.
144  bool findMatch(const ast_type_traits::DynTypedNode &DynNode) {
145    reset();
146    if (const Decl *D = DynNode.get<Decl>())
147      traverse(*D);
148    else if (const Stmt *S = DynNode.get<Stmt>())
149      traverse(*S);
150    // FIXME: Add other base types after adding tests.
151    return Matches;
152  }
153
154  // The following are overriding methods from the base visitor class.
155  // They are public only to allow CRTP to work. They are *not *part
156  // of the public API of this class.
157  bool TraverseDecl(Decl *DeclNode) {
158    return (DeclNode == NULL) || traverse(*DeclNode);
159  }
160  bool TraverseStmt(Stmt *StmtNode) {
161    const Stmt *StmtToTraverse = StmtNode;
162    if (Traversal ==
163        ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) {
164      const Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode);
165      if (ExprNode != NULL) {
166        StmtToTraverse = ExprNode->IgnoreParenImpCasts();
167      }
168    }
169    return (StmtToTraverse == NULL) || traverse(*StmtToTraverse);
170  }
171  bool TraverseType(QualType TypeNode) {
172    return traverse(TypeNode);
173  }
174
175  bool shouldVisitTemplateInstantiations() const { return true; }
176  bool shouldVisitImplicitCode() const { return true; }
177
178private:
179  // Used for updating the depth during traversal.
180  struct ScopedIncrement {
181    explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); }
182    ~ScopedIncrement() { --(*Depth); }
183
184   private:
185    int *Depth;
186  };
187
188  // Resets the state of this object.
189  void reset() {
190    Matches = false;
191    CurrentDepth = -1;
192  }
193
194  // Forwards the call to the corresponding Traverse*() method in the
195  // base visitor class.
196  bool baseTraverse(const Decl &DeclNode) {
197    return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode));
198  }
199  bool baseTraverse(const Stmt &StmtNode) {
200    return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode));
201  }
202  bool baseTraverse(QualType TypeNode) {
203    return VisitorBase::TraverseType(TypeNode);
204  }
205
206  // Traverses the subtree rooted at 'node'; returns true if the
207  // traversal should continue after this function returns; also sets
208  // matched_ to true if a match is found during the traversal.
209  template <typename T>
210  bool traverse(const T &Node) {
211    TOOLING_COMPILE_ASSERT(IsBaseType<T>::value,
212                           traverse_can_only_be_instantiated_with_base_type);
213    ScopedIncrement ScopedDepth(&CurrentDepth);
214    if (CurrentDepth == 0) {
215      // We don't want to match the root node, so just recurse.
216      return baseTraverse(Node);
217    }
218    if (Bind != ASTMatchFinder::BK_All) {
219      if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node),
220                           Finder, Builder)) {
221        Matches = true;
222        return false;  // Abort as soon as a match is found.
223      }
224      if (CurrentDepth < MaxDepth) {
225        // The current node doesn't match, and we haven't reached the
226        // maximum depth yet, so recurse.
227        return baseTraverse(Node);
228      }
229      // The current node doesn't match, and we have reached the
230      // maximum depth, so don't recurse (but continue the traversal
231      // such that other nodes at the current level can be visited).
232      return true;
233    } else {
234      BoundNodesTreeBuilder RecursiveBuilder;
235      if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node),
236                           Finder, &RecursiveBuilder)) {
237        // After the first match the matcher succeeds.
238        Matches = true;
239        Builder->addMatch(RecursiveBuilder.build());
240      }
241      if (CurrentDepth < MaxDepth) {
242        baseTraverse(Node);
243      }
244      // In kBindAll mode we always search for more matches.
245      return true;
246    }
247  }
248
249  const DynTypedMatcher *const Matcher;
250  ASTMatchFinder *const Finder;
251  BoundNodesTreeBuilder *const Builder;
252  int CurrentDepth;
253  const int MaxDepth;
254  const ASTMatchFinder::TraversalKind Traversal;
255  const ASTMatchFinder::BindKind Bind;
256  bool Matches;
257};
258
259// Controls the outermost traversal of the AST and allows to match multiple
260// matchers.
261class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
262                        public ASTMatchFinder {
263public:
264  MatchASTVisitor(std::vector<std::pair<const internal::DynTypedMatcher*,
265                                        MatchCallback*> > *MatcherCallbackPairs)
266     : MatcherCallbackPairs(MatcherCallbackPairs),
267       ActiveASTContext(NULL) {
268  }
269
270  void set_active_ast_context(ASTContext *NewActiveASTContext) {
271    ActiveASTContext = NewActiveASTContext;
272  }
273
274  // The following Visit*() and Traverse*() functions "override"
275  // methods in RecursiveASTVisitor.
276
277  bool VisitTypedefDecl(TypedefDecl *DeclNode) {
278    // When we see 'typedef A B', we add name 'B' to the set of names
279    // A's canonical type maps to.  This is necessary for implementing
280    // isDerivedFrom(x) properly, where x can be the name of the base
281    // class or any of its aliases.
282    //
283    // In general, the is-alias-of (as defined by typedefs) relation
284    // is tree-shaped, as you can typedef a type more than once.  For
285    // example,
286    //
287    //   typedef A B;
288    //   typedef A C;
289    //   typedef C D;
290    //   typedef C E;
291    //
292    // gives you
293    //
294    //   A
295    //   |- B
296    //   `- C
297    //      |- D
298    //      `- E
299    //
300    // It is wrong to assume that the relation is a chain.  A correct
301    // implementation of isDerivedFrom() needs to recognize that B and
302    // E are aliases, even though neither is a typedef of the other.
303    // Therefore, we cannot simply walk through one typedef chain to
304    // find out whether the type name matches.
305    const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr();
306    const Type *CanonicalType =  // root of the typedef tree
307        ActiveASTContext->getCanonicalType(TypeNode);
308    TypeAliases[CanonicalType].insert(DeclNode);
309    return true;
310  }
311
312  bool TraverseDecl(Decl *DeclNode);
313  bool TraverseStmt(Stmt *StmtNode);
314  bool TraverseType(QualType TypeNode);
315  bool TraverseTypeLoc(TypeLoc TypeNode);
316
317  // Matches children or descendants of 'Node' with 'BaseMatcher'.
318  bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
319                                  const DynTypedMatcher &Matcher,
320                                  BoundNodesTreeBuilder *Builder, int MaxDepth,
321                                  TraversalKind Traversal, BindKind Bind) {
322    const UntypedMatchInput input(Matcher.getID(), Node.getMemoizationData());
323    assert(input.second &&
324           "Fix getMemoizationData once more types allow recursive matching.");
325    std::pair<MemoizationMap::iterator, bool> InsertResult
326      = ResultCache.insert(std::make_pair(input, MemoizedMatchResult()));
327    if (InsertResult.second) {
328      BoundNodesTreeBuilder DescendantBoundNodesBuilder;
329      InsertResult.first->second.ResultOfMatch =
330        matchesRecursively(Node, Matcher, &DescendantBoundNodesBuilder,
331                           MaxDepth, Traversal, Bind);
332      InsertResult.first->second.Nodes =
333        DescendantBoundNodesBuilder.build();
334    }
335    InsertResult.first->second.Nodes.copyTo(Builder);
336    return InsertResult.first->second.ResultOfMatch;
337  }
338
339  // Matches children or descendants of 'Node' with 'BaseMatcher'.
340  bool matchesRecursively(const ast_type_traits::DynTypedNode &Node,
341                          const DynTypedMatcher &Matcher,
342                          BoundNodesTreeBuilder *Builder, int MaxDepth,
343                          TraversalKind Traversal, BindKind Bind) {
344    MatchChildASTVisitor Visitor(
345      &Matcher, this, Builder, MaxDepth, Traversal, Bind);
346    return Visitor.findMatch(Node);
347  }
348
349  virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
350                                  const Matcher<NamedDecl> &Base,
351                                  BoundNodesTreeBuilder *Builder);
352
353  // Implements ASTMatchFinder::MatchesChildOf.
354  virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
355                              const DynTypedMatcher &Matcher,
356                              BoundNodesTreeBuilder *Builder,
357                              TraversalKind Traversal,
358                              BindKind Bind) {
359    return matchesRecursively(Node, Matcher, Builder, 1, Traversal,
360                              Bind);
361  }
362  // Implements ASTMatchFinder::MatchesDescendantOf.
363  virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
364                                   const DynTypedMatcher &Matcher,
365                                   BoundNodesTreeBuilder *Builder,
366                                   BindKind Bind) {
367    return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX,
368                                      TK_AsIs, Bind);
369  }
370  // Implements ASTMatchFinder::matchesAncestorOf.
371  virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
372                                 const DynTypedMatcher &Matcher,
373                                 BoundNodesTreeBuilder *Builder) {
374    if (!Parents) {
375      // We always need to run over the whole translation unit, as
376      // \c hasAncestor can escape any subtree.
377      Parents.reset(ParentMapASTVisitor::buildMap(
378        *ActiveASTContext->getTranslationUnitDecl()));
379    }
380    ast_type_traits::DynTypedNode Ancestor = Node;
381    while (Ancestor.get<TranslationUnitDecl>() !=
382           ActiveASTContext->getTranslationUnitDecl()) {
383      assert(Ancestor.getMemoizationData() &&
384             "Invariant broken: only nodes that support memoization may be "
385             "used in the parent map.");
386      ParentMapASTVisitor::ParentMap::const_iterator I =
387        Parents->find(Ancestor.getMemoizationData());
388      if (I == Parents->end()) {
389        assert(false &&
390               "Found node that is not in the parent map.");
391        return false;
392      }
393      Ancestor = I->second;
394      if (Matcher.matches(Ancestor, this, Builder))
395        return true;
396    }
397    return false;
398  }
399
400  bool shouldVisitTemplateInstantiations() const { return true; }
401  bool shouldVisitImplicitCode() const { return true; }
402
403private:
404  // Implements a BoundNodesTree::Visitor that calls a MatchCallback with
405  // the aggregated bound nodes for each match.
406  class MatchVisitor : public BoundNodesTree::Visitor {
407  public:
408    MatchVisitor(ASTContext* Context,
409                 MatchFinder::MatchCallback* Callback)
410      : Context(Context),
411        Callback(Callback) {}
412
413    virtual void visitMatch(const BoundNodes& BoundNodesView) {
414      Callback->run(MatchFinder::MatchResult(BoundNodesView, Context));
415    }
416
417  private:
418    ASTContext* Context;
419    MatchFinder::MatchCallback* Callback;
420  };
421
422  // Returns true if 'TypeNode' has an alias that matches the given matcher.
423  bool typeHasMatchingAlias(const Type *TypeNode,
424                            const Matcher<NamedDecl> Matcher,
425                            BoundNodesTreeBuilder *Builder) {
426    const Type *const CanonicalType =
427      ActiveASTContext->getCanonicalType(TypeNode);
428    const std::set<const TypedefDecl*> &Aliases = TypeAliases[CanonicalType];
429    for (std::set<const TypedefDecl*>::const_iterator
430           It = Aliases.begin(), End = Aliases.end();
431         It != End; ++It) {
432      if (Matcher.matches(**It, this, Builder))
433        return true;
434    }
435    return false;
436  }
437
438  // Matches all registered matchers on the given node and calls the
439  // result callback for every node that matches.
440  template <typename T>
441  void match(const T &node) {
442    for (std::vector<std::pair<const internal::DynTypedMatcher*,
443                               MatchCallback*> >::const_iterator
444             I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end();
445         I != E; ++I) {
446      BoundNodesTreeBuilder Builder;
447      if (I->first->matches(ast_type_traits::DynTypedNode::create(node),
448                            this, &Builder)) {
449        BoundNodesTree BoundNodes = Builder.build();
450        MatchVisitor Visitor(ActiveASTContext, I->second);
451        BoundNodes.visitMatches(&Visitor);
452      }
453    }
454  }
455
456  std::vector<std::pair<const internal::DynTypedMatcher*,
457                        MatchCallback*> > *const MatcherCallbackPairs;
458  ASTContext *ActiveASTContext;
459
460  // Maps a canonical type to its TypedefDecls.
461  llvm::DenseMap<const Type*, std::set<const TypedefDecl*> > TypeAliases;
462
463  // Maps (matcher, node) -> the match result for memoization.
464  typedef llvm::DenseMap<UntypedMatchInput, MemoizedMatchResult> MemoizationMap;
465  MemoizationMap ResultCache;
466
467  llvm::OwningPtr<ParentMapASTVisitor::ParentMap> Parents;
468};
469
470// Returns true if the given class is directly or indirectly derived
471// from a base type with the given name.  A class is not considered to be
472// derived from itself.
473bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration,
474                                         const Matcher<NamedDecl> &Base,
475                                         BoundNodesTreeBuilder *Builder) {
476  if (!Declaration->hasDefinition())
477    return false;
478  typedef CXXRecordDecl::base_class_const_iterator BaseIterator;
479  for (BaseIterator It = Declaration->bases_begin(),
480                    End = Declaration->bases_end(); It != End; ++It) {
481    const Type *TypeNode = It->getType().getTypePtr();
482
483    if (typeHasMatchingAlias(TypeNode, Base, Builder))
484      return true;
485
486    // Type::getAs<...>() drills through typedefs.
487    if (TypeNode->getAs<DependentNameType>() != NULL ||
488        TypeNode->getAs<TemplateTypeParmType>() != NULL)
489      // Dependent names and template TypeNode parameters will be matched when
490      // the template is instantiated.
491      continue;
492    CXXRecordDecl *ClassDecl = NULL;
493    TemplateSpecializationType const *TemplateType =
494      TypeNode->getAs<TemplateSpecializationType>();
495    if (TemplateType != NULL) {
496      if (TemplateType->getTemplateName().isDependent())
497        // Dependent template specializations will be matched when the
498        // template is instantiated.
499        continue;
500
501      // For template specialization types which are specializing a template
502      // declaration which is an explicit or partial specialization of another
503      // template declaration, getAsCXXRecordDecl() returns the corresponding
504      // ClassTemplateSpecializationDecl.
505      //
506      // For template specialization types which are specializing a template
507      // declaration which is neither an explicit nor partial specialization of
508      // another template declaration, getAsCXXRecordDecl() returns NULL and
509      // we get the CXXRecordDecl of the templated declaration.
510      CXXRecordDecl *SpecializationDecl =
511        TemplateType->getAsCXXRecordDecl();
512      if (SpecializationDecl != NULL) {
513        ClassDecl = SpecializationDecl;
514      } else {
515        ClassDecl = llvm::dyn_cast<CXXRecordDecl>(
516            TemplateType->getTemplateName()
517                .getAsTemplateDecl()->getTemplatedDecl());
518      }
519    } else {
520      ClassDecl = TypeNode->getAsCXXRecordDecl();
521    }
522    assert(ClassDecl != NULL);
523    assert(ClassDecl != Declaration);
524    if (Base.matches(*ClassDecl, this, Builder))
525      return true;
526    if (classIsDerivedFrom(ClassDecl, Base, Builder))
527      return true;
528  }
529  return false;
530}
531
532bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
533  if (DeclNode == NULL) {
534    return true;
535  }
536  match(*DeclNode);
537  return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode);
538}
539
540bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) {
541  if (StmtNode == NULL) {
542    return true;
543  }
544  match(*StmtNode);
545  return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode);
546}
547
548bool MatchASTVisitor::TraverseType(QualType TypeNode) {
549  match(TypeNode);
550  return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
551}
552
553bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLoc) {
554  match(TypeLoc.getType());
555  return RecursiveASTVisitor<MatchASTVisitor>::
556      TraverseTypeLoc(TypeLoc);
557}
558
559class MatchASTConsumer : public ASTConsumer {
560public:
561  MatchASTConsumer(
562    std::vector<std::pair<const internal::DynTypedMatcher*,
563                          MatchCallback*> > *MatcherCallbackPairs,
564    MatchFinder::ParsingDoneTestCallback *ParsingDone)
565    : Visitor(MatcherCallbackPairs),
566      ParsingDone(ParsingDone) {}
567
568private:
569  virtual void HandleTranslationUnit(ASTContext &Context) {
570    if (ParsingDone != NULL) {
571      ParsingDone->run();
572    }
573    Visitor.set_active_ast_context(&Context);
574    Visitor.TraverseDecl(Context.getTranslationUnitDecl());
575    Visitor.set_active_ast_context(NULL);
576  }
577
578  MatchASTVisitor Visitor;
579  MatchFinder::ParsingDoneTestCallback *ParsingDone;
580};
581
582} // end namespace
583} // end namespace internal
584
585MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes,
586                                      ASTContext *Context)
587  : Nodes(Nodes), Context(Context),
588    SourceManager(&Context->getSourceManager()) {}
589
590MatchFinder::MatchCallback::~MatchCallback() {}
591MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {}
592
593MatchFinder::MatchFinder() : ParsingDone(NULL) {}
594
595MatchFinder::~MatchFinder() {
596  for (std::vector<std::pair<const internal::DynTypedMatcher*,
597                             MatchCallback*> >::const_iterator
598           It = MatcherCallbackPairs.begin(), End = MatcherCallbackPairs.end();
599       It != End; ++It) {
600    delete It->first;
601  }
602}
603
604void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,
605                             MatchCallback *Action) {
606  MatcherCallbackPairs.push_back(std::make_pair(
607    new internal::Matcher<Decl>(NodeMatch), Action));
608}
609
610void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
611                             MatchCallback *Action) {
612  MatcherCallbackPairs.push_back(std::make_pair(
613    new internal::Matcher<QualType>(NodeMatch), Action));
614}
615
616void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,
617                             MatchCallback *Action) {
618  MatcherCallbackPairs.push_back(std::make_pair(
619    new internal::Matcher<Stmt>(NodeMatch), Action));
620}
621
622ASTConsumer *MatchFinder::newASTConsumer() {
623  return new internal::MatchASTConsumer(&MatcherCallbackPairs, ParsingDone);
624}
625
626void MatchFinder::registerTestCallbackAfterParsing(
627    MatchFinder::ParsingDoneTestCallback *NewParsingDone) {
628  ParsingDone = NewParsingDone;
629}
630
631} // end namespace ast_matchers
632} // end namespace clang
633