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:
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.
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.
I also tried using the isFunctionPointerType()
, but this is returning false.
Here is a piece of source code that results in a 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?
I am using clang 3.1
Thanks