From 1aa4ccd4289970165bdfe3b39de3db0f4ed75af3 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 24 Jan 2000 10:59:02 +0000 Subject: [PATCH] cp-tree.h (get_vtable_decl): Prototype new function. * cp-tree.h (get_vtable_decl): Prototype new function. * class.c (get_vtable_decl): New function. Broken out from ... (build_vtable): ... here. Use it. * decl2.c (finish_vtable_vardecl): Ignore dummy vtables created by get_vtable_decl. From-SVN: r31583 --- gcc/cp/ChangeLog | 8 ++++ gcc/cp/class.c | 113 ++++++++++++++++++++++++++++++----------------- gcc/cp/cp-tree.h | 1 + gcc/cp/decl2.c | 4 ++ 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 45029296242..c50831b139f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2000-01-24 Nathan Sidwell + + * cp-tree.h (get_vtable_decl): Prototype new function. + * class.c (get_vtable_decl): New function. Broken out from ... + (build_vtable): ... here. Use it. + * decl2.c (finish_vtable_vardecl): Ignore dummy vtables created + by get_vtable_decl. + 2000-01-24 Nathan Sidwell * cp-tree.h (CPTI_TP_DESC_TYPE, CPTI_ACCESS_MODE_TYPE, diff --git a/gcc/cp/class.c b/gcc/cp/class.c index c2d815f0292..c1423247682 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -853,57 +853,34 @@ set_rtti_entry (virtuals, offset, type) TREE_VALUE (virtuals) = fn; } -/* Build a virtual function for type TYPE. - If BINFO is non-NULL, build the vtable starting with the initial - approximation that it is the same as the one which is the head of - the association list. */ +/* Get the VAR_DECL of the vtable for TYPE. TYPE need not be polymorphic, + or even complete. If this does not exist, create it. If COMPLETE is + non-zero, then complete the definition of it -- that will render it + impossible to actually build the vtable, but is useful to get at those + which are known to exist in the runtime. */ -static void -build_vtable (binfo, type) - tree binfo, type; +tree get_vtable_decl (type, complete) + tree type; + int complete; { tree name = get_vtable_name (type); - tree virtuals, decl; - - if (binfo) + tree decl = IDENTIFIER_GLOBAL_VALUE (name); + + if (decl) { - tree offset; - - if (BINFO_NEW_VTABLE_MARKED (binfo)) - /* We have already created a vtable for this base, so there's - no need to do it again. */ - return; - - virtuals = copy_list (BINFO_VIRTUALS (binfo)); - decl = build_lang_decl (VAR_DECL, name, - TREE_TYPE (BINFO_VTABLE (binfo))); - - /* Now do rtti stuff. */ - offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE); - offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset); - set_rtti_entry (virtuals, offset, type); + my_friendly_assert (TREE_CODE (decl) == VAR_DECL + && DECL_VIRTUAL_P (decl), 20000118); + return decl; } - else - { - virtuals = NULL_TREE; - decl = build_lang_decl (VAR_DECL, name, void_type_node); - } - -#ifdef GATHER_STATISTICS - n_vtables += 1; - n_vtable_elems += list_length (virtuals); -#endif - + + decl = build_lang_decl (VAR_DECL, name, void_type_node); + /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ import_export_vtable (decl, type, 0); decl = pushdecl_top_level (decl); SET_IDENTIFIER_GLOBAL_VALUE (name, decl); - /* Initialize the association list for this type, based - on our first approximation. */ - TYPE_BINFO_VTABLE (type) = decl; - TYPE_BINFO_VIRTUALS (type) = virtuals; - + DECL_ARTIFICIAL (decl) = 1; TREE_STATIC (decl) = 1; #ifndef WRITABLE_VTABLES @@ -916,7 +893,61 @@ build_vtable (binfo, type) DECL_ALIGN (decl)); DECL_VIRTUAL_P (decl) = 1; + + if (complete) + cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0); + DECL_CONTEXT (decl) = type; + return decl; +} + +/* Build a virtual function for type TYPE. + If BINFO is non-NULL, build the vtable starting with the initial + approximation that it is the same as the one which is the head of + the association list. */ + +static void +build_vtable (binfo, type) + tree binfo, type; +{ + tree virtuals, decl; + + decl = get_vtable_decl (type, /*complete=*/0); + + if (binfo) + { + tree offset; + + if (BINFO_NEW_VTABLE_MARKED (binfo)) + /* We have already created a vtable for this base, so there's + no need to do it again. */ + return; + + virtuals = copy_list (BINFO_VIRTUALS (binfo)); + TREE_TYPE (decl) = TREE_TYPE (BINFO_VTABLE (binfo)); + DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo))); + + /* Now do rtti stuff. */ + offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE); + offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset); + set_rtti_entry (virtuals, offset, type); + } + else + { + my_friendly_assert (TREE_CODE (TREE_TYPE (decl)) == VOID_TYPE, + 20000118); + virtuals = NULL_TREE; + } + +#ifdef GATHER_STATISTICS + n_vtables += 1; + n_vtable_elems += list_length (virtuals); +#endif + + /* Initialize the association list for this type, based + on our first approximation. */ + TYPE_BINFO_VTABLE (type) = decl; + TYPE_BINFO_VIRTUALS (type) = virtuals; binfo = TYPE_BINFO (type); SET_BINFO_NEW_VTABLE_MARKED (binfo); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index dea3c55bafb..8b2a3df2475 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3492,6 +3492,7 @@ extern tree perform_implicit_conversion PROTO((tree, tree)); extern tree build_vbase_path PROTO((enum tree_code, tree, tree, tree, int)); extern tree build_vtbl_ref PROTO((tree, tree)); extern tree build_vfn_ref PROTO((tree *, tree, tree)); +extern tree get_vtable_decl PROTO((tree, int)); extern void add_method PROTO((tree, tree *, tree)); extern int currently_open_class PROTO((tree)); extern tree get_vfield_offset PROTO((tree)); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index bf0f07e07ae..51f02ecea4b 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2551,6 +2551,10 @@ finish_vtable_vardecl (t, data) || (hack_decl_function_context (vars) && TREE_USED (vars))) && ! TREE_ASM_WRITTEN (vars)) { + if (TREE_TYPE (vars) == void_type_node) + /* It is a dummy vtable made by get_vtable_decl. Ignore it. */ + return 0; + /* Write it out. */ mark_vtable_entries (vars); if (TREE_TYPE (DECL_INITIAL (vars)) == 0)