AST matchers -> functionDecl finds definitions of structs

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

AST matchers -> functionDecl finds definitions of structs

David Blaikie via cfe-dev
Hello, I have a rather confusing problem.
As the email's subject says, I happen to match record definitions with the matcher functionDecl.

Using clang-query on simple example test files works perfectly, unless there is an include file involved. As soon, as clang-query (or my own tool) constructs an AST for a source, that refers to an include file, the matcher functionDecl will match on ANY record that is defined in the include file - not matching any defined in the cpp file.

The AST Matcher Reference on functionDecl is rather simple:
"Matches function declarations.

Example matches f 
  void f();"

No mentions of other node types, so how is this possible - any ideas to what i am doing wrong?

Thanks in advance!

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: AST matchers -> functionDecl finds definitions of structs

David Blaikie via cfe-dev
On 01/11/2018 14:52, Julian Mueller via cfe-dev wrote:

> Hello, I have a rather confusing problem.
> As the email's subject says, I happen to match record definitions with
> the matcher /functionDecl/.
>
> Using clang-query on simple example test files works perfectly, unless
> there is an include file involved. As soon, as clang-query (or my own
> tool) constructs an AST for a source, that refers to an include file,
> the matcher /functionDecl/ will match on ANY record that is defined in
> the include file - not matching any defined in the cpp file.
>
> The AST Matcher Reference on /functionDecl/ is rather simple:
> "/Matches function declarations./
>
> /Example matches f /
>
> /  void f();/"
>
> No mentions of other node types, so how is this possible - any ideas to
> what i am doing wrong?


You're hitting a confusing part of the AST as it relates to AST Matchers.

The AST contains lots of implicit things which get added in various
situations. Consider this:

$ cat struct.cpp

class A
{
  int foo();
};

#ifdef DEFINE_B_STRUCT
class B
{
   virtual int foo();
};
#endif


$ cat cmds.txt

m functionDecl()

set output dump

m functionDecl()


$ clang-query-6.0 -f cmds.txt struct.cpp --

Match #1:

struct.cpp:4:2: note: "root" binds here
  int foo();
  ^~~~~~~~~
1 match.

Match #1:

Binding for "root":
CXXMethodDecl 0x560d88cee3f8 <struct.cpp:4:2, col:10> col:6 foo 'int ()'

1 match.


Which is what you expect.

However, if the struct with a virtual method is part of the AST, you get
lots of things you don't expect:


clang-query-6.0 -f cmds.txt struct.cpp -- -DDEFINE_B_STRUCT

Match #1:

struct.cpp:4:2: note: "root" binds here
  int foo();
  ^~~~~~~~~

Match #2:

struct.cpp:10:3: note: "root" binds here
   virtual int foo();
   ^~~~~~~~~~~~~~~~~

Match #3:


Match #4:


Match #5:

struct.cpp:8:7: note: "root" binds here
class B
       ^
5 matches.

Match #1:

Binding for "root":
CXXMethodDecl 0x55df7fd37458 <struct.cpp:4:2, col:10> col:6 foo 'int ()'


Match #2:

Binding for "root":
CXXMethodDecl 0x55df7fd37720 <struct.cpp:10:3, col:19> col:15 foo 'int
()' virtual


Match #3:

Binding for "root":
CXXMethodDecl 0x55df7fd37818 <struct.cpp:8:7, <invalid sloc>> col:7
implicit constexpr operator= 'B &(const B &)' inline default
noexcept-unevaluated 0x55df7fd37818
`-ParmVarDecl 0x55df7fd37940 <col:7> col:7 'const B &'


Match #4:

Binding for "root":
CXXMethodDecl 0x55df7fd379d8 <struct.cpp:8:7, <invalid sloc>> col:7
implicit constexpr operator= 'B &(B &&)' inline default
noexcept-unevaluated 0x55df7fd379d8
`-ParmVarDecl 0x55df7fd37b00 <col:7> col:7 'B &&'


Match #5:

Binding for "root":
CXXDestructorDecl 0x55df7fd37b88 <struct.cpp:8:7> col:7 implicit ~B
'void ()' inline default trivial noexcept-unevaluated 0x55df7fd37b88

5 matches.


Anyway, I have already prototyped the removal of these nodes, but I
haven't submitted a patch yet. I submitted

  https://bugs.llvm.org/show_bug.cgi?id=39522

to track the task.

Meanwhile I suggest you simply ignore those nodes (they will disappear
when you make a more-specific matcher anyway), or use

m functionDecl(unless(isImplicit()))

if you are just exploring.

Thanks,

Stephen.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev