<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;background-color:#FFFFFF;font-family:Calibri,Arial,Helvetica,sans-serif;">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;background-color:#FFFFFF;font-family:Calibri,Arial,Helvetica,sans-serif;">
<p>Dear all,</p>
<p><br>
</p>
<p>This is the ast dump of the function call:</p>
<p><br>
</p>
<p></p>
<div>CallExpr 0x3adb460 'void'</div>
<div>|-ImplicitCastExpr 0x3adb448 'void (*)(const char *, const char *, __va_list_tag *)' <FunctionToPointerDecay></div>
<div>| `-ParenExpr 0x3adb3b0 'void (const char *, const char *, __va_list_tag *)':'void (const char *, const char *, __va_list_tag *)'</div>
<div>|   `-UnaryOperator 0x3adb390 'void (const char *, const char *, __va_list_tag *)':'void (const char *, const char *, __va_list_tag *)' prefix '*'</div>
<div>|     `-ImplicitCastExpr 0x3adb378 'TIFFErrorHandler':'void (*)(const char *, const char *, __va_list_tag *)' <LValueToRValue></div>
<div>|       `-DeclRefExpr 0x3adb350 'TIFFErrorHandler':'void (*)(const char *, const char *, __va_list_tag *)' lvalue Var 0x3ad89e0 '_TIFFerrorHandler' 'TIFFErrorHandler':'void (*)(const char *, const char *, __va_list_tag *)'</div>
<div>|-ImplicitCastExpr 0x3adb4a0 'const char *' <LValueToRValue></div>
<div>| `-DeclRefExpr 0x3adb3d0 'const char *' lvalue ParmVar 0x3adad80 'module' 'const char *'</div>
<div>|-ImplicitCastExpr 0x3adb4b8 'const char *' <LValueToRValue></div>
<div>| `-DeclRefExpr 0x3adb3f8 'const char *' lvalue ParmVar 0x3adadf0 'fmt' 'const char *'</div>
<div>`-ImplicitCastExpr 0x3adb4d0 '__va_list_tag *' <ArrayToPointerDecay></div>
<div>  `-DeclRefExpr 0x3adb420 'va_list':'__va_list_tag [1]' lvalue Var 0x3adafa0 'ap' 'va_list':'__va_list_tag [1]'</div>
<div>CallExpr 0x3adb688 'void'</div>
<div>|-ImplicitCastExpr 0x3adb670 'void (*)(thandle_t, const char *, const char *, __va_list_tag *)' <FunctionToPointerDecay></div>
<div>| `-ParenExpr 0x3adb5b8 'void (thandle_t, const char *, const char *, __va_list_tag *)':'void (thandle_t, const char *, const char *, __va_list_tag *)'</div>
<div>|   `-UnaryOperator 0x3adb598 'void (thandle_t, const char *, const char *, __va_list_tag *)':'void (thandle_t, const char *, const char *, __va_list_tag *)' prefix '*'</div>
<div>|     `-ImplicitCastExpr 0x3adb580 'TIFFErrorHandlerExt':'void (*)(thandle_t, const char *, const char *, __va_list_tag *)' <LValueToRValue></div>
<div>|       `-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 *)'</div>
<div>|-ImplicitCastExpr 0x3adb6d0 'thandle_t':'void *' <NullToPointer></div>
<div>| `-IntegerLiteral 0x3adb5d8 'int' 0</div>
<div>|-ImplicitCastExpr 0x3adb6e8 'const char *' <LValueToRValue></div>
<div>| `-DeclRefExpr 0x3adb5f8 'const char *' lvalue ParmVar 0x3adad80 'module' 'const char *'</div>
<div>|-ImplicitCastExpr 0x3adb700 'const char *' <LValueToRValue></div>
<div>| `-DeclRefExpr 0x3adb620 'const char *' lvalue ParmVar 0x3adadf0 'fmt' 'const char *'</div>
<div>`-ImplicitCastExpr 0x3adb718 '__va_list_tag *' <ArrayToPointerDecay></div>
<div>  `-DeclRefExpr 0x3adb648 'va_list':'__va_list_tag [1]' lvalue Var 0x3adafa0 'ap' 'va_list':'__va_list_tag [1]'</div>
<div><br>
</div>
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?
<p></p>
<p>Also you talked about removing the   <span style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 16px;">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. </span></p>
<p>Here is the code:</p>
<p><br>
</p>
<p></p>
<div>class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {</div>
<div>private:</div>
<div>    ASTContext *astContext; // used for getting additional AST info</div>
<div>public:</div>
<div>    explicit ExampleVisitor(CompilerInstance *CI)</div>
<div>      : astContext(&(CI->getASTContext()))// directly initialize private members</div>
<div>    {</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>}</div>
<div><br>
</div>
<div>    bool VisitVarDecl(VarDecl *var)</div>
<div>    {</div>
<div>        FullSourceLoc FullLocation = astContext->getFullLoc(var->getLocStart());</div>
<div>    <span class="Apple-tab-span" style="white-space:pre"></span>FileID fileID = FullLocation.getFileID();</div>
<div>    <span class="Apple-tab-span" style="white-space:pre"></span>//SourceManager SM(astContext->getSourceManager());</div>
<div>    <span class="Apple-tab-span" style="white-space:pre"></span>//FileID MFileID = SM.getMainFileID();</div>
<div>    <span class="Apple-tab-span" style="white-space:pre"></span>//unsigned int mainFileID = MFileID.getHashValue();</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>// if(thisFileID == mainFileID) do ...</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>unsigned int thisFileID = fileID.getHashValue();</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>if (thisFileID == 1) //checks if the node is in the main = input file.</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>{</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>if(var->hasLocalStorage() || var->isStaticLocal ())</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>{</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>//var->dump(); //prints the corresponding line of the AST.</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>numVariables++;</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>string varName = var->getQualifiedNameAsString();</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>string varType = var->getType().getAsString();</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>REPORT << "Variable Declaration: " << varName << " of type " << varType << "\n";</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>APIs << varType << ",";</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>}</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>}</div>
<div>        return true;</div>
<div>    }</div>
<br>
<p></p>
<p>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.</p>
<p>Again thank you for your time</p>
<p><br>
</p>
<p><br>
</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Richard Trieu <rtrieu@google.com><br>
<b>Sent:</b> 08 July 2016 22:39:02<br>
<b>To:</b> Georgiou, Andreas<br>
<b>Cc:</b> cfe-dev@lists.llvm.org<br>
<b>Subject:</b> Re: [cfe-dev] Clang function call expressions</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div>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.</div>
<div><br>
</div>
<div>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.</div>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Fri, Jul 8, 2016 at 7:48 AM, Georgiou, Andreas via cfe-dev
<span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">
<div style="font-size:12pt;color:#000000;background-color:#ffffff;font-family:Calibri,Arial,Helvetica,sans-serif">
<p>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:</p>
<p><br>
</p>
<p></p>
<div>void  //this is a part of the tiff library for linux. its in the source file tif_error.c in libtiff directory</div>
<div>TIFFError(const char* module, const char* fmt, ...)</div>
<div>{</div>
<div><span style="white-space:pre-wrap"></span>va_list ap;</div>
<div><span style="white-space:pre-wrap"></span>va_start(ap, fmt);    <------------------------------ THIS IS THE FUNCTION CALL</div>
<div><span style="white-space:pre-wrap"></span>if (_TIFFerrorHandler)</div>
<div><span style="white-space:pre-wrap"></span>(*_TIFFerrorHandler)(module, fmt, ap);</div>
<div><span style="white-space:pre-wrap"></span>if (_TIFFerrorHandlerExt)</div>
<div><span style="white-space:pre-wrap"></span>(*_TIFFerrorHandlerExt)(0, module, fmt, ap);</div>
<div><span style="white-space:pre-wrap"></span>va_end(ap);            <--------------------------------AND THIS ONE</div>
<div>}</div>
<br>
<p></p>
<p>My code of the ASTvisitor is this:</p>
<p><br>
</p>
<p></p>
<div> bool VisitStmt(Stmt *st)</div>
<div>    {</div>
<div>    <span style="white-space:pre-wrap"></span>FullSourceLoc FullLocation = astContext->getFullLoc(st->getLocStart());</div>
<div>    <span style="white-space:pre-wrap"></span>FileID fileID = FullLocation.getFileID();</div>
<div>    <span style="white-space:pre-wrap"></span>unsigned int thisFileID = fileID.getHashValue();</div>
<div>    <span style="white-space:pre-wrap"></span>if(thisFileID == 1) //checks if the node is in the main = input file.</div>
<div>    <span style="white-space:pre-wrap"></span>{</div>
<div>    <span style="white-space:pre-wrap"></span>if (CallExpr *call = dyn_cast<CallExpr>(st))</div>
<div>    <span style="white-space:pre-wrap"></span>{</div>
<div>    <span style="white-space:pre-wrap"></span>numFuncCalls++;</div>
<div><span style="white-space:pre-wrap"></span>//call->dump(); //prints the corresponding line of the AST.</div>
<div> <span style="white-space:pre-wrap"> </span>FunctionDecl *func_decl;</div>
<div><span style="white-space:pre-wrap"></span>if(call->getDirectCallee())</div>
<div><span style="white-space:pre-wrap"></span>{</div>
<div><span style="white-space:pre-wrap"></span>func_decl = call ->getDirectCallee();</div>
<div><span style="white-space:pre-wrap"></span>string funcCall = func_decl->getNameInfo().getName().getAsString();</div>
<div><span style="white-space:pre-wrap"></span>cout << "Function call: " << funcCall << " with arguments ";</div>
<div><span style="white-space:pre-wrap"></span>APIs << funcCall << ",";</div>
<div><span style="white-space:pre-wrap"></span>for(int i=0, j = call->getNumArgs(); i<j; i++)</div>
<div><span style="white-space:pre-wrap"></span>{</div>
<div><span style="white-space:pre-wrap"></span>//For each argument it prints its type. The function must be declared otherwise it will return int-for unknown argument type.</div>
<div><span style="white-space:pre-wrap"></span>APIs << call->getArg(i)->getType().getAsString()<< ",";</div>
<div><span style="white-space:pre-wrap"></span>cout << call->getArg(i)->getType().getAsString() << ", ";</div>
<div><span style="white-space:pre-wrap"></span>}</div>
<div><span style="white-space:pre-wrap"></span>cout << "\n";</div>
<div><span style="white-space:pre-wrap"></span>}</div>
<div><span style="white-space:pre-wrap"></span>else</div>
<div><span style="white-space:pre-wrap"></span>{</div>
<div><span style="white-space:pre-wrap"></span>Expr *expr = call->getCallee();</div>
<div><span style="white-space:pre-wrap"></span>string exprCall = expr->getStmtClassName();</div>
<div><span style="white-space:pre-wrap"></span>cout << "Expression call: " << exprCall << " with arguments ";</div>
<div><span style="white-space:pre-wrap"></span>APIs << exprCall << ",";</div>
<div><span style="white-space:pre-wrap"></span>for(int i=0, j = call->getNumArgs(); i<j; i++)</div>
<div><span style="white-space:pre-wrap"></span>{</div>
<div><span style="white-space:pre-wrap"></span>//For each argument it prints its type. The function must be declared otherwise it will return int-for unknown argument type.</div>
<div><span style="white-space:pre-wrap"></span>APIs << call->getArg(i)->getType().getAsString()<< ",";</div>
<div><span style="white-space:pre-wrap"></span>cout << call->getArg(i)->getType().getAsString() << ", ";</div>
<div><span style="white-space:pre-wrap"></span>}</div>
<div><span style="white-space:pre-wrap"></span>cout << "\n";</div>
<div><span style="white-space:pre-wrap"></span>}</div>
<div><span style="white-space:pre-wrap"></span>}</div>
<div>    <span style="white-space:pre-wrap"></span>}</div>
<div>    <span style="white-space:pre-wrap"></span>return true;</div>
<div>    }</div>
<br>
<p></p>
<p>The expression if(call->getDirectCallee()) is not true for those calls. </p>
<p><br>
</p>
<p>How can I extract the "function name" and its arguments like I am doing with the "normal" function calls?</p>
<p><br>
</p>
<p>Thank you.</p>
</div>
</div>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br>
</blockquote>
</div>
<br>
</div>
</div>
</div>
</body>
</html>