【发布时间】:2018-12-18 09:52:17
【问题描述】:
我正在尝试使用 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");
【问题讨论】:
-
你能指定你想要的“调用图”的类型吗? AST只是源代码的一种表示,可以构造一个Matcher来匹配函数中的两个
simplePointerIncr()。但是如果你想要信息就更复杂了,例如第二个调用是在 3 次迭代的 for 循环中等
标签: clang abstract-syntax-tree llvm-clang