[cfe-dev] Clang function call expressions

Georgiou, Andreas via cfe-dev cfe-dev at lists.llvm.org
Sat Jul 9 05:50:33 PDT 2016


Dear all,


This is the ast dump of the function call:


CallExpr 0x3adb460 'void'
|-ImplicitCastExpr 0x3adb448 'void (*)(const char *, const char *, __va_list_tag *)' <FunctionToPointerDecay>
| `-ParenExpr 0x3adb3b0 'void (const char *, const char *, __va_list_tag *)':'void (const char *, const char *, __va_list_tag *)'
|   `-UnaryOperator 0x3adb390 'void (const char *, const char *, __va_list_tag *)':'void (const char *, const char *, __va_list_tag *)' prefix '*'
|     `-ImplicitCastExpr 0x3adb378 'TIFFErrorHandler':'void (*)(const char *, const char *, __va_list_tag *)' <LValueToRValue>
|       `-DeclRefExpr 0x3adb350 'TIFFErrorHandler':'void (*)(const char *, const char *, __va_list_tag *)' lvalue Var 0x3ad89e0 '_TIFFerrorHandler' 'TIFFErrorHandler':'void (*)(const char *, const char *, __va_list_tag *)'
|-ImplicitCastExpr 0x3adb4a0 'const char *' <LValueToRValue>
| `-DeclRefExpr 0x3adb3d0 'const char *' lvalue ParmVar 0x3adad80 'module' 'const char *'
|-ImplicitCastExpr 0x3adb4b8 'const char *' <LValueToRValue>
| `-DeclRefExpr 0x3adb3f8 'const char *' lvalue ParmVar 0x3adadf0 'fmt' 'const char *'
`-ImplicitCastExpr 0x3adb4d0 '__va_list_tag *' <ArrayToPointerDecay>
  `-DeclRefExpr 0x3adb420 'va_list':'__va_list_tag [1]' lvalue Var 0x3adafa0 'ap' 'va_list':'__va_list_tag [1]'
CallExpr 0x3adb688 'void'
|-ImplicitCastExpr 0x3adb670 'void (*)(thandle_t, const char *, const char *, __va_list_tag *)' <FunctionToPointerDecay>
| `-ParenExpr 0x3adb5b8 'void (thandle_t, const char *, const char *, __va_list_tag *)':'void (thandle_t, const char *, const char *, __va_list_tag *)'
|   `-UnaryOperator 0x3adb598 'void (thandle_t, const char *, const char *, __va_list_tag *)':'void (thandle_t, const char *, const char *, __va_list_tag *)' prefix '*'
|     `-ImplicitCastExpr 0x3adb580 'TIFFErrorHandlerExt':'void (*)(thandle_t, const char *, const char *, __va_list_tag *)' <LValueToRValue>
|       `-DeclRefExpr 0x3adb558 'TIFFErrorHandlerExt':'void (*)(thandle_t, const char *, const char *, __va_list_tag *)' lvalue Var 0x3ada590 '_TIFFerrorHandlerExt' 'TIFFErrorHandlerExt':'void (*)(thandle_t, const char *, const char *, __va_list_tag *)'
|-ImplicitCastExpr 0x3adb6d0 'thandle_t':'void *' <NullToPointer>
| `-IntegerLiteral 0x3adb5d8 'int' 0
|-ImplicitCastExpr 0x3adb6e8 'const char *' <LValueToRValue>
| `-DeclRefExpr 0x3adb5f8 'const char *' lvalue ParmVar 0x3adad80 'module' 'const char *'
|-ImplicitCastExpr 0x3adb700 'const char *' <LValueToRValue>
| `-DeclRefExpr 0x3adb620 'const char *' lvalue ParmVar 0x3adadf0 'fmt' 'const char *'
`-ImplicitCastExpr 0x3adb718 '__va_list_tag *' <ArrayToPointerDecay>
  `-DeclRefExpr 0x3adb648 'va_list':'__va_list_tag [1]' lvalue Var 0x3adafa0 'ap' 'va_list':'__va_list_tag [1]'

On stackoverflow somebody told me its a macro which defines a function call. Is there a way I can extract the original function call from the macro definition?

Also you talked about removing the   if(thisFileID == 1), but I want a way to extract only the function calls  or variable definitions from the file i use as input. This was the only way I figure out to get it work. I know I have to use the SourceManager since the last has a function called getMainFileID() but I couldnt initialise the SourceManager.

Here is the code:


class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {
private:
    ASTContext *astContext; // used for getting additional AST info
public:
    explicit ExampleVisitor(CompilerInstance *CI)
      : astContext(&(CI->getASTContext()))// directly initialize private members
    {
}

    bool VisitVarDecl(VarDecl *var)
    {
        FullSourceLoc FullLocation = astContext->getFullLoc(var->getLocStart());
    FileID fileID = FullLocation.getFileID();
    //SourceManager SM(astContext->getSourceManager());
    //FileID MFileID = SM.getMainFileID();
    //unsigned int mainFileID = MFileID.getHashValue();
// if(thisFileID == mainFileID) do ...
unsigned int thisFileID = fileID.getHashValue();
if (thisFileID == 1) //checks if the node is in the main = input file.
{
if(var->hasLocalStorage() || var->isStaticLocal ())
{
//var->dump(); //prints the corresponding line of the AST.
numVariables++;
string varName = var->getQualifiedNameAsString();
string varType = var->getType().getAsString();
REPORT << "Variable Declaration: " << varName << " of type " << varType << "\n";
APIs << varType << ",";
}
}
        return true;
    }


As you can see my goal is to use a source file which includes header files and extract from it some variable type definitions function calls etc. Any ideas are welcomed.

Again thank you for your time



________________________________
From: Richard Trieu <rtrieu at google.com>
Sent: 08 July 2016 22:39:02
To: Georgiou, Andreas
Cc: cfe-dev at lists.llvm.org
Subject: Re: [cfe-dev] Clang function call expressions

Can you get the AST dump of the function call so we can have a look at it?  The output from "call->dump();" will help since va_start and va_end may be implemented differently on different systems.

Also another thing to consider is that the functions may actually be function-like macros, which may given an unexpected location for you.  Removing the check "if(thisFileID == 1)" may help.

On Fri, Jul 8, 2016 at 7:48 AM, Georgiou, Andreas via cfe-dev <cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>> wrote:

Hello I have implemented an AST visitor which is working quite good and it can print me on the console the information I want from the AST such as variable declarations, function declarations and function calls. Today while I was experimenting I came across a function call which is not recognized as a function call. syntacticaly is the same as a function call. Here is the code:


void  //this is a part of the tiff library for linux. its in the source file tif_error.c in libtiff directory
TIFFError(const char* module, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);    <------------------------------ THIS IS THE FUNCTION CALL
if (_TIFFerrorHandler)
(*_TIFFerrorHandler)(module, fmt, ap);
if (_TIFFerrorHandlerExt)
(*_TIFFerrorHandlerExt)(0, module, fmt, ap);
va_end(ap);            <--------------------------------AND THIS ONE
}


My code of the ASTvisitor is this:


 bool VisitStmt(Stmt *st)
    {
    FullSourceLoc FullLocation = astContext->getFullLoc(st->getLocStart());
    FileID fileID = FullLocation.getFileID();
    unsigned int thisFileID = fileID.getHashValue();
    if(thisFileID == 1) //checks if the node is in the main = input file.
    {
    if (CallExpr *call = dyn_cast<CallExpr>(st))
    {
    numFuncCalls++;
//call->dump(); //prints the corresponding line of the AST.
  FunctionDecl *func_decl;
if(call->getDirectCallee())
{
func_decl = call ->getDirectCallee();
string funcCall = func_decl->getNameInfo().getName().getAsString();
cout << "Function call: " << funcCall << " with arguments ";
APIs << funcCall << ",";
for(int i=0, j = call->getNumArgs(); i<j; i++)
{
//For each argument it prints its type. The function must be declared otherwise it will return int-for unknown argument type.
APIs << call->getArg(i)->getType().getAsString()<< ",";
cout << call->getArg(i)->getType().getAsString() << ", ";
}
cout << "\n";
}
else
{
Expr *expr = call->getCallee();
string exprCall = expr->getStmtClassName();
cout << "Expression call: " << exprCall << " with arguments ";
APIs << exprCall << ",";
for(int i=0, j = call->getNumArgs(); i<j; i++)
{
//For each argument it prints its type. The function must be declared otherwise it will return int-for unknown argument type.
APIs << call->getArg(i)->getType().getAsString()<< ",";
cout << call->getArg(i)->getType().getAsString() << ", ";
}
cout << "\n";
}
}
    }
    return true;
    }


The expression if(call->getDirectCallee()) is not true for those calls.


How can I extract the "function name" and its arguments like I am doing with the "normal" function calls?


Thank you.

_______________________________________________
cfe-dev mailing list
cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160709/65438018/attachment.html>


More information about the cfe-dev mailing list