Getting function body from CallExpr (function definition in .h, implementation in .c)

I have looked thru the previous posts on this topic in the mailing-list archives, and still can’t get things to work. Hence the repost — for which I apologize.

I would like to get the body of a called function when visiting a CallExpr.
I create a recursive AST visitor, and handle the translation units correctly (to the best of my knowledge), and still am not able to get the body. The function is declared in a header file and implemented in a .c file. For brevity, I am recreating a toy example here:

def.h:
void foo();

impl.c:
#include “def.h”

void foo(){
printf(“in func foo\n”);
}

main.c:
#include “def.h”

int main(){
foo();
}

Running my Visitor code here is able to parse the call expression, but returns nullptr on
callexpr->getDirectCallee()->getBody(). Similarly, callexpr->getDirectCallee()->hasBody()
returns false.
Could anyone kindly suggest what should I do?

Here is the simplified code for my visitor:
class FVisitor : public RecursiveASTVisitor {
public:
bool VisitCallExpr(CallExpr *C){
const FunctionDecl *FD = C->getDirectCallee();
// try both variants of getBody
if(FD->getBody())
cout << “found body”<<endl;
else if(FD->getBody(FD))
cout << “found body”<<endl;
return true;
}
};

Thanks,

Hi,

The compiler only knows what it has parsed. So unless you parse impl.c and then merge the AST, you can’t get the function’s body C.

Because it is enough for any compiler in main.c to know that foo is a function with no argument returning nothing. Its body is irrelevant for compiling main.c to an object file. You could have its source code (like you do in your example) or it could be in a library, it only matters when linking.

I know the API has some utilities for merging ASTs together (ASTMergeAction).

David.

Hi Himanshu,

I guess that you are looking at the AST of main.c. The definition/body of foo is not available in main.c (after expanding all includes),
thus you see the nullptr. The AST is per translation unit, not for the whole program.
When compiling, this is only resolved later by the linker.

I don’t know if there is a way to merge the ASTs of different translation units yet, I remember that I saw some
discussions on the mailing list.

Best wishes,
Matthias

Thanks Matthias and David!

I will try to look into ASTMergeAction.