[cfe-dev] On template instantiations and specializations.
Enea Zaffanella
zaffanella at cs.unipr.it
Tue Jun 15 00:35:32 PDT 2010
Abramo Bagnara wrote:
> Il 14/06/2010 22:33, Douglas Gregor ha scritto:
>> Hello Enea,
>>
>> On Jun 14, 2010, at 2:33 AM, Enea Zaffanella wrote:
>>
>>> Hello.
>>>
>>> clang AST is missing nodes able to represent various kinds of
>>> instantiations and/or specializations of (member of class) templates,
>>> such as the following:
>>>
>>> ============================================
>>> // Explicit specialization.
>>> template <> void foo<int>(int a) {}
>>>
>>> // Explicit instantiation declaration.
>>> extern template void foo<char*>(char* s);
>>>
>>> typedef char Char;
>>> // Another (redundant) explicit inst. decl.
>>> extern template void foo(Char* s);
>>>
>>> // Explicit instantiation definition.
>>> template void foo(double);
>>> ============================================
>>>
>>> Quoting from Sema::SemaTemplate.cpp:
>>>
>>> // FIXME: Create an ExplicitInstantiation node?
>>> [...]
>>> // FIXME: We may still want to build some representation of this
>>> // explicit specialization.
>>> [...]
>>> // FIXME: Create some kind of ExplicitInstantiationDecl here.
>>>
>>> We would like to hear opinions about the following proposal for filling
>>> in those FIXMEs. The main goal is to provide a better distinction
>>> between the syntactic and semantic issues. As hinted in the comments
>>> above, we should introduce a new Decl node whose purpose is to represent
>>> all syntactic aspects of the explicit specialization/instantiation of
>>> (members of) templates. Let us call this new class (better names are
>>> welcome)
>>>
>>> ExplicitSpecOrInstDecl
>>>
>>> In our opinion, this class should be derived directly from Decl (rather
>>> than inheriting from more concrete classes), provide all and only the
>>> syntactic info which is peculiar of explicit template
>>> specializations/instantiations (i.e., source locations of the optional
>>> "extern" keyword, of the "template" keyword and of the optional "<>"
>>> brackets) and then contain an appropriate Decl node for a proper
>>> representation of the other stuff. That is, the new node will be somehow
>>> similar to a LinkageSpecDecl node (but it will not be a DeclContext).
>>>
>>> Note that even the declaration contained in the ExplicitSpecOrInstDecl
>>> node will be mainly providing syntactic info: that is, for a construct
>>> such as
>>>
>>> extern template void foo(Char* s);
>>>
>>> we will have an ExplicitSpecOrInstDecl node
>>> (representing "extern template")
>>> containing a FunctionDecl node
>>> (representing "void foo(Char* s);"
>> I agree that this is a good way to model explicit instantiations and specializations.
>>
>>> The actual, semantic instantiation of the function template foo for
>>> template argument char* will be stored somewhere else (and will be
>>> possibly be completely unaffected by this syntactic declaration).
>> We'll need to create a (re-)declaration of the function template specialization that contains the various parameters, template arguments, etc. as written in the explicit specialization or instantiation.
>>
>>> If the proposal above makes some sense, then we should also consider
>>> whether or not it would be appropriate to extend it to the case of class
>>> template specializations or instantiations (and even member classes of
>>> class templates). We stress this point because currently for class
>>> template a different approach is being used, whereby a class template
>>> specialization is inheriting from CXXRecordDecl. This in our opinion is
>>> a suboptimal design choice.
>> There is a difference here... FunctionDecl stores its template arguments and associated specialization information in members, while CXXRecordDecl has the ClassTemplateSpecializationDecl subclass to store this information. How is it suboptimal?
>
> What'is the reason to not follow a similar pattern to what is proposed
> above for functions?
Having a uniform approach is one of the pros.
Anyway, when reasoning about the suboptimality of design, I was
(implicitly) referring to the whole CXXRecordDecl inheritance hierarchy.
It may just be a matter of taste (no one here is pretending to separate
what is "right" from what is "wrong"), but I find it strange to see a
ClassTemplatePartialSpecializationDecl inheriting from
ClassTemplateSpecializationDecl inheriting from CXXRecordDecl ... these
do not look to be proper ISA relationships. Why should a partial
specialization provide info about the "extern" keyword or the "<>"
braces? Why should it have method getSpecializationKind() when all
partial specialization are explicit?
To my eyes, a design based on containment rather than inheritance would
probably be a little bit cleaner. Unless there are other reasons to
prefer inheritance ...
Cheers,
Enea.
More information about the cfe-dev
mailing list