Mads Ravn via llvm-dev
2016-Nov-28 22:03 UTC
[llvm-dev] Looking for help with an ast matcher
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( > declRefExpr().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/20161128/a6def4bc/attachment.html>
Piotr Padlewski via llvm-dev
2016-Nov-29 12:25 UTC
[llvm-dev] Looking for help with an ast matcher
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>
Mads Ravn via llvm-dev
2016-Nov-29 17:35 UTC
[llvm-dev] Looking for help with an ast matcher
Hi Piotr, It was the versions which was the problem... I should have checked. I still haven't been able to find a matcher to bind str1 to anything. I found another way to ensure it is a string, though. My actual problem is solved, but I will still be trying to find out how I am going to bind str1. Hopefully, I can figure it out. Thank you for your assistance! Best regards, Mads Ravn On Tue, Nov 29, 2016 at 1:25 PM Piotr Padlewski <piotr.padlewski at gmail.com> wrote:> 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( > declRefExpr().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/255d8f4a/attachment-0001.html>