CGCalleeInfo set Decl to Null while using as dereferenced callee

Recently I have faced an interesting case (spec benchmark, 471.omnetpp) while working with Clang. Following is the case

double cPar::doubleValue()
if (isRedirected())
return ind.par->doubleValue();

if (isInput()) read();
if (typechar=='B' || typechar=='L')
return (double)lng.val;
else if (typechar=='D')
return dbl.val;
else if (typechar=='T')
return fromstat();
else if (typechar=='X')
return evaluate();
else if (typechar=='C')
return cexpr.expr->evaluate();
else if (typechar=='F')
return func.argc==0 ? ((MathFuncNoArg)func.f)() :
func.argc==1 ? ((MathFunc1Arg) func.f)(func.p1) :
func.argc==2 ? ((MathFunc2Args)func.f)(func.p1,func.p2) :
func.argc==3 ? ((MathFunc3Args)func.f)(func.p1,func.p2,func.p3) :
throw new cException(this,eBADCAST,typechar,'D');

Where each func.f is an indirect call and declared here:

struct { MathFunc f; int argc;
double p1,p2,p3,p4; } func; // F:math function

So, clearly f is declared as MathFunc type which later dereferenced to MathFuncNoArg, MathFunc1Arg etc.

Now, in the CGCalleeInfo, compiler set the Decl for the Callee. What I have discovered is that Decl *Expr::getReferencedDeclOfCallee() returns nullptr and for that call callee set to Decl as Null from CGCallee CodeGenFunction::EmitCallee(const Expr *E). I beleive this is not an expected behavior because it is declared as MathFunc and it should be set as that.

I would like to understand why it kept like this?

It mostly doesn’t matter because the callers of getReferencedDeclOfCallee/getCalleeDecl generally don’t care about declarations that aren’t a FunctionDecl, and code generally doesn’t call explicit casts of function pointers. What are you trying to do? -Eli

I actually try to instrument before those indirect call to extract the memory address of callee (in above case: func.f). I know I can extract that using GetAddrOfLocalVar if I know the Decl of the callee. But, the point I reached to createCall for indirect call, I don’t have that information anymore for these cases. I don’t know if there could be an alternative design possible to achieve it.

If I have the FieldDecl from a MemberExpression, is there anyway to extract the VarDecl of that FieldDecl for that MemberExpr? Or is there no VarDecl in such case? I basically want to extract the Address of that FieldDecl as like I can for VarDecl using GetAddrOfLocalVar.

Basically, this is the AST:
CStyleCastExpr 0x55d2681bcf68 ‘MathFuncNoArg’:‘double ()(void)’
-ImplicitCastExpr 0x55d2681bcf50 'MathFunc':'double (*)(...)' <LValueToRValue> -MemberExpr 0x55d2681bcf08 ‘MathFunc’:'double (
)(…)’ lvalue .f 0x55d26800bec0
-MemberExpr 0x55d2681bced0 'struct (anonymous struct at omnet_include/cpar.h:277:8)':'struct cPar::(anonymous at omnet_include/cpar.h:277:8)' lvalue .func 0x55d26800c188 -MemberExpr 0x55d2681bce80 ‘union cPar::(anonymous at omnet_include/cpar.h:272:5)’ lvalue → 0x55d268013d58
`-CXXThisExpr 0x55d2681bce68 ‘class cPar *’ this

and in the source:

Only variables have a VarDecl. You’re probably looking for CodeGenFunction::EmitLValueForField. -Eli