[cfe-commits] [Patch][Review request] RecursiveASTVisitor can now traverse template specializations

John McCall rjmccall at apple.com
Mon Aug 30 18:37:04 PDT 2010


On Aug 30, 2010, at 6:08 PM, John McCall wrote:
> On Aug 30, 2010, at 5:33 PM, Benoit Belley wrote:
>> I think that I’ll need a bit more explanation here. The infinite recursion occurs while traversing the instantiations of the class template definition and I do want to traverse these instantiations. That’s the whole point of my proposed change.
> 
> Yes, I understood that.  My point is that you're visiting the instantiations regardless of whether the current template declaration you're visiting is a redeclaration or not.  This creates two problems:  first, you end up visiting the instantiations multiple times if the template is redeclared; and second, if the template is redeclared within itself (which can only be done with friend declarations), you end up visiting it recursively, which blows up the stack.  The solution is to only visit implicit instantiations when you visit a pattern definition.
> 
>  template <class T> class A;  // <- don't visit any instantiations here
>  class B { template <class T> friend class A; };  // <- or here
>  template <class T> class A { ... }; // <- okay to visit implicit instantiations here

A few more notes.

First, note that my proposal means that you won't be visiting implicit instantiations for undefined templates.  I'm assuming that's okay;  otherwise, you'll need to use different logic (I think visiting instantiations for the first declaration should be sufficient).

Second, have you considered what you want to do with incomplete instantiations?  These arise when a template specialization is written but not required to be a complete type.  My thought is that these should be ignored, but you may feel differently.

Third, you need to decide what you want to do with instantiations of partial specializations.  A significant issue here is that it's possible to have complete instantiations of a template without having a definition for the primary template.  I think the most appropriate general solution is to visit instantiations whenever you reach their pattern;  for example:
  template <class T> class A { ... }; // visit A<bool>, A<int> here
  template <class T> class A<T*> { ... }; // visit A<char*>, A<int*> here

Finally, it looks like there's an existing bug (with a FIXME) where we're not visiting the bodies of explicit specializations.  If you could fix TraverseClassTemplateSpecializationDecl to visit the record when either your flag is set *or* it's an explicit specialization, that would be good.

John.



More information about the cfe-commits mailing list