我正在尝试使用函数调用来分析C源代码。我可以使用下面的源代码分析正常函数调用以获得他们的参数而没有问题,其中ce是CallExpr
对象:
1. if(ce != NULL) {
2. QualType q = ce->getType();
3. const Type *t = q.getTypePtrOrNull();
4.
5. if (t != NULL) {
6. llvm::errs() << "TYPE: " << t->isFunctionPointerType() << " " << q.getAsString() << " " << t->isPointerType() << "\n";
7. } else {
8. llvm::errs() << "FUNCTION CE HAS NO TYPE?\n";
9. }
10.
11.
12. const Decl* D = ce ->getCalleeDecl();
13. while(D->getPreviousDecl() != NULL)
14. D = D->getPreviousDecl();
15.
16. llvm::errs() << "Kind: " << D->getDeclKindName() << "\n";
17.
18. FunctionDecl* fd = (FunctionDecl*) llvm::dyn_cast<FunctionDecl>(D);
19. for(int x = 0; x< fd ->getNumParams(); x++) {
20. if(fd ->getParamDecl(x)->getType()->isAnyPointerType()) {
21. // Do Stuff Here
22. }
23. }
24. }
上面的源代码问题出现在第18行,当我尝试将Decl从CallExpr
强制转换为FunctionDecl
时,如果{NULL
,则会导致fd变为CallExpr
{1}}来自函数指针调用。
我尝试通过尝试在第16行打印类型进行调试。对于函数指针,它指定Decl on 12
是VarDecl
,而不是像正常函数调用一样的FunctionDecl。
我也尝试使用isFunctionPointerType()
,但这会返回false。
以下是一段导致段错误的源代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
void* (*mp)(size_t size);
void *mpp;
mp = &malloc;
mpp = mp(30);
free(mpp);
return (0);
}
有没有办法使用clang来检测CallExpr
是否是一个函数指针调用?如果是的话,如何获得参数列表?
我正在使用clang 3.1
由于
答案 0 :(得分:0)
使用getDirectCallee()
功能(我不确定它是否在clang 3.1
中可用)
FunctionDecl * func = ce-&gt; getDirectCallee();
if (func != NULL){
for(int i = 0; i < func->getNumParams(); i++){
if(func->getParamDecl(i)->getType()->isFunctionPointerType()){
// Do stuff here
}
}
}
答案 1 :(得分:0)
你应该从指针声明中获取函数原型,之后你将能够获得有关返回类型和参数类型的信息:
$diff = $currDateTime->diff($plan->start_day);
$formatted = sprintf('%02d:%02d:%02d', ($diff->days * 24) + $diff->h, $diff->i, $diff->s);