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:
parent
b53dcf3e5c
commit
415c974c0b
@ -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>
|
2004-06-02 Andrew Pinski <pinskia@physics.uc.edu>
|
||||||
|
|
||||||
* cp-tree.h: Fix typo.
|
* cp-tree.h: Fix typo.
|
||||||
|
@ -3889,7 +3889,7 @@ extern int more_specialized (tree, tree, int, int);
|
|||||||
extern void mark_class_instantiated (tree, int);
|
extern void mark_class_instantiated (tree, int);
|
||||||
extern void do_decl_instantiation (tree, tree);
|
extern void do_decl_instantiation (tree, tree);
|
||||||
extern void do_type_instantiation (tree, tree, tsubst_flags_t);
|
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 int push_tinst_level (tree);
|
||||||
extern void pop_tinst_level (void);
|
extern void pop_tinst_level (void);
|
||||||
extern int more_specialized_class (tree, tree, tree);
|
extern int more_specialized_class (tree, tree, tree);
|
||||||
|
@ -3069,7 +3069,7 @@ mark_used (tree decl)
|
|||||||
information. */
|
information. */
|
||||||
|| cp_function_chain->can_throw);
|
|| cp_function_chain->can_throw);
|
||||||
|
|
||||||
instantiate_decl (decl, defer);
|
instantiate_decl (decl, defer, /*undefined_ok=*/0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
82
gcc/cp/pt.c
82
gcc/cp/pt.c
@ -10131,13 +10131,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
|
|||||||
void
|
void
|
||||||
mark_decl_instantiated (tree result, int extern_p)
|
mark_decl_instantiated (tree result, int extern_p)
|
||||||
{
|
{
|
||||||
/* We used to set this unconditionally; we moved that to
|
SET_DECL_EXPLICIT_INSTANTIATION (result);
|
||||||
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
|
/* If this entity has already been written out, it's too late to
|
||||||
make any modifications. */
|
make any modifications. */
|
||||||
@ -10641,11 +10635,10 @@ do_decl_instantiation (tree decl, tree storage)
|
|||||||
error ("storage class `%D' applied to template instantiation",
|
error ("storage class `%D' applied to template instantiation",
|
||||||
storage);
|
storage);
|
||||||
|
|
||||||
SET_DECL_EXPLICIT_INSTANTIATION (result);
|
|
||||||
mark_decl_instantiated (result, extern_p);
|
mark_decl_instantiated (result, extern_p);
|
||||||
repo_template_instantiated (result, extern_p);
|
repo_template_instantiated (result, extern_p);
|
||||||
if (! extern_p)
|
if (! extern_p)
|
||||||
instantiate_decl (result, /*defer_ok=*/1);
|
instantiate_decl (result, /*defer_ok=*/1, /*undefined_ok=*/0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -10674,6 +10667,18 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
|
|||||||
do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
|
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
|
/* Perform an explicit instantiation of template class T. STORAGE, if
|
||||||
non-null, is the RID for extern, inline or static. COMPLAIN is
|
non-null, is the RID for extern, inline or static. COMPLAIN is
|
||||||
nonzero if this is called from the parser, zero if called recursively,
|
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;
|
tree tmp;
|
||||||
int explicitly_instantiate_members = 0;
|
|
||||||
|
|
||||||
/* In contrast to implicit instantiation, where only the
|
/* In contrast to implicit instantiation, where only the
|
||||||
declarations, and not the definitions, of members are
|
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
|
Of course, we can't instantiate member template classes, since
|
||||||
we don't have any arguments for them. Note that the standard
|
we don't have any arguments for them. Note that the standard
|
||||||
is unclear on whether the instantiation of the members are
|
is unclear on whether the instantiation of the members are
|
||||||
*explicit* instantiations or not. We choose to be generous,
|
*explicit* instantiations or not. However, the most natural
|
||||||
and not set DECL_EXPLICIT_INSTANTIATION. Therefore, we allow
|
interpretation is that it should be an explicit instantiation. */
|
||||||
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);
|
|
||||||
|
|
||||||
if (! static_p)
|
if (! static_p)
|
||||||
for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
|
for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))
|
||||||
if (TREE_CODE (tmp) == FUNCTION_DECL
|
if (TREE_CODE (tmp) == FUNCTION_DECL
|
||||||
&& DECL_TEMPLATE_INSTANTIATION (tmp))
|
&& DECL_TEMPLATE_INSTANTIATION (tmp))
|
||||||
{
|
instantiate_class_member (tmp, extern_p);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
|
for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
|
||||||
if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
|
if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))
|
||||||
{
|
instantiate_class_member (tmp, extern_p);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CLASSTYPE_NESTED_UTDS (t))
|
if (CLASSTYPE_NESTED_UTDS (t))
|
||||||
binding_table_foreach (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
|
/* 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
|
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
|
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 tmpl = DECL_TI_TEMPLATE (d);
|
||||||
tree gen_args;
|
tree gen_args;
|
||||||
@ -11105,6 +11083,9 @@ instantiate_decl (tree d, int defer_ok)
|
|||||||
import_export_decl (d);
|
import_export_decl (d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! pattern_defined && DECL_EXPLICIT_INSTANTIATION (d) && undefined_ok)
|
||||||
|
SET_DECL_IMPLICIT_INSTANTIATION (d);
|
||||||
|
|
||||||
if (!defer_ok)
|
if (!defer_ok)
|
||||||
{
|
{
|
||||||
/* Recheck the substitutions to obtain any warning messages
|
/* Recheck the substitutions to obtain any warning messages
|
||||||
@ -11340,7 +11321,7 @@ instantiate_pending_templates (void)
|
|||||||
fn;
|
fn;
|
||||||
fn = TREE_CHAIN (fn))
|
fn = TREE_CHAIN (fn))
|
||||||
if (! DECL_ARTIFICIAL (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))
|
if (COMPLETE_TYPE_P (instantiation))
|
||||||
{
|
{
|
||||||
instantiated_something = 1;
|
instantiated_something = 1;
|
||||||
@ -11364,7 +11345,8 @@ instantiate_pending_templates (void)
|
|||||||
&& !DECL_TEMPLATE_INSTANTIATED (instantiation))
|
&& !DECL_TEMPLATE_INSTANTIATED (instantiation))
|
||||||
{
|
{
|
||||||
instantiation = instantiate_decl (instantiation,
|
instantiation = instantiate_decl (instantiation,
|
||||||
/*defer_ok=*/0);
|
/*defer_ok=*/0,
|
||||||
|
/*undefined_ok=*/0);
|
||||||
if (DECL_TEMPLATE_INSTANTIATED (instantiation))
|
if (DECL_TEMPLATE_INSTANTIATED (instantiation))
|
||||||
{
|
{
|
||||||
instantiated_something = 1;
|
instantiated_something = 1;
|
||||||
|
@ -2057,7 +2057,7 @@ cp_cannot_inline_tree_fn (tree* fnp)
|
|||||||
(template_for_substitution (fn))))
|
(template_for_substitution (fn))))
|
||||||
return 1;
|
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)))
|
if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user