(C++) template statics linkage patch
Jason Merrill
jason@cygnus.com
Tue Mar 23 02:32:00 GMT 1999
We weren't emitting template statics in some cases, even with an explicit
instantiation. Caught by the libstdc++ v3 folks.
1999-03-23 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c (finish_file): Set at_eof to 2 after expanding ctors.
* decl.c (expand_static_init): Make sure we don't add any after
then.
* decl.c (cp_finish_decl): Move intelligence about handling
DECL_COMDAT for variables from here...
* decl2.c (comdat_linkage): ...to here.
(maybe_make_one_only): Tweak.
(import_export_decl): Call comdat_linkage for variables, too.
(finish_file): Handle template statics properly.
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.326
diff -c -p -r1.326 decl.c
*** decl.c 1999/03/19 01:21:03 1.326
--- decl.c 1999/03/23 10:09:42
*************** cp_finish_decl (decl, init, asmspec_tree
*** 7774,7804 ****
else if (TREE_CODE (decl) == VAR_DECL
&& DECL_LANG_SPECIFIC (decl)
&& DECL_COMDAT (decl))
! {
! /* Dynamically initialized vars go into common. */
! if (DECL_INITIAL (decl) == NULL_TREE
! || DECL_INITIAL (decl) == error_mark_node)
! DECL_COMMON (decl) = 1;
! else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
! {
! DECL_COMMON (decl) = 1;
! DECL_INITIAL (decl) = error_mark_node;
! }
! else
! {
! /* Statically initialized vars are weak or comdat, if
! supported. */
! if (flag_weak)
! make_decl_one_only (decl);
! else
! {
! /* We can't do anything useful; leave vars for explicit
! instantiation. */
! DECL_EXTERNAL (decl) = 1;
! DECL_NOT_REALLY_EXTERN (decl) = 0;
! }
! }
! }
if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
make_decl_rtl (decl, NULL_PTR, toplev);
--- 7774,7782 ----
else if (TREE_CODE (decl) == VAR_DECL
&& DECL_LANG_SPECIFIC (decl)
&& DECL_COMDAT (decl))
! /* Set it up again; we might have set DECL_INITIAL since the
! last time. */
! comdat_linkage (decl);
if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
make_decl_rtl (decl, NULL_PTR, toplev);
*************** expand_static_init (decl, init)
*** 8093,8098 ****
--- 8071,8079 ----
tree init;
{
tree oldstatic = value_member (decl, static_aggregates);
+
+ /* If at_eof is 2, we're too late. */
+ my_friendly_assert (at_eof <= 1, 990323);
if (oldstatic)
{
Index: decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.192
diff -c -p -r1.192 decl2.c
*** decl2.c 1999/03/15 13:08:26 1.192
--- decl2.c 1999/03/23 10:09:42
*************** comdat_linkage (decl)
*** 2370,2377 ****
{
if (flag_weak)
make_decl_one_only (decl);
! else
TREE_PUBLIC (decl) = 0;
if (DECL_LANG_SPECIFIC (decl))
DECL_COMDAT (decl) = 1;
--- 2370,2395 ----
{
if (flag_weak)
make_decl_one_only (decl);
! else if (TREE_CODE (decl) == FUNCTION_DECL)
TREE_PUBLIC (decl) = 0;
+ else
+ {
+ if (DECL_INITIAL (decl) == 0
+ || DECL_INITIAL (decl) == error_mark_node)
+ DECL_COMMON (decl) = 1;
+ else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
+ {
+ DECL_COMMON (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+ }
+ else
+ {
+ /* We can't do anything useful; leave vars for explicit
+ instantiation. */
+ DECL_EXTERNAL (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 0;
+ }
+ }
if (DECL_LANG_SPECIFIC (decl))
DECL_COMDAT (decl) = 1;
*************** maybe_make_one_only (decl)
*** 2391,2404 ****
return;
/* We can't set DECL_COMDAT on functions, or finish_file will think
! we can get away with not emitting them if they aren't used.
! We can't use make_decl_one_only for variables, because their
! DECL_INITIAL may not have been set properly yet. */
! if (TREE_CODE (decl) == FUNCTION_DECL)
! make_decl_one_only (decl);
! else
! comdat_linkage (decl);
}
/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
--- 2409,2422 ----
return;
/* We can't set DECL_COMDAT on functions, or finish_file will think
! we can get away with not emitting them if they aren't used. We need
! to for variables so that cp_finish_decl will update their linkage,
! because their DECL_INITIAL may not have been set properly yet. */
! make_decl_one_only (decl);
!
! if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl))
! DECL_COMDAT (decl) = 1;
}
/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
*************** import_export_decl (decl)
*** 2730,2739 ****
/* Templates are allowed to have internal linkage. See
[basic.link]. */
;
- else if (TREE_CODE (decl) == FUNCTION_DECL)
- comdat_linkage (decl);
else
! DECL_COMDAT (decl) = 1;
}
else
DECL_NOT_REALLY_EXTERN (decl) = 0;
--- 2748,2755 ----
/* Templates are allowed to have internal linkage. See
[basic.link]. */
;
else
! comdat_linkage (decl);
}
else
DECL_NOT_REALLY_EXTERN (decl) = 0;
*************** finish_file ()
*** 3344,3355 ****
/* Done with C language context needs. */
pop_lang_context ();
/* Now write out any static class variables (which may have since
learned how to be initialized). */
! while (pending_statics)
{
tree decl = TREE_VALUE (pending_statics);
/* Output DWARF debug information. */
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
--- 3360,3377 ----
/* Done with C language context needs. */
pop_lang_context ();
+ /* Let expand_static_init know it's too late for more ctors. */
+ at_eof = 2;
+
/* Now write out any static class variables (which may have since
learned how to be initialized). */
! for (; pending_statics; pending_statics = TREE_CHAIN (pending_statics))
{
tree decl = TREE_VALUE (pending_statics);
+ if (TREE_ASM_WRITTEN (decl))
+ continue;
+
/* Output DWARF debug information. */
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
*************** finish_file ()
*** 3360,3370 ****
dwarf2out_decl (decl);
#endif
! DECL_DEFER_OUTPUT (decl) = 0;
rest_of_decl_compilation
(decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1);
-
- pending_statics = TREE_CHAIN (pending_statics);
}
this_time = get_run_time ();
--- 3382,3396 ----
dwarf2out_decl (decl);
#endif
! /* We currently handle template statics here. We ought to handle
! them the same way we do template functions, i.e. only emit them if
! the symbol is needed. */
! import_export_decl (decl);
! if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl))
! DECL_EXTERNAL (decl) = 0;
!
rest_of_decl_compilation
(decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1);
}
this_time = get_run_time ();
*************** finish_file ()
*** 3426,3432 ****
continue;
if (TREE_ASM_WRITTEN (decl)
! || (DECL_SAVED_INSNS (decl) == 0 && ! DECL_ARTIFICIAL (decl)))
*p = TREE_CHAIN (*p);
else if (DECL_INITIAL (decl) == 0)
p = &TREE_CHAIN (*p);
--- 3452,3459 ----
continue;
if (TREE_ASM_WRITTEN (decl)
! || (DECL_SAVED_INSNS (decl) == 0
! && ! DECL_ARTIFICIAL (decl)))
*p = TREE_CHAIN (*p);
else if (DECL_INITIAL (decl) == 0)
p = &TREE_CHAIN (*p);
*************** finish_file ()
*** 3475,3481 ****
}
/* Now delete from the chain of variables all virtual function tables.
! We output them all ourselves, because each will be treated specially. */
walk_vtables ((void (*) PROTO((tree, tree))) 0,
prune_vtable_vardecl);
--- 3502,3509 ----
}
/* Now delete from the chain of variables all virtual function tables.
! We output them all ourselves, because each will be treated
! specially. */
walk_vtables ((void (*) PROTO((tree, tree))) 0,
prune_vtable_vardecl);
More information about the Gcc-patches
mailing list