<div dir="ltr"><div>Hi All,<br><br>I'm struggling to figure out the order in which MatchFinder invokes callbacks.<br><br>Here are my matches. Each match callback just dumps the file and line no.<br><br>    ClangTool Tool(OptionsParser.getCompilations(),<br>        OptionsParser.getSourcePathList());<br><br>    MyMatchCallback Mcb;<br>    MatchFinder Finder;<br><br>    Finder.addMatcher(<br>        functionDecl().bind("fn"),<br>        &Mcb);<br>        <br>    ...<br>    <br>    Finder.addMatcher(<br>        returnStmt().bind("rtn"),<br>        &Mcb);<br>    <br>    Finder.addMatcher(<br>        callExpr().bind("call"),<br>        &Mcb);<br>        <br>    return Tool.run(newFrontendActionFactory(&Finder).get());<br><br>I run the tool on this src file:<br><br>  1 int fn1(void) {return 1;}<br>  2 int fn2(void) {return 1;}<br>  3 int fn3(void) {return 1;}<br>  4 int fn4(void) {return 1;}<br>  5<br>  6 int (main)(void) {<br>  7     fn1();<br>  8     return 1;<br>  9<br> 10     if (fn2())<br> 11         return 1;<br> 12<br> 13     { /* arbitrary block */<br> 14         if(fn3())<br> 15             return 1;<br> 16     }<br> 17<br> 18     fn4();<br> 19<br> 20     return 1;<br> 21 }<br> <br>This is the output I get:  <file>:<line_no><br><br>    fnDecl main /home/.../match_order_test.c:6<br>    fn call fn1/home/.../match_order_test.c:7<br>    Rtn /home/.../match_order_test.c:8<br>    fn call fn4/home/.../match_order_test.c:18    << hey! line 10 should be next?<br>    Rtn /home/.../match_order_test.c:20<br>    fn call fn2/home/.../match_order_test.c:10<br>    Rtn /home/.../match_order_test.c:11<br>    fn call fn3/home/.../match_order_test.c:14<br>    Rtn /home/.../match_order_test.c:15<br>    <br>I was expecting the matches to be in line-number order. In fact I'm really depending on that for the custom tool I want to build as it needs to analyze the order in which certain fns are called.<br><br>Looking at the ast-dump of the src file and adding in the order in which the CallExprs and ReturnStmt's were matched MatchFinder looks to be doing a kind of breadth-first traversal.<br> <br>    TranslationUnitDecl 0x7fffc2a2b238 <<invalid sloc>> <invalid sloc><br>    |-TypedefDecl 0x7fffc2a2bad0 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'<br>    ...<br>    `-FunctionDecl 0x7fffc2a8a588 <line:6:1, line:21:1> line:6:6 main 'int (void)':'int (void)'<br>      `-CompoundStmt 0x7fffc2a8a8f0 <col:18, line:21:1><br>    #1  |-CallExpr 0x7fffc2a8a6c0 <line:7:5, col:9> 'int'<br>        | `-ImplicitCastExpr 0x7fffc2a8a6a8 <col:5> 'int (*)(void)' <FunctionToPointerDecay><br>        |   `-DeclRefExpr 0x7fffc2a8a658 <col:5> 'int (void)' Function 0x7fffc2a89ef0 'fn1' 'int (void)'<br>    #2  |-ReturnStmt 0x7fffc2a8a700 <line:8:5, col:12><br>        | `-IntegerLiteral 0x7fffc2a8a6e0 <col:12> 'int' 1<br>        |-IfStmt 0x7fffc2a8a798 <line:10:5, line:11:16><br>    #5  | |-CallExpr 0x7fffc2a8a748 <line:10:9, col:13> 'int'<br>        | | `-ImplicitCastExpr 0x7fffc2a8a730 <col:9> 'int (*)(void)' <FunctionToPointerDecay><br>        | |   `-DeclRefExpr 0x7fffc2a8a710 <col:9> 'int (void)' Function 0x7fffc2a8a0c0 'fn2' 'int (void)'<br>    #6  | `-ReturnStmt 0x7fffc2a8a788 <line:11:9, col:16><br>        |   `-IntegerLiteral 0x7fffc2a8a768 <col:16> 'int' 1<br>        |-CompoundStmt 0x7fffc2a8a850 <line:13:5, line:16:5><br>        | `-IfStmt 0x7fffc2a8a838 <line:14:9, line:15:20><br>    #7  |   |-CallExpr 0x7fffc2a8a7e8 <line:14:12, col:16> 'int'<br>        |   | `-ImplicitCastExpr 0x7fffc2a8a7d0 <col:12> 'int (*)(void)' <FunctionToPointerDecay><br>        |   |   `-DeclRefExpr 0x7fffc2a8a7b0 <col:12> 'int (void)' Function 0x7fffc2a8a248 'fn3' 'int (void)'<br>    #8  |   `-ReturnStmt 0x7fffc2a8a828 <line:15:13, col:20><br>        |     `-IntegerLiteral 0x7fffc2a8a808 <col:20> 'int' 1<br>    #3  |-CallExpr 0x7fffc2a8a8a0 <line:18:5, col:9> 'int'<br>        | `-ImplicitCastExpr 0x7fffc2a8a888 <col:5> 'int (*)(void)' <FunctionToPointerDecay><br>        |   `-DeclRefExpr 0x7fffc2a8a868 <col:5> 'int (void)' Function 0x7fffc2a8a3d0 'fn4' 'int (void)'<br>    #4   `-ReturnStmt 0x7fffc2a8a8e0 <line:20:5, col:12><br>          `-IntegerLiteral 0x7fffc2a8a8c0 <col:12> 'int' 1<br>          <br>          <br>In the documentation for MatchFinder it says "The order of matches is guaranteed to be equivalent to doing a pre-order traversal on the AST, and applying the matchers in the order in which they were added to the MatchFinder." but I can't reconcile what I see with what I found on the wikipedia for 'pre-order traversal'. <br><br>Is this a bug?<br><br>How can I influence the traversal order so that my matchers fire in source-code order?<br><br>Thanks,<br>Billy.<br></div></div>