I am trying to analyse C source code with function calls within them. I am able to analyse normal function calls to get their arguments without problem using the source code below where ce is a CallExpr
object:
我正在尝试分析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. }
The problem with the above source code comes on line 18, when I try to typecast the Decl from the CallExpr
to a FunctionDecl
, this results in fd becoming NULL
if the CallExpr
is from a function pointer call.
上面的源代码的问题出现在第18行,当我试图将Decl从CallExpr类型转换为FunctionDecl时,如果CallExpr来自函数指针调用,这将导致fd变为NULL。
I tried to debug by trying to print the kind on line 16. For function pointers, it specifies the Decl on 12
is a VarDecl
, not a FunctionDecl like normal function calls.
我试图通过在第16行中打印这种类型来调试。对于函数指针,它指定12上的Decl是VarDecl,而不是像普通函数调用那样的FunctionDecl。
I also tried using the isFunctionPointerType()
, but this is returning false.
我还尝试了使用isFunctionPointerType(),但是返回的是false。
Here is a piece of source code that results in a segfault:
下面是导致segfault的一段源代码:
#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);
}
Is there a way using clang to detect whether a CallExpr
is a function pointer call? and if so, how to get a list of the arguments?
是否有一种方法可以使用clang来检测CallExpr是否为函数指针调用?如果是,如何得到参数列表?
I am using clang 3.1
我用的是clang 3.1
Thanks
谢谢
2 个解决方案
#1
0
Use getDirectCallee()
function (I am not sure if it is available in clang 3.1
or not) FunctionDecl *func = ce->getDirectCallee();
使用getDirectCallee()函数(我不确定clang 3.1是否可用)FunctionDecl *func = ce->getDirectCallee();
if (func != NULL){
for(int i = 0; i < func->getNumParams(); i++){
if(func->getParamDecl(i)->getType()->isFunctionPointerType()){
// Do stuff here
}
}
}
#2
0
You should get function prototype from pointer declaration, after that you will be able to get information about return type and parameters types:
您应该从指针声明中获得函数原型,然后您将能够获得关于返回类型和参数类型的信息:
clang::CallExpr* expr;
...
auto decl = expr->getCalleeDecl();
if (decl != nullptr) {
if (decl->getKind() == clang::Decl::Var) {
clang::VarDecl *varDecl = clang::dyn_cast<clang::VarDecl>(decl);
if(varDecl->getType()->isFunctionPointerType() == true) {
const clang::PointerType *pt = varDecl->getType()->getAs<clang::PointerType>();
const clang::FunctionProtoType *ft = pt->getPointeeType()->getAs<clang::FunctionProtoType>();
if (ft != nullptr) {
std::string retTypeName = ft->getReturnType().getAsString();
...
auto paramsCount = funcType->getNumParams();
for (size_t i = 0; i < paramsCount; ++i) {
clang::QualType paramType = funcType->getParamType(i);
std::string paramTypeName = paramType.getAsString();
...
}
}
}
}
}
#1
0
Use getDirectCallee()
function (I am not sure if it is available in clang 3.1
or not) FunctionDecl *func = ce->getDirectCallee();
使用getDirectCallee()函数(我不确定clang 3.1是否可用)FunctionDecl *func = ce->getDirectCallee();
if (func != NULL){
for(int i = 0; i < func->getNumParams(); i++){
if(func->getParamDecl(i)->getType()->isFunctionPointerType()){
// Do stuff here
}
}
}
#2
0
You should get function prototype from pointer declaration, after that you will be able to get information about return type and parameters types:
您应该从指针声明中获得函数原型,然后您将能够获得关于返回类型和参数类型的信息:
clang::CallExpr* expr;
...
auto decl = expr->getCalleeDecl();
if (decl != nullptr) {
if (decl->getKind() == clang::Decl::Var) {
clang::VarDecl *varDecl = clang::dyn_cast<clang::VarDecl>(decl);
if(varDecl->getType()->isFunctionPointerType() == true) {
const clang::PointerType *pt = varDecl->getType()->getAs<clang::PointerType>();
const clang::FunctionProtoType *ft = pt->getPointeeType()->getAs<clang::FunctionProtoType>();
if (ft != nullptr) {
std::string retTypeName = ft->getReturnType().getAsString();
...
auto paramsCount = funcType->getNumParams();
for (size_t i = 0; i < paramsCount; ++i) {
clang::QualType paramType = funcType->getParamType(i);
std::string paramTypeName = paramType.getAsString();
...
}
}
}
}
}