Traversing a function body for call expressions. How ?

Hi,
In a RecursiveASTVisitor implementation, I implement VisitFunctionDecl.
Now, from the FunctionDecl I have, I can call getBody and get a Stmt.

How can I visit all the functions this function calls ?
I have tried creating a StmtVisitor and ..err..defining VisitCallExpr !
That didn't work.

Can anyone point me to what I should be doing ?

Manasij Mukherjee

Hi,

It should work. Define an StmtVisitor subclass, provide a VisitCallExpr. Then in your Visitor::VisitFunctionDecl, construct an StmtVisitor object, then call its Visit method with the function’s body.

In the future, please also provide source code, to allow us to spot any bugs and problems in your code (e.g. you may believe that the code does what you say it does, but you might have a bug, etc.).

Hi,
Here is my code, sorry for the delay.

class FunctionBodyVisitor : public clang::StmtVisitor<FunctionBodyVisitor> {
public:
  void VisitCallExpr(clang::CallExpr* Expr) {
    llvm::outs() << Expr->getCalleeDecl()->getAsFunction()->getName() << "\n";
    //this is never called
  }
};

class DummyVisitor : public clang::RecursiveASTVisitor<DummyVisitor> {
public:
  bool VisitFunctionDecl(clang::FunctionDecl* Decl) {
    llvm::outs() << Decl->getName() << "\n"; // this part visibly works
    stmtVisitor.Visit(Decl->getBody());
    return true;
  }
private:
  FunctionBodyVisitor stmtVisitor;
};

The code on which this is called is:
void foo()
{

}
int main()
{
    foo(); // I want to get to this call expression
}

Manasij

This looks good to me, I’m not sure what could be the issue. Try implementing FunctionBodyVisitor::VisitStmt() where you just the Stmt visited to see where the traversal stops.

As a side-note, in DummyVisitor::VisitFunctionDecl, you should probably call the parent’s VisitFunctionDecl at the end (although I seriously doubt this would make any difference here).

Hi,
Here is my code, sorry for the delay.

class FunctionBodyVisitor : public clang::StmtVisitor<FunctionBodyVisitor>
{
public:
  void VisitCallExpr(clang::CallExpr* Expr) {
    llvm::outs() << Expr->getCalleeDecl()->getAsFunction()->getName() <<
"\n";
    //this is never called
  }
};

class DummyVisitor : public clang::RecursiveASTVisitor<DummyVisitor> {
public:
  bool VisitFunctionDecl(clang::FunctionDecl* Decl) {
    llvm::outs() << Decl->getName() << "\n"; // this part visibly works
    stmtVisitor.Visit(Decl->getBody());
    return true;
  }
private:
  FunctionBodyVisitor stmtVisitor;
};

The code on which this is called is:
void foo()
{

}
int main()
{
    foo(); // I want to get to this call expression
}

Note that StmtVisitor is not recursive; the statement you're visiting is a
CompoundStmt, not a CallExpr. A RecursiveASTVisitor that just implements
VisitCallExpr may do what you want here.