[cfe-dev] Why is RecursiveASTVisitor::TraverseStmt structured differently from other Traverse*s?

David Rector via cfe-dev cfe-dev at lists.llvm.org
Mon Jan 6 17:35:33 PST 2020


I have been experimenting with adjusting RecursiveASTVisitor to perform VisitPre* and VisitPost* (via corresponding WalkUpFromPre* and WalkUpFromPost* methods) surrounding the inner component traversals within each Traverse* definition.  This would allow one to easily define visitors that can e.g. keep track of the current traversal state, do pushes/pops around traversals of selected node kinds, etc.

This works great with Decl and Type nodes, as DEF_TRAVERSE_DECL and DEF_TRAVERSE_TYPE are straightforward: if a node D has children D1 and D2, which in turn have children d11 and d12 / d21 and d22 respectively, the descendants of D will be processed in this order:

D1, d11, d12, D2, d21, d22

So, my VisitPre*Decl(D1) and VisitPost*Decl(D1) would surround all the visitations of d11 and d12 and their descendants and none of D2’s visitations, as one might expect.

However, DEF_TRAVERSE_STMT is another matter entirely.  It endows each Traverse* function with a "DataRecursionQueue *" parameter.  No specific traversals definitions seem to use it idiosyncratically though — instead, all that parameter seems to do is permit the root TraverseStmt definition to process descendants of a Stmt S in the following order, if I am not mistaken:

S1, S2, s11, s12, s21, s22

This defeats my intention of fully surrounding the processing of e.g. S1 and its descendants with pre and post visitation.  But I can’t discern why it must be done this way — the reasoning is not documented anywhere.  Anyone know why Stmts/Exprs are processed in this order, but not Decls and Types?

Thanks,

Dave


More information about the cfe-dev mailing list