/// 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); }
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();
+ 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;
// 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];
+}