aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@casey.cygnus.com>2000-03-04 00:45:24 +0000
committerJason Merrill <jason@gcc.gnu.org>2000-03-03 19:45:24 -0500
commit6db201439a6635a374ec572561d961c9cf734ee2 (patch)
tree5ce9ac0c720473894250630fd62d659f1ffa7372
parent49634cde481046798cf98c775317df99a5cade05 (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/cp/decl.c13
-rw-r--r--gcc/cp/decl2.c76
-rw-r--r--gcc/cp/search.c107
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 (). */