我正在尝试使用Clang AST构建调用图。
是否可以通过某种方式将函数的参数链接到内部函数调用的参数?
例如,给定以下功能:
void chainedIncrement(int *ptr) {
simplePointerIncr(ptr);
for (int i=0;i<3;i++) {
simplePointerIncr(ptr);
}
}
我正在寻找一种方法,可以将ptr
函数中的chainedIncrement
链接到simplePointerIncr
函数的参数。这样做将允许构建调用图。
也许有一种方法可以在对参数和参数调用getId()
时获得相同的ID。
我尝试使用以下AST匹配器:
functionDecl(hasDescendant(callExpr(callee(functionDecl().bind("calleeFunc")),unless(isExpansionInSystemHeader())).bind("callExpr");)).bind("outerFunc")
似乎参数是Expr
类型,而函数参数是ParmVarDecl
类型。
假设参数按原样传递,而无需修改内部函数,是否有办法以某种方式链接它们?
谢谢
更新:添加了我的解决方案
有一个名为forEachArgumentWithParam()
的匹配器。它允许将被调用方函数的参数绑定到其参数。
另一个匹配器equalsBoundNode()
允许将外部函数的参数绑定到被调用函数的参数。
auto calleeArgVarDecl = declRefExpr(to(varDecl().bind("callerArg")));
auto innerCallExpr = callExpr(
forEachArgumentWithParam(calleeArgVarDecl, parmVarDecl().bind("calleeParam")),
callee(functionDecl().bind("calleeFunc")),unless(isExpansionInSystemHeader())).bind("callExpr");
auto fullMatcher = functionDecl(forEachDescendant(innerCallExpr),forEachDescendant(parmVarDecl(equalsBoundNode("callerArg")).bind("outerFuncParam"))).bind("outerFunc");
答案 0 :(得分:0)
这是一个简化的示例:
int add2(int var) {
return var+2;
}
int caller(int var) {
add2(var);
for (int i=0; i<3; i++) {
add2(var);
}
return var;
}
int main(int argc, const char **argv) {
int ret = 0;
caller(ret);
return 0;
}
使用Clang查询显示匹配结果:
clang-query> match callExpr(hasAnyArgument(hasAncestor(functionDecl(hasName("caller")))))
Match #1:
~/main.cpp:5:3: note: "root" binds here
add2(var);
^~~~~~~~~
Match #2:
~/main.cpp:7:5: note: "root" binds here
add2(var);
^~~~~~~~~
2 matches.
它与使用函数caller
的参数的函数调用匹配
答案 1 :(得分:0)
有一个名为forEachArgumentWithParam()
的匹配器。它允许将被调用方函数的参数绑定到其参数。
另一个匹配器equalsBoundNode()
允许将外部函数的参数绑定到被调用函数的参数。
auto calleeArgVarDecl = declRefExpr(to(varDecl().bind("callerArg")));
auto innerCallExpr = callExpr(
forEachArgumentWithParam(calleeArgVarDecl, parmVarDecl().bind("calleeParam")),
callee(functionDecl().bind("calleeFunc")),unless(isExpansionInSystemHeader())).bind("callExpr");
auto fullMatcher = functionDecl(forEachDescendant(innerCallExpr),forEachDescendant(parmVarDecl(equalsBoundNode("callerArg")).bind("outerFuncParam"))).bind("outerFunc");