Extra parameters to Traverse* functions in ASTVisitor

Hello everyone,

I am new to Clang and am trying to build a Static Checker for one of my projects. I am currently using a RecursiveASTVisitor to walk through the AST. But I also need to pass some state to the Traverse* functions, while walking through the AST. For example, when I call TraverseStmt recursively, I need to pass some extra arguments, but the Traverse* functions only accept single arguments. Is there any way I could achieve this?

I can keep a local stack within the ASTVisitor, but I was wondering if there would be a cleaner way to do it.


I’ve not worked directly with RecurisiveASTVisitor, but in my own compiler, I have my own ASTVisitor class, and the way I pass “extra information” is to add it to the class that is doing the visiting. In the RecursiveASTVisitor, that would mean adding it to the Derived class that is the template parameter. You then call getDerived() to get the derived class and dig out your extra argument that way. Would that work for your case?

Hi Mats,

Thanks for the reply.

That’s something I had thought about. I was thinking of adding a stack to my Visitor class, and the Traverse* functions would push and pop on to the stack to store and fetch the argument. I was hoping there would be a cleaner way to do this.
If not, I think it would definitely be a good improvement to Clang. The functions within the Visitor classes should accept one more parameter that could point to any extra data the programmer wants to send.


The best way currently indeed is to add state to your visitor class - addings a stack to keep track of parents is a fairly typical use.

The reason why it’s (probably) not part of Clang, is probably because it’s trivial to implement yourself - with some caveats, like calling the base class’ Traverse* method and noting that for an AST node, the Traverse is only called for the root of its base hierarchy (i.e. Stmt, Decl, etc.) and the most specific type (e.g. CXXOperatorCallExpr), but not any intermediate base classes.

Furthermore, what you actually need to track varies a lot. In a lot of uses, I had to keep track only of the parent FunctionDecl-s, and I didn’t even need to go down into the Stmt level. Very often, what I actually need to keep track of is not only the AST nodes themselves, but to some data related to them…

Covering any one of the possible use cases would be too narrow, and trying to cover them all would have to be so generic that it’s basically useless.