[cfe-dev] clang-tidy or static analyzer or ...
Stephen Kelly via cfe-dev
cfe-dev at lists.llvm.org
Thu Sep 12 15:08:37 PDT 2019
On 11/09/2019 01:13, Artem Dergachev via cfe-dev wrote:
>
>
> On 9/10/19 3:54 PM, Stephen Kelly via cfe-dev wrote:
>> On 10/09/2019 23:46, Artem Dergachev via cfe-dev wrote:
>>> Yup, the most principled way of doing this with ASTMatchers is to
>>> start with the function decl and then recurse inside it:
>>>
>>> functionDecl(matchesName(...), forEachDescendant(returnStmt(...)))
>>>
>>> You can always do this in an inside out, but it most likely has
>>> performance implications (i never really understood how ASTMatcher
>>> performance works as i've never had any real performance problems
>>> with them):
>>>
>>> returnStmt(..., hasAncestor(functionDecl(matchesName(...))))
>>>
>> These will give unexpected results in the presence of lambdas for
>> example. The `forFunction` expression should be used instead.
>>
>
> Yay nice, i never noticed this one, thanks!
>
> Would it make sense to make a "direct" variant of this matcher as well,
> i.e. a variant of forEachDescendant for functionDecls that only scans
> statements within that function and doesn't descend into nested
> declarations?
I've found that in practice, forEachDescendant is far less useful than
it seems. For example, you might think that it helps you match
descendants which are ints in a function called takeValue:
takeValue(someInt);
Imagine there is also a string overload of takeValue too.
However, if you use forEachDescendant to match the ints, you'll match
the wrong stuff:
takeValue(toString(someInt));
Always use a semantically specific matcher instead of
has/hasDescendant/forEachDescendant etc. And if a semantically specific
matcher doesn't exist, create it (either in your own code or upstream).
Thanks,
Stephen.
More information about the cfe-dev
mailing list