RecursiveASTVisitor::TraverseStmt for UnaryOperator's

Hi everyone,

I have a RecursiveASTVisitor that overrides the TraverseStmt method and store every node in a stack, to be able to know what the last traversed Stmt was when visiting a node, like this :

bool MyVisitor::TraverseStmt(Stmt* S) {
     DEBUG(llvm::errs() << S << "\n";
                 S->dumpColor());

     NodeStack.push_back(DynTypedNode::create<Stmt>(*S));
     RecursiveASTVisitor::TraverseStmt(S);
     NodeStack.pop_back();
     return true;
}

I did not find if there was already a way to do that in Clang, but still, it works well for almost every node.
But *almost* means that it does not traverse at least *some* UnaryOperator's nodes. It does traverse UO_(Post|Pre)(Inc|Dec) nodes but never does it traverse UO_AddrOf nor UO_Deref nodes.

This is the output snippet I get for *array = 3 :
0x2a0e7b8
BinaryOperator 0x2a0e7b8 'int' '='

-UnaryOperator 0x2a0e778 'int' lvalue prefix '*'
`-ImplicitCastExpr 0x2a0e760 'int *' <ArrayToPointerDecay>
  `-DeclRefExpr 0x2a0e738 'int [2]' lvalue Var 0x29e0450 'array' 'int [2]'

`-IntegerLiteral 0x2a0e798 'int' 3
0x2a0e760
ImplicitCastExpr 0x2a0e760 'int *' <ArrayToPointerDecay>
`-DeclRefExpr 0x2a0e738 'int [2]' lvalue Var 0x29e0450 'array' 'int [2]'
0x2a0e738
DeclRefExpr 0x2a0e738 'int [2]' lvalue Var 0x29e0450 'array' 'int [2]'
no uoparent was found for array
0x2a0e798
IntegerLiteral 0x2a0e798 'int' 3

It does show that we "skip" the UO traversal. But for ++x; it does dump the UOperator node. Would this be a bug?

I also tried to override TraverseUnaryOperator but my program never went through this method, even though I when I commented out TraverseStmt.

Does anyone have an idea why UO_AddrOf and UO_Deref are never traversed ?

Hi Hugues,

I'm just guessing here, but have you tried to override
shouldUseDataRecursionFor() to always return false?

-- Mathieu

Actually I was wrong, UnaryOperator nodes whose OpCode is UO_AddrOf seem to be always traversed and this was my mistake. On the other hand, UOp nodes whose OpCode is kind are never traversed by in my tests. So would this be a ?

Well thank you Mathieu for your answer !
I did not know about this method until you told me.
This clearly solved the issue.
Do you know what the "extreme cases" refer to in the method
description:

Return whether param S should be traversed using data recursion
to avoid a stack overflow with extreme cases.

Are they talking about particularly nested Stmt ?

You are welcome.

I will let more informed people answer :slight_smile:
The logs point to rdar://10941790
http://llvm.org/viewvc/llvm-project?view=revision&revision=152820
http://llvm.org/viewvc/llvm-project?view=revision&revision=152819