looking "up" the tree in RecursiveASTVisitor?


Is there a straightforward way to look "up" the tree when implementing
a clang plugin using RecursiveASTVisitor ?

I've bumped into this a couple of times and never found a "nice" answer.

For example, I have overridden

       VisitCallExpr(const CallExpr* expr)

and I want to know in which context the call is happening i.e. from
which FunctionDecl the call is being made.

It seems like there should be an easy way to walk back up the tree?

Thanks, Noel Grandin

I /think/ what you’re looking for is the “ParentMap” - the AST doesn’t have one by default, but for many tools it’s handy to build one (& there’s one available in Clang & used in many tools)

Hi Noel,

This is common question, I’ve seen it a couple of times here in the mailing list.

Here’s the solution a use. However, you do need the ASTContext, which you can get from any Decl object by calling the getASTContext() method.

2016-01-04 7:28 GMT+00:00 Mikhail Ramalho <mikhail.ramalho@gmail.com>:


You can use the following code to walk through the parents of a stmt/expr:

const clang::Decl* get_DeclContext_from_Stmt(const clang::Stmt& stmt)
auto it = ASTContext->getParents(stmt).begin();

if(it == ASTContext->getParents(stmt).end())
return nullptr;

const clang::Decl *aDecl = it->getclang::Decl();
return aDecl;

const clang::Stmt *aStmt = it->getclang::Stmt();
return get_DeclContext_from_Stmt(*aStmt);

return nullptr;

It tries to find a declaration, but you can change it to find any stmt/expr.

Best regards,

To get the FunctionDecl, I use the following code:

const clang::FunctionDecl* get_top_FunctionDecl_from_Stmt(
const clang::Stmt& stmt)
const clang::Decl decl = get_DeclContext_from_Stmt(stmt);
return static_cast<const clang::FunctionDecl

return nullptr;

I don’t know if there is some weird corner case in which it won’t work but it’s working so far (I tried in about 7000 different programs, from simple programs to some weird preprocessed device drivers).

Thank you,

Thank you very much, that did the trick!