Adding "extern template" (version 2)

Introduction:

A common technique for implementing automatic instantiation is for the
compiler to instantiate a function in each translation unit in which it
is referenced and for the linker to eliminate redundant copies of the
instantiation. A drawback of this technique is that for some programs
the cost can be large both in compilation time and object file size.
A number of compilers allow the programmer to suppress the
implicit instantiation of templates by prefixing an explicit instantiation
directive with the extern keyword.
This document proposes specific semantics for this feature.

Semantic Summary:

This feature was first proposed to the committee in N1448 by Mat Marcus
and Gabriel Dos Reis. While there was widespread agreement on the need
to support "extern template", there was not support for having
"extern template" suppress the instantiation of inline functions. In
addition, N1448 proposed "extern template" as a mechanism to provide
greater control over the point of instantiation of a template. It should
be noted that the current standard provides no such guarantees, even in
the presence of explicit instantiations, and this proposal does not
attempt to provide such a feature.

As a result of reflector discussions and discussions in the Core and
Evolution groups, the following rules are proposed:

If an extern template directive appears in a translation unit,
an explicit instantiation of the entity must appear in another translation
unit, or later in the same translation unit.

An extern template directive may not name a static function
(but may name a static class member).

An extern template directive that names a class applies to
the members of the class, not the class itself. It results in the implicit
instantiation of the class as well as that of any nested classes.

extern template has no normative affect on inline functions.
A note should be included indicating that implementations are encouraged to
suppress out-of-line copies of inline functions that were declared with
extern template. Such inline functions are instantiated
though (so that they can be inlined).

Drafting notes:

An issue I ran into when drafting this is that something that used to
say "If X is explicitly instantiated" is transformed to
"If X is the subject of an explicit instantiation declaration".
A more pithy phrase would be helpful. One possibility is
"If X is explicitly instantiation-declared".

Working Paper Changes:

Add to the end of 7.1.1 paragraph 5:

[Note: The extern keyword can also be used in
explicit-instantiations and linkage-specifications, but it
is not a storage-class-specifier in such contexts.]

Revise 14.6.4.1 paragraph 5 as follows:

An explicit instantiation definitiondirective is an
instantiation point for the specialization or specializations specified
by the explicit instantiation directive.

Revise 14.7 paragraph 5 as follows:

an explicit instantiation definition shall appear at most
once in a program.

Revise 14.7.2, paragraph 2 as follows:

explicit-instantiation:extern opttemplate declaration

There are two forms of explicit instantiation: an explicit instantiation
definition and an explicit instantiation declaration. An explicit
instantiation declaration begins with the extern keyword.

Revise 14.7.2 paragraph 4 as follows:

Otherwise, for an explicit instantiation definition
the definition of a non-exported ...

Revise 14.7.2 paragraph 7 as follows:

TheAn
explicit instantiation
that namesof a class template specialization
is analso explicit instantiationesof the same kind (declaration or definition) of
each of its members (not including members inherited from base classes)
whose definition is visible at the point of instantiation and
that has not been previously explicitly specialized in the translation
unit containing the explicit specialization, except as described below.

At the end of 14.7.2 paragraph 7, add the following:

An explicit instantiation definition that names a class template specialization
explicitly instantiates the class template specialization
and is only an explicit instantiation definition of members
whose definition is visible at the point of instantiation.

An explicit instantiation declaration that names a class template
specialization has no effect on the class template specialization
itself (except for perhaps resulting in its implicit instantiation).
Except for inline functions, other explicit instantiation declarations have
the effect of suppressing the implicit instantiation of the entity to which
they refer. [Note: The intent is that an inline function
that is the subject of an explicit instantiation declaration will still be
implicitly instantiated when used so that the body can be considered for
inlining, but that no out-of-line copy of the inline function would be
generated in the translation unit. -- end note]

If an entity is the subject of both an explicit instantiation declaration
and an explicit instantiation definition in the same translation unit,
the definition shall follow the declaration.
An entity that is the subject of an explicit instantiation declaration and that
is also used in the translation unit shall be the subject of an explicit
instantiation definition somewhere in the program; otherwise the program
is ill-formed, no diagnostic required. [Note: This rule does
apply to inline functions even though an explicit instantiation declaration
of such an entity has no other normative effect. This is needed to ensure that
if the address of an inline function is taken in a translation unit in which
the implementation chose to suppress the out-of-line body, another
translation unit will supply the body. --end note]
An explicit instantiation declaration shall not name a specialization of
a template with internal linkage.