<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Please CC cfe-dev on these discussions. (Reply All)<div><br><div><div>On Dec 23, 2008, at 5:11 PM, Andrew Sutton wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><br><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;"><div style=""><div><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>
<div></div></div></div></div></blockquote><div> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div style=""><div><div><div>I think my way is simpler :)<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 class="Ih2E3d"><div></div></div></div></div></div></blockquote><div><br>To summarize, we're talking about something like this:<br><br>class TemplateDecl : ScopedDecl // (?)<br>{<br>  ScopedDecl* decl;<br>  // One of FunctionDecl, ClassDecl, etc.<br>
  // but not one of *TemplateDecl?<br>};<br><br>class ClassTemplateDecl : TemplateDecl { };<br>class FunctionTemplateDecl : TemplateDecl { };<br>// template alias, template template parameter, etc.<br><br>And we'd generally be creating derived decl nodes during parsing. Is that about right?</div></div></blockquote><div><br></div><div>Yes.</div><br><blockquote type="cite"><div class="gmail_quote"><div><br>This makes me wonder what the AST would look like for something like this:<br><br>template <typename T><br>struct S<br>{<br>  template <typename U> void f(U u);<br>};<br><br>template <typename T><br>
template <typenameU><br>void S<T>::f(U u)<br>{ }<br><br>It looks like we'd have to a) defer the creation of the ClassTemplateDecl until we see S<T> or b) I'm misintepreting what you're saying and we'd create a TemplateDecl for each template<...>, and then create a ClassTemplateDecl when we S<T> and have it reference the outer-most TemplateDecl.</div></div></blockquote></div></div><div><br></div><div>So, walking through this: when we get the ActOnTag callback, we create the TemplateDecl and RecordDecl for class template 'S' (basically, when we see the '{' after the 'S'). </div><div><br></div><div>When we get the ActOnDeclarator callback for 'f', we build the FunctionDecl and TemplateDecl for that member template.</div><div><br></div><div>For the out-of-line member definition, we'll get an ActOnDeclarator call with a declarator 'f' in scope S<T>. We'll then create a TemplateDecl+FunctionDecl for that out-of-line definition.</div><div><br></div></body></html>