void
mark_decl_instantiated (tree result, int extern_p)
{
- /* We used to set this unconditionally; we moved that to
- do_decl_instantiation so it wouldn't get set on members of
- explicit class template instantiations. But we still need to set
- it here for the 'extern template' case in order to suppress
- implicit instantiations. */
- if (extern_p)
- SET_DECL_EXPLICIT_INSTANTIATION (result);
+ SET_DECL_EXPLICIT_INSTANTIATION (result);
/* If this entity has already been written out, it's too late to
make any modifications. */
error ("storage class `%D' applied to template instantiation",
storage);
- SET_DECL_EXPLICIT_INSTANTIATION (result);
mark_decl_instantiated (result, extern_p);
repo_template_instantiated (result, extern_p);
if (! extern_p)
- instantiate_decl (result, /*defer_ok=*/1);
+ instantiate_decl (result, /*defer_ok=*/1, /*undefined_ok=*/0);
}
void
do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
}
+/* Called from do_type_instantiation to instantiate a member
+ (a member function or a static member variable) of an
+ explicitly instantiated class template. */
+static void
+instantiate_class_member (tree decl, int extern_p)
+{
+ mark_decl_instantiated (decl, extern_p);
+ repo_template_instantiated (decl, extern_p);
+ if (! extern_p)
+ instantiate_decl (decl, /*defer_ok=*/1, /* undefined_ok=*/1);
+}
+
/* Perform an explicit instantiation of template class T. STORAGE, if
non-null, is the RID for extern, inline or static. COMPLAIN is
nonzero if this is called from the parser, zero if called recursively,
{
tree tmp;
- int explicitly_instantiate_members = 0;
/* In contrast to implicit instantiation, where only the
declarations, and not the definitions, of members are
Of course, we can't instantiate member template classes, since
we don't have any arguments for them. Note that the standard
is unclear on whether the instantiation of the members are
- *explicit* instantiations or not. We choose to be generous,
- and not set DECL_EXPLICIT_INSTANTIATION. Therefore, we allow
- the explicit instantiation of a class where some of the members
- have no definition in the current translation unit. Exception:
- on some targets (e.g. Darwin), weak symbols do not get put in
- a static archive's TOC. The problematic case is if we're doing
- a non-extern explicit instantiation of an extern template: we
- have to put member functions in the TOC in that case, or we'll
- get unresolved symbols at link time. */
-
- explicitly_instantiate_members =
- TARGET_EXPLICIT_INSTANTIATIONS_ONE_ONLY
- && previous_instantiation_extern_p && ! extern_p
- && ! TYPE_FOR_JAVA (t);
+ *explicit* instantiations or not. However, the most natural
+ interpretation is that it should be an explicit instantiation. */
if (! static_p)
for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
if (TREE_CODE (tmp) == FUNCTION_DECL
&& DECL_TEMPLATE_INSTANTIATION (tmp))
- {
- if (explicitly_instantiate_members)
- do_decl_instantiation (tmp, NULL_TREE);
- else
- {
- mark_decl_instantiated (tmp, extern_p);
- repo_template_instantiated (tmp, extern_p);
- if (! extern_p)
- instantiate_decl (tmp, /*defer_ok=*/1);
- }
- }
+ instantiate_class_member (tmp, extern_p);
for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
- {
- if (explicitly_instantiate_members)
- do_decl_instantiation (tmp, NULL_TREE);
- else
- {
- mark_decl_instantiated (tmp, extern_p);
- repo_template_instantiated (tmp, extern_p);
- if (! extern_p)
- instantiate_decl (tmp, /*defer_ok=*/1);
- }
- }
+ instantiate_class_member (tmp, extern_p);
if (CLASSTYPE_NESTED_UTDS (t))
binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
/* Produce the definition of D, a _DECL generated from a template. If
DEFER_OK is nonzero, then we don't have to actually do the
- instantiation now; we just have to do it sometime. */
+ instantiation now; we just have to do it sometime. Normally it is
+ an error if this is an explicit instantiation but D is undefined.
+ If UNDEFINED_OK is nonzero, then instead we treat it as an implicit
+ instantiation. UNDEFINED_OK is nonzero only if we are being used
+ to instantiate the members of an explicitly instantiated class
+ template. */
+
tree
-instantiate_decl (tree d, int defer_ok)
+instantiate_decl (tree d, int defer_ok, int undefined_ok)
{
tree tmpl = DECL_TI_TEMPLATE (d);
tree gen_args;
import_export_decl (d);
}
+ if (! pattern_defined && DECL_EXPLICIT_INSTANTIATION (d) && undefined_ok)
+ SET_DECL_IMPLICIT_INSTANTIATION (d);
+
if (!defer_ok)
{
/* Recheck the substitutions to obtain any warning messages
fn;
fn = TREE_CHAIN (fn))
if (! DECL_ARTIFICIAL (fn))
- instantiate_decl (fn, /*defer_ok=*/0);
+ instantiate_decl (fn, /*defer_ok=*/0, /*undefined_ok=*/0);
if (COMPLETE_TYPE_P (instantiation))
{
instantiated_something = 1;
&& !DECL_TEMPLATE_INSTANTIATED (instantiation))
{
instantiation = instantiate_decl (instantiation,
- /*defer_ok=*/0);
+ /*defer_ok=*/0,
+ /*undefined_ok=*/0);
if (DECL_TEMPLATE_INSTANTIATED (instantiation))
{
instantiated_something = 1;