Метод getDirectCallee()
может получить вызываемого (быть вызванным методом / функцией) выражения вызова, но есть ли способ получить вызывающего (метод / функцию, который его вызвал) CallExpr*
в VisitCallExpr()
метод?
Есть ли другие способы узнать, кто вызвал одно выражение вызова?
Лучший способ справиться с этим — использовать AST matchers.
вы можете в основном искать все узлы callExpr в сопоставителе AST и связывать их, а также связывать соответствующие узлы вызывающего (CXXRecordDecl) с другой строкой.
Например:
CallBackFunc callBackFunc;
Matchers.addMatcher(callExpr(isExpansionInMainFile(), callee(), hasAncestor(recordDecl().bind("caller"))).bind("callee"), &callBackFunc);
Затем в функции 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.
}
};
(Я могу дать больше информации, если требуется)
Мой ответ может быть не идеальным, но он работает.
Прямого метода, предоставляющего прямой вызов выражения вызова, не существует. Но если мы посмотрим на путь AST traverse, при входе в функцию callee, если мы каким-то образом сохраним последний посещенный 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;
}
}
}