[RecursiveASTVisitor] Introduce dataTraverseStmtPre()/dataTraverseStmtPost() to allow clients to do before/after actions during data recursive visitation.

This should fix the asan bot that hits stack overflow in a couple of test/Index tests.

llvm-svn: 260785
This commit is contained in:
Argyrios Kyrtzidis 2016-02-13 01:24:19 +00:00
parent d2759212b8
commit a36dd12e44
2 changed files with 23 additions and 4 deletions

View File

@ -163,6 +163,18 @@ public:
/// otherwise (including when the argument is nullptr).
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
/// Invoked before visiting a statement or expression via data recursion.
///
/// \returns false to skip visiting the node, true otherwise.
bool dataTraverseStmtPre(Stmt *S) { return true; }
/// Invoked after visiting a statement or expression via data recursion.
/// This is not invoked if the previously invoked \c dataTraverseStmtPre
/// returned false.
///
/// \returns false if the visitation was terminated early, true otherwise.
bool dataTraverseStmtPost(Stmt *S) { return true; }
/// \brief Recursively visit a type, by dispatching to
/// Traverse*Type() based on the argument's getTypeClass() property.
///
@ -557,7 +569,10 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S,
Stmt *CurrS = LocalQueue.pop_back_val();
size_t N = LocalQueue.size();
TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
if (getDerived().dataTraverseStmtPre(CurrS)) {
TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
TRY_TO(dataTraverseStmtPost(CurrS));
}
// Process new children in the order they were added.
std::reverse(LocalQueue.begin() + N, LocalQueue.end());
}

View File

@ -29,11 +29,15 @@ public:
bool shouldWalkTypesOfTypeLocs() const { return false; }
bool TraverseStmt(Stmt *S) {
bool dataTraverseStmtPre(Stmt *S) {
StmtStack.push_back(S);
bool ret = base::TraverseStmt(S);
return true;
}
bool dataTraverseStmtPost(Stmt *S) {
assert(StmtStack.back() == S);
StmtStack.pop_back();
return ret;
return true;
}
bool TraverseTypeLoc(TypeLoc TL) {