[cfe-dev] Clang function call expressions

mats petersson via cfe-dev cfe-dev at lists.llvm.org
Mon Jul 11 03:34:16 PDT 2016


Your AST dump doesn't list the va_start, which is EITHER because it expands
to nothing, or because your code filters it out and doesn't print it - as
suggested above, that the "location" is not what you expect, because a
macro expands with the location from the macro definition, not the location
of the macro being used.

va_start and va_end are implementation defined, and are usually macros.
Depending on the system, this may expand to a function or some other
expression - or nothing. It all depends on "what needs to be done" in the
calling convention combination of compiler, OS and processor architecture.


--
Mats

On 9 July 2016 at 13:50, Georgiou, Andreas via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> 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> 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
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
>>
>
> _______________________________________________
> cfe-dev mailing list
> 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/20160711/725ae519/attachment.html>


More information about the cfe-dev mailing list