Hi all,
One thing that confused me in Clang AST is that ClassTemplatePartialSpecializationDecl is derived from ClassTemplateSpecializationDecl, and thus is a TypeDecl.
What is the reasoning behind this decision?
I thought that partial specialization is still a template in C++, and only when it is fully specialized it becomes a real class.
-Roman
Hi all,
One thing that confused me in Clang AST is that
ClassTemplatePartialSpecializationDecl is derived from
ClassTemplateSpecializationDecl, and thus is a TypeDecl.
What is the reasoning behind this decision?
I think the original design idea was that a
ClassTemplatePartialSpecializationDecl is a templated form of
ClassTemplateSpecializationDecl (in the same way that a ClassTemplateDecl
is a templated form of CXXRecordDecl etc.) That makes sense if you think
about it -- a partial specialization is a template whose templated
declaration is a specialization of a template. Only it's not quite
implemented like that, because ClassTemplatePartialSpecializationDecl isn't
a template wrapper *around* a ClassTemplateSpecializationDecl -- it's
actually both a class and a template all at once.
This non-uniformity of template representation is quite awkward, and I
think we know enough about how it works out now to consider it a minor
design error.
However, having the ClassTemplatePartialSpecializationDecl (or, in the
template-around-a-ClassTemplateSpecializationDecl case, the
ClassTemplateSpecializationDecl) be a TypeDecl is actually a sensible and
essentially necessary choice -- it represents the type of the "injected
class name" within the template, that is, the (dependent) type of "*this"
within the definition of the template and its members.
I thought that partial specialization is still a template in C++, and only
when it is fully specialized it becomes a real class.
Yes, but correct semantic analysis of C++ templates requires modeling a
family of dependent types too. Eg, within:
template<typename T> struct A;
template<typename T> struct A<T*> {
using X = int;
void f() {
A<T*>::X *y;
}
};
... we need to identify that A<T*> refers to the (dependent, not yet
instantiated) class template partial specialization we're currently
defining in order to look up X and determine that it's a type, which allows
"A<T*>::X *y;" to be parsed as a declaration rather than as a
multiplication expression.
Thanks for response.
However, having the ClassTemplatePartialSpecializationDecl (or, in the template-around-a-ClassTemplateSpecializationDecl case, the ClassTemplateSpecializationDecl) be a TypeDecl is actually a sensible and essentially necessary choice – it represents the type of the “injected class name” within the template, that is, the (dependent) type of “*this” within the definition of the template and its members.
But in this case ClassTemplateDecl should also be a TypeDecl? But it is not according to diagram:
https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateDecl.html#details
… we need to identify that A<T*> refers to the (dependent, not yet instantiated) class template partial specialization we’re currently defining in order to look up X and determine that it’s a type, which allows “A<T*>::X *y;” to be parsed as a declaration rather than as a multiplication expression.
I understand. I don’t yet looked into the parser code, so it was not evident for me that it influences AST type hierarchy.
Thanks for response.
However, having the ClassTemplatePartialSpecializationDecl (or, in the
template-around-a-ClassTemplateSpecializationDecl case, the
ClassTemplateSpecializationDecl) be a TypeDecl is actually a sensible
and essentially necessary choice -- it represents the type of the "injected
class name" within the template, that is, the (dependent) type of "*this"
within the definition of the template and its members.
But in this case ClassTemplateDecl should also be a TypeDecl? But it is
not according to diagram:
https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateDecl.html#
details
A ClassTemplateDecl is a wrapper around a CXXRecordDecl, which is a
TypeDecl.
Oh, now I see it. Missed this point in first reply.
Thanks!