<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 27, 2018, at 7:41 AM, FarSight Studios via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div dir="ltr" class="">Thank you so much for your help. I will check these options.</div><div dir="ltr" class=""><br class=""><div class="">I was able to make a connection between nodes located in different ASTs using Name Mangling.</div><div class="">Every function, and parameter has its own unique mangled name. I am getting these names from MangleContext and pragmatically connect the functions later in my application. It seems to work fine.</div></div></div></div></blockquote><div><br class=""></div><div>This might be good enough. If you want anything more precise you might try asking your linker about this (for example ld with —cref option).</div><div><br class=""></div><div>Hope this helps!</div><div><br class=""></div><div>Jan</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div dir="ltr" class=""><div class=""><div class=""><br class=""></div></div></div></div><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div class="gmail_quote" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;"><div dir="ltr" class="">On Tue, Dec 25, 2018 at 10:47 PM Gábor Márton <<a href="mailto:martongabesz@gmail.com" class="">martongabesz@gmail.com</a>> wrote:<br class=""></div><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" class=""><div dir="ltr" class=""><div dir="ltr" class="">> How I can get to the definition to a callee function from a caller location which located in a different source file (different AST)?<div class=""><br class=""></div><div class="">AFAIK you have two options, under the hoods both of them use the ASTImporter class in Clang.</div><div class="">1) Use the "-ast-merge" option of cc1, which will merge all top level declarations of the given AST(PCH) file into the actual ASTContext and then the original compiler action will be executed. You may merge as many files as you want this way. </div><div class="">2) Use CrossTranslationUnitContext::getCrossTUDefinition() from the CTU library to load a function definition from an external AST file and merge it into the the original AST. Clang static analyzer is a client of the CTU library, so you may find in the static analyzer code how we use it (CallEvent.cpp).</div><div class=""><br class=""></div><div class="">Hope this helps,</div><div class="">Gabor</div></div></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Tue, Dec 25, 2018 at 8:57 AM FarSight Studios via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>> wrote:<br class=""></div><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" class=""><div class="">Dear all,</div><div class=""><br class=""></div><div class="">I am trying to implement an ability to keep track of reads and writes to a variables and objects. The object can be passed by reference or by pointer to other functions.</div><div class="">I am using CLang AST matcher for this task.</div><div class="">My solution seems to work, but only when all the functions are located in the same source file.</div><div class="">When functionA calls functionB, whose definition is located in another cpp file, I am unable to get the location of the definition of functionB, I only able to get the declaration which located in its header file.</div><div class=""><br class=""></div><div class="">My questions are:</div><div class="">How I can get to the definition to a callee function from a caller location which located in a different source file (different AST)?</div><div class="">Do I need to somehow pass the linkage stage to make it work?</div><div class=""><br class=""></div><div class="">I have seen in other posts that CLang libTooling does not support Cross Translation Unit feature.</div><div class="">I also seen that LibClang allowed to impenitent this by using Unified Symbol Resolution. Does libTooling offer something like that?<br class=""></div><div class=""><br class=""></div><div class="">Is there any other option to getting to function definition when more than one source file is used?</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I have searched the web for a few days to find any solution with no luck.</div><div class="">Any help will be much appreciated.</div><div class=""><br class=""></div><div class="">Thank you</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Here is more details about how and what I am trying to accomplish. It is a bit LONG so please don't read it if you don't have time:</div><div class="">-------------------------------------------</div><div class=""><br class=""></div><div class="">I wrote two matchers:</div><div class="">One for matching all the write operations to a parameter inside a funcion:</div><div class=""><span style="white-space: pre-wrap;" class="">       </span>binaryOperator(</div><div class=""><span style="white-space: pre-wrap;" class="">                  </span>isAssignmentOperator(),</div><div class=""><span style="white-space: pre-wrap;" class="">                  </span>hasLHS(ignoringParenImpCasts(</div><div class=""><span style="white-space: pre-wrap;" class="">                                    </span>anyOf(</div><div class=""><span style="white-space: pre-wrap;" class="">                                                   </span>unaryOperator(hasUnaryOperand(ignoringParenImpCasts(declRefExpr(to(parmVarDecl().bind("parmVarDecl")))))),</div><div class=""><span style="white-space: pre-wrap;" class="">                                                     </span>declRefExpr(to(parmVarDecl().bind("parmVarDecl"))),</div><div class=""><span style="white-space: pre-wrap;" class="">                                                    </span>arraySubscriptExpr(hasLHS(ignoringParenImpCasts(declRefExpr(to(parmVarDecl().bind("parmVarDecl"))))))</div><div class=""><span style="white-space: pre-wrap;" class="">                                  </span>))</div><div class=""><span style="white-space: pre-wrap;" class="">                       </span>)</div><div class=""><span style="white-space: pre-wrap;" class="">                        </span>,unless(isExpansionInSystemHeader())).bind("binaryOpAssignment")</div><div class=""><br class=""></div><div class="">Another one is for matching outer function parameters to the arguments of a callee function.</div><div class=""><span style="white-space: pre-wrap;" class="">  </span>auto innerCallExpr = callExpr(</div><div class=""><span style="white-space: pre-wrap;" class="">           </span>forEachArgumentWithParam(</div><div class=""><span style="white-space: pre-wrap;" class="">                        </span>anyOf(unaryOperator(hasDescendant(calleeArgVarDecl)),calleeArgVarDecl),parmVarDecl().bind("calleeParam")),</div><div class=""><span style="white-space: pre-wrap;" class="">                     </span>callee(functionDecl().bind("calleeFunc")),unless(isExpansionInSystemHeader())).bind("callExpr");</div><div class=""><br class=""></div><div class=""><span style="white-space: pre-wrap;" class="">      </span>auto outerFuncDect = functionDecl(forEachDescendant(innerCallExpr)).bind("outerFunc");</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Using these two matchers allows me to build a graph in which I create:</div><div class="">1) Node for each function-parameter pairs (named FUNC-NAME_PARAM-NAME)</div><div class="">2) Relation for each function call in which the parameter is passed to another function.</div><div class=""><br class=""></div><div class="">For example, given the following functions:</div><div class=""><br class=""></div><div class="">void useSwap(int &p_1, int &p_2) {</div><div class=""><br class=""></div><div class="">   <span class="Apple-converted-space"> </span>swap(p_1, p_2, 1);</div><div class="">}</div><div class=""><br class=""></div><div class="">void swap(int &x, int &y, int junk) {</div><div class="">   <span class="Apple-converted-space"> </span>int temp;</div><div class="">   <span class="Apple-converted-space"> </span>temp = x; </div><div class="">   <span class="Apple-converted-space"> </span>x = y;             // << SOURCE_CODE_WRITE_LOCATION_OF_x</div><div class="">   <span class="Apple-converted-space"> </span>y = temp;</div><div class=""><br class=""></div><div class="">   <span class="Apple-converted-space"> </span>return;</div><div class="">}</div><div class=""><br class=""></div><div class="">I can follow useSwap's function parameter with the folowing graph nodes and relations:</div><div class=""><br class=""></div><div class="">(useSwap_p_1) -[:CALLS]-> (swap_x) -[:WRITES]-> (NODE_FOR_SOURCE_CODE_WRITE_LOCATION_OF_x)</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">For building this proof of concept I have used the LibASTMatchers tutorial from <a href="https://clang.llvm.org/docs/LibASTMatchersTutorial.html" target="_blank" class="">https://clang.llvm.org/docs/LibASTMatchersTutorial.html</a></div><div class="">In that tutorial, CommonOptionParser, ClangTool are used, and the Tool runs with a matcher.</div><div class="">If I pass few source files as agrument to the application, an AST created for each of these files individualy.</div><div class="">I cannot map the funcions from one AST to another so my call chain is broken.</div><div class=""><br class=""></div><div class="">I tryed to pass a the following compilation database file as an argumet to the application:</div><div class="">[<span style="white-space: pre-wrap;" class="">   </span></div><div class=""><span style="white-space: pre-wrap;" class=""> </span>{</div><div class=""><span style="white-space: pre-wrap;" class="">                </span>"directory": "/home/test",</div><div class=""><span style="white-space: pre-wrap;" class="">           </span>"command": "g++ -I/usr/include/c++/5 -I/usr/include/x86_64-linux-gnu/c++/5 -I/usr/include/c++/5/backward -I/usr/local/include -I/usr/include/x86_64-linux-gnu -I/usr/include -std=c++11 /home/test/file1.cpp",</div><div class=""><span style="white-space: pre-wrap;" class="">               </span>"file": "/home/test/file1.cpp"</div><div class=""><span style="white-space: pre-wrap;" class="">       </span>}</div><div class=""><span style="white-space: pre-wrap;" class="">        </span>,</div><div class=""><span style="white-space: pre-wrap;" class="">        </span>{</div><div class=""><span style="white-space: pre-wrap;" class="">                </span>"directory": "/home/test",</div><div class=""><span style="white-space: pre-wrap;" class="">           </span>"command": "g++ -I/usr/include/c++/5 -I/usr/include/x86_64-linux-gnu/c++/5 -I/usr/include/c++/5/backward -I/usr/local/include -I/usr/include/x86_64-linux-gnu -I/usr/include -std=c++11 /home/test/file2.cpp",</div><div class=""><span style="white-space: pre-wrap;" class="">               </span>"file": "/home/test/file2.cpp"</div><div class=""><span style="white-space: pre-wrap;" class="">       </span>}</div><div class="">]</div><div class=""><br class=""></div><div class="">Got the following error and warnings and linkage stage failed.</div><div class=""><br class=""></div><div class="">warning: /home/test/compile_commands.json: 'linker' input unused [-Wunused-command-line-argument]</div><div class="">warning: argument unused during compilation: '-I /usr/include/c++/5' [-Wunused-command-line-argument]</div><div class="">warning: argument unused during compilation: '-I /usr/include/x86_64-linux-gnu/c++/5' [-Wunused-command-line-argument]</div><div class="">warning: argument unused during compilation: '-I /usr/include/c++/5/backward' [-Wunused-command-line-argument]</div><div class="">warning: argument unused during compilation: '-I /usr/local/include' [-Wunused-command-line-argument]</div><div class="">warning: argument unused during compilation: '-I /usr/include/x86_64-linux-gnu' [-Wunused-command-line-argument]</div><div class="">warning: argument unused during compilation: '-I /usr/include' [-Wunused-command-line-argument]</div><div class="">error: unable to handle compilation, expected exactly one compiler job in ''</div><div class="">Error while processing /home/test/compile_commands.json.</div><div class=""><br class=""></div><div class="">Replacing the "command" section with somethin like "clang++ -c /home/test/file1.cpp" also did not work. I got the following error:</div><div class=""><br class=""></div><div class="">warning: /home/dev/projects/samlaCode/clang-tool/examples/compile_commands.json: 'linker' input unused [-Wunused-command-line-argument]</div><div class="">warning: argument unused during compilation: '-c' [-Wunused-command-line-argument]</div><div class="">error: unable to handle compilation, expected exactly one compiler job in ''</div><div class="">Error while processing /home/dev/projects/samlaCode/clang-tool/examples/compile_commands.json.</div></div>_______________________________________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br class=""></blockquote></div></blockquote></div><br clear="all" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class=""></div><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">--<span class="Apple-converted-space"> </span></span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div dir="ltr" class="gmail_signature" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">-------------------------------------<br class="">FarSight Studios<br class=""><a href="http://design.shadas.net/" target="_blank" class="">http://design.shadas.net</a></div><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">_______________________________________________</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">cfe-dev mailing list</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><a href="mailto:cfe-dev@lists.llvm.org" style="font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">cfe-dev@lists.llvm.org</a><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" style="font-family: Helvetica; font-size: 13px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a></div></blockquote></div><br class=""></body></html>