Lot*_*tay 8 c++ recursion clang abstract-syntax-tree
该方法getDirectCallee()可以获取调用表达式的被调用者(称为方法/函数),但有没有办法获取CallExpr*in VisitCallExpr()方法的调用者(调用它的方法/函数)?
有没有其他方法可以知道一个调用表达式的调用者?
解决这个问题的更好方法是使用 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)
(如果需要,我可以提供更多信息)
我的答案可能并不完美,但它有效。
没有直接方法可以为您提供调用表达式的直接调用者。但是如果我们看看 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)