summaryrefslogtreecommitdiff
path: root/lib/ASTMatchers/ASTMatchFinder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ASTMatchers/ASTMatchFinder.cpp')
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp37
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) {