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.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits