<div dir="ltr">The ASTContext holds a reference to a SourceManager that you can use. The function getSourceManager() will let you access it. The getExpansionLoc from SourceManager will help get the source of the macro expansion.<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 11, 2016 at 3:34 AM, mats petersson <span dir="ltr"><<a href="mailto:mats@planetcatfish.com" target="_blank">mats@planetcatfish.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>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.<br></div><div><br>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. <br><br><br>--<br></div>Mats<br></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On 9 July 2016 at 13:50, 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:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div style="font-size:12pt;color:rgb(0,0,0);font-family:calibri,arial,helvetica,sans-serif;background-color:rgb(255,255,255)">
<div style="font-size:12pt;color:rgb(0,0,0);font-family:calibri,arial,helvetica,sans-serif;background-color:rgb(255,255,255)">
<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 style="white-space:pre-wrap"></span>}</div>
<div><br>
</div>
<div> bool VisitVarDecl(VarDecl *var)</div>
<div> {</div>
<div> FullSourceLoc FullLocation = astContext->getFullLoc(var->getLocStart());</div>
<div> <span style="white-space:pre-wrap"></span>FileID fileID = FullLocation.getFileID();</div>
<div> <span style="white-space:pre-wrap"></span>//SourceManager SM(astContext->getSourceManager());</div>
<div> <span style="white-space:pre-wrap"></span>//FileID MFileID = SM.getMainFileID();</div>
<div> <span style="white-space:pre-wrap"></span>//unsigned int mainFileID = MFileID.getHashValue();</div>
<div><span style="white-space:pre-wrap"></span>// if(thisFileID == mainFileID) do ...</div><span>
<div><span style="white-space:pre-wrap"></span>unsigned int thisFileID = fileID.getHashValue();</div>
</span><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(var->hasLocalStorage() || var->isStaticLocal ())</div>
<div><span style="white-space:pre-wrap"></span>{</div>
<div><span style="white-space:pre-wrap"></span>//var->dump(); //prints the corresponding line of the AST.</div>
<div><span style="white-space:pre-wrap"></span>numVariables++;</div>
<div><span style="white-space:pre-wrap"></span>string varName = var->getQualifiedNameAsString();</div>
<div><span style="white-space:pre-wrap"></span>string varType = var->getType().getAsString();</div>
<div><span style="white-space:pre-wrap"></span>REPORT << "Variable Declaration: " << varName << " of type " << varType << "\n";</div>
<div><span style="white-space:pre-wrap"></span>APIs << varType << ",";</div>
<div><span style="white-space:pre-wrap"></span>}</div>
<div><span style="white-space:pre-wrap"></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%">
<div dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> Richard Trieu <<a href="mailto:rtrieu@google.com" target="_blank">rtrieu@google.com</a>><br>
<b>Sent:</b> 08 July 2016 22:39:02<br>
<b>To:</b> Georgiou, Andreas<br>
<b>Cc:</b> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<b>Subject:</b> Re: [cfe-dev] Clang function call expressions</font>
<div> </div>
</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:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div style="font-size:12pt;color:rgb(0,0,0);font-family:calibri,arial,helvetica,sans-serif;background-color:rgb(255,255,255)">
<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" target="_blank">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></div></div>
</div>
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">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></blockquote></div><br></div></div>