使用VisitCallExpr查找模板函数实例化中函数的所有调用



我想找到函数myFunction:的所有调用

void myFunction(int value) {
}
template <typename T>
void wrapper(T value) {
myFunction(value);
}
int
main(int argc, char const* argv[]) {
wrapper<int>(42);
return 0;
}

访问者的代码:

bool VisitCallExpr(CallExpr *Expr) {
if (Expr) {
Expr->dump();
auto decl = dyn_cast_or_null<FunctionDecl>(Expr->getCalleeDecl());
if (decl) {
decl->dump();
}
}
return true;
}

访问者发现两个调用:模板函数wrappermyFunction的调用和wrapper本身的调用。myFunction的AST似乎并不完整,因为它是从模板函数调用的。我想要wrapper的每一个具体调用的AST。

CallExpr 0x564a42a6c018 '<dependent type>'
|-UnresolvedLookupExpr 0x564a42a6bfb0 '<overloaded function type>' lvalue (ADL) = 'myFunction' 0x564a42a6bb68
`-DeclRefExpr 0x564a42a6bff8 'T' lvalue ParmVar 0x564a42a6bd40 'value' 'T'
CallExpr 0x564a42a6c7c0 'void'
|-ImplicitCastExpr 0x564a42a6c7a8 'void (*)(int)' <FunctionToPointerDecay>
| `-DeclRefExpr 0x564a42a6c6f8 'void (int)' lvalue Function 0x564a42a6c5f8 'wrapper' 'void (int)' (FunctionTemplate 0x564a42a6bed8 'wrapper')
`-IntegerLiteral 0x564a42a6c418 'int' 42

当我查看调用wrapper的函数decl时,我可以看到确实存在我正在寻找的CallExpr

FunctionDecl 0x564a42a6c5f8 <...> line:510:6 used wrapper 'void (int)'
|-TemplateArgument type 'int'
| `-BuiltinType 0x564a42a24270 'int'
|-ParmVarDecl 0x564a42a6c538 <col:14, col:16> col:16 used value 'int':'int'
`-CompoundStmt 0x564a42a6c918 <col:23, line:512:1>
`-CallExpr 0x564a42a6c8d8 <line:511:3, col:19> 'void'
|-ImplicitCastExpr 0x564a42a6c8c0 <col:3> 'void (*)(int)' <FunctionToPointerDecay>
| `-DeclRefExpr 0x564a42a6c8a0 <col:3> 'void (int)' lvalue Function 0x564a42a6bb68 'myFunction' 'void (int)'
`-ImplicitCastExpr 0x564a42a6c900 <col:14> 'int':'int' <LValueToRValue>
`-DeclRefExpr 0x564a42a6c880 <col:14> 'int':'int' lvalue ParmVar 0x564a42a6c538 'value' 'int':'int'

但该节点从未被访问过。我真的不知道我做错了什么。希望你能帮助我。

只需调用显式TraverseDecl就会得到预期结果:

bool VisitCallExpr(CallExpr *Expr) {
FunctionDecl *decl = dyn_cast_or_null<FunctionDecl>(Expr->getCalleeDecl());
if (Expr) {
Expr->dump();
if (decl) {
static bool tarverseTemplateSpecialization = false;
if (!tarverseTemplateSpecialization && decl->isFunctionTemplateSpecialization()) {
tarverseTemplateSpecialization = true;
TraverseDecl(decl);
tarverseTemplateSpecialization = false;
}
}
}
// ...
}

最新更新