[AST/RecursiveASTVisitor] Correction so that dataTraverseStmtPost will get called after the statement has been visited.

Fixes the indexing client of this.

llvm-svn: 262206
This commit is contained in:
Argyrios Kyrtzidis 2016-02-29 07:55:55 +00:00
parent d97ec18fe4
commit c97c7c88c0
2 changed files with 32 additions and 11 deletions

View File

@ -139,7 +139,9 @@ public:
/// Parameters involving this type are used to implement data
/// recursion over Stmts and Exprs within this class, and should
/// typically not be explicitly specified by derived classes.
typedef SmallVectorImpl<Stmt *> DataRecursionQueue;
/// The bool bit indicates whether the statement has been traversed or not.
typedef SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>>
DataRecursionQueue;
/// \brief Return a reference to the derived class.
Derived &getDerived() { return *static_cast<Derived *>(this); }
@ -561,23 +563,32 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S,
return true;
if (Queue) {
Queue->push_back(S);
Queue->push_back({S, false});
return true;
}
SmallVector<Stmt *, 8> LocalQueue;
LocalQueue.push_back(S);
SmallVector<llvm::PointerIntPair<Stmt *, 1, bool>, 8> LocalQueue;
LocalQueue.push_back({S, false});
while (!LocalQueue.empty()) {
Stmt *CurrS = LocalQueue.pop_back_val();
size_t N = LocalQueue.size();
if (getDerived().dataTraverseStmtPre(CurrS)) {
TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
auto &CurrSAndVisited = LocalQueue.back();
Stmt *CurrS = CurrSAndVisited.getPointer();
bool Visited = CurrSAndVisited.getInt();
if (Visited) {
LocalQueue.pop_back();
TRY_TO(dataTraverseStmtPost(CurrS));
continue;
}
if (getDerived().dataTraverseStmtPre(CurrS)) {
CurrSAndVisited.setInt(true);
size_t N = LocalQueue.size();
TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
// Process new children in the order they were added.
std::reverse(LocalQueue.begin() + N, LocalQueue.end());
} else {
LocalQueue.pop_back();
}
// Process new children in the order they were added.
std::reverse(LocalQueue.begin() + N, LocalQueue.end());
}
return true;

View File

@ -6,3 +6,13 @@
// CHECK: [[@LINE-1]]:1 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Decl,Dyn,RelChild | rel: 1
// CHECK-NEXT: RelChild | Base | c:objc(cs)Base
@end
void foo();
// CHECK: [[@LINE+1]]:6 | function/C | goo | c:@F@goo | _goo | Def | rel: 0
void goo(Base *b) {
// CHECK: [[@LINE+1]]:3 | function/C | foo | c:@F@foo | _foo | Ref,Call | rel: 0
foo();
// CHECK: [[@LINE+2]]:6 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Ref,Call,Dyn,RelRec | rel: 1
// CHECK-NEXT: RelRec | Base | c:objc(cs)Base
[b meth];
}