Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to get the caller of the CallExpr* in VisitCallExpr method with clang?

The method getDirectCallee() can get the callee (be called method/function) of the call expression, but is there any way to get the caller (the method/ function who called it) of the CallExpr* in VisitCallExpr() method?

Are there any other ways to know the caller of one call expression?

like image 935
Lotay Avatar asked Dec 29 '13 12:12

Lotay


2 Answers

Better way to deal with this is to use AST matchers. you can basically look for all callExpr nodes in an AST matcher and bind them and at the same time bind the corresponding caller (CXXRecordDecl) nodes as well with a different string.

For Example:

CallBackFunc callBackFunc;

Matchers.addMatcher(callExpr(isExpansionInMainFile(), callee(), hasAncestor(recordDecl().bind("caller"))).bind("callee"), &callBackFunc);

Then in the callBack function you can retrieve theses callee and caller functions like this:

class CallBackFunc : public MatchFinder::MatchCallBack {
  public:
     virtual void run(const MatcherFinder::MatchResult &Results) {
        auto callee = Results.Nodes.getNodeAs<clang::CallExpr>("callee");
        auto caller = Results.Nodes.getNodeAs<clang::CXXRecordDecl>("caller"); 

       // Do what is required with callee and caller.
    }
};

(I can give more information if required)

like image 56
G Gill Avatar answered Nov 13 '22 06:11

G Gill


My answer might not be perfect but it works.

There is no direct method, which gives you direct caller of the call expression. But if we look at the way AST traverse, while entering into callee function, if we somehow store last visited FunctionDecl name, it will give you the direct caller of that CallExpr*.

Example

string CallerFunc = ""; //declared in class (private/public)    
virtual bool VisitFunctionDecl(FunctionDecl *func)
{
    CallerFunc = func->getNameInfo().getName().getAsString();
    return true;
}
virtual bool VisitCallExpr(CallExpr *E)
{
    if (E != NULL){
        QualType q = E->getType();
        const Type *t = q.getTypePtrOrNull();

        if(t != NULL)
        {
            FunctionDecl *func = E->getDirectCallee(); //gives you callee function
            string callee = func->getNameInfo().getName().getAsString();
            cout << callee << " is called by " << CallerFunc;
        }
    }
}
like image 40
Saumya Suhagiya Avatar answered Nov 13 '22 08:11

Saumya Suhagiya