Commit eba839f9 by Mark Mitchell Committed by Mark Mitchell

re PR c++/22263 (explicit instantiation fails to emit symbols defined later)

	PR c++/22263
	* cp-tree.h (instantiate_decl): Change prototype.
	* decl2.c (mark_used): Adjust accordingly.
	* pt.c (do_decl_instantiation): Likewise.
	(instantiate_class_member): Likewise.
	(instantiate_decl): Rename undefined_ok as expl_inst_class_mem_p.
	Clear DECL_INTERFACE_KNOWN for an explicitly instantiated template
	that has no definition available.
	(instantiate_pending_templates): Adjust call to instantiate_decl.

	PR c++/22263
	* g++.dg/template/explicit7.C: New test.

From-SVN: r102133
parent 28356f52
2005-07-18 Mark Mitchell <mark@codesourcery.com>
PR c++/22263
* cp-tree.h (instantiate_decl): Change prototype.
* decl2.c (mark_used): Adjust accordingly.
* pt.c (do_decl_instantiation): Likewise.
(instantiate_class_member): Likewise.
(instantiate_decl): Rename undefined_ok as expl_inst_class_mem_p.
Clear DECL_INTERFACE_KNOWN for an explicitly instantiated template
that has no definition available.
(instantiate_pending_templates): Adjust call to instantiate_decl.
2005-07-17 Mark Mitchell <mark@codesourcery.com> 2005-07-17 Mark Mitchell <mark@codesourcery.com>
PR c++/22139 PR c++/22139
......
...@@ -3997,7 +3997,7 @@ extern int more_specialized_fn (tree, tree, int); ...@@ -3997,7 +3997,7 @@ extern int more_specialized_fn (tree, tree, 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, int); extern tree instantiate_decl (tree, int, bool);
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);
......
...@@ -3278,7 +3278,8 @@ mark_used (tree decl) ...@@ -3278,7 +3278,8 @@ mark_used (tree decl)
times. Maintaining a stack of active functions is expensive, times. Maintaining a stack of active functions is expensive,
and the inliner knows to instantiate any functions it might and the inliner knows to instantiate any functions it might
need. */ need. */
instantiate_decl (decl, /*defer_ok=*/true, /*undefined_ok=*/0); instantiate_decl (decl, /*defer_ok=*/true,
/*expl_inst_class_mem_p=*/false);
} }
#include "gt-cp-decl2.h" #include "gt-cp-decl2.h"
...@@ -11010,7 +11010,8 @@ do_decl_instantiation (tree decl, tree storage) ...@@ -11010,7 +11010,8 @@ do_decl_instantiation (tree decl, tree storage)
mark_decl_instantiated (result, extern_p); mark_decl_instantiated (result, extern_p);
if (! extern_p) if (! extern_p)
instantiate_decl (result, /*defer_ok=*/1, /*undefined_ok=*/0); instantiate_decl (result, /*defer_ok=*/1,
/*expl_inst_class_mem_p=*/false);
} }
void void
...@@ -11047,7 +11048,8 @@ instantiate_class_member (tree decl, int extern_p) ...@@ -11047,7 +11048,8 @@ instantiate_class_member (tree decl, int extern_p)
{ {
mark_decl_instantiated (decl, extern_p); mark_decl_instantiated (decl, extern_p);
if (! extern_p) if (! extern_p)
instantiate_decl (decl, /*defer_ok=*/1, /* undefined_ok=*/1); instantiate_decl (decl, /*defer_ok=*/1,
/*expl_inst_class_mem_p=*/true);
} }
/* Perform an explicit instantiation of template class T. STORAGE, if /* Perform an explicit instantiation of template class T. STORAGE, if
...@@ -11343,14 +11345,12 @@ template_for_substitution (tree decl) ...@@ -11343,14 +11345,12 @@ template_for_substitution (tree decl)
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. Normally it is instantiation now; we just have to do it sometime. Normally it is
an error if this is an explicit instantiation but D is undefined. 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 EXPL_INST_CLASS_MEM_P is true iff D is a member of an
instantiation. UNDEFINED_OK is nonzero only if we are being used explicitly instantiated class template. */
to instantiate the members of an explicitly instantiated class
template. */
tree tree
instantiate_decl (tree d, int defer_ok, int undefined_ok) instantiate_decl (tree d, int defer_ok,
bool expl_inst_class_mem_p)
{ {
tree tmpl = DECL_TI_TEMPLATE (d); tree tmpl = DECL_TI_TEMPLATE (d);
tree gen_args; tree gen_args;
...@@ -11439,9 +11439,14 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok) ...@@ -11439,9 +11439,14 @@ instantiate_decl (tree d, int defer_ok, int undefined_ok)
input_location = DECL_SOURCE_LOCATION (d); input_location = DECL_SOURCE_LOCATION (d);
if (! pattern_defined && DECL_EXPLICIT_INSTANTIATION (d) && undefined_ok) /* If D is a member of an explicitly instantiated class template,
and no definition is available, treat it like an implicit
instantiation. */
if (!pattern_defined && expl_inst_class_mem_p
&& DECL_EXPLICIT_INSTANTIATION (d))
{ {
DECL_NOT_REALLY_EXTERN (d) = 0; DECL_NOT_REALLY_EXTERN (d) = 0;
DECL_INTERFACE_KNOWN (d) = 0;
SET_DECL_IMPLICIT_INSTANTIATION (d); SET_DECL_IMPLICIT_INSTANTIATION (d);
} }
...@@ -11678,8 +11683,9 @@ instantiate_pending_templates (int retries) ...@@ -11678,8 +11683,9 @@ instantiate_pending_templates (int retries)
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,
/*undefined_ok=*/0); /*defer_ok=*/0,
/*expl_inst_class_mem_p=*/false);
if (COMPLETE_TYPE_P (instantiation)) if (COMPLETE_TYPE_P (instantiation))
reconsider = 1; reconsider = 1;
} }
...@@ -11699,9 +11705,10 @@ instantiate_pending_templates (int retries) ...@@ -11699,9 +11705,10 @@ instantiate_pending_templates (int retries)
if (!DECL_TEMPLATE_SPECIALIZATION (instantiation) if (!DECL_TEMPLATE_SPECIALIZATION (instantiation)
&& !DECL_TEMPLATE_INSTANTIATED (instantiation)) && !DECL_TEMPLATE_INSTANTIATED (instantiation))
{ {
instantiation = instantiate_decl (instantiation, instantiation
/*defer_ok=*/0, = instantiate_decl (instantiation,
/*undefined_ok=*/0); /*defer_ok=*/0,
/*expl_inst_class_mem_p=*/false);
if (DECL_TEMPLATE_INSTANTIATED (instantiation)) if (DECL_TEMPLATE_INSTANTIATED (instantiation))
reconsider = 1; reconsider = 1;
} }
......
2005-07-18 Mark Mitchell <mark@codesourcery.com>
PR c++/22263
* g++.dg/template/explicit7.C: New test.
2005-07-17 Jerry DeLisle <jvdelisle@verizon.net> 2005-07-17 Jerry DeLisle <jvdelisle@verizon.net>
* gfortran.fortran-torture/execute/nan_inf_fmt.f90: Change case of field * gfortran.fortran-torture/execute/nan_inf_fmt.f90: Change case of field
width of 8 to +Inf and -Inf. width of 8 to +Inf and -Inf.
......
// PR c++/22263
// { dg-do link }
template <class T> struct S { T foo (); T bar (); };
template <class T> T S<T>::foo () { return bar (); }
template struct S<int>;
template <class T> T S<T>::bar () { return T (); }
#if !__GXX_WEAK__
template int S<int>::bar ();
#endif
int main () { return S<int>().foo (); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment