ASTMatchFinder.cpp revision b7488d77414b000ce2506b520a6b29f845fb3950
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 <deque>
24#include <set>
25
26namespace clang {
27namespace ast_matchers {
28namespace internal {
29namespace {
30
31typedef MatchFinder::MatchCallback MatchCallback;
32
33// The maximum number of memoization entries to store.
34// 10k has been experimentally found to give a good trade-off
35// of performance vs. memory consumption by running matcher
36// that match on every statement over a very large codebase.
37//
38// FIXME: Do some performance optimization in general and
39// revisit this number; also, put up micro-benchmarks that we can
40// optimize this on.
41static const unsigned MaxMemoizationEntries = 10000;
42
43// We use memoization to avoid running the same matcher on the same
44// AST node twice.  This struct is the key for looking up match
45// result.  It consists of an ID of the MatcherInterface (for
46// identifying the matcher), a pointer to the AST node and the
47// bound nodes before the matcher was executed.
48//
49// We currently only memoize on nodes whose pointers identify the
50// nodes (\c Stmt and \c Decl, but not \c QualType or \c TypeLoc).
51// For \c QualType and \c TypeLoc it is possible to implement
52// generation of keys for each type.
53// FIXME: Benchmark whether memoization of non-pointer typed nodes
54// provides enough benefit for the additional amount of code.
55struct MatchKey {
56  uint64_t MatcherID;
57  ast_type_traits::DynTypedNode Node;
58  BoundNodesTreeBuilder BoundNodes;
59
60  bool operator<(const MatchKey &Other) const {
61    if (MatcherID != Other.MatcherID)
62      return MatcherID < Other.MatcherID;
63    if (Node != Other.Node)
64      return Node < Other.Node;
65    return BoundNodes < Other.BoundNodes;
66  }
67};
68
69// Used to store the result of a match and possibly bound nodes.
70struct MemoizedMatchResult {
71  bool ResultOfMatch;
72  BoundNodesTreeBuilder Nodes;
73};
74
75// A RecursiveASTVisitor that traverses all children or all descendants of
76// a node.
77class MatchChildASTVisitor
78    : public RecursiveASTVisitor<MatchChildASTVisitor> {
79public:
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,
87                       ASTMatchFinder *Finder,
88                       BoundNodesTreeBuilder *Builder,
89                       int MaxDepth,
90                       ASTMatchFinder::TraversalKind Traversal,
91                       ASTMatchFinder::BindKind Bind)
92      : Matcher(Matcher),
93        Finder(Finder),
94        Builder(Builder),
95        CurrentDepth(0),
96        MaxDepth(MaxDepth),
97        Traversal(Traversal),
98        Bind(Bind),
99        Matches(false) {}
100
101  // Returns true if a match is found in the subtree rooted at the
102  // given AST node. This is done via a set of mutually recursive
103  // functions. Here's how the recursion is done (the  *wildcard can
104  // actually be Decl, Stmt, or Type):
105  //
106  //   - Traverse(node) calls BaseTraverse(node) when it needs
107  //     to visit the descendants of node.
108  //   - BaseTraverse(node) then calls (via VisitorBase::Traverse*(node))
109  //     Traverse*(c) for each child c of 'node'.
110  //   - Traverse*(c) in turn calls Traverse(c), completing the
111  //     recursion.
112  bool findMatch(const ast_type_traits::DynTypedNode &DynNode) {
113    reset();
114    if (const Decl *D = DynNode.get<Decl>())
115      traverse(*D);
116    else if (const Stmt *S = DynNode.get<Stmt>())
117      traverse(*S);
118    else if (const NestedNameSpecifier *NNS =
119             DynNode.get<NestedNameSpecifier>())
120      traverse(*NNS);
121    else if (const NestedNameSpecifierLoc *NNSLoc =
122             DynNode.get<NestedNameSpecifierLoc>())
123      traverse(*NNSLoc);
124    else if (const QualType *Q = DynNode.get<QualType>())
125      traverse(*Q);
126    else if (const TypeLoc *T = DynNode.get<TypeLoc>())
127      traverse(*T);
128    // FIXME: Add other base types after adding tests.
129
130    // It's OK to always overwrite the bound nodes, as if there was
131    // no match in this recursive branch, the result set is empty
132    // anyway.
133    *Builder = ResultBindings;
134
135    return Matches;
136  }
137
138  // The following are overriding methods from the base visitor class.
139  // They are public only to allow CRTP to work. They are *not *part
140  // of the public API of this class.
141  bool TraverseDecl(Decl *DeclNode) {
142    ScopedIncrement ScopedDepth(&CurrentDepth);
143    return (DeclNode == NULL) || traverse(*DeclNode);
144  }
145  bool TraverseStmt(Stmt *StmtNode) {
146    ScopedIncrement ScopedDepth(&CurrentDepth);
147    const Stmt *StmtToTraverse = StmtNode;
148    if (Traversal ==
149        ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) {
150      const Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode);
151      if (ExprNode != NULL) {
152        StmtToTraverse = ExprNode->IgnoreParenImpCasts();
153      }
154    }
155    return (StmtToTraverse == NULL) || traverse(*StmtToTraverse);
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 == NULL) || 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
197  bool shouldVisitTemplateInstantiations() const { return true; }
198  bool shouldVisitImplicitCode() const { return true; }
199  // Disables data recursion. We intercept Traverse* methods in the RAV, which
200  // are not triggered during data recursion.
201  bool shouldUseDataRecursionFor(clang::Stmt *S) const { return false; }
202
203private:
204  // Used for updating the depth during traversal.
205  struct ScopedIncrement {
206    explicit ScopedIncrement(int *Depth) : Depth(Depth) { ++(*Depth); }
207    ~ScopedIncrement() { --(*Depth); }
208
209   private:
210    int *Depth;
211  };
212
213  // Resets the state of this object.
214  void reset() {
215    Matches = false;
216    CurrentDepth = 0;
217  }
218
219  // Forwards the call to the corresponding Traverse*() method in the
220  // base visitor class.
221  bool baseTraverse(const Decl &DeclNode) {
222    return VisitorBase::TraverseDecl(const_cast<Decl*>(&DeclNode));
223  }
224  bool baseTraverse(const Stmt &StmtNode) {
225    return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode));
226  }
227  bool baseTraverse(QualType TypeNode) {
228    return VisitorBase::TraverseType(TypeNode);
229  }
230  bool baseTraverse(TypeLoc TypeLocNode) {
231    return VisitorBase::TraverseTypeLoc(TypeLocNode);
232  }
233  bool baseTraverse(const NestedNameSpecifier &NNS) {
234    return VisitorBase::TraverseNestedNameSpecifier(
235        const_cast<NestedNameSpecifier*>(&NNS));
236  }
237  bool baseTraverse(NestedNameSpecifierLoc NNS) {
238    return VisitorBase::TraverseNestedNameSpecifierLoc(NNS);
239  }
240
241  // Sets 'Matched' to true if 'Matcher' matches 'Node' and:
242  //   0 < CurrentDepth <= MaxDepth.
243  //
244  // Returns 'true' if traversal should continue after this function
245  // returns, i.e. if no match is found or 'Bind' is 'BK_All'.
246  template <typename T>
247  bool match(const T &Node) {
248    if (CurrentDepth == 0 || CurrentDepth > MaxDepth) {
249      return true;
250    }
251    if (Bind != ASTMatchFinder::BK_All) {
252      BoundNodesTreeBuilder RecursiveBuilder(*Builder);
253      if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
254                           &RecursiveBuilder)) {
255        Matches = true;
256        ResultBindings.addMatch(RecursiveBuilder);
257        return false; // Abort as soon as a match is found.
258      }
259    } else {
260      BoundNodesTreeBuilder RecursiveBuilder(*Builder);
261      if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
262                           &RecursiveBuilder)) {
263        // After the first match the matcher succeeds.
264        Matches = true;
265        ResultBindings.addMatch(RecursiveBuilder);
266      }
267    }
268    return true;
269  }
270
271  // Traverses the subtree rooted at 'Node'; returns true if the
272  // traversal should continue after this function returns.
273  template <typename T>
274  bool traverse(const T &Node) {
275    TOOLING_COMPILE_ASSERT(IsBaseType<T>::value,
276                           traverse_can_only_be_instantiated_with_base_type);
277    if (!match(Node))
278      return false;
279    return baseTraverse(Node);
280  }
281
282  const DynTypedMatcher *const Matcher;
283  ASTMatchFinder *const Finder;
284  BoundNodesTreeBuilder *const Builder;
285  BoundNodesTreeBuilder ResultBindings;
286  int CurrentDepth;
287  const int MaxDepth;
288  const ASTMatchFinder::TraversalKind Traversal;
289  const ASTMatchFinder::BindKind Bind;
290  bool Matches;
291};
292
293// Controls the outermost traversal of the AST and allows to match multiple
294// matchers.
295class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
296                        public ASTMatchFinder {
297public:
298  MatchASTVisitor(
299      std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *
300          MatcherCallbackPairs)
301      : MatcherCallbackPairs(MatcherCallbackPairs), ActiveASTContext(NULL) {}
302
303  void onStartOfTranslationUnit() {
304    for (std::vector<std::pair<internal::DynTypedMatcher,
305                               MatchCallback *> >::const_iterator
306             I = MatcherCallbackPairs->begin(),
307             E = MatcherCallbackPairs->end();
308         I != E; ++I) {
309      I->second->onStartOfTranslationUnit();
310    }
311  }
312
313  void onEndOfTranslationUnit() {
314    for (std::vector<std::pair<internal::DynTypedMatcher,
315                               MatchCallback *> >::const_iterator
316             I = MatcherCallbackPairs->begin(),
317             E = MatcherCallbackPairs->end();
318         I != E; ++I) {
319      I->second->onEndOfTranslationUnit();
320    }
321  }
322
323  void set_active_ast_context(ASTContext *NewActiveASTContext) {
324    ActiveASTContext = NewActiveASTContext;
325  }
326
327  // The following Visit*() and Traverse*() functions "override"
328  // methods in RecursiveASTVisitor.
329
330  bool VisitTypedefNameDecl(TypedefNameDecl *DeclNode) {
331    // When we see 'typedef A B', we add name 'B' to the set of names
332    // A's canonical type maps to.  This is necessary for implementing
333    // isDerivedFrom(x) properly, where x can be the name of the base
334    // class or any of its aliases.
335    //
336    // In general, the is-alias-of (as defined by typedefs) relation
337    // is tree-shaped, as you can typedef a type more than once.  For
338    // example,
339    //
340    //   typedef A B;
341    //   typedef A C;
342    //   typedef C D;
343    //   typedef C E;
344    //
345    // gives you
346    //
347    //   A
348    //   |- B
349    //   `- C
350    //      |- D
351    //      `- E
352    //
353    // It is wrong to assume that the relation is a chain.  A correct
354    // implementation of isDerivedFrom() needs to recognize that B and
355    // E are aliases, even though neither is a typedef of the other.
356    // Therefore, we cannot simply walk through one typedef chain to
357    // find out whether the type name matches.
358    const Type *TypeNode = DeclNode->getUnderlyingType().getTypePtr();
359    const Type *CanonicalType =  // root of the typedef tree
360        ActiveASTContext->getCanonicalType(TypeNode);
361    TypeAliases[CanonicalType].insert(DeclNode);
362    return true;
363  }
364
365  bool TraverseDecl(Decl *DeclNode);
366  bool TraverseStmt(Stmt *StmtNode);
367  bool TraverseType(QualType TypeNode);
368  bool TraverseTypeLoc(TypeLoc TypeNode);
369  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
370  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
371
372  // Matches children or descendants of 'Node' with 'BaseMatcher'.
373  bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
374                                  const DynTypedMatcher &Matcher,
375                                  BoundNodesTreeBuilder *Builder, int MaxDepth,
376                                  TraversalKind Traversal, BindKind Bind) {
377    // For AST-nodes that don't have an identity, we can't memoize.
378    if (!Node.getMemoizationData())
379      return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal,
380                                Bind);
381
382    MatchKey Key;
383    Key.MatcherID = Matcher.getID();
384    Key.Node = Node;
385    // Note that we key on the bindings *before* the match.
386    Key.BoundNodes = *Builder;
387
388    MemoizationMap::iterator I = ResultCache.find(Key);
389    if (I != ResultCache.end()) {
390      *Builder = I->second.Nodes;
391      return I->second.ResultOfMatch;
392    }
393
394    MemoizedMatchResult Result;
395    Result.Nodes = *Builder;
396    Result.ResultOfMatch = matchesRecursively(Node, Matcher, &Result.Nodes,
397                                              MaxDepth, Traversal, Bind);
398    ResultCache[Key] = Result;
399    *Builder = Result.Nodes;
400    return Result.ResultOfMatch;
401  }
402
403  // Matches children or descendants of 'Node' with 'BaseMatcher'.
404  bool matchesRecursively(const ast_type_traits::DynTypedNode &Node,
405                          const DynTypedMatcher &Matcher,
406                          BoundNodesTreeBuilder *Builder, int MaxDepth,
407                          TraversalKind Traversal, BindKind Bind) {
408    MatchChildASTVisitor Visitor(
409      &Matcher, this, Builder, MaxDepth, Traversal, Bind);
410    return Visitor.findMatch(Node);
411  }
412
413  virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
414                                  const Matcher<NamedDecl> &Base,
415                                  BoundNodesTreeBuilder *Builder);
416
417  // Implements ASTMatchFinder::matchesChildOf.
418  virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
419                              const DynTypedMatcher &Matcher,
420                              BoundNodesTreeBuilder *Builder,
421                              TraversalKind Traversal,
422                              BindKind Bind) {
423    if (ResultCache.size() > MaxMemoizationEntries)
424      ResultCache.clear();
425    return memoizedMatchesRecursively(Node, Matcher, Builder, 1, Traversal,
426                                      Bind);
427  }
428  // Implements ASTMatchFinder::matchesDescendantOf.
429  virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
430                                   const DynTypedMatcher &Matcher,
431                                   BoundNodesTreeBuilder *Builder,
432                                   BindKind Bind) {
433    if (ResultCache.size() > MaxMemoizationEntries)
434      ResultCache.clear();
435    return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX,
436                                      TK_AsIs, Bind);
437  }
438  // Implements ASTMatchFinder::matchesAncestorOf.
439  virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
440                                 const DynTypedMatcher &Matcher,
441                                 BoundNodesTreeBuilder *Builder,
442                                 AncestorMatchMode MatchMode) {
443    // Reset the cache outside of the recursive call to make sure we
444    // don't invalidate any iterators.
445    if (ResultCache.size() > MaxMemoizationEntries)
446      ResultCache.clear();
447    return memoizedMatchesAncestorOfRecursively(Node, Matcher, Builder,
448                                                MatchMode);
449  }
450
451  // Matches all registered matchers on the given node and calls the
452  // result callback for every node that matches.
453  void match(const ast_type_traits::DynTypedNode& Node) {
454    for (std::vector<std::pair<internal::DynTypedMatcher,
455                               MatchCallback *> >::const_iterator
456             I = MatcherCallbackPairs->begin(),
457             E = MatcherCallbackPairs->end();
458         I != E; ++I) {
459      BoundNodesTreeBuilder Builder;
460      if (I->first.matches(Node, this, &Builder)) {
461        MatchVisitor Visitor(ActiveASTContext, I->second);
462        Builder.visitMatches(&Visitor);
463      }
464    }
465  }
466
467  template <typename T> void match(const T &Node) {
468    match(ast_type_traits::DynTypedNode::create(Node));
469  }
470
471  // Implements ASTMatchFinder::getASTContext.
472  virtual ASTContext &getASTContext() const { return *ActiveASTContext; }
473
474  bool shouldVisitTemplateInstantiations() const { return true; }
475  bool shouldVisitImplicitCode() const { return true; }
476  // Disables data recursion. We intercept Traverse* methods in the RAV, which
477  // are not triggered during data recursion.
478  bool shouldUseDataRecursionFor(clang::Stmt *S) const { return false; }
479
480private:
481  // Returns whether an ancestor of \p Node matches \p Matcher.
482  //
483  // The order of matching ((which can lead to different nodes being bound in
484  // case there are multiple matches) is breadth first search.
485  //
486  // To allow memoization in the very common case of having deeply nested
487  // expressions inside a template function, we first walk up the AST, memoizing
488  // the result of the match along the way, as long as there is only a single
489  // parent.
490  //
491  // Once there are multiple parents, the breadth first search order does not
492  // allow simple memoization on the ancestors. Thus, we only memoize as long
493  // as there is a single parent.
494  bool memoizedMatchesAncestorOfRecursively(
495      const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher,
496      BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) {
497    if (Node.get<TranslationUnitDecl>() ==
498        ActiveASTContext->getTranslationUnitDecl())
499      return false;
500    assert(Node.getMemoizationData() &&
501           "Invariant broken: only nodes that support memoization may be "
502           "used in the parent map.");
503    ASTContext::ParentVector Parents = ActiveASTContext->getParents(Node);
504    if (Parents.empty()) {
505      assert(false && "Found node that is not in the parent map.");
506      return false;
507    }
508    MatchKey Key;
509    Key.MatcherID = Matcher.getID();
510    Key.Node = Node;
511    Key.BoundNodes = *Builder;
512
513    // Note that we cannot use insert and reuse the iterator, as recursive
514    // calls to match might invalidate the result cache iterators.
515    MemoizationMap::iterator I = ResultCache.find(Key);
516    if (I != ResultCache.end()) {
517      *Builder = I->second.Nodes;
518      return I->second.ResultOfMatch;
519    }
520    MemoizedMatchResult Result;
521    Result.ResultOfMatch = false;
522    Result.Nodes = *Builder;
523    if (Parents.size() == 1) {
524      // Only one parent - do recursive memoization.
525      const ast_type_traits::DynTypedNode Parent = Parents[0];
526      if (Matcher.matches(Parent, this, &Result.Nodes)) {
527        Result.ResultOfMatch = true;
528      } else if (MatchMode != ASTMatchFinder::AMM_ParentOnly) {
529        // Reset the results to not include the bound nodes from the failed
530        // match above.
531        Result.Nodes = *Builder;
532        Result.ResultOfMatch = memoizedMatchesAncestorOfRecursively(
533            Parent, Matcher, &Result.Nodes, MatchMode);
534        // Once we get back from the recursive call, the result will be the
535        // same as the parent's result.
536      }
537    } else {
538      // Multiple parents - BFS over the rest of the nodes.
539      llvm::DenseSet<const void *> Visited;
540      std::deque<ast_type_traits::DynTypedNode> Queue(Parents.begin(),
541                                                      Parents.end());
542      while (!Queue.empty()) {
543        Result.Nodes = *Builder;
544        if (Matcher.matches(Queue.front(), this, &Result.Nodes)) {
545          Result.ResultOfMatch = true;
546          break;
547        }
548        if (MatchMode != ASTMatchFinder::AMM_ParentOnly) {
549          ASTContext::ParentVector Ancestors =
550              ActiveASTContext->getParents(Queue.front());
551          for (ASTContext::ParentVector::const_iterator I = Ancestors.begin(),
552                                                        E = Ancestors.end();
553               I != E; ++I) {
554            // Make sure we do not visit the same node twice.
555            // Otherwise, we'll visit the common ancestors as often as there
556            // are splits on the way down.
557            if (Visited.insert(I->getMemoizationData()).second)
558              Queue.push_back(*I);
559          }
560        }
561        Queue.pop_front();
562      }
563    }
564    ResultCache[Key] = Result;
565
566    *Builder = Result.Nodes;
567    return Result.ResultOfMatch;
568  }
569
570  // Implements a BoundNodesTree::Visitor that calls a MatchCallback with
571  // the aggregated bound nodes for each match.
572  class MatchVisitor : public BoundNodesTreeBuilder::Visitor {
573  public:
574    MatchVisitor(ASTContext* Context,
575                 MatchFinder::MatchCallback* Callback)
576      : Context(Context),
577        Callback(Callback) {}
578
579    virtual void visitMatch(const BoundNodes& BoundNodesView) {
580      Callback->run(MatchFinder::MatchResult(BoundNodesView, Context));
581    }
582
583  private:
584    ASTContext* Context;
585    MatchFinder::MatchCallback* Callback;
586  };
587
588  // Returns true if 'TypeNode' has an alias that matches the given matcher.
589  bool typeHasMatchingAlias(const Type *TypeNode,
590                            const Matcher<NamedDecl> Matcher,
591                            BoundNodesTreeBuilder *Builder) {
592    const Type *const CanonicalType =
593      ActiveASTContext->getCanonicalType(TypeNode);
594    const std::set<const TypedefNameDecl *> &Aliases =
595        TypeAliases[CanonicalType];
596    for (std::set<const TypedefNameDecl*>::const_iterator
597           It = Aliases.begin(), End = Aliases.end();
598         It != End; ++It) {
599      BoundNodesTreeBuilder Result(*Builder);
600      if (Matcher.matches(**It, this, &Result)) {
601        *Builder = Result;
602        return true;
603      }
604    }
605    return false;
606  }
607
608  std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *const
609  MatcherCallbackPairs;
610  ASTContext *ActiveASTContext;
611
612  // Maps a canonical type to its TypedefDecls.
613  llvm::DenseMap<const Type*, std::set<const TypedefNameDecl*> > TypeAliases;
614
615  // Maps (matcher, node) -> the match result for memoization.
616  typedef std::map<MatchKey, MemoizedMatchResult> MemoizationMap;
617  MemoizationMap ResultCache;
618};
619
620static CXXRecordDecl *getAsCXXRecordDecl(const Type *TypeNode) {
621  // Type::getAs<...>() drills through typedefs.
622  if (TypeNode->getAs<DependentNameType>() != NULL ||
623      TypeNode->getAs<DependentTemplateSpecializationType>() != NULL ||
624      TypeNode->getAs<TemplateTypeParmType>() != NULL)
625    // Dependent names and template TypeNode parameters will be matched when
626    // the template is instantiated.
627    return NULL;
628  TemplateSpecializationType const *TemplateType =
629      TypeNode->getAs<TemplateSpecializationType>();
630  if (TemplateType == NULL) {
631    return TypeNode->getAsCXXRecordDecl();
632  }
633  if (TemplateType->getTemplateName().isDependent())
634    // Dependent template specializations will be matched when the
635    // template is instantiated.
636    return NULL;
637
638  // For template specialization types which are specializing a template
639  // declaration which is an explicit or partial specialization of another
640  // template declaration, getAsCXXRecordDecl() returns the corresponding
641  // ClassTemplateSpecializationDecl.
642  //
643  // For template specialization types which are specializing a template
644  // declaration which is neither an explicit nor partial specialization of
645  // another template declaration, getAsCXXRecordDecl() returns NULL and
646  // we get the CXXRecordDecl of the templated declaration.
647  CXXRecordDecl *SpecializationDecl = TemplateType->getAsCXXRecordDecl();
648  if (SpecializationDecl != NULL) {
649    return SpecializationDecl;
650  }
651  NamedDecl *Templated =
652      TemplateType->getTemplateName().getAsTemplateDecl()->getTemplatedDecl();
653  if (CXXRecordDecl *TemplatedRecord = dyn_cast<CXXRecordDecl>(Templated)) {
654    return TemplatedRecord;
655  }
656  // Now it can still be that we have an alias template.
657  TypeAliasDecl *AliasDecl = dyn_cast<TypeAliasDecl>(Templated);
658  assert(AliasDecl);
659  return getAsCXXRecordDecl(AliasDecl->getUnderlyingType().getTypePtr());
660}
661
662// Returns true if the given class is directly or indirectly derived
663// from a base type with the given name.  A class is not considered to be
664// derived from itself.
665bool MatchASTVisitor::classIsDerivedFrom(const CXXRecordDecl *Declaration,
666                                         const Matcher<NamedDecl> &Base,
667                                         BoundNodesTreeBuilder *Builder) {
668  if (!Declaration->hasDefinition())
669    return false;
670  typedef CXXRecordDecl::base_class_const_iterator BaseIterator;
671  for (BaseIterator It = Declaration->bases_begin(),
672                    End = Declaration->bases_end();
673       It != End; ++It) {
674    const Type *TypeNode = It->getType().getTypePtr();
675
676    if (typeHasMatchingAlias(TypeNode, Base, Builder))
677      return true;
678
679    CXXRecordDecl *ClassDecl = getAsCXXRecordDecl(TypeNode);
680    if (ClassDecl == NULL)
681      continue;
682    if (ClassDecl == Declaration) {
683      // This can happen for recursive template definitions; if the
684      // current declaration did not match, we can safely return false.
685      return false;
686    }
687    BoundNodesTreeBuilder Result(*Builder);
688    if (Base.matches(*ClassDecl, this, &Result)) {
689      *Builder = Result;
690      return true;
691    }
692    if (classIsDerivedFrom(ClassDecl, Base, Builder))
693      return true;
694  }
695  return false;
696}
697
698bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
699  if (DeclNode == NULL) {
700    return true;
701  }
702  match(*DeclNode);
703  return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode);
704}
705
706bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) {
707  if (StmtNode == NULL) {
708    return true;
709  }
710  match(*StmtNode);
711  return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode);
712}
713
714bool MatchASTVisitor::TraverseType(QualType TypeNode) {
715  match(TypeNode);
716  return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
717}
718
719bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {
720  // The RecursiveASTVisitor only visits types if they're not within TypeLocs.
721  // We still want to find those types via matchers, so we match them here. Note
722  // that the TypeLocs are structurally a shadow-hierarchy to the expressed
723  // type, so we visit all involved parts of a compound type when matching on
724  // each TypeLoc.
725  match(TypeLocNode);
726  match(TypeLocNode.getType());
727  return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode);
728}
729
730bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
731  match(*NNS);
732  return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS);
733}
734
735bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
736    NestedNameSpecifierLoc NNS) {
737  match(NNS);
738  // We only match the nested name specifier here (as opposed to traversing it)
739  // because the traversal is already done in the parallel "Loc"-hierarchy.
740  match(*NNS.getNestedNameSpecifier());
741  return
742      RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS);
743}
744
745class MatchASTConsumer : public ASTConsumer {
746public:
747  MatchASTConsumer(
748      std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *
749          MatcherCallbackPairs,
750      MatchFinder::ParsingDoneTestCallback *ParsingDone)
751      : Visitor(MatcherCallbackPairs), ParsingDone(ParsingDone) {}
752
753private:
754  virtual void HandleTranslationUnit(ASTContext &Context) {
755    if (ParsingDone != NULL) {
756      ParsingDone->run();
757    }
758    Visitor.set_active_ast_context(&Context);
759    Visitor.onStartOfTranslationUnit();
760    Visitor.TraverseDecl(Context.getTranslationUnitDecl());
761    Visitor.onEndOfTranslationUnit();
762    Visitor.set_active_ast_context(NULL);
763  }
764
765  MatchASTVisitor Visitor;
766  MatchFinder::ParsingDoneTestCallback *ParsingDone;
767};
768
769} // end namespace
770} // end namespace internal
771
772MatchFinder::MatchResult::MatchResult(const BoundNodes &Nodes,
773                                      ASTContext *Context)
774  : Nodes(Nodes), Context(Context),
775    SourceManager(&Context->getSourceManager()) {}
776
777MatchFinder::MatchCallback::~MatchCallback() {}
778MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {}
779
780MatchFinder::MatchFinder() : ParsingDone(NULL) {}
781
782MatchFinder::~MatchFinder() {}
783
784void MatchFinder::addMatcher(const DeclarationMatcher &NodeMatch,
785                             MatchCallback *Action) {
786  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
787}
788
789void MatchFinder::addMatcher(const TypeMatcher &NodeMatch,
790                             MatchCallback *Action) {
791  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
792}
793
794void MatchFinder::addMatcher(const StatementMatcher &NodeMatch,
795                             MatchCallback *Action) {
796  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
797}
798
799void MatchFinder::addMatcher(const NestedNameSpecifierMatcher &NodeMatch,
800                             MatchCallback *Action) {
801  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
802}
803
804void MatchFinder::addMatcher(const NestedNameSpecifierLocMatcher &NodeMatch,
805                             MatchCallback *Action) {
806  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
807}
808
809void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,
810                             MatchCallback *Action) {
811  MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action));
812}
813
814ASTConsumer *MatchFinder::newASTConsumer() {
815  return new internal::MatchASTConsumer(&MatcherCallbackPairs, ParsingDone);
816}
817
818void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node,
819                        ASTContext &Context) {
820  internal::MatchASTVisitor Visitor(&MatcherCallbackPairs);
821  Visitor.set_active_ast_context(&Context);
822  Visitor.match(Node);
823}
824
825void MatchFinder::registerTestCallbackAfterParsing(
826    MatchFinder::ParsingDoneTestCallback *NewParsingDone) {
827  ParsingDone = NewParsingDone;
828}
829
830} // end namespace ast_matchers
831} // end namespace clang
832