diff options
Diffstat (limited to 'lib/ASTMatchers/ASTMatchFinder.cpp')
-rw-r--r-- | lib/ASTMatchers/ASTMatchFinder.cpp | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp index 02aee4b46ddd1..63f8395b82778 100644 --- a/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/lib/ASTMatchers/ASTMatchFinder.cpp @@ -145,17 +145,22 @@ public: ScopedIncrement ScopedDepth(&CurrentDepth); return (DeclNode == nullptr) || traverse(*DeclNode); } - bool TraverseStmt(Stmt *StmtNode) { + bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr) { + // If we need to keep track of the depth, we can't perform data recursion. + if (CurrentDepth == 0 || (CurrentDepth <= MaxDepth && MaxDepth < INT_MAX)) + Queue = nullptr; + ScopedIncrement ScopedDepth(&CurrentDepth); - const Stmt *StmtToTraverse = StmtNode; - if (Traversal == - ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) { - const Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode); - if (ExprNode) { + Stmt *StmtToTraverse = StmtNode; + if (Traversal == ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) { + if (Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode)) StmtToTraverse = ExprNode->IgnoreParenImpCasts(); - } } - return (StmtToTraverse == nullptr) || traverse(*StmtToTraverse); + if (!StmtToTraverse) + return true; + if (!match(*StmtToTraverse)) + return false; + return VisitorBase::TraverseStmt(StmtToTraverse, Queue); } // We assume that the QualType and the contained type are on the same // hierarchy level. Thus, we try to match either of them. @@ -378,7 +383,7 @@ public: } bool TraverseDecl(Decl *DeclNode); - bool TraverseStmt(Stmt *StmtNode); + bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr); bool TraverseType(QualType TypeNode); bool TraverseTypeLoc(TypeLoc TypeNode); bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); @@ -506,7 +511,7 @@ private: TimeBucketRegion() : Bucket(nullptr) {} ~TimeBucketRegion() { setBucket(nullptr); } - /// \brief Start timing for \p NewBucket. + /// Start timing for \p NewBucket. /// /// If there was a bucket already set, it will finish the timing for that /// other bucket. @@ -529,7 +534,7 @@ private: llvm::TimeRecord *Bucket; }; - /// \brief Runs all the \p Matchers on \p Node. + /// Runs all the \p Matchers on \p Node. /// /// Used by \c matchDispatch() below. template <typename T, typename MC> @@ -585,7 +590,7 @@ private: } /// @{ - /// \brief Overloads to pair the different node types to their matchers. + /// Overloads to pair the different node types to their matchers. void matchDispatch(const Decl *Node) { return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node)); } @@ -747,14 +752,14 @@ private: return false; } - /// \brief Bucket to record map. + /// Bucket to record map. /// /// Used to get the appropriate bucket for each matcher. llvm::StringMap<llvm::TimeRecord> TimeByBucket; const MatchFinder::MatchersByType *Matchers; - /// \brief Filtered list of matcher indices for each matcher kind. + /// Filtered list of matcher indices for each matcher kind. /// /// \c Decl and \c Stmt toplevel matchers usually apply to a specific node /// kind (and derived kinds) so it is a waste to try every matcher on every @@ -841,12 +846,12 @@ bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) { return RecursiveASTVisitor<MatchASTVisitor>::TraverseDecl(DeclNode); } -bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) { +bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) { if (!StmtNode) { return true; } match(*StmtNode); - return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode); + return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode, Queue); } bool MatchASTVisitor::TraverseType(QualType TypeNode) { |