<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 5 October 2017 at 12:47, Roman Popov via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi all,<div><br></div><div>One thing that confused me in Clang AST is that <wbr>ClassTemplatePartialSpecializa<wbr>tionDecl is derived from <wbr>ClassTemplateSpecializationDec<wbr>l, and thus is a TypeDecl. </div><div><br></div><div>What is the reasoning behind this decision?</div></div></blockquote><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I thought that partial specialization is still a template in C++, and only when it is fully specialized it becomes a real class.</div></div></blockquote><div><br></div><div>Yes, but correct semantic analysis of C++ templates requires modeling a family of dependent types too. Eg, within:</div><div><br></div><div>template<typename T> struct A;</div><div>template<typename T> struct A<T*> {</div><div>  using X = int;</div><div>  void f() {</div><div>    A<T*>::X *y;</div><div>  }</div><div>};</div><div><br></div><div>... 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.</div></div></div></div>