<div dir="ltr"><div>Dear all,</div><div><br></div><div>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>I am using CLang AST matcher for this task.</div><div>My solution seems to work, but only when all the functions are located in the same source file.</div><div>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><br></div><div>My questions are:</div><div>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>Do I need to somehow pass the linkage stage to make it work?</div><div><br></div><div>I have seen in other posts that CLang libTooling does not support Cross Translation Unit feature.</div><div>I also seen that LibClang allowed to impenitent this by using Unified Symbol Resolution. Does libTooling offer something like that?<br></div><div><br></div><div>Is there any other option to getting to function definition when more than one source file is used?</div><div><br></div><div><br></div><div><br></div><div>I have searched the web for a few days to find any solution with no luck.</div><div>Any help will be much appreciated.</div><div><br></div><div>Thank you</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>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>-------------------------------------------</div><div><br></div><div>I wrote two matchers:</div><div>One for matching all the write operations to a parameter inside a funcion:</div><div><span style="white-space:pre-wrap">    </span>binaryOperator(</div><div><span style="white-space:pre-wrap">                  </span>isAssignmentOperator(),</div><div><span style="white-space:pre-wrap">                  </span>hasLHS(ignoringParenImpCasts(</div><div><span style="white-space:pre-wrap">                                    </span>anyOf(</div><div><span style="white-space:pre-wrap">                                                   </span>unaryOperator(hasUnaryOperand(ignoringParenImpCasts(declRefExpr(to(parmVarDecl().bind("parmVarDecl")))))),</div><div><span style="white-space:pre-wrap">                                                     </span>declRefExpr(to(parmVarDecl().bind("parmVarDecl"))),</div><div><span style="white-space:pre-wrap">                                                    </span>arraySubscriptExpr(hasLHS(ignoringParenImpCasts(declRefExpr(to(parmVarDecl().bind("parmVarDecl"))))))</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>,unless(isExpansionInSystemHeader())).bind("binaryOpAssignment")</div><div><br></div><div>Another one is for matching outer function parameters to the arguments of a callee function.</div><div><span style="white-space:pre-wrap">   </span>auto innerCallExpr = callExpr(</div><div><span style="white-space:pre-wrap">           </span>forEachArgumentWithParam(</div><div><span style="white-space:pre-wrap">                        </span>anyOf(unaryOperator(hasDescendant(calleeArgVarDecl)),calleeArgVarDecl),parmVarDecl().bind("calleeParam")),</div><div><span style="white-space:pre-wrap">                     </span>callee(functionDecl().bind("calleeFunc")),unless(isExpansionInSystemHeader())).bind("callExpr");</div><div><br></div><div><span style="white-space:pre-wrap">    </span>auto outerFuncDect = functionDecl(forEachDescendant(innerCallExpr)).bind("outerFunc");</div><div><br></div><div><br></div><div>Using these two matchers allows me to build a graph in which I create:</div><div>1) Node for each function-parameter pairs (named FUNC-NAME_PARAM-NAME)</div><div>2) Relation for each function call in which the parameter is passed to another function.</div><div><br></div><div>For example, given the following functions:</div><div><br></div><div>void useSwap(int &p_1, int &p_2) {</div><div><br></div><div>    swap(p_1, p_2, 1);</div><div>}</div><div><br></div><div>void swap(int &x, int &y, int junk) {</div><div>    int temp;</div><div>    temp = x; </div><div>    x = y;             // << SOURCE_CODE_WRITE_LOCATION_OF_x</div><div>    y = temp;</div><div><br></div><div>    return;</div><div>}</div><div><br></div><div>I can follow useSwap's function parameter with the folowing graph nodes and relations:</div><div><br></div><div>(useSwap_p_1) -[:CALLS]-> (swap_x) -[:WRITES]-> (NODE_FOR_SOURCE_CODE_WRITE_LOCATION_OF_x)</div><div><br></div><div><br></div><div>For building this proof of concept I have used the LibASTMatchers tutorial from <a href="https://clang.llvm.org/docs/LibASTMatchersTutorial.html" target="_blank">https://clang.llvm.org/docs/LibASTMatchersTutorial.html</a></div><div>In that tutorial, CommonOptionParser, ClangTool are used, and the Tool runs with a matcher.</div><div>If I pass few source files as agrument to the application, an AST created for each of these files individualy.</div><div>I cannot map the funcions from one AST to another so my call chain is broken.</div><div><br></div><div>I tryed to pass a the following compilation database file as an argumet to the application:</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>"directory": "/home/test",</div><div><span style="white-space:pre-wrap">           </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><span style="white-space:pre-wrap">               </span>"file": "/home/test/file1.cpp"</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>"directory": "/home/test",</div><div><span style="white-space:pre-wrap">           </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><span style="white-space:pre-wrap">               </span>"file": "/home/test/file2.cpp"</div><div><span style="white-space:pre-wrap">       </span>}</div><div>]</div><div><br></div><div>Got the following error and warnings and linkage stage failed.</div><div><br></div><div>warning: /home/test/compile_commands.json: 'linker' input unused [-Wunused-command-line-argument]</div><div>warning: argument unused during compilation: '-I /usr/include/c++/5' [-Wunused-command-line-argument]</div><div>warning: argument unused during compilation: '-I /usr/include/x86_64-linux-gnu/c++/5' [-Wunused-command-line-argument]</div><div>warning: argument unused during compilation: '-I /usr/include/c++/5/backward' [-Wunused-command-line-argument]</div><div>warning: argument unused during compilation: '-I /usr/local/include' [-Wunused-command-line-argument]</div><div>warning: argument unused during compilation: '-I /usr/include/x86_64-linux-gnu' [-Wunused-command-line-argument]</div><div>warning: argument unused during compilation: '-I /usr/include' [-Wunused-command-line-argument]</div><div>error: unable to handle compilation, expected exactly one compiler job in ''</div><div>Error while processing /home/test/compile_commands.json.</div><div><br></div><div>Replacing the "command" section with somethin like "clang++ -c /home/test/file1.cpp" also did not work. I got the following error:</div><div><br></div><div>warning: /home/dev/projects/samlaCode/clang-tool/examples/compile_commands.json: 'linker' input unused [-Wunused-command-line-argument]</div><div>warning: argument unused during compilation: '-c' [-Wunused-command-line-argument]</div><div>error: unable to handle compilation, expected exactly one compiler job in ''</div><div>Error while processing /home/dev/projects/samlaCode/clang-tool/examples/compile_commands.json.</div></div>