<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">[CC'ing cfe-dev]<div><br><div><div>On Dec 23, 2008, at 3:51 PM, Andrew Sutton wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Yes, I agree with this. I think we'll need a TemplateDecl AST node to represent any kind of template. TemplateDecl will store the template parameters themselves, and the various kinds of templates (class template, function template, template alias, or template-template parameter) will probably have corresponding subclasses (ClassTemplateDecl, FunctionTemplateDecl, TemplateAliasDecl, TemplateTemplateParmDecl) with whatever members are appropriate for that kind of template. Class templates will have instantiations, specializations, and partial specializations; function templates will just have instantiations and specializations, etc.</blockquote>
<div><br>Don't forget about concept_maps :) </div></div></blockquote><div><br></div><div>Eh? What's that?</div><br><blockquote type="cite"><div class="gmail_quote"><div>I was thinking along these lines, but hoping to avoid the explosion of template-derived subclasses. After giving it some thought, the alternatives are probably less attractive.</div></div></blockquote><div><br></div><div>I think there are only 4 template-derived subclasses (5, when concept maps come along). The trick is that FunctionTemplate covers all of the various subclasses of FunctionDecl under a single TemplateDecl subclass.</div><br><blockquote type="cite"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">I suggest that the TemplateDecl not be a DeclContext. Rather, it should have a ScopedDecl member for the "underlying declaration" of the template, which is essentially the AST node that was parsed for the template itself. For example, given<br>

<br>
        template<typename T> void foo(T);<br>
<br>
"foo" would be represented by a TemplateDecl or subclass, and its underlying declaration would be a FunctionDecl. </blockquote><div><br>So a FunctionTemplateDecl holding and FunctionDecl in this case?</div></div></blockquote><div><br></div><div>Yes. TemplateDecl will probably have a ScopedDecl* for its underlying declaration; FunctionTemplateDecl can just cast this to a FunctionDecl*.</div><br><blockquote type="cite"><div class="gmail_quote"><div> From a parsing perspective, I suppose that means we have to defer the creation of of the TemplateDecl-derived node until we know what the underlying declaration is.</div></div></blockquote><div><br></div><div>Yes. I suspect that the template parameters will be passed directly to ActOnDeclarator, so it can do the work of building the template declaration.</div><br><blockquote type="cite"><div class="gmail_quote"><div><br>It might be easier to simply have a general TemplateDecl node that then holds the TemplateFunctionDecl. The contained node would be part function, part template-decl "glue", and know about its specializations (and partials for classes) and instances.</div></div></blockquote><div><br></div><div>I think my way is simpler :)</div><div><br></div><div>We have the TemplateDecl, which has a ScopedDecl of some sort. Clients that deal with templates abstractly can use TemplateDecl. Then, there are subclasses of TemplateDecl that put more requirements on that underlying declaration and add extra fields (specializations, instantiations, partial specializations, etc.).</div><div><br></div><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Thanks for working on this. I have a few specific comments about your current changeset:<br>

<br>
+  static TemplateDecl *Create(ASTContext &C, Kind DK, DeclContext *DC,<br>
+                              SourceLocation L, IdentifierInfo *Id);<br>
Please use DeclarationName instead of IdentifierInfo *. DeclarationName supports constructors\ names, overloaded operator names, and other special names that IdentifierInfo* does not.</blockquote><div><br>Should I update the other template nodes to use these? My svn version doesn't seem to use them.</div></div></blockquote><div><br></div><div>Those template nodes that can have these special names (or have subclasses that can have these special names) should use DeclarationName. FunctionTemplateDecl is probably the only subclass that will need DeclarationName, depending on how we deal with the names of specializations and partial specializations.</div><br><blockquote type="cite"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">+ static bool classof(const Decl *D) {<br>
+ return D->getKind() == Template;<br>
+ }<br>
You also need to check for D->getKind() == TemplateTemplateParm. Actually, I suggest that you add aliases TemplateFirst and TemplateLast to the enumeration, since we'll eventually have several kinds of templates.</blockquote>
<div><br>This is the node-kind "hierarchy"? I think I see how this works. </div></div></blockquote><div><br></div><div>Yes.</div><br><blockquote type="cite"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Additionally, you'll want to add<br>
<br>
        static bool classof(const TemplateTemplateParmDecl *) { return true; }<br>
<br>
(and similarly for other template declarations, as we add them).</blockquote><div><br>I thought I had that... maybe not.</div></div></blockquote><div><br></div><div>You want it both in TemplateDecl and in TemplateTemplateParmDecl. That way, if some code asks "is a TemplateTemplateParmDecl a TemplateDecl?" we have an immediate answer rather than looking into the declaration kind.</div><br><blockquote type="cite"><div class="gmail_quote"><div><br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
In Decl::getIdentifierNamespace(), I suggest that all TemplateDecls return IDNS_Ordinary | IDNS_Tag, since template names need to be unique in their scope.</blockquote><div><br>Sounds good to me. I really don't understand the meaning of these tags - or at least how it plays into the parsing/name resolution.</div></div></blockquote><div><br></div><div>Within a single scope, you can have both an ordinary name and a tag name. For example, this is well-formed</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">  </span>class A;<br></div><div><span class="Apple-tab-span" style="white-space:pre">   </span>int A;<br></div><div><br></div><div>This works because the class 'A' is in the "tag" identifier namespace while the int 'A' is in the ordinary namespace. In C++, ordinary name lookup actually searches both identifier namespaces, but prefers the ordinary name. Thus, 'A' refers to the integer (even if it is declared before the class). The terminology really comes from C, but it's used in C++ as well.</div><div><br></div><div>C++-specific entities like templates and namespaces basically live in both namespaces, because you can't declare, e.g., a namespace and a type, with the same name in the same scope.</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug<br></div></div></div></body></html>