From 4a314e0c77f06189ef52888d417faa7e5759c116 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 11 Jan 2000 02:28:01 +0000 Subject: [PATCH] class.c (dfs_finish_vtbls): New function. * class.c (dfs_finish_vtbls): New function. (finish_vtbls): Use it. (dump_class_hierarchy): New function. From-SVN: r31313 --- gcc/cp/ChangeLog | 4 +++ gcc/cp/class.c | 88 +++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c456698..405e80b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2000-01-10 Mark Mitchell + * class.c (dfs_finish_vtbls): New function. + (finish_vtbls): Use it. + (dump_class_hierarchy): New function. + * cp-tree.h (BINFO_PRIMARY_MARKED_P): Change definition. (BINFO_VBASE_PRIMARY_P): New macro. (BINFO_VIRTUALS): Add to documentation. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 89d6877..fe29af2 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -84,7 +84,8 @@ static void build_vtable PROTO((tree, tree)); static void prepare_fresh_vtable PROTO((tree, tree)); static void fixup_vtable_deltas1 PROTO((tree, tree)); static void fixup_vtable_deltas PROTO((tree, int, tree)); -static void finish_vtbls PROTO((tree, int, tree)); +static tree dfs_finish_vtbls PROTO((tree, void *)); +static void finish_vtbls PROTO((tree)); static void modify_vtable_entry PROTO((tree, tree, tree)); static tree get_vtable_entry_n PROTO((tree, unsigned HOST_WIDE_INT)); static void add_virtual_function PROTO((tree *, tree *, int *, tree, tree)); @@ -2228,43 +2229,44 @@ build_vtbl_initializer (binfo) return build_nt (CONSTRUCTOR, NULL_TREE, inits); } -/* finish up all new vtables. */ +/* Called from finish_vtbls via dfs_walk. */ -static void -finish_vtbls (binfo, do_self, t) +static tree +dfs_finish_vtbls (binfo, data) tree binfo; - int do_self; - tree t; + void *data ATTRIBUTE_UNUSED; { - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) + if (!BINFO_PRIMARY_MARKED_P (binfo) + && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)) + && BINFO_NEW_VTABLE_MARKED (binfo)) { - if (BINFO_NEW_VTABLE_MARKED (binfo)) - { - tree decl, context; - - decl = BINFO_VTABLE (binfo); - context = DECL_CONTEXT (decl); - DECL_CONTEXT (decl) = 0; - DECL_INITIAL (decl) = build_vtbl_initializer (binfo); - cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0); - DECL_CONTEXT (decl) = context; - } - CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); + tree decl; + tree context; + + decl = BINFO_VTABLE (binfo); + context = DECL_CONTEXT (decl); + DECL_CONTEXT (decl) = 0; + DECL_INITIAL (decl) = build_vtbl_initializer (binfo); + cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0); + DECL_CONTEXT (decl) = context; } - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - if (TREE_VIA_VIRTUAL (base_binfo)) - base_binfo = BINFO_FOR_VBASE (BINFO_TYPE (base_binfo), t); - finish_vtbls (base_binfo, is_not_base_vtable, t); - } + CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); + SET_BINFO_MARKED (binfo); + + return NULL_TREE; +} + +/* Create all the necessary vtables for T and its base classes. */ + +static void +finish_vtbls (t) + tree t; +{ + dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls, + dfs_unmarked_real_bases_queue_p, t); + dfs_walk (TYPE_BINFO (t), dfs_unmark, + dfs_marked_real_bases_queue_p, t); } /* True if we should override the given BASE_FNDECL with the given @@ -4793,7 +4795,7 @@ finish_struct_1 (t) /* Make the rtl for any new vtables we have created, and unmark the base types we marked. */ - finish_vtbls (TYPE_BINFO (t), 1, t); + finish_vtbls (t); hack_incomplete_structures (t); if (warn_overloaded_virtual) @@ -6010,3 +6012,23 @@ note_name_declared_in_class (name, decl) (tree) n->value); } } + +/* Dump the offsets of all the bases rooted at BINFO to stderr. + INDENT should be zero when called from the top level; it is + incremented recursively. */ + +void +dump_class_hierarchy (binfo, indent) + tree binfo; + int indent; +{ + int i; + + fprintf (stderr, "%*s0x%x (%s) %d\n", indent, "", + (unsigned int) binfo, + type_as_string (binfo, TS_PLAIN), + TREE_INT_CST_LOW (BINFO_OFFSET (binfo))); + + for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i) + dump_class_hierarchy (BINFO_BASETYPE (binfo, i), indent + 2); +} -- 2.7.4