Hi Andy,
I found that I'm going to have a little free time since my university is basically shutting down for the holidays, so I thought I'd spend some time revisiting my previous templates work. I'm just not entirely sure where to start. I started looking at building an AST node for template template parameters (for parity with type and non-type params) and realized that I probably have to define a TemplateDecl AST node as a base class that can also serve as a utility or node for template definitions.
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.
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
template<typename T> void foo(T);
"foo" would be represented by a TemplateDecl or subclass, and its underlying declaration would be a FunctionDecl. The underlying declaration of a class template is a RecordDecl, the underlying declaration of a template alias would be some kind of alias-declaration or typedef, and the underlying declaration of a template template parameter might also be a RecordDecl (?).
In any case, starting with the representation of template template parameters is a good idea, IMHO, because introducing TemplateDecls for function and class templates is going to require quite a lot of logic in, e.g., declaration matching and overloading. Much better to get the TemplateDecl pieces in place *first*.
Thanks for working on this. I have a few specific comments about your current changeset:
+ static TemplateDecl *Create(ASTContext &C, Kind DK, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id);
Please use DeclarationName instead of IdentifierInfo *. DeclarationName supports constructors\ names, overloaded operator names, and other special names that IdentifierInfo* does not.
+ static bool classof(const Decl *D) {
+ return D->getKind() == Template;
+ }
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.
Additionally, you'll want to add
static bool classof(const TemplateTemplateParmDecl *) { return true; }
(and similarly for other template declarations, as we add them).
In Decl::getIdentifierNamespace(), I suggest that all TemplateDecls return IDNS_Ordinary | IDNS_Tag, since template names need to be unique in their scope.
I actually have a partial patch (that includes a TemplateDecl that's surprisingly similar to yours <g>) which starts to deal with some of the AST nodes and parser state for template parameter lists. It might answer the question you have in the ActOnTemplateTemplateParameter FIXME about the "signature" of the template template parameter. I'll try to commit the non-TemplateDecl parts of that tonight, so you don't have to re-invent it (and we don't conflict).
+TemplateDecl *TemplateDecl::Create(ASTContext &C, Kind DK, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id) {
+ void *Mem = C.getAllocator().Allocate<TranslationUnitDecl>();
I suspect that TemplateDecl and TranslationUnitDecl won't always be the same size 
In Sema::ActOnTemplateTemplateParameter, you can go ahead and S- >AddDecl(Param) the parameter you create.
You should update Sema::isTemplateName to return "true" when it sees a TemplateDecl (or any of its subclasses). It won't actually work yet, but that'll enable template-ids whose template-name is a template template parameter.
- Doug