Why ClassTemplatePartialSpecializationDecl derived from ClassTemplateSpecializationDecl and not from ClassTemplateDecl ?

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

Why ClassTemplatePartialSpecializationDecl derived from ClassTemplateSpecializationDecl and not from ClassTemplateDecl ?

Eric Fiselier via cfe-dev
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

_______________________________________________
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: Why ClassTemplatePartialSpecializationDecl derived from ClassTemplateSpecializationDecl and not from ClassTemplateDecl ?

Eric Fiselier via cfe-dev
On 5 October 2017 at 12:47, Roman Popov via cfe-dev <[hidden email]> wrote:
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.

_______________________________________________
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: Why ClassTemplatePartialSpecializationDecl derived from ClassTemplateSpecializationDecl and not from ClassTemplateDecl ?

Eric Fiselier via cfe-dev
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:


... 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.

2017-10-05 14:02 GMT-07:00 Richard Smith <[hidden email]>:
On 5 October 2017 at 12:47, Roman Popov via cfe-dev <[hidden email]> wrote:
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.


_______________________________________________
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: Why ClassTemplatePartialSpecializationDecl derived from ClassTemplateSpecializationDecl and not from ClassTemplateDecl ?

Eric Fiselier via cfe-dev
On 5 October 2017 at 14:55, Roman Popov via cfe-dev <[hidden email]> wrote:
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:

A ClassTemplateDecl is a wrapper around a CXXRecordDecl, which is a TypeDecl.
 
... 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.

2017-10-05 14:02 GMT-07:00 Richard Smith <[hidden email]>:
On 5 October 2017 at 12:47, Roman Popov via cfe-dev <[hidden email]> wrote:
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.


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



_______________________________________________
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: Why ClassTemplatePartialSpecializationDecl derived from ClassTemplateSpecializationDecl and not from ClassTemplateDecl ?

Eric Fiselier via cfe-dev
Oh, now I see it.  Missed this point in first reply.

Thanks!

2017-10-05 17:16 GMT-07:00 Richard Smith <[hidden email]>:
On 5 October 2017 at 14:55, Roman Popov via cfe-dev <[hidden email]> wrote:
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:

A ClassTemplateDecl is a wrapper around a CXXRecordDecl, which is a TypeDecl.
 
... 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.

2017-10-05 14:02 GMT-07:00 Richard Smith <[hidden email]>:
On 5 October 2017 at 12:47, Roman Popov via cfe-dev <[hidden email]> wrote:
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.


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




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