From d569399b271087152bb6f25e3625f4407dc11153 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 11 Jan 2000 02:43:00 +0000 Subject: [PATCH] cp-tree.h (expand_direct_vtbls_init): Remove declaration. * cp-tree.h (expand_direct_vtbls_init): Remove declaration. (initialize_vtbl_ptrs): New function. (expand_indirect_vtbls_init): Change prototype. (convert_pointer_to_vbase): Declare. * init.c (expand_direct_vtbls_init): Remove. (dfs_initialize_vtbl_ptrs): New function. (initialize_vtbl_ptrs): Likewise. (emit_base_init): Use initialize_vtbl_ptrs. * search.c (convert_pointer_to_vbase): Make it global. (expand_indirect_vtbls_init): Remove vtable initialization code. * semantics.c (setup_vtbl_ptr): Use initialize_vtbl_ptrs. From-SVN: r31314 --- gcc/cp/ChangeLog | 12 ++++++ gcc/cp/cp-tree.h | 5 ++- gcc/cp/init.c | 99 +++++++++++++++++++++------------------------- gcc/cp/search.c | 29 +++----------- gcc/cp/semantics.c | 10 ++--- 5 files changed, 68 insertions(+), 87 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 405e80b7715..5d38a576847 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,17 @@ 2000-01-10 Mark Mitchell + * cp-tree.h (expand_direct_vtbls_init): Remove declaration. + (initialize_vtbl_ptrs): New function. + (expand_indirect_vtbls_init): Change prototype. + (convert_pointer_to_vbase): Declare. + * init.c (expand_direct_vtbls_init): Remove. + (dfs_initialize_vtbl_ptrs): New function. + (initialize_vtbl_ptrs): Likewise. + (emit_base_init): Use initialize_vtbl_ptrs. + * search.c (convert_pointer_to_vbase): Make it global. + (expand_indirect_vtbls_init): Remove vtable initialization code. + * semantics.c (setup_vtbl_ptr): Use initialize_vtbl_ptrs. + * class.c (dfs_finish_vtbls): New function. (finish_vtbls): Use it. (dump_class_hierarchy): New function. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 269c398166a..beaa4168338 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3734,7 +3734,6 @@ extern tree do_friend PROTO((tree, tree, tree, tree, tree, enum overload_flag /* in init.c */ extern void init_init_processing PROTO((void)); -extern void expand_direct_vtbls_init PROTO((tree, tree, int, int, tree)); extern tree emit_base_init PROTO((tree)); extern void check_base_init PROTO((tree)); extern void expand_member_init PROTO((tree, tree, tree)); @@ -3757,6 +3756,7 @@ extern tree build_vec_delete PROTO((tree, tree, tree, int)); extern tree create_temporary_var PROTO((tree)); extern void begin_init_stmts PROTO((tree *, tree *)); extern tree finish_init_stmts PROTO((tree, tree)); +extern void initialize_vtbl_ptrs PROTO((tree, tree)); /* in input.c */ @@ -3926,7 +3926,7 @@ extern tree lookup_nested_tag PROTO((tree, tree)); extern tree get_matching_virtual PROTO((tree, tree, int)); extern void get_pure_virtuals PROTO((tree)); extern tree init_vbase_pointers PROTO((tree, tree)); -extern void expand_indirect_vtbls_init PROTO((tree, tree, tree)); +extern void expand_indirect_vtbls_init PROTO((tree, tree)); extern void clear_search_slots PROTO((tree)); extern void get_vbase_types PROTO((tree)); extern void maybe_suppress_debug_info PROTO((tree)); @@ -3955,6 +3955,7 @@ extern tree dfs_skip_nonprimary_vbases_markedp PROTO((tree, void *)); extern tree dfs_unmarked_real_bases_queue_p PROTO((tree, void *)); extern tree dfs_marked_real_bases_queue_p PROTO((tree, void *)); extern void mark_primary_bases PROTO((tree)); +extern tree convert_pointer_to_vbase PROTO((tree, tree)); /* in semantics.c */ extern void finish_expr_stmt PROTO((tree)); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 893ee545688..ed2a3d70a16 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1,5 +1,5 @@ /* Handle initialization things in C++. - Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc. + Copyright (C) 1987, 89, 92-98, 1999, 2000 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -48,6 +48,7 @@ static tree initializing_context PROTO((tree)); static tree build_java_class_ref PROTO((tree)); static void expand_cleanup_for_base PROTO((tree, tree)); static tree get_temp_regvar PROTO((tree, tree)); +static tree dfs_initialize_vtbl_ptrs PROTO((tree, void *)); /* Set up local variable for this file. MUST BE CALLED AFTER INIT_DECL_PROCESSING. */ @@ -77,59 +78,55 @@ void init_init_processing () ggc_add_tree_root (&BI_header_size, 1); } -/* Subroutine of emit_base_init. For BINFO, initialize all the - virtual function table pointers, except those that come from - virtual base classes. Initialize binfo's vtable pointer, if - INIT_SELF is true. CAN_ELIDE is true when we know that all virtual - function table pointers in all bases have been initialized already, - probably because their constructors have just be run. ADDR is the - pointer to the object whos vtables we are going to initialize. +/* Called from initialize_vtbl_ptrs via dfs_walk. */ - REAL_BINFO is usually the same as BINFO, except when addr is not of - pointer to the type of the real derived type that we want to - initialize for. This is the case when addr is a pointer to a sub - object of a complete object, and we only want to do part of the - complete object's initialization of vtable pointers. This is done - for all virtual table pointers in virtual base classes. REAL_BINFO - is used to find the BINFO_VTABLE that we initialize with. BINFO is - used for conversions of addr to subobjects. +static tree +dfs_initialize_vtbl_ptrs (binfo, data) + tree binfo; + void *data; +{ + if (!BINFO_PRIMARY_MARKED_P (binfo) + && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) + { + tree base_ptr = TREE_VALUE ((tree) data); - BINFO_TYPE (real_binfo) must be BINFO_TYPE (binfo). + if (TREE_VIA_VIRTUAL (binfo)) + base_ptr = convert_pointer_to_vbase (BINFO_TYPE (binfo), + base_ptr); + else + base_ptr + = build_vbase_path (PLUS_EXPR, + build_pointer_type (BINFO_TYPE (binfo)), + base_ptr, + binfo, + /*nonnull=*/1); - Relies upon binfo being inside TYPE_BINFO (TREE_TYPE (TREE_TYPE - (addr))). */ + expand_virtual_init (binfo, base_ptr); + } + + SET_BINFO_MARKED (binfo); + + return NULL_TREE; +} + +/* Initialize all the vtable pointers for the hierarchy dominated by + TYPE. */ void -expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr) - tree real_binfo, binfo, addr; - int init_self, can_elide; +initialize_vtbl_ptrs (type, addr) + tree type; + tree addr; { - tree real_binfos = BINFO_BASETYPES (real_binfo); - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0; + tree list = build_tree_list (type, addr); - for (i = 0; i < n_baselinks; i++) - { - tree real_base_binfo = TREE_VEC_ELT (real_binfos, i); - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo)); - if (! TREE_VIA_VIRTUAL (real_base_binfo)) - expand_direct_vtbls_init (real_base_binfo, base_binfo, - is_not_base_vtable, can_elide, addr); - } -#if 0 - /* Before turning this on, make sure it is correct. */ - if (can_elide && ! BINFO_MODIFIED (binfo)) - return; -#endif - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo))) - { - tree base_ptr = convert_pointer_to_real (binfo, addr); - expand_virtual_init (real_binfo, base_ptr); - } + dfs_walk (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, + dfs_unmarked_real_bases_queue_p, list); + dfs_walk (TYPE_BINFO (type), dfs_unmark, + dfs_marked_real_bases_queue_p, type); + if (TYPE_USES_VIRTUAL_BASECLASSES (type)) + expand_indirect_vtbls_init (TYPE_BINFO (type), addr); } + /* 348 - 351 */ /* Subroutine of emit_base_init. */ @@ -547,14 +544,8 @@ emit_base_init (t) rbase_init_list = TREE_CHAIN (rbase_init_list); } - /* Initialize all the virtual function table fields that - do come from virtual base classes. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - expand_indirect_vtbls_init (t_binfo, current_class_ref, current_class_ptr); - - /* Initialize all the virtual function table fields that - do not come from virtual base classes. */ - expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_ptr); + /* Initialize the vtable pointers for the class. */ + initialize_vtbl_ptrs (t, current_class_ptr); for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) { diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 0637376b280..335a183fc5b 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -77,7 +77,6 @@ static struct search_level *search_stack; static tree next_baselink PROTO((tree)); static tree get_vbase_1 PROTO((tree, tree, unsigned int *)); -static tree convert_pointer_to_vbase PROTO((tree, tree)); static tree lookup_field_1 PROTO((tree, tree)); static tree convert_pointer_to_single_level PROTO((tree, tree)); static int lookup_fnfields_here PROTO((tree, tree)); @@ -249,7 +248,7 @@ get_vbase (parent, binfo) EXPR is a non-null POINTER_TYPE to RECORD_TYPE. We also know that the type of what expr points to has a virtual base of type TYPE. */ -static tree +tree convert_pointer_to_vbase (type, expr) tree type; tree expr; @@ -3004,9 +3003,9 @@ fixup_all_virtual_upcast_offsets (type, decl_ptr) sub-object we are initializing. */ void -expand_indirect_vtbls_init (binfo, true_exp, decl_ptr) +expand_indirect_vtbls_init (binfo, decl_ptr) tree binfo; - tree true_exp, decl_ptr; + tree decl_ptr; { tree type = BINFO_TYPE (binfo); @@ -3025,29 +3024,11 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr) { tree vbases = CLASSTYPE_VBASECLASSES (type); struct vbase_info vi; - vi.decl_ptr = (true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) - : decl_ptr); + vi.decl_ptr = decl_ptr; vi.vbase_types = vbases; dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi); - - /* Initialized with vtables of type TYPE. */ - for (; vbases; vbases = TREE_CHAIN (vbases)) - { - tree addr; - - addr = convert_pointer_to_vbase (TREE_TYPE (vbases), vi.decl_ptr); - - /* Do all vtables from this virtual base. */ - /* This assumes that virtual bases can never serve as parent - binfos. (in the CLASSTYPE_VFIELD_PARENT sense) */ - expand_direct_vtbls_init (vbases, TYPE_BINFO (BINFO_TYPE (vbases)), - 1, 0, addr); - } - - fixup_all_virtual_upcast_offsets (type, - vi.decl_ptr); - + fixup_all_virtual_upcast_offsets (type, vi.decl_ptr); dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0); } } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index efcfc1aeaad..41928ba21ab 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3,7 +3,7 @@ building RTL. These routines are used both during actual parsing and during the instantiation of template functions. - Copyright (C) 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. Written by Mark Mitchell (mmitchell@usa.net) based on code found formerly in parse.y and pt.c. @@ -1245,7 +1245,6 @@ setup_vtbl_ptr () else if (DECL_DESTRUCTOR_P (current_function_decl) && !processing_template_decl) { - tree binfo = TYPE_BINFO (current_class_type); tree if_stmt; tree compound_stmt; int saved_cfnd; @@ -1279,11 +1278,8 @@ setup_vtbl_ptr () /* Make all virtual function table pointers in non-virtual base classes point to CURRENT_CLASS_TYPE's virtual function tables. */ - expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_ptr); - - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - expand_indirect_vtbls_init (binfo, current_class_ref, - current_class_ptr); + initialize_vtbl_ptrs (current_class_type, + current_class_ptr); finish_compound_stmt (/*has_no_scope=*/0, compound_stmt); finish_then_clause (if_stmt);