[llvm-dev] Looking for help with an ast matcher

Piotr Padlewski via llvm-dev llvm-dev at lists.llvm.org
Tue Nov 29 04:25:03 PST 2016


Well, I don't know if it works or not, but the name suggest that it matches
to the "this" object.
Check if it works, check implementation and unit tests to find out :)

BTW you should check matches on the clang-query with the same version as
the one you develop on, because the implementation and names could change
since 3.8.1.
Piotr

2016-11-28 23:03 GMT+01:00 Mads Ravn <madsravn at gmail.com>:

> Hi Piotr,
>
> Thanks. Yeah, it seemed a little weird, but it was what got me closest. I
> found out that the matcher I supplied here was working for clang-query
> 3.8.1. I'm working on a clang-tidy module for 4.0.0 - it's not working
> there.
>
> Could you elaborate on the "onImplicitObjectArgument"? There is no
> document on it on the clang page. So I wouldn't know how it works or what
> it does.
>
> Best regards,
> Mads Ravn
>
> On Mon, Nov 28, 2016 at 10:50 PM Piotr Padlewski <
> piotr.padlewski at gmail.com> wrote:
>
>> Hi Mads,
>> I formatted your matcher a little bit just to understand it:
>>
>> ifStmt(hasCondition(implicitCastExpr(hasImplicitDestinationType(
>> isInteger()),
>>                     has(cxxMemberCallExpr(callee(cxxMethodDecl(hasName("
>> compare"))),
>>                                           hasArgument(0,
>> declRefExpr().bind("str2")),
>>                                           callee(memberExpr(has(declRefE
>> xpr().bind("str1"))))))))).bind("case1")
>>
>> And this is the AST part that we care about
>> |-IfStmt 0x7fba9625f5e8 <line:8:5, line:10:5>
>>   | |-<<<NULL>>>
>>   | |-<<<NULL>>>
>>   | |-ImplicitCastExpr 0x7fba96258a80 <line:8:8, col:25> '_Bool'
>> <IntegralToBoolean>
>>   | | `-CXXMemberCallExpr 0x7fba96258a20 <col:8, col:25> 'int'
>>   | |   |-MemberExpr 0x7fba962589e8 <col:8, col:13> '<bound member
>> function type>' .compare 0x7fba956ba078
>>   | |   | `-ImplicitCastExpr 0x7fba96258a50 <col:8> 'const class
>> std::__1::basic_string<char>' lvalue <NoOp>
>>   | |   |   `-DeclRefExpr 0x7fba962588e0 <col:8> 'std::string':'class
>> std::__1::basic_string<char>' lvalue Var 0x7fba962585b8 'str1'
>> 'std::string':'class std::__1::basic_string<char>'
>>   | |   `-ImplicitCastExpr 0x7fba96258a68 <col:21> 'const class
>> std::__1::basic_string<char>' lvalue <NoOp>
>>   | |     `-DeclRefExpr 0x7fba962589b0 <col:21> 'std::string':'class
>> std::__1::basic_string<char>' lvalue Var 0x7fba96258770 'str2'
>> 'std::string':'class std::__1::basic_string<char>'
>>
>>
>> The callee called twice seems weird. Try to replace second one with
>> "onImplicitObjectArgument", or "on", or in the worst case - "has" (which
>> would not be totally valid).
>>
>>
>> Piotr.
>>
>> 2016-11-28 <20%2016%2011%2028> 9:06 GMT+01:00 Mads Ravn <
>> madsravn at gmail.com>:
>>
>> Hi Piotr,
>>
>> I think I found a working matcher: match ifStmt(hasCondition(
>> implicitCastExpr(hasImplicitDestinationType(isInteger()),
>> has(cxxMemberCallExpr(callee(cxxMethodDecl(hasName("compare"))),
>> hasArgument(0, declRefExpr().bind("str2")), callee(memberExpr(has(
>> declRefExpr().bind("str1"))))))))).bind("case1")
>>
>> This one bind to both str1 and str2 in str1.compare(str2). I have
>> included a code segment below. I have attached a screenshot of this matcher
>> working from clang-query.
>> HOWEVER - when I try to use the matcher in clang-tidy it will not work.
>> It is because of the callee(memberExpr(has(declRefExpr().bind("str1"))))
>> part of the matcher. If I remove that, I can match on the
>> str1.compare(str2) from the code. But I need to bind str1 as well to test
>> if it is a string.
>>
>> Do you  have any idea why a matcher would work in clang-query, but not in
>> clang-tidy? It's the same piece of code it is working on. Is there
>> something wrong with my matcher (undefined behavior or something)?
>>
>> Code:
>> #include <iostream>
>> #include <string>
>>
>> int main() {
>>     std::string str1{"aa"};
>>     std::string str2{"bb"};
>>
>>     if(str1.compare(str2)) {
>>         std::cout << "Strings not equal" << std::endl;
>>     }
>>
>>     return 0;
>>
>> }
>>
>>
>>
>>
>> On Sun, Nov 27, 2016 at 10:39 PM Piotr Padlewski <
>> piotr.padlewski at gmail.com> wrote:
>>
>> Sorry for writing 3 emails,
>> I looked into http://clang.llvm.org/docs/LibASTMatchersReference.html?
>> and it seems that matcher
>> on :
>> Matcher<CXXMemberCallExpr
>> <http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html>> ->
>> Matcher<Expr <http://clang.llvm.org/doxygen/classclang_1_1Expr.html>>
>> InnerMatcher
>> would be my candidate to check. If it won't gonna work then send the test
>> and AST dump and I will try to help.
>>
>> Piotr
>>
>> 2016-11-27 22:35 GMT+01:00 Piotr Padlewski <piotr.padlewski at gmail.com>:
>>
>> Adding cfe-dev, because it is related to clang, not LLVM.
>>
>> 2016-11-27 22:34 GMT+01:00 Piotr Padlewski <piotr.padlewski at gmail.com>:
>>
>> Hi Mads,
>> Can you provide the code that you run clang-query on, or at least AST for
>> the fragment you want to match?
>>
>> Piotr
>>
>> 2016-11-26 22:27 GMT+01:00 Mads Ravn via llvm-dev <
>> llvm-dev at lists.llvm.org>:
>>
>> Hi,
>>
>> Hope this is the right channel for this question. I am trying to make an
>> ast matcher for clang-tidy to find str1.compare(str2), where both str1 and
>> str2 are std::string. I have this so far: http://i.imgur.com/sUma9WC.png .
>> But I am having a hard time finding a way to bind an id to the str1 part of
>> the expression.
>>
>> Can anyone help me out with an idea?
>>
>> Best regards,
>> Mads Ravn
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>
>>
>>
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161129/f29279ba/attachment.html>


More information about the llvm-dev mailing list