From ea56c40c484e89e5a67f71a2c90a1ad645c89540 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sat, 26 Apr 2003 01:27:09 +0000 Subject: [PATCH] decl2.c (finish_file): Don't call import_export_decl for functions that are not defined. * decl2.c (finish_file): Don't call import_export_decl for functions that are not defined. (handle_class_head): Robustify. * pt.c (instantiate_decl): Do not call cp_finish_decl for variables that are not defined. * g++.old-deja/g++.pt/instantiate12.C: Explicit instantiate initialized static data members. From-SVN: r66095 --- gcc/cp/ChangeLog | 8 +++++ gcc/cp/decl2.c | 18 +++++++--- gcc/cp/pt.c | 43 ++++++++++++++++++----- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C | 10 ++++++ 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f246bee..e4b5602 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2003-04-25 Mark Mitchell + + * decl2.c (finish_file): Don't call import_export_decl for + functions that are not defined. + (handle_class_head): Robustify. + * pt.c (instantiate_decl): Do not call cp_finish_decl for + variables that are not defined. + 2003-04-24 Sylvain Pion * call.c (print_z_candidates): Fix off by one error. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 3f9c66f..a52bdaa 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2730,9 +2730,7 @@ finish_file () for (i = 0; i < deferred_fns_used; ++i) { tree decl = VARRAY_TREE (deferred_fns, i); - - import_export_decl (decl); - + /* Does it need synthesizing? */ if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) && TREE_USED (decl) @@ -2749,6 +2747,15 @@ finish_file () reconsider = true; } + /* If the function has no body, avoid calling + import_export_decl. On a system without weak symbols, + calling import_export_decl will make an inline template + instantiation "static", which will result in errors about + the use of undefined functions if there is no body for + the function. */ + if (!DECL_SAVED_TREE (decl)) + continue; + /* We lie to the back-end, pretending that some functions are not defined when they really are. This keeps these functions from being put out unnecessarily. But, we must @@ -4668,7 +4675,10 @@ handle_class_head (enum tag_types tag_kind, tree scope, tree id, if (!decl) { - decl = TYPE_MAIN_DECL (xref_tag (tag_kind, id, attributes, false)); + decl = xref_tag (tag_kind, id, attributes, false); + if (decl == error_mark_node) + return error_mark_node; + decl = TYPE_MAIN_DECL (decl); xrefd_p = true; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 74f497e..9faf035 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10927,11 +10927,6 @@ instantiate_decl (d, defer_ok) if (need_push) push_to_top_level (); - /* We're now committed to instantiating this template. Mark it as - instantiated so that recursive calls to instantiate_decl do not - try to instantiate it again. */ - DECL_TEMPLATE_INSTANTIATED (d) = 1; - /* Regenerate the declaration in case the template has been modified by a subsequent redeclaration. */ regenerate_decl_from_template (d, td); @@ -10950,10 +10945,36 @@ instantiate_decl (d, defer_ok) DECL_IN_AGGR_P (d) = 0; import_export_decl (d); DECL_EXTERNAL (d) = ! DECL_NOT_REALLY_EXTERN (d); - cp_finish_decl (d, - (!DECL_INITIALIZED_IN_CLASS_P (d) - ? DECL_INITIAL (d) : NULL_TREE), - NULL_TREE, 0); + + if (DECL_EXTERNAL (d)) + { + /* The fact that this code is executing indicates that: + + (1) D is a template static data member, for which a + definition is available. + + (2) An implicit or explicit instantiation has occured. + + (3) We are not going to emit a definition of the static + data member at this time. + + This situation is peculiar, but it occurs on platforms + without weak symbols when performing an implicit + instantiation. There, we cannot implicitly instantiate a + defined static data member in more than one translation + unit, so import_export_decl marks the declaration as + external; we must rely on explicit instantiation. */ + } + else + { + /* Mark D as instantiated so that recursive calls to + instantiate_decl do not try to instantiate it again. */ + DECL_TEMPLATE_INSTANTIATED (d) = 1; + cp_finish_decl (d, + (!DECL_INITIALIZED_IN_CLASS_P (d) + ? DECL_INITIAL (d) : NULL_TREE), + NULL_TREE, 0); + } } else if (TREE_CODE (d) == FUNCTION_DECL) { @@ -10962,6 +10983,10 @@ instantiate_decl (d, defer_ok) tree tmpl_parm; tree spec_parm; + /* Mark D as instantiated so that recursive calls to + instantiate_decl do not try to instantiate it again. */ + DECL_TEMPLATE_INSTANTIATED (d) = 1; + /* Save away the current list, in case we are instantiating one template from within the body of another. */ saved_local_specializations = local_specializations; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bfc4ff2..2590adf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-04-25 Mark Mitchell + + * g++.old-deja/g++.pt/instantiate12.C: Explicit instantiate + initialized static data members. + 2003-04-25 H.J. Lu * gcc.dg/ia64-sync-4.c: New test. diff --git a/gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C b/gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C index e1cc853..ce1efe0 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C @@ -48,3 +48,13 @@ int main () return 9; return 0; } + +// On platforms that do not have weak symbols, these static data +// members must be explicitly instantiated. The iflag and jflag data +// members should not have to be explicitly instantiated because their +// const-ness should allow the compiler to elide references to the +// actual variables. +template const bool X::cflag; +template const bool X::flag; +template const bool X::cflag; +template const bool X::flag; -- 2.7.4