<div dir="ltr"><div>Hi,</div><div><br></div><div>I've been writing a project specific clang-tidy check (thanks to Artem and Steve for their help). I've matchers written and working but was seeing some strange things about the order in which my matcher callbacks were being called.<br></div><div><br></div><div>I noticed that 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 <a class="el" href="https://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder.html" title="A class to allow finding matches over the Clang AST.">MatchFinder</a>."</div><div><br></div><div>As my checker is checking that certain functions follow certain steps in order (check the "device" arg ptr for NULL, lock the device, do NOT return while the device is locked, unlock the device) I was expecting (depending on) in AST-order of the match callbacks. Not all the device-ptr-check matches first, then all the return matches, then all the etc etc.matches.</div><div><br></div><div><br></div><div>So two questions:<br></div><div>* Can this call-back order be changed somehow? - worth a shot ;)</div><div><br></div><div>* Failing this I can maintain information about the function and line number of all the steps in all the functions and figure out the AST-order from that. But I notice that using srcLocation often returns the same value for several statements (this is because in the code the Lock is actually done in a macro which locks the device but also returns if the lock fails - so I end up with a lock and a return both reporting the same srcLocation  - is there a way to determine which comes before which. (I think I came across a way of matching on macros too but I had already written working AST matchers at that point).<br></div><div><br></div><div>Thanks for reading,</div><div><br></div><div>Billy.<br></div><div><br></div><div><br></div><div>--------------</div><div><br></div><div><br></div><div>
<div>Here's an example of one of the type of function I want to check with some examples of errors in the code order:</div><div><br></div><div>int api_foo(device_t *<span class="gmail-il">dev</span>) {</div><div>    int ret_val = 0;<br></div><div><br></div><div>    bar();  
// fn calls & decls before api_enter is ok- just don't access <span class="gmail-il">dev</span>.</div><div>    <span class="gmail-il">dev</span>->bla = 1; // NO! device access before api_enter() called</div><div>    api_enter(<span class="gmail-il">dev</span>);   // error if this call is not present exactly once</div><div><br></div><div>    if (<span class="gmail-il">dev</span>->bla)</div><div>        return; // NO! didn't call api_exit before rtn. Also two return points</div><div><br></div><div>    if (<span class="gmail-il">dev</span>->ma) {</div><div>        ret_val = 1;<br></div><div>        goto cleanup;</div><div>    }</div><div>    tweak(<span class="gmail-il">dev</span>);<br></div><div><br></div><div>cleanup:</div><div>    api_exit(<span class="gmail-il">dev</span>); // error if this is not present exactly once<br></div><div>    <span class="gmail-il">dev</span>->bla = 1; //NO! device access after api_exit()<br></div><div>    return ret_val;<br></div><div>}</div>

</div></div>