[cfe-dev] Linking files while using Clang AST matchers to implement a call graph

Gábor Márton via cfe-dev cfe-dev at lists.llvm.org
Tue Dec 25 12:47:19 PST 2018


> How I can get to the definition to a callee function from a caller
location which located in a different source file (different AST)?

AFAIK you have two options, under the hoods both of them use the
ASTImporter class in Clang.
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.
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).

Hope this helps,
Gabor

On Tue, Dec 25, 2018 at 8:57 AM FarSight Studios via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

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


More information about the cfe-dev mailing list