有没有办法在使用clang的VisitCallExpr方法中获取CallExpr *的调用者?

时间:2013-12-29 12:46:19

标签: c++ recursion clang abstract-syntax-tree

方法getDirectCallee()可以获得调用表达式的被调用者(被称为方法/函数),但有没有办法获得{{1}的调用者(调用它的方法/函数)在CallExpr*方法中?

有没有其他方法可以知道一个调用表达式的调用者?

2 个答案:

答案 0 :(得分:4)

更好的方法是使用AST匹配器。 你基本上可以在AST匹配器中查找所有callExpr节点并绑定它们,同时绑定相应的调用者(CXXRecordDecl)节点以及不同的字符串。

例如:

CallBackFunc callBackFunc;

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

然后在callBack函数中,你可以检索这些callee和caller函数:

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.
    }
};

(如果需要,我可以提供更多信息)

答案 1 :(得分:1)

我的回答可能并不完美但有效。

没有直接的方法,它可以直接调用调用表达式。但是如果我们看看AST遍历的方式,在进入被调用函数时,如果我们以某种方式存储最后访问过的FunctionDecl名称,它将为您提供CallExpr*的直接调用者。

示例

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;
        }
    }
}