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

Lot*_*tay 8 c++ recursion clang abstract-syntax-tree

该方法getDirectCallee()可以获取调用表达式的被调用者(称为方法/函数),但有没有办法获取CallExpr*in VisitCallExpr()方法的调用者(调用它的方法/函数)?

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

G G*_*ill 7

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

例如:

CallBackFunc callBackFunc;

Matchers.addMatcher(callExpr(isExpansionInMainFile(), callee(), hasAncestor(recordDecl().bind("caller"))).bind("callee"), &callBackFunc);
Run Code Online (Sandbox Code Playgroud)

然后在 callBack 函数中,您可以像这样检索这些被调用者和调用者函数:

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.
    }
};
Run Code Online (Sandbox Code Playgroud)

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


Sau*_*iya 3

我的答案可能并不完美,但它有效。

没有直接方法可以为您提供调用表达式的直接调用者。但是如果我们看看 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)