diff options
author | Jason Merrill <jason@casey.cygnus.com> | 2000-03-04 00:45:24 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2000-03-03 19:45:24 -0500 |
commit | 6db201439a6635a374ec572561d961c9cf734ee2 (patch) | |
tree | 5ce9ac0c720473894250630fd62d659f1ffa7372 | |
parent | 49634cde481046798cf98c775317df99a5cade05 (diff) | |
download | gcc-6db201439a6635a374ec572561d961c9cf734ee2.zip gcc-6db201439a6635a374ec572561d961c9cf734ee2.tar.gz gcc-6db201439a6635a374ec572561d961c9cf734ee2.tar.bz2 |
decl2.c (key_method): Break out from...
* decl2.c (key_method): Break out from...
(import_export_vtable, import_export_class): ...here.
* decl.c (finish_function): Don't mess with flag_keep_inline_functions.
* decl2.c (finish_vtable_vardecl): Don't check decl_function_context.
* search.c (note_debug_info_needed, dfs_debug_mark,
dfs_debug_unmarkedp): Uncomment. Adjust for new scheme.
* decl2.c (finish_vtable_vardecl): Call note_debug_info_needed.
From-SVN: r32319
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/decl.c | 13 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 76 | ||||
-rw-r--r-- | gcc/cp/search.c | 107 |
4 files changed, 91 insertions, 117 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 26f3733..b97b555 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2000-03-03 Jason Merrill <jason@casey.cygnus.com> + + * decl2.c (key_method): Break out from... + (import_export_vtable, import_export_class): ...here. + + * decl.c (finish_function): Don't mess with flag_keep_inline_functions. + * decl2.c (finish_vtable_vardecl): Don't check decl_function_context. + + * search.c (note_debug_info_needed, dfs_debug_mark, + dfs_debug_unmarkedp): Uncomment. Adjust for new scheme. + * decl2.c (finish_vtable_vardecl): Call note_debug_info_needed. + 2000-03-03 Nathan Sidwell <nathan@codesourcery.com> * decl.c (cp_finish_decl): Remove obsolete obstack comments, fix diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8c8fc32..c3d070d 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13883,21 +13883,10 @@ finish_function (lineno, flags) { int returns_null; int returns_value; - int saved_flag_keep_inline_functions = - flag_keep_inline_functions; /* So we can tell if jump_optimize sets it to 1. */ can_reach_end = 0; - if (DECL_CONTEXT (fndecl) != NULL_TREE - && decl_function_context (fndecl)) - /* Trick rest_of_compilation into not deferring output of this - function, even if it is inline, since the rtl_obstack for - this function is the function_obstack of the enclosing - function and will be deallocated when the enclosing - function is gone. See save_tree_status. */ - flag_keep_inline_functions = 1; - /* Before we call rest_of_compilation (which will pop the CURRENT_FUNCTION), we must save these values. */ returns_null = current_function_returns_null; @@ -13934,8 +13923,6 @@ finish_function (lineno, flags) if (function_depth > 1) ggc_pop_context (); - flag_keep_inline_functions = saved_flag_keep_inline_functions; - if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl)) { /* Set DECL_EXTERNAL so that assemble_external will be called as diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index b961f26..8e66bb6 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -92,6 +92,7 @@ static int generate_ctor_and_dtor_functions_for_priority static tree prune_vars_needing_no_initialization PARAMS ((tree)); static void write_out_vars PARAMS ((tree)); static void import_export_class PARAMS ((tree)); +static tree key_method PARAMS ((tree)); extern int current_class_depth; @@ -2378,6 +2379,29 @@ maybe_make_one_only (decl) DECL_COMDAT (decl) = 1; } +/* Returns the virtual function with which the vtable for TYPE is + emitted, or NULL_TREE if that heuristic is not applicable to TYPE. */ + +static tree +key_method (type) + tree type; +{ + tree method; + + if (TYPE_FOR_JAVA (type) + || CLASSTYPE_INTERFACE_KNOWN (type)) + return NULL_TREE; + + for (method = TYPE_METHODS (type); method != NULL_TREE; + method = TREE_CHAIN (method)) + if (DECL_VINDEX (method) != NULL_TREE + && ! DECL_THIS_INLINE (method) + && ! DECL_PURE_VIRTUAL_P (method)) + return method; + + return NULL_TREE; +} + /* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL, based on TYPE and other static flags. @@ -2409,21 +2433,8 @@ import_export_vtable (decl, type, final) /* We can only wait to decide if we have real non-inline virtual functions in our class, or if we come from a template. */ - int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type); - - if (! found && ! final) - { - tree method; - for (method = TYPE_METHODS (type); method != NULL_TREE; - method = TREE_CHAIN (method)) - if (DECL_VINDEX (method) != NULL_TREE - && ! DECL_THIS_INLINE (method) - && ! DECL_PURE_VIRTUAL_P (method)) - { - found = 1; - break; - } - } + int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type) + || key_method (type)); if (final || ! found) { @@ -2482,23 +2493,14 @@ import_export_class (ctype) import_export = -1; /* Base our import/export status on that of the first non-inline, - non-abstract virtual function, if any. */ + non-pure virtual function, if any. */ if (import_export == 0 && TYPE_POLYMORPHIC_P (ctype) && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)) { - tree method; - for (method = TYPE_METHODS (ctype); method != NULL_TREE; - method = TREE_CHAIN (method)) - { - if (DECL_VINDEX (method) != NULL_TREE - && !DECL_THIS_INLINE (method) - && !DECL_PURE_VIRTUAL_P (method)) - { - import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1); - break; - } - } + tree method = key_method (ctype); + if (method) + import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1); } #ifdef MULTIPLE_SYMBOL_SPACES @@ -2552,8 +2554,7 @@ finish_vtable_vardecl (t, data) import_export_vtable (vars, ctype, 1); if (! DECL_EXTERNAL (vars) - && (DECL_NEEDED_P (vars) - || (decl_function_context (vars) && TREE_USED (vars))) + && DECL_NEEDED_P (vars) && ! TREE_ASM_WRITTEN (vars)) { if (TREE_TYPE (vars) == void_type_node) @@ -2607,17 +2608,16 @@ finish_vtable_vardecl (t, data) /* Since we're writing out the vtable here, also write the debug info. */ - if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (ctype))) - { - TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (ctype)) = 0; - rest_of_type_compilation (ctype, toplevel_bindings_p ()); - } + note_debug_info_needed (ctype); return 1; } - else if (!DECL_NEEDED_P (vars)) - /* We don't know what to do with this one yet. */ - return 0; + + /* If the references to this class' vtables were optimized away, still + emit the appropriate debugging information. See dfs_debug_mark. */ + if (DECL_COMDAT (vars) + && CLASSTYPE_DEBUG_REQUESTED (ctype)) + note_debug_info_needed (ctype); return 0; } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index bc0ab26..9f8f5de 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2571,15 +2571,6 @@ unmarked_pushdecls_p (binfo, data) #if 0 static int dfs_search_slot_nonempty_p (binfo) tree binfo; { return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; } - -static tree -dfs_debug_unmarkedp (binfo, data) - tree binfo; - void *data ATTRIBUTE_UNUSED; -{ - return (!CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) - ? binfo : NULL_TREE); -} #endif /* The worker functions for `dfs_walk'. These do not need to @@ -2639,36 +2630,6 @@ dfs_unmark_new_vtable (binfo) tree binfo; static void dfs_clear_search_slot (binfo) tree binfo; { CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; } - -/* Keep this code around in case we later want to control debug info - based on whether a type is "used". Currently, we only suppress debug - info if we can emit it with the vtable. jason 1999-11-11) */ -static tree -dfs_debug_mark (binfo, data) - tree binfo; - void *data ATTRIBUTE_UNUSED; -{ - tree t = BINFO_TYPE (binfo); - - CLASSTYPE_DEBUG_REQUESTED (t) = 1; - - /* If interface info is known, either we've already emitted the debug - info or we don't need to. */ - if (CLASSTYPE_INTERFACE_KNOWN (t)) - return NULL_TREE; - - /* If the class has virtual functions, we'll emit the debug info - with the vtable. */ - if (TYPE_POLYMORPHIC_P (t)) - return NULL_TREE; - - /* We cannot rely on some alien method to solve our problems, - so we must write out the debug info ourselves. */ - TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0; - rest_of_type_compilation (t, toplevel_bindings_p ()); - - return NULL_TREE; -} #endif struct vbase_info @@ -3254,44 +3215,58 @@ maybe_suppress_debug_info (t) /* Otherwise, just emit the debug info normally. */ } -#if 0 -/* Keep this code around in case we later want to control debug info - based on whether a type is "used". Currently, we only suppress debug - info if we can emit it with the vtable. jason 1999-11-11) */ +/* Note that we want debugging information for a base class of a class + whose vtable is being emitted. Normally, this would happen because + calling the constructor for a derived class implies calling the + constructors for all bases, which involve initializing the + appropriate vptr with the vtable for the base class; but in the + presence of optimization, this initialization may be optimized + away, so we tell finish_vtable_vardecl that we want the debugging + information anyway. */ + +static tree +dfs_debug_mark (binfo, data) + tree binfo; + void *data ATTRIBUTE_UNUSED; +{ + tree t = BINFO_TYPE (binfo); + + CLASSTYPE_DEBUG_REQUESTED (t) = 1; + + return NULL_TREE; +} + +/* Returns BINFO if we haven't already noted that we want debugging + info for this base class. */ + +static tree +dfs_debug_unmarkedp (binfo, data) + tree binfo; + void *data ATTRIBUTE_UNUSED; +{ + return (!CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) + ? binfo : NULL_TREE); +} -/* If we want debug info for a type TYPE, make sure all its base types - are also marked as being potentially interesting. This avoids - the problem of not writing any debug info for intermediate basetypes - that have abstract virtual functions. Also mark member types. */ +/* Write out the debugging information for TYPE, whose vtable is being + emitted. Also walk through our bases and note that we want to + write out information for them. This avoids the problem of not + writing any debug info for intermediate basetypes whose + constructors, and thus the references to their vtables, and thus + the vtables themselves, were optimized away. */ void note_debug_info_needed (type) tree type; { - tree field; - - if (current_template_parms) - return; - - if (TYPE_BEING_DEFINED (type)) - /* We can't go looking for the base types and fields just yet. */ + if (! TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type))) return; - /* See the comment in maybe_suppress_debug_info. */ - if (write_symbols == DWARF_DEBUG || write_symbols == NO_DEBUG) - return; + TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)) = 0; + rest_of_type_compilation (type, toplevel_bindings_p ()); dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp, 0); - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) - { - tree ttype; - if (TREE_CODE (field) == FIELD_DECL - && IS_AGGR_TYPE (ttype = target_type (TREE_TYPE (field))) - && dfs_debug_unmarkedp (TYPE_BINFO (ttype), 0)) - note_debug_info_needed (ttype); - } } -#endif /* Subroutines of push_class_decls (). */ |