[cfe-dev] Templates (again)

Douglas Gregor dgregor at apple.com
Tue Dec 23 10:45:01 PST 2008


Hi Andy,

On Dec 23, 2008, at 1:09 PM, Andrew Sutton wrote:

> 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



More information about the cfe-dev mailing list