From 7a94864d1be1797b245dd57b788484c0bdae59c2 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Mon, 29 Feb 2016 07:55:55 +0000 Subject: [PATCH] [AST/RecursiveASTVisitor] Correction so that dataTraverseStmtPost will get called after the statement has been visited. Fixes the indexing client of this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@262206 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/RecursiveASTVisitor.h | 29 +++++++++++++++++-------- test/Index/Core/index-source.m | 10 +++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 8b746f05d6..07bd0e1fcf 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -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 DataRecursionQueue; + /// The bool bit indicates whether the statement has been traversed or not. + typedef SmallVectorImpl> + DataRecursionQueue; /// \brief Return a reference to the derived class. Derived &getDerived() { return *static_cast(this); } @@ -561,23 +563,32 @@ bool RecursiveASTVisitor::TraverseStmt(Stmt *S, return true; if (Queue) { - Queue->push_back(S); + Queue->push_back({S, false}); return true; } - SmallVector LocalQueue; - LocalQueue.push_back(S); + SmallVector, 8> LocalQueue; + LocalQueue.push_back({S, false}); while (!LocalQueue.empty()) { - Stmt *CurrS = LocalQueue.pop_back_val(); + auto &CurrSAndVisited = LocalQueue.back(); + Stmt *CurrS = CurrSAndVisited.getPointer(); + bool Visited = CurrSAndVisited.getInt(); + if (Visited) { + LocalQueue.pop_back(); + TRY_TO(dataTraverseStmtPost(CurrS)); + continue; + } - size_t N = LocalQueue.size(); if (getDerived().dataTraverseStmtPre(CurrS)) { + CurrSAndVisited.setInt(true); + size_t N = LocalQueue.size(); 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()); + } else { + LocalQueue.pop_back(); } - // Process new children in the order they were added. - std::reverse(LocalQueue.begin() + N, LocalQueue.end()); } return true; diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m index 6bff76ed27..3307ec5439 100644 --- a/test/Index/Core/index-source.m +++ b/test/Index/Core/index-source.m @@ -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]; +} -- 2.40.0