AST Matching: Maching FieldDecl while excluding matches in ClassTemplateDecl

Hello,

I am trying to identify FieldDecl's within a class declaration using AST matchers. However, when the class is a template class, I notice that ClassTemplateSpecializationDecl and ClassTemplateDecl are generated by the AST. I do not want to match with the ClassTemplateDecl.

For the following example:

class A {
  public:
    int x; // #1
};

template< typename T>
class B {
  public:
  A a; // #2
  B() : a{} {}
};

int main() {
  B<int> b{};
  return 0;
}

I would like to match with #1 and #2, but #2 for only the ClassTemplateSpecializationDecl.

When I use: fieldDecl().bind("fd")

I get:

Match #1:

Binding for "fd":
FieldDecl 0x2726d88 </home/twiga/code/github/cfe-dev/FieldDecl-constructor.cpp:4:5, col:9> col:9 x 'int'

Match #2:

Binding for "fd":
FieldDecl 0x2727268 </home/twiga/code/github/cfe-dev/FieldDecl-constructor.cpp:10:3, col:5> col:5 a 'A'

Match #3:

Binding for "fd":
FieldDecl 0x27279c8 </home/twiga/code/github/cfe-dev/FieldDecl-constructor.cpp:10:3, col:5> col:5 a 'A'

Note that Match #1 and #3 are what I want. Match #2 is coming from the ClassTemplateDecl, which I do not want to match on. Could someone provide me with some guidance to exclude matches for a FieldDecl's parent class declaration being a template declaration but not a class template specialization?

Thanks.
Hiren

Hi Hiren,

Note that Match #1 and #3 are what I want. Match #2 is coming from
the ClassTemplateDecl, which I do not want to match on. Could someone
provide me with some guidance to exclude matches for a FieldDecl's
parent class declaration being a template declaration but not a class
template specialization?

I guess what you want is that either it's not a template class or it's a
template instantiation, i.e.

fieldDecl(
    anyOf(unless(hasParent(cxxRecordDecl(hasParent(classTemplateDecl())))),
          hasParent(cxxRecordDecl(isTemplateInstantiation()))))

Does that help?

Regards,

Miklos