When a class template is explicitly instantiated, its member should be too.

* cp-tree.h (instantiate_decl): new boolean parameter,
	undefined_ok. Current behavior is equivalent to its being 0.
	* decl2.c (mark_used): Add new argument when calling instantiate_decl
	* pt.c (mark_decl_instantiated): Unconditionally make
	instantiations explicit unconditionally
	(do_decl_instantiation): Don't call SET_DECL_EXPLICIT_INSTANTIATION,
	since mark_decl_instantiated now does it.
	(instantiate_class_member): New.  Instantiate a member of an
	explicitly instantiated class template.
	(do_type_instantiation): Explicitly instantiate members of an
	explicitly instantiated class template.
	(instantiate_decl): if undefined_ok is nonzero, and if we're
	trying to explicitly instantiated a template with no definition,
	change it to an implicit instantiation.
	(instantiate_pending_templates): Add new argument to instantiate_decl.
	* tree.c (cp_cannot_inline_tree_fn): Likewise.

From-SVN: r82585
This commit is contained in:
Matt Austern 2004-06-02 21:12:54 +00:00 committed by Matt Austern
parent b53dcf3e5c
commit 415c974c0b
5 changed files with 54 additions and 53 deletions

View File

@ -1,3 +1,22 @@
2004-06-02 Matt Austern <austern@apple.com>
* cp-tree.h (instantiate_decl): new boolean parameter,
undefined_ok. Current behavior is equivalent to its being 0.
* decl2.c (mark_used): Add new argument when calling instantiate_decl
* pt.c (mark_decl_instantiated): Unconditionally make
instantiations explicit unconditionally
(do_decl_instantiation): Don't call SET_DECL_EXPLICIT_INSTANTIATION,
since mark_decl_instantiated now does it.
(instantiate_class_member): New. Instantiate a member of an
explicitly instantiated class template.
(do_type_instantiation): Explicitly instantiate members of an
explicitly instantiated class template.
(instantiate_decl): if undefined_ok is nonzero, and if we're
trying to explicitly instantiated a template with no definition,
change it to an implicit instantiation.
(instantiate_pending_templates): Add new argument to instantiate_decl.
* tree.c (cp_cannot_inline_tree_fn): Likewise.
2004-06-02 Andrew Pinski <pinskia@physics.uc.edu>
* cp-tree.h: Fix typo.

View File

@ -3889,7 +3889,7 @@ extern int more_specialized (tree, tree, int, int);
extern void mark_class_instantiated (tree, int);
extern void do_decl_instantiation (tree, tree);
extern void do_type_instantiation (tree, tree, tsubst_flags_t);
extern tree instantiate_decl (tree, int);
extern tree instantiate_decl (tree, int, int);
extern int push_tinst_level (tree);
extern void pop_tinst_level (void);
extern int more_specialized_class (tree, tree, tree);

View File

@ -3069,7 +3069,7 @@ mark_used (tree decl)
information. */
|| cp_function_chain->can_throw);
instantiate_decl (decl, defer);
instantiate_decl (decl, defer, /*undefined_ok=*/0);
}
}

View File

@ -10131,12 +10131,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
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);
/* If this entity has already been written out, it's too late to
@ -10641,11 +10635,10 @@ do_decl_instantiation (tree decl, tree storage)
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
@ -10674,6 +10667,18 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
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,
@ -10773,7 +10778,6 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
{
tree tmp;
int explicitly_instantiate_members = 0;
/* In contrast to implicit instantiation, where only the
declarations, and not the definitions, of members are
@ -10789,50 +10793,18 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
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),
@ -10995,10 +10967,16 @@ template_for_substitution (tree decl)
/* 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;
@ -11105,6 +11083,9 @@ instantiate_decl (tree d, int defer_ok)
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
@ -11340,7 +11321,7 @@ instantiate_pending_templates (void)
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;
@ -11364,7 +11345,8 @@ instantiate_pending_templates (void)
&& !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;

View File

@ -2057,7 +2057,7 @@ cp_cannot_inline_tree_fn (tree* fnp)
(template_for_substitution (fn))))
return 1;
fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0);
fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0, /*undefined_ok=*/0);
if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
return 1;