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