From dbbf88d1b81a71c5376fb4dbf0e952cb7834dcc7 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 20 Feb 2003 17:51:46 +0000 Subject: [PATCH] Change base class access representation. * tree.h (TREE_VIA_PUBLIC, TREE_VIA_PROTECTED, TREE_VIA_PRIVATE): Remove. (BINFO_BASEACCESSES): New binfo elt. (BINFO_BASEACCESS): New accessor. (BINFO_ELTS): Increase. (TI_ACCESS_PUBLIC, TI_ACCESS_PROTECTED, TI_ACCESS_PRIVATE): New. (access_public_node, access_protected_node, access_private_node): New global nodes. * tree.c (build_common_tree_nodes_2): Initialize access nodes. * dbxout.c (dbxout_type): Adjust. * dwarf2out.c (gen_inheritance_die): Add access parameter. (gen_member_die): Adjust. * dwarfout.c (output_inheritance_die): ARG is array of two trees. (output_type): Adjust. * tree-dump.c (dequeue_and_dump): Adjust binfo dumping. Change base class access representation. Share virtual base binfos. * cp/call.c (build_special_member_call): Remove binfo_for_vbase call. * cp/class.c (build_base_path): Likewise. (build_primary_vtable): Adjust BINFO_NEW_VTABLE_MARKED use. (build_secondary_vtable): Remove FOR_TYPE arg. Adjust. (make_new_vtable): Adjust. (force_canonical_binfo_r): Delete. (force_canonical_binfo): Delete. (mark_primary_virtual_base): Delete. (dfs_unshared_virtual_bases): Delete. (mark_primary_bases): Adjust. (maybe_warn_about_overly_private_class): Adjust. (dfs_base_derived_from): Delete. (base_derived_from): Follow the inheritance chain. (struct find_final_overrider_data): Add vpath member. (dfs_find_final_overrider): Adjust. (dfs_find_final_overrider_q, dfs_find_final_overrider_post): New. (find_final_overrider): Adjust. (update_vtable_entry_for_fn): Adjust. (modify_all_vtables): Adjust. (walk_subobject_offsets): Adjust. (layout_nonempty_base_or_field): Adjust. (layout_empty_base): Remove last parameter. Adjust. (build_base_field): Adjust. (build_base_fields): Adjust. (propagate_binfo_offsets): Remove last parameter. Adjust. (dfs_set_offset_for_unshared_vbases): Delete. (layout_virtual_bases): Adjust. (finish_struct_1): Adjust. (init_class_processing): Don't init access nodes. (dfs_get_primary_binfo): Delete. (get_primary_binfo): Adjust. (dump_class_hierarchy_r): Remove most derived arg, add IGO parameter. Adjust. (dump_class_hierarchy): Adjust. (finish_vtbls): Adjust. (get_original_base): Delete. (build_vtt_inits): Adjust. (dfs_build_secondary_vptr_vtt_inits): Adjust. (dfs_ctor_vtable_bases_queue_p): Adjust. (build_ctor_vtbl_group): Adjust. (dfs_accumulate_vtbl_inits): Adjust. (build_vtbl_initializer): Adjust. (build_vbase_offset_vtbl_entries): Adjust. (add_vcall_offset_vtbl_entries_1): Adjust. * cp/cp-tree.h (CPTI_ACCESS_*): Remove. (access_*_node): Remove. (CANONICAL_BINFO): Delete. (BINFO_UNSHARED_MARKED): Remove. (BINFO_MARKED): Set LANG_FLAG_0 directly. (SET_BINFO_MARKED, CLEAR_BINFO_MARKED): Delete. (BINFO_VTABLE_PATH_MARKED): Set LANG_FLAG_3 directly. (SET_BINFO_VTABLE_PATH_MARKED, CLEAR_BINFO_VTABLE_PATH_MARKED): Delete. (BINFO_NEW_VTABLE_MARKED): Set LANG_FLAG_4 directly. (SET_BINFO_NEW_VTABLE_MARKED): Adjust. (SET_BINFO_PUSHDECLS_MARKED, CLEAR_BINFO_PUSHDECLS_MARKED): Delete. (BINFO_DEPENDENT_BASE_P): New. (dfs_walk, dfs_walk_real): Queue function takes derived binfo and index. (markedp, unmarkedp): Adjust. (dfs_unmarked_real_bases_queue_p, dfs_marked_real_bases_queue_p, dfs_skip_vbases, marked_vtable_pathp, unmarked_vtable_pathp, find_vbase_instance, binfo_for_vbase): Delete. (copied_binfo, original_binfo): Declare. (finish_base_specifier): Add virtual_p arg. (unshare_base_binfos): Delete. (copy_base_binfos): Declare. (reverse_path): Delete. * cp/decl.c (xref_basetypes): Access and virtuality passed differently. Don't copy direct base binfos here. Call copy_base_binfos. * cp/init.c (dfs_initialize_vtbl_ptrs): Adjust. (initialize_vtbl_ptrs): Adjust. (expand_member_init): Adjust. * cp/parser.c (cp_parser_base_specifier): Adjust. * cp/pt.c (instantiate_class_template): Adjust. (get_template_base_recursive): Adjust. * cp/rtti.c (get_pseudo_ti_init): Adjust. (get_pseudo_ti_desc): Adjust. * cp/tree.c (unshare_base_binfos): Rename to ... (copy_base_binfos): ... here, reimplement. (make_binfo): Set BINFO_DEPENDENT_BASE_P. (reverse_path): Remove. * cp/typeck.c (get_delta_difference): Adjust error messages. * cp/semantics.c (finish_base_specifier): Add virtual arg, adjust. * cp/search.c (lookup_base_r): Adjust. (dynamic_cast_base_recurse): Adjust. (canonical_binfo): Remove. (dfs_canonical_queue): Remove. (dfs_assert_unmarked_p): Remove. (assert_canonical_unmarked): Remove. (shared_marked_p, shared_unmarked_p): Remove. (BINFO_ACCESS, SET_BINFO_ACCESS): Use TREE_PUBLIC & TREE_PRIVATE. (dfs_access_in_type): Adjust. (access_in_type): Adjust. (dfs_accessible_queue_p): Adjust. (dfs_accessible_p): Adjust. (is_subobject_of_p_1, is_subobject_of_p): Remove. (struct lookup_field_info): Remove from_dep_base_p field. (lookup_field_queue_p): Adjust, test BINFO_DEPENDENT_BASE_P. (lookup_field_r): Remove dependent base code. (lookup_member): Likewise. (dfs_walk, dfs_walk_real): Add access arg to queue fn. (dfs_unmarked_real_bases_queue_p): Remove. (dfs_marked_real_bases_queue_p): Remove. (dfs_skip_vbases): Remove. (dfs_get_pure_virtuals): Adjust. (markedp, unmarkedp): Adjust. (marked_vtable_pathp, unmarked_vtable_pathp): Remove. (marked_pushdecls_p, unmarked_pushdecls_p): Adjust. (dfs_unmark): Adjust. (dfs_get_vbase_types):Remove. (dfs_build_inheritance_graph_order): Remove. (get_vbase_types): Remove (dfs_find_vbase_instance): Remove. (find_vbase_instance): Remove. (dfs_debug_unmarkedp): Adjust. (dependent_base_p): Remove. (dfs_push_type_decls): Adjust. (dfs_push_decls): Adjust. (dfs_no_overlap_yet): Adjust. (copied_binfo): New function. (original_binfo): New function. (binfo_for_vbase): Remove. Change base class access representation. * java/class.c (set_super_info): Don't set TREE_VIA_PUBLIC. (add_interface_do): Likewise. From-SVN: r63172 --- gcc/ChangeLog | 152 +++++++++ gcc/cp/ChangeLog | 131 ++++++++ gcc/cp/call.c | 2 - gcc/cp/class.c | 791 +++++++++++++------------------------------- gcc/cp/cp-tree.h | 149 +++------ gcc/cp/decl.c | 246 +++++++------- gcc/cp/init.c | 27 +- gcc/cp/parser.c | 23 +- gcc/cp/pt.c | 36 +- gcc/cp/rtti.c | 16 +- gcc/cp/search.c | 797 ++++++++++++++++----------------------------- gcc/cp/semantics.c | 20 +- gcc/cp/tree.c | 129 +++++--- gcc/cp/typeck.c | 15 +- gcc/dbxout.c | 14 +- gcc/dwarf2out.c | 20 +- gcc/dwarfout.c | 24 +- gcc/java/ChangeLog | 6 + gcc/java/class.c | 2 - gcc/tree-dump.c | 39 ++- gcc/tree.h | 39 +-- 21 files changed, 1169 insertions(+), 1509 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0bdc28dd7a6..9a3464e924a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,155 @@ +2003-02-20 Nathan Sidwell + + Change base class access representation. + * tree.h (TREE_VIA_PUBLIC, TREE_VIA_PROTECTED, + TREE_VIA_PRIVATE): Remove. + (BINFO_BASEACCESSES): New binfo elt. + (BINFO_BASEACCESS): New accessor. + (BINFO_ELTS): Increase. + (TI_ACCESS_PUBLIC, TI_ACCESS_PROTECTED, TI_ACCESS_PRIVATE): New. + (access_public_node, access_protected_node, + access_private_node): New global nodes. + * tree.c (build_common_tree_nodes_2): Initialize access nodes. + * dbxout.c (dbxout_type): Adjust. + * dwarf2out.c (gen_inheritance_die): Add access parameter. + (gen_member_die): Adjust. + * dwarfout.c (output_inheritance_die): ARG is array of two trees. + (output_type): Adjust. + * tree-dump.c (dequeue_and_dump): Adjust binfo dumping. + + Change base class access representation. Share virtual base + binfos. + * cp/call.c (build_special_member_call): Remove binfo_for_vbase + call. + * cp/class.c (build_base_path): Likewise. + (build_primary_vtable): Adjust BINFO_NEW_VTABLE_MARKED use. + (build_secondary_vtable): Remove FOR_TYPE arg. Adjust. + (make_new_vtable): Adjust. + (force_canonical_binfo_r): Delete. + (force_canonical_binfo): Delete. + (mark_primary_virtual_base): Delete. + (dfs_unshared_virtual_bases): Delete. + (mark_primary_bases): Adjust. + (maybe_warn_about_overly_private_class): Adjust. + (dfs_base_derived_from): Delete. + (base_derived_from): Follow the inheritance chain. + (struct find_final_overrider_data): Add vpath member. + (dfs_find_final_overrider): Adjust. + (dfs_find_final_overrider_q, dfs_find_final_overrider_post): New. + (find_final_overrider): Adjust. + (update_vtable_entry_for_fn): Adjust. + (modify_all_vtables): Adjust. + (walk_subobject_offsets): Adjust. + (layout_nonempty_base_or_field): Adjust. + (layout_empty_base): Remove last parameter. Adjust. + (build_base_field): Adjust. + (build_base_fields): Adjust. + (propagate_binfo_offsets): Remove last parameter. Adjust. + (dfs_set_offset_for_unshared_vbases): Delete. + (layout_virtual_bases): Adjust. + (finish_struct_1): Adjust. + (init_class_processing): Don't init access nodes. + (dfs_get_primary_binfo): Delete. + (get_primary_binfo): Adjust. + (dump_class_hierarchy_r): Remove most derived arg, add IGO + parameter. Adjust. + (dump_class_hierarchy): Adjust. + (finish_vtbls): Adjust. + (get_original_base): Delete. + (build_vtt_inits): Adjust. + (dfs_build_secondary_vptr_vtt_inits): Adjust. + (dfs_ctor_vtable_bases_queue_p): Adjust. + (build_ctor_vtbl_group): Adjust. + (dfs_accumulate_vtbl_inits): Adjust. + (build_vtbl_initializer): Adjust. + (build_vbase_offset_vtbl_entries): Adjust. + (add_vcall_offset_vtbl_entries_1): Adjust. + * cp/cp-tree.h (CPTI_ACCESS_*): Remove. + (access_*_node): Remove. + (CANONICAL_BINFO): Delete. + (BINFO_UNSHARED_MARKED): Remove. + (BINFO_MARKED): Set LANG_FLAG_0 directly. + (SET_BINFO_MARKED, CLEAR_BINFO_MARKED): Delete. + (BINFO_VTABLE_PATH_MARKED): Set LANG_FLAG_3 directly. + (SET_BINFO_VTABLE_PATH_MARKED, CLEAR_BINFO_VTABLE_PATH_MARKED): + Delete. + (BINFO_NEW_VTABLE_MARKED): Set LANG_FLAG_4 directly. + (SET_BINFO_NEW_VTABLE_MARKED): Adjust. + (SET_BINFO_PUSHDECLS_MARKED, CLEAR_BINFO_PUSHDECLS_MARKED): + Delete. + (BINFO_DEPENDENT_BASE_P): New. + (dfs_walk, dfs_walk_real): Queue function takes derived binfo and + index. + (markedp, unmarkedp): Adjust. + (dfs_unmarked_real_bases_queue_p, dfs_marked_real_bases_queue_p, + dfs_skip_vbases, marked_vtable_pathp, unmarked_vtable_pathp, + find_vbase_instance, binfo_for_vbase): Delete. + (copied_binfo, original_binfo): Declare. + (finish_base_specifier): Add virtual_p arg. + (unshare_base_binfos): Delete. + (copy_base_binfos): Declare. + (reverse_path): Delete. + * cp/decl.c (xref_basetypes): Access and virtuality passed + differently. Don't copy direct base binfos here. Call + copy_base_binfos. + * cp/init.c (dfs_initialize_vtbl_ptrs): Adjust. + (initialize_vtbl_ptrs): Adjust. + (expand_member_init): Adjust. + * cp/parser.c (cp_parser_base_specifier): Adjust. + * cp/pt.c (instantiate_class_template): Adjust. + (get_template_base_recursive): Adjust. + * cp/rtti.c (get_pseudo_ti_init): Adjust. + (get_pseudo_ti_desc): Adjust. + * cp/tree.c (unshare_base_binfos): Rename to ... + (copy_base_binfos): ... here, reimplement. + (make_binfo): Set BINFO_DEPENDENT_BASE_P. + (reverse_path): Remove. + * cp/typeck.c (get_delta_difference): Adjust error messages. + * cp/semantics.c (finish_base_specifier): Add virtual arg, adjust. + * cp/search.c (lookup_base_r): Adjust. + (dynamic_cast_base_recurse): Adjust. + (canonical_binfo): Remove. + (dfs_canonical_queue): Remove. + (dfs_assert_unmarked_p): Remove. + (assert_canonical_unmarked): Remove. + (shared_marked_p, shared_unmarked_p): Remove. + (BINFO_ACCESS, SET_BINFO_ACCESS): Use TREE_PUBLIC & TREE_PRIVATE. + (dfs_access_in_type): Adjust. + (access_in_type): Adjust. + (dfs_accessible_queue_p): Adjust. + (dfs_accessible_p): Adjust. + (is_subobject_of_p_1, is_subobject_of_p): Remove. + (struct lookup_field_info): Remove from_dep_base_p field. + (lookup_field_queue_p): Adjust, test BINFO_DEPENDENT_BASE_P. + (lookup_field_r): Remove dependent base code. + (lookup_member): Likewise. + (dfs_walk, dfs_walk_real): Add access arg to queue fn. + (dfs_unmarked_real_bases_queue_p): Remove. + (dfs_marked_real_bases_queue_p): Remove. + (dfs_skip_vbases): Remove. + (dfs_get_pure_virtuals): Adjust. + (markedp, unmarkedp): Adjust. + (marked_vtable_pathp, unmarked_vtable_pathp): Remove. + (marked_pushdecls_p, unmarked_pushdecls_p): Adjust. + (dfs_unmark): Adjust. + (dfs_get_vbase_types):Remove. + (dfs_build_inheritance_graph_order): Remove. + (get_vbase_types): Remove + (dfs_find_vbase_instance): Remove. + (find_vbase_instance): Remove. + (dfs_debug_unmarkedp): Adjust. + (dependent_base_p): Remove. + (dfs_push_type_decls): Adjust. + (dfs_push_decls): Adjust. + (dfs_no_overlap_yet): Adjust. + (copied_binfo): New function. + (original_binfo): New function. + (binfo_for_vbase): Remove. + + Change base class access representation. + * java/class.c (set_super_info): Don't set TREE_VIA_PUBLIC. + (add_interface_do): Likewise. + 2003-02-20 David Edelsohn * config/rs6000/sysv4.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Define. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3006cfdd2a9..e013cf02e19 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,134 @@ +2003-02-20 Nathan Sidwell + + Change base class access representation. Share virtual base + binfos. + * cp/call.c (build_special_member_call): Remove binfo_for_vbase + call. + * cp/class.c (build_base_path): Likewise. + (build_primary_vtable): Adjust BINFO_NEW_VTABLE_MARKED use. + (build_secondary_vtable): Remove FOR_TYPE arg. Adjust. + (make_new_vtable): Adjust. + (force_canonical_binfo_r): Delete. + (force_canonical_binfo): Delete. + (mark_primary_virtual_base): Delete. + (dfs_unshared_virtual_bases): Delete. + (mark_primary_bases): Adjust. + (maybe_warn_about_overly_private_class): Adjust. + (dfs_base_derived_from): Delete. + (base_derived_from): Follow the inheritance chain. + (struct find_final_overrider_data): Add vpath member. + (dfs_find_final_overrider): Adjust. + (dfs_find_final_overrider_q, dfs_find_final_overrider_post): New. + (find_final_overrider): Adjust. + (update_vtable_entry_for_fn): Adjust. + (modify_all_vtables): Adjust. + (walk_subobject_offsets): Adjust. + (layout_nonempty_base_or_field): Adjust. + (layout_empty_base): Remove last parameter. Adjust. + (build_base_field): Adjust. + (build_base_fields): Adjust. + (propagate_binfo_offsets): Remove last parameter. Adjust. + (dfs_set_offset_for_unshared_vbases): Delete. + (layout_virtual_bases): Adjust. + (finish_struct_1): Adjust. + (init_class_processing): Don't init access nodes. + (dfs_get_primary_binfo): Delete. + (get_primary_binfo): Adjust. + (dump_class_hierarchy_r): Remove most derived arg, add IGO + parameter. Adjust. + (dump_class_hierarchy): Adjust. + (finish_vtbls): Adjust. + (get_original_base): Delete. + (build_vtt_inits): Adjust. + (dfs_build_secondary_vptr_vtt_inits): Adjust. + (dfs_ctor_vtable_bases_queue_p): Adjust. + (build_ctor_vtbl_group): Adjust. + (dfs_accumulate_vtbl_inits): Adjust. + (build_vtbl_initializer): Adjust. + (build_vbase_offset_vtbl_entries): Adjust. + (add_vcall_offset_vtbl_entries_1): Adjust. + * cp/cp-tree.h (CPTI_ACCESS_*): Remove. + (access_*_node): Remove. + (CANONICAL_BINFO): Delete. + (BINFO_UNSHARED_MARKED): Remove. + (BINFO_MARKED): Set LANG_FLAG_0 directly. + (SET_BINFO_MARKED, CLEAR_BINFO_MARKED): Delete. + (BINFO_VTABLE_PATH_MARKED): Set LANG_FLAG_3 directly. + (SET_BINFO_VTABLE_PATH_MARKED, CLEAR_BINFO_VTABLE_PATH_MARKED): + Delete. + (BINFO_NEW_VTABLE_MARKED): Set LANG_FLAG_4 directly. + (SET_BINFO_NEW_VTABLE_MARKED): Adjust. + (SET_BINFO_PUSHDECLS_MARKED, CLEAR_BINFO_PUSHDECLS_MARKED): + Delete. + (BINFO_DEPENDENT_BASE_P): New. + (dfs_walk, dfs_walk_real): Queue function takes derived binfo and + index. + (markedp, unmarkedp): Adjust. + (dfs_unmarked_real_bases_queue_p, dfs_marked_real_bases_queue_p, + dfs_skip_vbases, marked_vtable_pathp, unmarked_vtable_pathp, + find_vbase_instance, binfo_for_vbase): Delete. + (copied_binfo, original_binfo): Declare. + (finish_base_specifier): Add virtual_p arg. + (unshare_base_binfos): Delete. + (copy_base_binfos): Declare. + (reverse_path): Delete. + * cp/decl.c (xref_basetypes): Access and virtuality passed + differently. Don't copy direct base binfos here. Call + copy_base_binfos. + * cp/init.c (dfs_initialize_vtbl_ptrs): Adjust. + (initialize_vtbl_ptrs): Adjust. + (expand_member_init): Adjust. + * cp/parser.c (cp_parser_base_specifier): Adjust. + * cp/pt.c (instantiate_class_template): Adjust. + (get_template_base_recursive): Adjust. + * cp/rtti.c (get_pseudo_ti_init): Adjust. + (get_pseudo_ti_desc): Adjust. + * cp/tree.c (unshare_base_binfos): Rename to ... + (copy_base_binfos): ... here, reimplement. + (make_binfo): Set BINFO_DEPENDENT_BASE_P. + (reverse_path): Remove. + * cp/typeck.c (get_delta_difference): Adjust error messages. + * cp/semantics.c (finish_base_specifier): Add virtual arg, adjust. + * cp/search.c (lookup_base_r): Adjust. + (dynamic_cast_base_recurse): Adjust. + (canonical_binfo): Remove. + (dfs_canonical_queue): Remove. + (dfs_assert_unmarked_p): Remove. + (assert_canonical_unmarked): Remove. + (shared_marked_p, shared_unmarked_p): Remove. + (BINFO_ACCESS, SET_BINFO_ACCESS): Use TREE_PUBLIC & TREE_PRIVATE. + (dfs_access_in_type): Adjust. + (access_in_type): Adjust. + (dfs_accessible_queue_p): Adjust. + (dfs_accessible_p): Adjust. + (is_subobject_of_p_1, is_subobject_of_p): Remove. + (struct lookup_field_info): Remove from_dep_base_p field. + (lookup_field_queue_p): Adjust, test BINFO_DEPENDENT_BASE_P. + (lookup_field_r): Remove dependent base code. + (lookup_member): Likewise. + (dfs_walk, dfs_walk_real): Add access arg to queue fn. + (dfs_unmarked_real_bases_queue_p): Remove. + (dfs_marked_real_bases_queue_p): Remove. + (dfs_skip_vbases): Remove. + (dfs_get_pure_virtuals): Adjust. + (markedp, unmarkedp): Adjust. + (marked_vtable_pathp, unmarked_vtable_pathp): Remove. + (marked_pushdecls_p, unmarked_pushdecls_p): Adjust. + (dfs_unmark): Adjust. + (dfs_get_vbase_types):Remove. + (dfs_build_inheritance_graph_order): Remove. + (get_vbase_types): Remove + (dfs_find_vbase_instance): Remove. + (find_vbase_instance): Remove. + (dfs_debug_unmarkedp): Adjust. + (dependent_base_p): Remove. + (dfs_push_type_decls): Adjust. + (dfs_push_decls): Adjust. + (dfs_no_overlap_yet): Adjust. + (copied_binfo): New function. + (original_binfo): New function. + (binfo_for_vbase): Remove. + 2003-02-18 Zack Weinberg * cp/search.c (grow_bfs_bases): New subroutine of bfs_walk. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0aa2d5360a5..98b60a10a53 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4653,8 +4653,6 @@ build_special_member_call (tree instance, tree name, tree args, current_in_charge_parm, integer_zero_node), current_vtt_parm, vtt); - if (TREE_VIA_VIRTUAL (binfo)) - binfo = binfo_for_vbase (class_type, current_class_type); my_friendly_assert (BINFO_SUBVTT_INDEX (binfo), 20010110); sub_vtt = build (PLUS_EXPR, TREE_TYPE (vtt), vtt, BINFO_SUBVTT_INDEX (binfo)); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 5ee67bca780..89c11e653a0 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -110,7 +110,7 @@ static void finish_struct_anon (tree); static tree get_vtable_name (tree); static tree get_basefndecls (tree, tree); static int build_primary_vtable (tree, tree); -static int build_secondary_vtable (tree, tree); +static int build_secondary_vtable (tree); static void finish_vtbls (tree); static void modify_vtable_entry (tree, tree, tree, tree, tree *); static tree delete_duplicate_fields_1 (tree, tree); @@ -152,9 +152,8 @@ static void layout_class_type (tree, tree *); static void fixup_pending_inline (tree); static void fixup_inline_methods (tree); static void set_primary_base (tree, tree); -static void propagate_binfo_offsets (tree, tree, tree); +static void propagate_binfo_offsets (tree, tree); static void layout_virtual_bases (record_layout_info, splay_tree); -static tree dfs_set_offset_for_unshared_vbases (tree, void *); static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *); static void add_vcall_offset_vtbl_entries_r (tree, vtbl_init_data *); static void add_vcall_offset_vtbl_entries_1 (tree, vtbl_init_data *); @@ -162,10 +161,12 @@ static void build_vcall_offset_vtbl_entries (tree, vtbl_init_data *); static void add_vcall_offset (tree, tree, vtbl_init_data *); static void layout_vtable_decl (tree, int); static tree dfs_find_final_overrider (tree, void *); +static tree dfs_find_final_overrider_post (tree, void *); +static tree dfs_find_final_overrider_q (tree, int, void *); static tree find_final_overrider (tree, tree, tree); static int make_new_vtable (tree, tree); static int maybe_indent_hierarchy (FILE *, int, int); -static void dump_class_hierarchy_r (FILE *, int, tree, tree, int); +static tree dump_class_hierarchy_r (FILE *, int, tree, tree, int); static void dump_class_hierarchy (tree); static void dump_array (FILE *, tree); static void dump_vtable (tree, tree, tree); @@ -176,18 +177,14 @@ static void initialize_array (tree, tree); static void layout_nonempty_base_or_field (record_layout_info, tree, tree, splay_tree); static tree end_of_class (tree, int); -static bool layout_empty_base (tree, tree, splay_tree, tree); +static bool layout_empty_base (tree, tree, splay_tree); static void accumulate_vtbl_inits (tree, tree, tree, tree, tree); static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree); static void build_rtti_vtbl_entries (tree, vtbl_init_data *); static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *); -static void force_canonical_binfo_r (tree, tree, tree, tree); -static void force_canonical_binfo (tree, tree, tree, tree); -static tree dfs_unshared_virtual_bases (tree, void *); static void mark_primary_bases (tree); -static tree mark_primary_virtual_base (tree, tree); static void clone_constructors_and_destructors (tree); static tree build_clone (tree, tree); static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned); @@ -197,10 +194,8 @@ static void build_vtt (tree); static tree binfo_ctor_vtable (tree); static tree *build_vtt_inits (tree, tree, tree *, tree *); static tree dfs_build_secondary_vptr_vtt_inits (tree, void *); -static tree dfs_ctor_vtable_bases_queue_p (tree, void *data); +static tree dfs_ctor_vtable_bases_queue_p (tree, int, void *data); static tree dfs_fixup_binfo_vtbls (tree, void *); -static tree get_original_base (tree, tree); -static tree dfs_get_primary_binfo (tree, void*); static int record_subobject_offset (tree, tree, splay_tree); static int check_subobject_offset (tree, tree, splay_tree); static int walk_subobject_offsets (tree, subobject_offset_fn, @@ -212,7 +207,6 @@ static int splay_tree_compare_integer_csts (splay_tree_key k1, static void warn_about_ambiguous_bases (tree); static bool type_requires_array_cookie (tree); static bool contains_empty_class_p (tree); -static tree dfs_base_derived_from (tree, void *); static bool base_derived_from (tree, tree); static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree); static tree end_of_base (tree); @@ -311,8 +305,6 @@ build_base_path (enum tree_code code, tree v_offset = build_vfield_ref (build_indirect_ref (expr, NULL), TREE_TYPE (TREE_TYPE (expr))); - v_binfo = binfo_for_vbase (BINFO_TYPE (v_binfo), BINFO_TYPE (d_binfo)); - v_offset = build (PLUS_EXPR, TREE_TYPE (v_offset), v_offset, BINFO_VPTR_FIELD (v_binfo)); v_offset = build1 (NOP_EXPR, @@ -443,10 +435,8 @@ build_vtbl_ref_1 (tree instance, tree idx) } if (!vtbl) - { - vtbl = build_vfield_ref (instance, basetype); - } - + vtbl = build_vfield_ref (instance, basetype); + assemble_external (vtbl); aref = build_array_ref (vtbl, idx); @@ -592,7 +582,7 @@ build_primary_vtable (tree binfo, tree type) if (binfo) { - if (BINFO_NEW_VTABLE_MARKED (binfo, type)) + 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 0; @@ -618,7 +608,7 @@ build_primary_vtable (tree binfo, tree type) on our first approximation. */ TYPE_BINFO_VTABLE (type) = decl; TYPE_BINFO_VIRTUALS (type) = virtuals; - SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type), type); + SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type)); return 1; } @@ -637,18 +627,16 @@ build_primary_vtable (tree binfo, tree type) can result. */ static int -build_secondary_vtable (tree binfo, tree for_type) +build_secondary_vtable (tree binfo) { - my_friendly_assert (binfo == CANONICAL_BINFO (binfo, for_type), 20010605); - - if (BINFO_NEW_VTABLE_MARKED (binfo, for_type)) + if (BINFO_NEW_VTABLE_MARKED (binfo)) /* We already created a vtable for this base. There's no need to do it again. */ return 0; /* Remember that we've created a vtable for this BINFO, so that we don't try to do so again. */ - SET_BINFO_NEW_VTABLE_MARKED (binfo, for_type); + SET_BINFO_NEW_VTABLE_MARKED (binfo); /* Make fresh virtual list, so we can smash it later. */ BINFO_VIRTUALS (binfo) = copy_virtuals (binfo); @@ -678,7 +666,7 @@ make_new_vtable (tree t, tree binfo) we will fill in all the virtual functions that override the virtual functions in these base classes which are not defined by the current type. */ - return build_secondary_vtable (binfo, t); + return build_secondary_vtable (binfo); } /* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO @@ -692,7 +680,7 @@ modify_vtable_entry (tree t, tree binfo, tree fndecl, tree delta, - tree* virtuals) + tree *virtuals) { tree v; @@ -1296,170 +1284,6 @@ check_bases (tree t, } } -/* Binfo FROM is within a virtual hierarchy which is being reseated to - TO. Move primary information from FROM to TO, and recursively traverse - into FROM's bases. The hierarchy is dominated by TYPE. MAPPINGS is an - assoc list of binfos that have already been reseated. */ - -static void -force_canonical_binfo_r (tree to, tree from, tree type, tree mappings) -{ - int i, n_baseclasses = BINFO_N_BASETYPES (from); - - my_friendly_assert (to != from, 20010905); - BINFO_INDIRECT_PRIMARY_P (to) - = BINFO_INDIRECT_PRIMARY_P (from); - BINFO_INDIRECT_PRIMARY_P (from) = 0; - BINFO_UNSHARED_MARKED (to) = BINFO_UNSHARED_MARKED (from); - BINFO_UNSHARED_MARKED (from) = 0; - BINFO_LOST_PRIMARY_P (to) = BINFO_LOST_PRIMARY_P (from); - BINFO_LOST_PRIMARY_P (from) = 0; - if (BINFO_PRIMARY_P (from)) - { - tree primary = BINFO_PRIMARY_BASE_OF (from); - tree assoc; - - /* We might have just moved the primary base too, see if it's on our - mappings. */ - assoc = purpose_member (primary, mappings); - if (assoc) - primary = TREE_VALUE (assoc); - BINFO_PRIMARY_BASE_OF (to) = primary; - BINFO_PRIMARY_BASE_OF (from) = NULL_TREE; - } - my_friendly_assert (same_type_p (BINFO_TYPE (to), BINFO_TYPE (from)), - 20010104); - mappings = tree_cons (from, to, mappings); - - if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (from)) - && TREE_VIA_VIRTUAL (CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (from)))) - { - tree from_primary = get_primary_binfo (from); - - if (BINFO_PRIMARY_BASE_OF (from_primary) == from) - force_canonical_binfo (get_primary_binfo (to), from_primary, - type, mappings); - } - - for (i = 0; i != n_baseclasses; i++) - { - tree from_binfo = BINFO_BASETYPE (from, i); - tree to_binfo = BINFO_BASETYPE (to, i); - - if (TREE_VIA_VIRTUAL (from_binfo)) - { - if (BINFO_PRIMARY_P (from_binfo) && - purpose_member (BINFO_PRIMARY_BASE_OF (from_binfo), mappings)) - /* This base is a primary of some binfo we have already - reseated. We must reseat this one too. */ - force_canonical_binfo (to_binfo, from_binfo, type, mappings); - } - else - force_canonical_binfo_r (to_binfo, from_binfo, type, mappings); - } -} - -/* FROM is the canonical binfo for a virtual base. It is being reseated to - make TO the canonical binfo, within the hierarchy dominated by TYPE. - MAPPINGS is an assoc list of binfos that have already been reseated. - Adjust any non-virtual bases within FROM, and also move any virtual bases - which are canonical. This complication arises because selecting primary - bases walks in inheritance graph order, but we don't share binfos for - virtual bases, hence we can fill in the primaries for a virtual base, - and then discover that a later base requires the virtual as its - primary. */ - -static void -force_canonical_binfo (tree to, tree from, tree type, tree mappings) -{ - tree assoc = purpose_member (BINFO_TYPE (to), - CLASSTYPE_VBASECLASSES (type)); - if (TREE_VALUE (assoc) != to) - { - TREE_VALUE (assoc) = to; - force_canonical_binfo_r (to, from, type, mappings); - } -} - -/* Make BASE_BINFO the a primary virtual base within the hierarchy - dominated by TYPE. Returns BASE_BINFO, if it is not already one, NULL - otherwise (because something else has already made it primary). */ - -static tree -mark_primary_virtual_base (tree base_binfo, tree type) -{ - tree shared_binfo = binfo_for_vbase (BINFO_TYPE (base_binfo), type); - - if (BINFO_PRIMARY_P (shared_binfo)) - { - /* It's already allocated in the hierarchy. BINFO won't have a - primary base in this hierarchy, even though the complete object - BINFO is for, would do. */ - return NULL_TREE; - } - - /* We need to make sure that the assoc list - CLASSTYPE_VBASECLASSES of TYPE, indicates this particular - primary BINFO for the virtual base, as this is the one - that'll really exist. */ - if (base_binfo != shared_binfo) - force_canonical_binfo (base_binfo, shared_binfo, type, NULL); - - return base_binfo; -} - -/* If BINFO is an unmarked virtual binfo for a class with a primary virtual - base, then BINFO has no primary base in this graph. Called from - mark_primary_bases. DATA is the most derived type. */ - -static tree -dfs_unshared_virtual_bases (tree binfo, void* data) -{ - tree t = (tree) data; - - if (!BINFO_UNSHARED_MARKED (binfo) - && CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) - { - /* This morally virtual base has a primary base when it - is a complete object. We need to locate the shared instance - of this binfo in the type dominated by T. We duplicate the - primary base information from there to here. */ - tree vbase; - tree unshared_base; - - for (vbase = binfo; !TREE_VIA_VIRTUAL (vbase); - vbase = BINFO_INHERITANCE_CHAIN (vbase)) - continue; - unshared_base = get_original_base (binfo, - binfo_for_vbase (BINFO_TYPE (vbase), - t)); - my_friendly_assert (unshared_base != binfo, 20010612); - BINFO_LOST_PRIMARY_P (binfo) = BINFO_LOST_PRIMARY_P (unshared_base); - if (!BINFO_LOST_PRIMARY_P (binfo)) - BINFO_PRIMARY_BASE_OF (get_primary_binfo (binfo)) = binfo; - } - - if (binfo != TYPE_BINFO (t)) - /* The vtable fields will have been copied when duplicating the - base binfos. That information is bogus, make sure we don't try - and use it. */ - BINFO_VTABLE (binfo) = NULL_TREE; - - /* If this is a virtual primary base, make sure its offset matches - that which it is primary for. */ - if (BINFO_PRIMARY_P (binfo) && TREE_VIA_VIRTUAL (binfo) && - binfo_for_vbase (BINFO_TYPE (binfo), t) == binfo) - { - tree delta = size_diffop (BINFO_OFFSET (BINFO_PRIMARY_BASE_OF (binfo)), - BINFO_OFFSET (binfo)); - if (!integer_zerop (delta)) - propagate_binfo_offsets (binfo, delta, t); - } - - BINFO_UNSHARED_MARKED (binfo) = 0; - return NULL; -} - /* Set BINFO_PRIMARY_BASE_OF for all binfos in the hierarchy dominated by TYPE that are primary bases. */ @@ -1471,33 +1295,29 @@ mark_primary_bases (tree type) /* Walk the bases in inheritance graph order. */ for (binfo = TYPE_BINFO (type); binfo; binfo = TREE_CHAIN (binfo)) { - tree base_binfo; - - if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) - /* Not a dynamic base. */ - continue; - - base_binfo = get_primary_binfo (binfo); - - if (TREE_VIA_VIRTUAL (base_binfo)) - base_binfo = mark_primary_virtual_base (base_binfo, type); + tree base_binfo = get_primary_binfo (binfo); - if (base_binfo) - BINFO_PRIMARY_BASE_OF (base_binfo) = binfo; - else + if (!base_binfo) + /* Not a dynamic base. */; + else if (BINFO_PRIMARY_P (base_binfo)) BINFO_LOST_PRIMARY_P (binfo) = 1; - - BINFO_UNSHARED_MARKED (binfo) = 1; + else + { + BINFO_PRIMARY_BASE_OF (base_binfo) = binfo; + /* A virtual binfo might have been copied from within + another hierarchy. As we're about to use it as a primary + base, make sure the offsets match. */ + if (TREE_VIA_VIRTUAL (base_binfo)) + { + tree delta = size_diffop (convert (ssizetype, + BINFO_OFFSET (binfo)), + convert (ssizetype, + BINFO_OFFSET (base_binfo))); + + propagate_binfo_offsets (base_binfo, delta); + } + } } - /* There could remain unshared morally virtual bases which were not - visited in the inheritance graph walk. These bases will have lost - their virtual primary base (should they have one). We must now - find them. Also we must fix up the BINFO_OFFSETs of primary - virtual bases. We could not do that as we went along, as they - were originally copied from the bases we inherited from by - unshare_base_binfos. That may have decided differently about - where a virtual primary base went. */ - dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, type); } /* Make the BINFO the primary base of T. */ @@ -1802,10 +1622,10 @@ maybe_warn_about_overly_private_class (tree t) issues error messages specifically referring to constructors/destructors.) */ int i; - tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); - for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++) - if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i)) - || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i))) + tree binfo = TYPE_BINFO (t); + + for (i = 0; i < BINFO_N_BASETYPES (binfo); i++) + if (BINFO_BASEACCESS (binfo, i) != access_private_node) { has_nonprivate_method = 1; break; @@ -2220,27 +2040,27 @@ same_signature_p (tree fndecl, tree base_fndecl) return 0; } -/* Called from base_derived_from via dfs_walk. */ - -static tree -dfs_base_derived_from (tree binfo, void *data) -{ - tree base = (tree) data; - - if (same_type_p (TREE_TYPE (base), TREE_TYPE (binfo)) - && tree_int_cst_equal (BINFO_OFFSET (base), BINFO_OFFSET (binfo))) - return error_mark_node; - - return NULL_TREE; -} - /* Returns TRUE if DERIVED is a binfo containing the binfo BASE as a subobject. */ static bool base_derived_from (tree derived, tree base) { - return dfs_walk (derived, dfs_base_derived_from, NULL, base) != NULL_TREE; + tree probe; + + for (probe = base; probe; probe = BINFO_INHERITANCE_CHAIN (probe)) + { + if (probe == derived) + return true; + else if (TREE_VIA_VIRTUAL (probe)) + /* If we meet a virtual base, we can't follow the inheritance + any more. See if the complete type of DERIVED contains + such a virtual base. */ + return purpose_member (BINFO_TYPE (probe), + CLASSTYPE_VBASECLASSES (BINFO_TYPE (derived))) + != NULL_TREE; + } + return false; } typedef struct find_final_overrider_data_s { @@ -2252,6 +2072,8 @@ typedef struct find_final_overrider_data_s { tree most_derived_type; /* The candidate overriders. */ tree candidates; + /* Binfos which inherited virtually on the currrent path. */ + tree vpath; } find_final_overrider_data; /* Called from find_final_overrider via dfs_walk. */ @@ -2261,61 +2083,82 @@ dfs_find_final_overrider (tree binfo, void* data) { find_final_overrider_data *ffod = (find_final_overrider_data *) data; - if (same_type_p (BINFO_TYPE (binfo), - BINFO_TYPE (ffod->declaring_base)) - && tree_int_cst_equal (BINFO_OFFSET (binfo), - BINFO_OFFSET (ffod->declaring_base))) - { - tree path; - tree method; - - /* We haven't found an overrider yet. */ - method = NULL_TREE; - /* We've found a path to the declaring base. Walk down the path - looking for an overrider for FN. */ - path = reverse_path (binfo); - while (!same_type_p (BINFO_TYPE (TREE_VALUE (path)), - ffod->most_derived_type)) - path = TREE_CHAIN (path); - while (path) + if (binfo == ffod->declaring_base) + { + /* We've found a path to the declaring base. Walk the path from + derived to base, looking for an overrider for FN. */ + tree path, probe, vpath; + + /* Build the path, using the inheritance chain and record of + virtual inheritance. */ + for (path = NULL_TREE, probe = binfo, vpath = ffod->vpath;;) { - method = look_for_overrides_here (BINFO_TYPE (TREE_VALUE (path)), - ffod->fn); + path = tree_cons (NULL_TREE, probe, path); + if (same_type_p (BINFO_TYPE (probe), ffod->most_derived_type)) + break; + if (TREE_VIA_VIRTUAL (probe)) + { + probe = TREE_VALUE (vpath); + vpath = TREE_CHAIN (vpath); + } + else + probe = BINFO_INHERITANCE_CHAIN (probe); + } + /* Now walk path, looking for overrides. */ + for (; path; path = TREE_CHAIN (path)) + { + tree method = look_for_overrides_here + (BINFO_TYPE (TREE_VALUE (path)), ffod->fn); + if (method) { + tree *candidate = &ffod->candidates; path = TREE_VALUE (path); + + /* Remove any candidates overridden by this new function. */ + while (*candidate) + { + /* If *CANDIDATE overrides METHOD, then METHOD + cannot override anything else on the list. */ + if (base_derived_from (TREE_VALUE (*candidate), path)) + return NULL_TREE; + /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */ + if (base_derived_from (path, TREE_VALUE (*candidate))) + *candidate = TREE_CHAIN (*candidate); + else + candidate = &TREE_CHAIN (*candidate); + } + + /* Add the new function. */ + ffod->candidates = tree_cons (method, path, ffod->candidates); break; } - - path = TREE_CHAIN (path); } + } - /* If we found an overrider, record the overriding function, and - the base from which it came. */ - if (path) - { - tree *candidate; + return NULL_TREE; +} - /* Remove any candidates overridden by this new function. */ - candidate = &ffod->candidates; - while (*candidate) - { - /* If *CANDIDATE overrides METHOD, then METHOD - cannot override anything else on the list. */ - if (base_derived_from (TREE_VALUE (*candidate), path)) - return NULL_TREE; - /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */ - if (base_derived_from (path, TREE_VALUE (*candidate))) - *candidate = TREE_CHAIN (*candidate); - else - candidate = &TREE_CHAIN (*candidate); - } +static tree +dfs_find_final_overrider_q (tree derived, int ix, void *data) +{ + tree binfo = BINFO_BASETYPE (derived, ix); + find_final_overrider_data *ffod = (find_final_overrider_data *) data; - /* Add the new function. */ - ffod->candidates = tree_cons (method, path, ffod->candidates); - } - } + if (TREE_VIA_VIRTUAL (binfo)) + ffod->vpath = tree_cons (NULL_TREE, derived, ffod->vpath); + + return binfo; +} +static tree +dfs_find_final_overrider_post (tree binfo, void *data) +{ + find_final_overrider_data *ffod = (find_final_overrider_data *) data; + + if (TREE_VIA_VIRTUAL (binfo) && TREE_CHAIN (ffod->vpath)) + ffod->vpath = TREE_CHAIN (ffod->vpath); + return NULL_TREE; } @@ -2354,11 +2197,13 @@ find_final_overrider (tree derived, tree binfo, tree fn) ffod.declaring_base = binfo; ffod.most_derived_type = BINFO_TYPE (derived); ffod.candidates = NULL_TREE; + ffod.vpath = NULL_TREE; - dfs_walk (derived, - dfs_find_final_overrider, - NULL, - &ffod); + dfs_walk_real (derived, + dfs_find_final_overrider, + dfs_find_final_overrider_post, + dfs_find_final_overrider_q, + &ffod); /* If there was no winner, issue an error message. */ if (!ffod.candidates || TREE_CHAIN (ffod.candidates)) @@ -2448,9 +2293,6 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, { fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn)); virtual_offset = THUNK_VIRTUAL_OFFSET (fn); - if (virtual_offset) - virtual_offset = binfo_for_vbase (BINFO_TYPE (virtual_offset), - TREE_TYPE (over_return)); } else fixed_offset = virtual_offset = NULL_TREE; @@ -2477,11 +2319,10 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, base and adjust the fixed offset to be from there. */ while (!TREE_VIA_VIRTUAL (thunk_binfo)) thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo); - - virtual_offset = binfo_for_vbase (BINFO_TYPE (thunk_binfo), - TREE_TYPE (over_return)); + + virtual_offset = thunk_binfo; offset = size_binop (MINUS_EXPR, offset, - BINFO_OFFSET (virtual_offset)); + BINFO_OFFSET (virtual_offset)); } if (fixed_offset) /* There was an existing fixed offset, this must be @@ -2520,8 +2361,11 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, /* If we find a virtual base, and we haven't yet found the overrider, then there is a virtual base between the declaring base (first_defn) and the final overrider. */ - if (!virtual_base && TREE_VIA_VIRTUAL (b)) - virtual_base = b; + if (TREE_VIA_VIRTUAL (b)) + { + virtual_base = b; + break; + } } if (overrider_fn != overrider_target && !virtual_base) @@ -2619,7 +2463,7 @@ dfs_modify_vtables (tree binfo, void* data) &virtuals, ix); } - SET_BINFO_MARKED (binfo); + BINFO_MARKED (binfo) = 1; return NULL_TREE; } @@ -2640,11 +2484,8 @@ modify_all_vtables (tree t, tree virtuals) tree *fnsp; /* Update all of the vtables. */ - dfs_walk (binfo, - dfs_modify_vtables, - dfs_unmarked_real_bases_queue_p, - t); - dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t); + dfs_walk (binfo, dfs_modify_vtables, unmarkedp, t); + dfs_walk (binfo, dfs_unmark, markedp, t); /* Add virtual functions not already in our primary vtable. These will be both those introduced by this class, and those overridden @@ -3639,22 +3480,14 @@ walk_subobject_offsets (tree type, virtual. (If it is non-virtual, then it was walked above.) */ vbase = get_primary_binfo (type_binfo); - if (vbase && TREE_VIA_VIRTUAL (vbase)) + if (vbase && TREE_VIA_VIRTUAL (vbase) + && BINFO_PRIMARY_BASE_OF (vbase) == type_binfo) { - tree derived = type_binfo; - while (BINFO_INHERITANCE_CHAIN (derived)) - derived = BINFO_INHERITANCE_CHAIN (derived); - derived = TREE_TYPE (derived); - vbase = binfo_for_vbase (TREE_TYPE (vbase), derived); - - if (BINFO_PRIMARY_BASE_OF (vbase) == type_binfo) - { - r = (walk_subobject_offsets - (vbase, f, offset, - offsets, max_offset, /*vbases_p=*/0)); - if (r) - return r; - } + r = (walk_subobject_offsets + (vbase, f, offset, + offsets, max_offset, /*vbases_p=*/0)); + if (r) + return r; } } } @@ -3774,7 +3607,6 @@ layout_nonempty_base_or_field (record_layout_info rli, tree binfo, splay_tree offsets) { - tree t = rli->t; tree offset = NULL_TREE; bool field_p; tree type; @@ -3855,8 +3687,7 @@ layout_nonempty_base_or_field (record_layout_info rli, propagate_binfo_offsets (binfo, size_diffop (convert (ssizetype, offset), convert (ssizetype, - BINFO_OFFSET (binfo))), - t); + BINFO_OFFSET (binfo)))); } /* Returns true if TYPE is empty and OFFSET is nonzero. */ @@ -3876,7 +3707,7 @@ empty_base_at_nonzero_offset_p (tree type, type. Return nonzero iff we added it at the end. */ static bool -layout_empty_base (tree binfo, tree eoc, splay_tree offsets, tree t) +layout_empty_base (tree binfo, tree eoc, splay_tree offsets) { tree alignment; tree basetype = BINFO_TYPE (binfo); @@ -3903,7 +3734,7 @@ layout_empty_base (tree binfo, tree eoc, splay_tree offsets, tree t) /* That didn't work. Now, we move forward from the next available spot in the class. */ atend = true; - propagate_binfo_offsets (binfo, convert (ssizetype, eoc), t); + propagate_binfo_offsets (binfo, convert (ssizetype, eoc)); while (1) { if (!layout_conflict_p (binfo, @@ -3914,7 +3745,7 @@ layout_empty_base (tree binfo, tree eoc, splay_tree offsets, tree t) break; /* There's overlap here, too. Bump along to the next spot. */ - propagate_binfo_offsets (binfo, alignment, t); + propagate_binfo_offsets (binfo, alignment); } } return atend; @@ -3978,7 +3809,7 @@ build_base_field (record_layout_info rli, tree binfo, byte-aligned. */ eoc = round_up (rli_size_unit_so_far (rli), CLASSTYPE_ALIGN_UNIT (basetype)); - atend = layout_empty_base (binfo, eoc, offsets, t); + atend = layout_empty_base (binfo, eoc, offsets); /* A nearly-empty class "has no proper base class that is empty, not morally virtual, and at an offset other than zero." */ if (!TREE_VIA_VIRTUAL (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t)) @@ -4057,11 +3888,9 @@ build_base_fields (record_layout_info rli, if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t)) continue; - /* A primary virtual base class is allocated just like any other - base class, but a non-primary virtual base is allocated - later, in layout_virtual_bases. */ - if (TREE_VIA_VIRTUAL (base_binfo) - && !BINFO_PRIMARY_P (base_binfo)) + /* Virtual bases are added at the end (a primary virtual base + will have already been added). */ + if (TREE_VIA_VIRTUAL (base_binfo)) continue; next_field = build_base_field (rli, base_binfo, @@ -4658,7 +4487,7 @@ fixup_inline_methods (tree type) OFFSET, which is a type offset, is number of bytes. */ static void -propagate_binfo_offsets (tree binfo, tree offset, tree t) +propagate_binfo_offsets (tree binfo, tree offset) { int i; tree primary_binfo; @@ -4699,39 +4528,13 @@ propagate_binfo_offsets (tree binfo, tree offset, tree t) /* Skip virtual bases that aren't our canonical primary base. */ if (TREE_VIA_VIRTUAL (base_binfo) - && (BINFO_PRIMARY_BASE_OF (base_binfo) != binfo - || base_binfo != binfo_for_vbase (BINFO_TYPE (base_binfo), t))) + && BINFO_PRIMARY_BASE_OF (base_binfo) != binfo) continue; - propagate_binfo_offsets (base_binfo, offset, t); + propagate_binfo_offsets (base_binfo, offset); } } -/* Called via dfs_walk from layout_virtual bases. */ - -static tree -dfs_set_offset_for_unshared_vbases (tree binfo, void* data) -{ - /* If this is a virtual base, make sure it has the same offset as - the shared copy. If it's a primary base, then we know it's - correct. */ - if (TREE_VIA_VIRTUAL (binfo)) - { - tree t = (tree) data; - tree vbase; - tree offset; - - vbase = binfo_for_vbase (BINFO_TYPE (binfo), t); - if (vbase != binfo) - { - offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo)); - propagate_binfo_offsets (binfo, offset, t); - } - } - - return NULL_TREE; -} - /* Set BINFO_OFFSET for all of the virtual bases for RLI->T. Update TYPE_ALIGN and TYPE_SIZE for T. OFFSETS gives the location of empty subobjects of T. */ @@ -4739,7 +4542,7 @@ dfs_set_offset_for_unshared_vbases (tree binfo, void* data) static void layout_virtual_bases (record_layout_info rli, splay_tree offsets) { - tree vbases; + tree vbase; tree t = rli->t; bool first_vbase = true; tree *next_field; @@ -4771,17 +4574,11 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) /* Go through the virtual bases, allocating space for each virtual base that is not already a primary base class. These are allocated in inheritance graph order. */ - for (vbases = TYPE_BINFO (t); - vbases; - vbases = TREE_CHAIN (vbases)) + for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase)) { - tree vbase; - - if (!TREE_VIA_VIRTUAL (vbases)) + if (!TREE_VIA_VIRTUAL (vbase)) continue; - vbase = binfo_for_vbase (BINFO_TYPE (vbases), t); - if (!BINFO_PRIMARY_P (vbase)) { tree basetype = TREE_TYPE (vbase); @@ -4812,13 +4609,6 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets) first_vbase = false; } } - - /* Now, go through the TYPE_BINFO hierarchy, setting the - BINFO_OFFSETs correctly for all non-primary copies of the virtual - bases and their direct and indirect bases. The ambiguity checks - in lookup_base depend on the BINFO_OFFSETs being set - correctly. */ - dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t); } /* Returns the offset of the byte just past the end of the base class @@ -5391,7 +5181,7 @@ finish_struct_1 (tree t) /* We must enter these virtuals into the table. */ if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) build_primary_vtable (NULL_TREE, t); - else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t)) + else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t))) /* Here we know enough to change the type of our virtual function table, but we will wait until later this function. */ build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t); @@ -5729,15 +5519,6 @@ init_class_processing (void) * sizeof (struct class_stack_node)); VARRAY_TREE_INIT (local_classes, 8, "local_classes"); - access_default_node = build_int_2 (0, 0); - access_public_node = build_int_2 (ak_public, 0); - access_protected_node = build_int_2 (ak_protected, 0); - access_private_node = build_int_2 (ak_private, 0); - access_default_virtual_node = build_int_2 (4, 0); - access_public_virtual_node = build_int_2 (4 | ak_public, 0); - access_protected_virtual_node = build_int_2 (4 | ak_protected, 0); - access_private_virtual_node = build_int_2 (4 | ak_private, 0); - ridpointers[(int) RID_PUBLIC] = access_public_node; ridpointers[(int) RID_PRIVATE] = access_private_node; ridpointers[(int) RID_PROTECTED] = access_protected_node; @@ -6778,102 +6559,24 @@ get_vtbl_decl_for_binfo (tree binfo) return decl; } -/* Called from get_primary_binfo via dfs_walk. DATA is a TREE_LIST - who's TREE_PURPOSE is the TYPE of the required primary base and - who's TREE_VALUE is a list of candidate binfos that we fill in. */ - -static tree -dfs_get_primary_binfo (tree binfo, void* data) -{ - tree cons = (tree) data; - tree primary_base = TREE_PURPOSE (cons); - if (TREE_VIA_VIRTUAL (binfo) - && same_type_p (BINFO_TYPE (binfo), primary_base)) - /* This is the right type of binfo, but it might be an unshared - instance, and the shared instance is later in the dfs walk. We - must keep looking. */ - TREE_VALUE (cons) = tree_cons (NULL, binfo, TREE_VALUE (cons)); - - return NULL_TREE; -} - -/* Returns the unshared binfo for the primary base of BINFO. Note - that in a complex hierarchy the resulting BINFO may not actually - *be* primary. In particular if the resulting BINFO is a virtual - base, and it occurs elsewhere in the hierarchy, then this - occurrence may not actually be a primary base in the complete - object. Check BINFO_PRIMARY_P to be sure. */ +/* Returns the binfo for the primary base of BINFO. If the resulting + BINFO is a virtual base, and it is inherited elsewhere in the + hierarchy, then the returned binfo might not be the primary base of + BINFO in the complete object. Check BINFO_PRIMARY_P or + BINFO_LOST_PRIMARY_P to be sure. */ tree get_primary_binfo (tree binfo) { tree primary_base; - tree result = NULL_TREE; - tree virtuals; + tree result; primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo)); if (!primary_base) return NULL_TREE; - /* A non-virtual primary base is always a direct base, and easy to - find. */ - if (!TREE_VIA_VIRTUAL (primary_base)) - { - int i; - - /* Scan the direct basetypes until we find a base with the same - type as the primary base. */ - for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i) - { - tree base_binfo = BINFO_BASETYPE (binfo, i); - - if (same_type_p (BINFO_TYPE (base_binfo), - BINFO_TYPE (primary_base))) - return base_binfo; - } - - /* We should always find the primary base. */ - abort (); - } - - /* For a primary virtual base, we have to scan the entire hierarchy - rooted at BINFO; the virtual base could be an indirect virtual - base. There could be more than one instance of the primary base - in the hierarchy, and if one is the canonical binfo we want that - one. If it exists, it should be the first one we find, but as a - consistency check we find them all and make sure. */ - virtuals = build_tree_list (BINFO_TYPE (primary_base), NULL_TREE); - dfs_walk (binfo, dfs_get_primary_binfo, NULL, virtuals); - virtuals = TREE_VALUE (virtuals); - - /* We must have found at least one instance. */ - my_friendly_assert (virtuals, 20010612); - - if (TREE_CHAIN (virtuals)) - { - /* We found more than one instance of the base. If one is the - canonical one, choose that one. */ - tree complete_binfo; - tree canonical; - - for (complete_binfo = binfo; - BINFO_INHERITANCE_CHAIN (complete_binfo); - complete_binfo = BINFO_INHERITANCE_CHAIN (complete_binfo)) - continue; - canonical = binfo_for_vbase (BINFO_TYPE (primary_base), - BINFO_TYPE (complete_binfo)); - - for (; virtuals; virtuals = TREE_CHAIN (virtuals)) - { - result = TREE_VALUE (virtuals); - - if (canonical == result) - break; - } - } - else - result = TREE_VALUE (virtuals); + result = copied_binfo (primary_base, binfo); return result; } @@ -6887,24 +6590,32 @@ maybe_indent_hierarchy (FILE * stream, int indent, int indented_p) return 1; } -/* Dump the offsets of all the bases rooted at BINFO (in the hierarchy - dominated by T) to stderr. INDENT should be zero when called from - the top level; it is incremented recursively. */ +/* Dump the offsets of all the bases rooted at BINFO to STREAM. + INDENT should be zero when called from the top level; it is + incremented recursively. IGO indicates the next expected BINFO in + inheritance graph ordering. */ -static void -dump_class_hierarchy_r (FILE * stream, +static tree +dump_class_hierarchy_r (FILE *stream, int flags, - tree t, tree binfo, + tree igo, int indent) { - int i; int indented = 0; + tree base_binfos; indented = maybe_indent_hierarchy (stream, indent, 0); fprintf (stream, "%s (0x%lx) ", type_as_string (binfo, TFF_PLAIN_IDENTIFIER), (unsigned long) binfo); + if (binfo != igo) + { + fprintf (stream, "alternative-path\n"); + return igo; + } + igo = TREE_CHAIN (binfo); + fprintf (stream, HOST_WIDE_INT_PRINT_DEC, tree_low_cst (BINFO_OFFSET (binfo), 0)); if (is_empty_class (BINFO_TYPE (binfo))) @@ -6912,15 +6623,7 @@ dump_class_hierarchy_r (FILE * stream, else if (CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (binfo))) fprintf (stream, " nearly-empty"); if (TREE_VIA_VIRTUAL (binfo)) - { - tree canonical = binfo_for_vbase (BINFO_TYPE (binfo), t); - - fprintf (stream, " virtual"); - if (canonical == binfo) - fprintf (stream, " canonical"); - else - fprintf (stream, " non-canonical"); - } + fprintf (stream, " virtual"); fprintf (stream, "\n"); indented = 0; @@ -6977,11 +6680,22 @@ dump_class_hierarchy_r (FILE * stream, fprintf (stream, "\n"); } + base_binfos = BINFO_BASETYPES (binfo); + if (base_binfos) + { + int ix, n; - for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i) - dump_class_hierarchy_r (stream, flags, - t, BINFO_BASETYPE (binfo, i), - indent + 2); + n = TREE_VEC_LENGTH (base_binfos); + for (ix = 0; ix != n; ix++) + { + tree base_binfo = TREE_VEC_ELT (base_binfos, ix); + + igo = dump_class_hierarchy_r (stream, flags, base_binfo, + igo, indent + 2); + } + } + + return igo; } /* Dump the BINFO hierarchy for T. */ @@ -6999,7 +6713,12 @@ dump_class_hierarchy (tree t) fprintf (stream, " size=%lu align=%lu\n", (unsigned long)(tree_low_cst (TYPE_SIZE (t), 0) / BITS_PER_UNIT), (unsigned long)(TYPE_ALIGN (t) / BITS_PER_UNIT)); - dump_class_hierarchy_r (stream, flags, t, TYPE_BINFO (t), 0); + fprintf (stream, " base size=%lu base align=%lu\n", + (unsigned long)(tree_low_cst (TYPE_SIZE (CLASSTYPE_AS_BASE (t)), 0) + / BITS_PER_UNIT), + (unsigned long)(TYPE_ALIGN (CLASSTYPE_AS_BASE (t)) + / BITS_PER_UNIT)); + dump_class_hierarchy_r (stream, flags, TYPE_BINFO (t), TYPE_BINFO (t), 0); fprintf (stream, "\n"); dump_end (TDI_class, stream); } @@ -7085,7 +6804,6 @@ finish_vtbls (tree t) { tree list; tree vbase; - int i; /* We lay out the primary and secondary vtables in one contiguous vtable. The primary vtable is first, followed by the non-virtual @@ -7097,29 +6815,9 @@ finish_vtbls (tree t) /* Then come the virtual bases, also in inheritance graph order. */ for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase)) { - tree real_base; - if (!TREE_VIA_VIRTUAL (vbase)) continue; - - /* Although we walk in inheritance order, that might not get the - canonical base. */ - real_base = binfo_for_vbase (BINFO_TYPE (vbase), t); - - accumulate_vtbl_inits (real_base, real_base, - TYPE_BINFO (t), t, list); - } - - /* Fill in BINFO_VPTR_FIELD in the immediate binfos for our virtual - base classes, for the benefit of the debugging backends. */ - for (i = 0; i < BINFO_N_BASETYPES (TYPE_BINFO (t)); ++i) - { - tree base = BINFO_BASETYPE (TYPE_BINFO (t), i); - if (TREE_VIA_VIRTUAL (base)) - { - vbase = binfo_for_vbase (BINFO_TYPE (base), t); - BINFO_VPTR_FIELD (base) = BINFO_VPTR_FIELD (vbase); - } + accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), t, list); } if (TYPE_BINFO_VTABLE (t)) @@ -7199,31 +6897,6 @@ build_vtt (tree t) dump_vtt (t, vtt); } -/* The type corresponding to BASE_BINFO is a base of the type of BINFO, but - from within some hierarchy which is inherited from the type of BINFO. - Return BASE_BINFO's equivalent binfo from the hierarchy dominated by - BINFO. */ - -static tree -get_original_base (tree base_binfo, tree binfo) -{ - tree derived; - int ix; - - if (same_type_p (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo))) - return binfo; - if (TREE_VIA_VIRTUAL (base_binfo)) - return binfo_for_vbase (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo)); - derived = get_original_base (BINFO_INHERITANCE_CHAIN (base_binfo), binfo); - - for (ix = 0; ix != BINFO_N_BASETYPES (derived); ix++) - if (same_type_p (BINFO_TYPE (base_binfo), - BINFO_TYPE (BINFO_BASETYPE (derived, ix)))) - return BINFO_BASETYPE (derived, ix); - abort (); - return NULL; -} - /* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo, and CHAIN the vtable pointer for this binfo after construction is @@ -7333,13 +7006,10 @@ build_vtt_inits (tree binfo, tree t, tree* inits, tree* index) if (top_level_p) for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b)) { - tree vbase; - if (!TREE_VIA_VIRTUAL (b)) continue; - vbase = binfo_for_vbase (BINFO_TYPE (b), t); - inits = build_vtt_inits (vbase, t, inits, index); + inits = build_vtt_inits (b, t, inits, index); } if (!top_level_p) @@ -7376,7 +7046,7 @@ dfs_build_secondary_vptr_vtt_inits (tree binfo, void* data) t = TREE_CHAIN (l); top_level_p = VTT_TOP_LEVEL_P (l); - SET_BINFO_MARKED (binfo); + BINFO_MARKED (binfo) = 1; /* We don't care about bases that don't have vtables. */ if (!TYPE_VFIELD (BINFO_TYPE (binfo))) @@ -7427,12 +7097,11 @@ dfs_build_secondary_vptr_vtt_inits (tree binfo, void* data) hierarchy. */ static tree -dfs_ctor_vtable_bases_queue_p (tree binfo, void* data) +dfs_ctor_vtable_bases_queue_p (tree derived, int ix, + void* data) { - if (TREE_VIA_VIRTUAL (binfo)) - /* Get the shared version. */ - binfo = binfo_for_vbase (BINFO_TYPE (binfo), TREE_PURPOSE ((tree) data)); - + tree binfo = BINFO_BASETYPE (derived, ix); + if (!BINFO_MARKED (binfo) == VTT_MARKED_BINFO_P ((tree) data)) return NULL_TREE; return binfo; @@ -7446,7 +7115,7 @@ dfs_ctor_vtable_bases_queue_p (tree binfo, void* data) static tree dfs_fixup_binfo_vtbls (tree binfo, void* data) { - CLEAR_BINFO_MARKED (binfo); + BINFO_MARKED (binfo) = 0; /* We don't care about bases that don't have vtables. */ if (!TYPE_VFIELD (BINFO_TYPE (binfo))) @@ -7497,14 +7166,12 @@ build_ctor_vtbl_group (tree binfo, tree t) vbase = TREE_CHAIN (vbase)) { tree b; - tree orig_base; if (!TREE_VIA_VIRTUAL (vbase)) continue; - b = binfo_for_vbase (BINFO_TYPE (vbase), t); - orig_base = binfo_for_vbase (BINFO_TYPE (vbase), BINFO_TYPE (binfo)); + b = copied_binfo (vbase, binfo); - accumulate_vtbl_inits (b, orig_base, binfo, t, list); + accumulate_vtbl_inits (b, vbase, binfo, t, list); } inits = TREE_VALUE (list); @@ -7634,8 +7301,8 @@ dfs_accumulate_vtbl_inits (tree binfo, either case, we share our vtable with LAST, i.e. the derived-most base within B of which we are a primary. */ if (b == rtti_binfo - || (b && binfo_for_vbase (BINFO_TYPE (b), - BINFO_TYPE (rtti_binfo)))) + || (b && purpose_member (BINFO_TYPE (b), + CLASSTYPE_VBASECLASSES (BINFO_TYPE (rtti_binfo))))) /* Just set our BINFO_VTABLE to point to LAST, as we may not have set LAST's BINFO_VTABLE yet. We'll extract the actual vptr in binfo_ctor_vtable after everything's been set up. */ @@ -7643,7 +7310,7 @@ dfs_accumulate_vtbl_inits (tree binfo, /* Otherwise, this is case 3 and we get our own. */ } - else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo, BINFO_TYPE (rtti_binfo))) + else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo)) return inits; if (!vtbl) @@ -7746,7 +7413,7 @@ build_vtbl_initializer (tree binfo, for (vbase = CLASSTYPE_VBASECLASSES (t); vbase; vbase = TREE_CHAIN (vbase)) - CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase)); + BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase)) = 0; /* If the target requires padding between data entries, add that now. */ if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1) @@ -7950,13 +7617,13 @@ build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid) /* Find the instance of this virtual base in the complete object. */ - b = binfo_for_vbase (BINFO_TYPE (vbase), t); + b = copied_binfo (vbase, binfo); /* If we've already got an offset for this virtual base, we don't need another one. */ if (BINFO_VTABLE_PATH_MARKED (b)) continue; - SET_BINFO_VTABLE_PATH_MARKED (b); + BINFO_VTABLE_PATH_MARKED (b) = 1; /* Figure out where we can find this vbase offset. */ delta = size_binop (MULT_EXPR, @@ -7968,16 +7635,10 @@ build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid) if (binfo != TYPE_BINFO (t)) { - tree orig_vbase; - - /* Find the instance of this virtual base in the type of BINFO. */ - orig_vbase = binfo_for_vbase (BINFO_TYPE (vbase), - BINFO_TYPE (binfo)); - /* The vbase offset had better be the same. */ - if (!tree_int_cst_equal (delta, - BINFO_VPTR_FIELD (orig_vbase))) - abort (); + my_friendly_assert (tree_int_cst_equal (delta, + BINFO_VPTR_FIELD (vbase)), + 20030202); } /* The next vbase will come at a more negative offset. */ @@ -8131,8 +7792,8 @@ add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid) if (vid->ctor_vtbl_p) /* For a ctor vtable we need the equivalent binfo within the hierarchy where rtti_binfo is the most derived type. */ - non_primary_binfo = get_original_base - (non_primary_binfo, TYPE_BINFO (BINFO_TYPE (vid->rtti_binfo))); + non_primary_binfo + = original_binfo (non_primary_binfo, vid->rtti_binfo); for (base_virtuals = BINFO_VIRTUALS (binfo), derived_virtuals = BINFO_VIRTUALS (non_primary_binfo), diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 02a724d89f6..e463fb4b68c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -58,7 +58,7 @@ struct diagnostic_context; TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE). INHERITED_VALUE_BINDING_P (in CPLUS_BINDING) ICS_ELLIPSIS_FLAG (in _CONV) - BINFO_ACCESS (in BINFO) + BINFO_DEPENDENT_BASE_P (in BINFO) DECL_INITIALIZED_P (in VAR_DECL) 2: IDENTIFIER_OPNAME_P. TYPE_POLYMORPHIC_P (in _TYPE) @@ -79,7 +79,7 @@ struct diagnostic_context; NEED_TEMPORARY_P (in REF_BIND, BASE_CONV) IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) 5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE) - 6: BINFO_ACCESS (in BINFO) + 6: For future expansion Usage of TYPE_LANG_FLAG_?: 0: TYPE_DEPENDENT_P @@ -592,15 +592,6 @@ enum cp_tree_index CPTI_GLOBAL_DELETE_FNDECL, CPTI_AGGR_TAG, - CPTI_ACCESS_DEFAULT, - CPTI_ACCESS_PUBLIC, - CPTI_ACCESS_PROTECTED, - CPTI_ACCESS_PRIVATE, - CPTI_ACCESS_DEFAULT_VIRTUAL, - CPTI_ACCESS_PUBLIC_VIRTUAL, - CPTI_ACCESS_PROTECTED_VIRTUAL, - CPTI_ACCESS_PRIVATE_VIRTUAL, - CPTI_CTOR_IDENTIFIER, CPTI_COMPLETE_CTOR_IDENTIFIER, CPTI_BASE_CTOR_IDENTIFIER, @@ -682,19 +673,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; #define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL] #define current_aggr cp_global_trees[CPTI_AGGR_TAG] -/* Define the sets of attributes that member functions and baseclasses - can have. These are sensible combinations of {public,private,protected} - cross {virtual,non-virtual}. */ - -#define access_default_node cp_global_trees[CPTI_ACCESS_DEFAULT] -#define access_public_node cp_global_trees[CPTI_ACCESS_PUBLIC] -#define access_protected_node cp_global_trees[CPTI_ACCESS_PROTECTED] -#define access_private_node cp_global_trees[CPTI_ACCESS_PRIVATE] -#define access_default_virtual_node cp_global_trees[CPTI_ACCESS_DEFAULT_VIRTUAL] -#define access_public_virtual_node cp_global_trees[CPTI_ACCESS_PUBLIC_VIRTUAL] -#define access_protected_virtual_node cp_global_trees[CPTI_ACCESS_PROTECTED_VIRTUAL] -#define access_private_virtual_node cp_global_trees[CPTI_ACCESS_PRIVATE_VIRTUAL] - /* We cache these tree nodes so as to call get_identifier less frequently. */ @@ -768,6 +746,11 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; #define keyed_classes cp_global_trees[CPTI_KEYED_CLASSES] +/* Node to indicate default access. This must be distinct from the + access nodes in tree.h. */ + +#define access_default_node null_node + /* Global state. */ struct saved_scope GTY(()) @@ -1414,21 +1397,9 @@ struct lang_type GTY(()) /* A chain of BINFOs for the direct and indirect virtual base classes that this type uses in a post-order depth-first left-to-right order. (In other words, these bases appear in the order that they - should be initialized.) If a virtual base is primary, then the - primary copy will appear on this list. Thus, the BINFOs on this - list are all "real"; they are the same BINFOs that will be - encountered when using dfs_unmarked_real_bases_queue_p and related - functions. */ + should be initialized.) */ #define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases) -/* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the - binfo_for_vbase. C is the most derived class for the hierarchy - containing BINFO. */ -#define CANONICAL_BINFO(BINFO, C) \ - (TREE_VIA_VIRTUAL (BINFO) \ - ? binfo_for_vbase (BINFO_TYPE (BINFO), C) \ - : (BINFO)) - /* Number of direct baseclasses of NODE. */ #define CLASSTYPE_N_BASECLASSES(NODE) \ (BINFO_N_BASETYPES (TYPE_BINFO (NODE))) @@ -1551,63 +1522,28 @@ struct lang_type GTY(()) /* Additional macros for inheritance information. */ /* The BINFO_INHERITANCE_CHAIN is used opposite to the description in - gcc/tree.h. In particular if D is derived from B then the BINFO - for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to - D. In tree.h, this pointer is described as pointing in other - direction. There is a different BINFO for each path to a virtual - base; BINFOs for virtual bases are not shared. - - We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private - inheritance is indicated by the absence of the other two flags, not - by TREE_VIA_PRIVATE, which is unused. */ - -/* Mark the binfo, whether shared or not. Each instance of a virtual - base can be separately marked. */ -#define BINFO_UNSHARED_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) + gcc/tree.h. In particular if D is non-virtually derived from B + then the BINFO for B (in D) will have a BINFO_INHERITANCE_CHAIN + pointing to D. If D is virtually derived, its + BINFO_INHERITANCE_CHAIN will point to the most derived binfo. In + tree.h, this pointer is described as pointing in other + direction. The binfos of virtual bases are shared. */ /* Nonzero means marked by DFS or BFS search. */ -#define BINFO_MARKED(NODE) \ - (TREE_VIA_VIRTUAL (NODE) \ - ? CLASSTYPE_MARKED (BINFO_TYPE (NODE)) \ - : TREE_LANG_FLAG_0 (NODE)) -/* Macros needed because of C compilers that don't allow conditional - expressions to be lvalues. Grr! */ -#define SET_BINFO_MARKED(NODE) \ - (TREE_VIA_VIRTUAL(NODE) \ - ? SET_CLASSTYPE_MARKED (BINFO_TYPE (NODE)) \ - : (void)(TREE_LANG_FLAG_0 (NODE) = 1)) -#define CLEAR_BINFO_MARKED(NODE) \ - (TREE_VIA_VIRTUAL (NODE) \ - ? CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (NODE)) \ - : (void)(TREE_LANG_FLAG_0 (NODE) = 0)) +#define BINFO_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) /* Nonzero means that this class is on a path leading to a new vtable. */ -#define BINFO_VTABLE_PATH_MARKED(NODE) \ - (TREE_VIA_VIRTUAL (NODE) \ - ? CLASSTYPE_MARKED3 (BINFO_TYPE (NODE)) \ - : TREE_LANG_FLAG_3 (NODE)) -#define SET_BINFO_VTABLE_PATH_MARKED(NODE) \ - (TREE_VIA_VIRTUAL(NODE) \ - ? SET_CLASSTYPE_MARKED3 (BINFO_TYPE (NODE)) \ - : (TREE_LANG_FLAG_3 (NODE) = 1)) -#define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) \ - (TREE_VIA_VIRTUAL (NODE) \ - ? CLEAR_CLASSTYPE_MARKED3 (BINFO_TYPE (NODE))\ - : (TREE_LANG_FLAG_3 (NODE) = 0)) - -/* Nonzero means B (a BINFO) has its own vtable. Under the old ABI, - secondary vtables are sometimes shared. Any copies will not have - this flag set. - - B is part of the hierarchy dominated by C. */ -#define BINFO_NEW_VTABLE_MARKED(B, C) \ - (TREE_LANG_FLAG_4 (CANONICAL_BINFO (B, C))) +#define BINFO_VTABLE_PATH_MARKED(NODE) TREE_LANG_FLAG_3 (NODE) + +/* Nonzero means B (a BINFO) has its own vtable. Any copies will not + have this flag set. */ +#define BINFO_NEW_VTABLE_MARKED(B) (TREE_LANG_FLAG_4 (B)) /* Any subobject that needs a new vtable must have a vptr and must not be a non-virtual primary base (since it would then use the vtable from a derived class and never become non-primary.) */ -#define SET_BINFO_NEW_VTABLE_MARKED(B, C) \ - (BINFO_NEW_VTABLE_MARKED (B, C) = 1, \ +#define SET_BINFO_NEW_VTABLE_MARKED(B) \ + (BINFO_NEW_VTABLE_MARKED (B) = 1, \ my_friendly_assert (!BINFO_PRIMARY_P (B) \ || TREE_VIA_VIRTUAL (B), 20000517), \ my_friendly_assert (CLASSTYPE_VFIELDS (BINFO_TYPE (B)) != NULL_TREE, \ @@ -1615,8 +1551,6 @@ struct lang_type GTY(()) /* Nonzero means this class has done dfs_pushdecls. */ #define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE) -#define SET_BINFO_PUSHDECLS_MARKED(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE) -#define CLEAR_BINFO_PUSHDECLS_MARKED(NODE) CLEAR_BINFO_VTABLE_PATH_MARKED (NODE) /* Nonzero if this BINFO is a primary base class. Note, this can be set for non-canononical virtual bases. For a virtual primary base @@ -1643,6 +1577,10 @@ struct lang_type GTY(()) #define BINFO_LANG_ELTS (BINFO_ELTS + 3) +/* Nonzero if this binfo is for a dependent base - one that should not + be searched. */ +#define BINFO_DEPENDENT_BASE_P(NODE) TREE_LANG_FLAG_1(NODE) + /* Nonzero if this binfo has lost its primary base binfo (because that is a nearly-empty virtual base that has been taken by some other base in the complete hierarchy. */ @@ -3077,7 +3015,7 @@ typedef enum tmpl_spec_kind { /* The various kinds of access. BINFO_ACCESS depends on these being two bit quantities. The numerical values are important; they are used to initialize RTTI data structures, so changing them changes - the ABI. */ + the ABI. */ typedef enum access_kind { ak_none = 0, /* Inaccessible. */ ak_public = 1, /* Accessible, as a `public' thing. */ @@ -4142,28 +4080,24 @@ extern tree binfo_from_vbase (tree); extern tree look_for_overrides_here (tree, tree); extern int check_final_overrider (tree, tree); extern tree dfs_walk (tree, - tree (*) (tree, void *), - tree (*) (tree, void *), - void *); + tree (*) (tree, void *), + tree (*) (tree, int, void *), + void *); extern tree dfs_walk_real (tree, - tree (*) (tree, void *), - tree (*) (tree, void *), - tree (*) (tree, void *), - void *); + tree (*) (tree, void *), + tree (*) (tree, void *), + tree (*) (tree, int, void *), + void *); extern tree dfs_unmark (tree, void *); -extern tree markedp (tree, void *); -extern tree unmarkedp (tree, void *); -extern tree dfs_unmarked_real_bases_queue_p (tree, void *); -extern tree dfs_marked_real_bases_queue_p (tree, void *); -extern tree dfs_skip_vbases (tree, void *); -extern tree marked_vtable_pathp (tree, void *); -extern tree unmarked_vtable_pathp (tree, void *); -extern tree find_vbase_instance (tree, tree); -extern tree binfo_for_vbase (tree, tree); +extern tree markedp (tree, int, void *); +extern tree unmarkedp (tree, int, void *); extern tree binfo_via_virtual (tree, tree); extern tree build_baselink (tree, tree, tree, tree); extern tree adjust_result_of_qualified_name_lookup (tree, tree, tree); +extern tree copied_binfo (tree, tree); +extern tree original_binfo (tree, tree); + /* in semantics.c */ extern void push_deferring_access_checks (bool defer_p); extern void resume_deferring_access_checks (void); @@ -4245,7 +4179,7 @@ extern void finish_default_args (void); extern tree finish_member_class_template (tree); extern void finish_template_decl (tree); extern tree finish_template_type (tree, tree, int); -extern tree finish_base_specifier (tree, tree); +extern tree finish_base_specifier (tree, tree, bool); extern void finish_member_declaration (tree); extern void check_multiple_declarators (void); extern tree finish_typeof (tree); @@ -4275,7 +4209,7 @@ extern void init_tree (void); extern int pod_type_p (tree); extern int zero_init_p (tree); extern tree canonical_type_variant (tree); -extern void unshare_base_binfos (tree); +extern tree copy_base_binfos (tree, tree, tree); extern int member_p (tree); extern cp_lvalue_kind real_lvalue_p (tree); extern int non_cast_lvalue_p (tree); @@ -4293,7 +4227,6 @@ extern tree hash_tree_cons (tree, tree, tree); extern tree hash_tree_chain (tree, tree); extern tree hash_chainon (tree, tree); extern tree make_binfo (tree, tree, tree, tree); -extern tree reverse_path (tree); extern int count_functions (tree); extern int is_overloaded_fn (tree); extern tree get_first_fn (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 94cd4c3e7d2..3f22b748618 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12829,17 +12829,17 @@ xref_tag_from_type (tree old, tree id, int globalize) } /* REF is a type (named NAME), for which we have just seen some - baseclasses. BINFO is a list of those baseclasses; the + baseclasses. BASE_LIST is a list of those baseclasses; the TREE_PURPOSE is an access_* node, and the TREE_VALUE is the type of - the base-class. CODE_TYPE_NODE indicates whether REF is a class, + the base-class. TREE_VIA_VIRTUAL indicates virtual + inheritance. CODE_TYPE_NODE indicates whether REF is a class, struct, or union. */ void -xref_basetypes (tree ref, tree binfo) +xref_basetypes (tree ref, tree base_list) { /* In the declaration `A : X, Y, ... Z' we mark all the types (A, X, Y, ..., Z) so we can check for duplicates. */ - tree binfos; tree *basep; int i; @@ -12857,145 +12857,147 @@ xref_basetypes (tree ref, tree binfo) instantiated. This ensures that if we call ourselves recursively we do not get confused about which classes are marked and which are not. */ - basep = &binfo; + basep = &base_list; while (*basep) { tree basetype = TREE_VALUE (*basep); if (!(processing_template_decl && uses_template_parms (basetype)) && !complete_type_or_else (basetype, NULL)) - /* An incomplete type. Remove it form the list. */ + /* An incomplete type. Remove it from the list. */ *basep = TREE_CHAIN (*basep); else basep = &TREE_CHAIN (*basep); } SET_CLASSTYPE_MARKED (ref); - BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos - = make_tree_vec (list_length (binfo)); - - for (i = 0; binfo; binfo = TREE_CHAIN (binfo)) - { - /* The base of a derived struct is public by default. */ - int via_public - = (TREE_PURPOSE (binfo) == access_public_node - || TREE_PURPOSE (binfo) == access_public_virtual_node - || (tag_code != class_type - && (TREE_PURPOSE (binfo) == access_default_node - || TREE_PURPOSE (binfo) == access_default_virtual_node))); - int via_protected - = (TREE_PURPOSE (binfo) == access_protected_node - || TREE_PURPOSE (binfo) == access_protected_virtual_node); - int via_virtual - = (TREE_PURPOSE (binfo) == access_private_virtual_node - || TREE_PURPOSE (binfo) == access_protected_virtual_node - || TREE_PURPOSE (binfo) == access_public_virtual_node - || TREE_PURPOSE (binfo) == access_default_virtual_node); - tree basetype = TREE_VALUE (binfo); - tree base_binfo; - - if (basetype && TREE_CODE (basetype) == TYPE_DECL) - basetype = TREE_TYPE (basetype); - if (!basetype - || (TREE_CODE (basetype) != RECORD_TYPE - && TREE_CODE (basetype) != TYPENAME_TYPE - && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM - && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM)) - { - error ("base type `%T' fails to be a struct or class type", - TREE_VALUE (binfo)); - continue; - } - - if (CLASSTYPE_MARKED (basetype)) + i = list_length (base_list); + if (i) + { + tree binfo = TYPE_BINFO (ref); + tree binfos = make_tree_vec (i); + tree accesses = make_tree_vec (i); + + BINFO_BASETYPES (binfo) = binfos; + BINFO_BASEACCESSES (binfo) = accesses; + + for (i = 0; base_list; base_list = TREE_CHAIN (base_list)) { - if (basetype == ref) - error ("recursive type `%T' undefined", basetype); + tree access = TREE_PURPOSE (base_list); + int via_virtual = TREE_VIA_VIRTUAL (base_list); + tree basetype = TREE_VALUE (base_list); + tree base_binfo; + + if (access == access_default_node) + /* The base of a derived struct is public by default. */ + access = (tag_code == class_type + ? access_private_node : access_public_node); + + if (basetype && TREE_CODE (basetype) == TYPE_DECL) + basetype = TREE_TYPE (basetype); + if (!basetype + || (TREE_CODE (basetype) != RECORD_TYPE + && TREE_CODE (basetype) != TYPENAME_TYPE + && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM + && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM)) + { + error ("base type `%T' fails to be a struct or class type", + basetype); + continue; + } + + if (CLASSTYPE_MARKED (basetype)) + { + if (basetype == ref) + error ("recursive type `%T' undefined", basetype); + else + error ("duplicate base type `%T' invalid", basetype); + continue; + } + + if (TYPE_FOR_JAVA (basetype) + && (current_lang_depth () == 0)) + TYPE_FOR_JAVA (ref) = 1; + + if (CLASS_TYPE_P (basetype)) + { + base_binfo = TYPE_BINFO (basetype); + /* This flag will be in the binfo of the base type, we must + clear it after copying the base binfos. */ + BINFO_DEPENDENT_BASE_P (base_binfo) + = dependent_type_p (basetype); + } else - error ("duplicate base type `%T' invalid", basetype); - continue; + base_binfo = make_binfo (size_zero_node, basetype, + NULL_TREE, NULL_TREE); + + TREE_VEC_ELT (binfos, i) = base_binfo; + TREE_VEC_ELT (accesses, i) = access; + /* This flag will be in the binfo of the base type, we must + clear it after copying the base binfos. */ + TREE_VIA_VIRTUAL (base_binfo) = via_virtual; + + SET_CLASSTYPE_MARKED (basetype); + + /* We are free to modify these bits because they are meaningless + at top level, and BASETYPE is a top-level type. */ + if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype)) + { + TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1; + /* Converting to a virtual base class requires looking + up the offset of the virtual base. */ + TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1; + } + + if (CLASS_TYPE_P (basetype)) + { + TYPE_HAS_NEW_OPERATOR (ref) + |= TYPE_HAS_NEW_OPERATOR (basetype); + TYPE_HAS_ARRAY_NEW_OPERATOR (ref) + |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype); + TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype); + /* If the base-class uses multiple inheritance, so do we. */ + TYPE_USES_MULTIPLE_INHERITANCE (ref) + |= TYPE_USES_MULTIPLE_INHERITANCE (basetype); + /* Likewise, if converting to a base of the base may require + code, then we may need to generate code to convert to a + base as well. */ + TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) + |= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype); + } + i++; } - - if (TYPE_FOR_JAVA (basetype) - && (current_lang_depth () == 0)) - TYPE_FOR_JAVA (ref) = 1; - - /* Note that the BINFO records which describe individual - inheritances are *not* shared in the lattice! They - cannot be shared because a given baseclass may be - inherited with different `accessibility' by different - derived classes. (Each BINFO record describing an - individual inheritance contains flags which say what - the `accessibility' of that particular inheritance is.) */ - - base_binfo - = make_binfo (size_zero_node, basetype, - CLASS_TYPE_P (basetype) - ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE, - CLASS_TYPE_P (basetype) - ? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE); - - TREE_VEC_ELT (binfos, i) = base_binfo; - TREE_VIA_PUBLIC (base_binfo) = via_public; - TREE_VIA_PROTECTED (base_binfo) = via_protected; - TREE_VIA_VIRTUAL (base_binfo) = via_virtual; - BINFO_INHERITANCE_CHAIN (base_binfo) = TYPE_BINFO (ref); - - /* We need to unshare the binfos now so that lookups during class - definition work. */ - unshare_base_binfos (base_binfo); - - SET_CLASSTYPE_MARKED (basetype); - - /* We are free to modify these bits because they are meaningless - at top level, and BASETYPE is a top-level type. */ - if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype)) - { - TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1; - /* Converting to a virtual base class requires looking - up the offset of the virtual base. */ + if (i) + TREE_VEC_LENGTH (accesses) = TREE_VEC_LENGTH (binfos) = i; + else + BINFO_BASEACCESSES (binfo) = BINFO_BASETYPES (binfo) = NULL_TREE; + + if (i > 1) + { + TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1; + /* If there is more than one non-empty they cannot be at the same + address. */ TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1; } - + } + + /* Copy the base binfos, collect the virtual bases and set the + inheritance order chain. */ + copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE); + CLASSTYPE_VBASECLASSES (ref) = nreverse (CLASSTYPE_VBASECLASSES (ref)); + + /* Unmark all the types. */ + while (i--) + { + tree basetype = BINFO_TYPE (BINFO_BASETYPE (TYPE_BINFO (ref), i)); + + CLEAR_CLASSTYPE_MARKED (basetype); if (CLASS_TYPE_P (basetype)) { - TYPE_HAS_NEW_OPERATOR (ref) - |= TYPE_HAS_NEW_OPERATOR (basetype); - TYPE_HAS_ARRAY_NEW_OPERATOR (ref) - |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype); - TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype); - /* If the base-class uses multiple inheritance, so do we. */ - TYPE_USES_MULTIPLE_INHERITANCE (ref) - |= TYPE_USES_MULTIPLE_INHERITANCE (basetype); - /* Likewise, if converting to a base of the base may require - code, then we may need to generate code to convert to a - base as well. */ - TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) - |= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype); + TREE_VIA_VIRTUAL (TYPE_BINFO (basetype)) = 0; + BINFO_DEPENDENT_BASE_P (TYPE_BINFO (basetype)) = 0; } - - i += 1; - } - if (i) - TREE_VEC_LENGTH (binfos) = i; - else - BINFO_BASETYPES (TYPE_BINFO (ref)) = NULL_TREE; - - if (i > 1) - { - TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1; - /* If there is more than one non-empty they cannot be at the same - address. */ - TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1; } - - /* Unmark all the types. */ - while (--i >= 0) - CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i))); CLEAR_CLASSTYPE_MARKED (ref); - - /* Now that we know all the base-classes, set up the list of virtual - bases. */ - get_vbase_types (ref); } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index bb387ce1b01..7036aa02fb6 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1,6 +1,6 @@ /* Handle initialization things in C++. Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -127,7 +127,7 @@ dfs_initialize_vtbl_ptrs (binfo, data) expand_virtual_init (binfo, base_ptr); } - SET_BINFO_MARKED (binfo); + BINFO_MARKED (binfo) = 1; return NULL_TREE; } @@ -149,10 +149,9 @@ initialize_vtbl_ptrs (addr) class. We do these in pre-order because can't find the virtual bases for a class until we've initialized the vtbl for that class. */ - dfs_walk_real (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, - NULL, dfs_unmarked_real_bases_queue_p, list); - dfs_walk (TYPE_BINFO (type), dfs_unmark, - dfs_marked_real_bases_queue_p, type); + dfs_walk_real (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, + NULL, unmarkedp, list); + dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, type); } /* Return an expression for the zero-initialization of an object with @@ -1001,15 +1000,9 @@ expand_member_init (tree name, tree init) binfo = lookup_base (current_class_type, basetype, ba_ignore, NULL); - if (binfo) - { - if (TREE_VIA_VIRTUAL (binfo)) - binfo = binfo_for_vbase (basetype, current_class_type); - else if (BINFO_INHERITANCE_CHAIN (binfo) - != TYPE_BINFO (current_class_type)) - binfo = NULL_TREE; - } - if (!binfo) + if (!binfo || (!TREE_VIA_VIRTUAL (binfo) + && (BINFO_INHERITANCE_CHAIN (binfo) + != TYPE_BINFO (current_class_type)))) { if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) error ("type `%D' is not a direct or virtual base of `%T'", @@ -1019,9 +1012,7 @@ expand_member_init (tree name, tree init) name, current_class_type); return NULL_TREE; } - - if (binfo) - return build_tree_list (binfo, init); + return build_tree_list (binfo, init); } else { diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c81c3df5e94..79ec8be6417 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12419,22 +12419,13 @@ cp_parser_base_clause (cp_parser* parser) static tree cp_parser_base_specifier (cp_parser* parser) { - static const tree *const access_nodes[][2] = - { - /* This ordering must match the access_kind enumeration. */ - {&access_default_node, &access_default_virtual_node}, - {&access_public_node, &access_public_virtual_node}, - {&access_protected_node, &access_protected_virtual_node}, - {&access_private_node, &access_private_virtual_node} - }; cp_token *token; bool done = false; bool virtual_p = false; bool duplicate_virtual_error_issued_p = false; bool duplicate_access_error_issued_p = false; bool class_scope_p, template_p; - access_kind access = ak_none; - tree access_node; + tree access = access_default_node; tree type; /* Process the optional `virtual' and `access-specifier'. */ @@ -12466,16 +12457,15 @@ cp_parser_base_specifier (cp_parser* parser) case RID_PRIVATE: /* If more than one access specifier appears, issue an error. */ - if (access != ak_none && !duplicate_access_error_issued_p) + if (access != access_default_node + && !duplicate_access_error_issued_p) { cp_parser_error (parser, "more than one access specifier in base-specified"); duplicate_access_error_issued_p = true; } - access = ((access_kind) - tree_low_cst (ridpointers[(int) token->keyword], - /*pos=*/1)); + access = ridpointers[(int) token->keyword]; /* Consume the access-specifier. */ cp_lexer_consume_token (parser->lexer); @@ -12488,9 +12478,6 @@ cp_parser_base_specifier (cp_parser* parser) } } - /* Map `virtual_p' and `access' onto one of the access tree-nodes. */ - access_node = *access_nodes[access][virtual_p]; - /* Look for the optional `::' operator. */ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false); /* Look for the nested-name-specifier. The simplest way to @@ -12526,7 +12513,7 @@ cp_parser_base_specifier (cp_parser* parser) if (type == error_mark_node) return error_mark_node; - return finish_base_specifier (access_node, TREE_TYPE (type)); + return finish_base_specifier (TREE_TYPE (type), access, virtual_p); } /* Exception handling [gram.exception] */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 959bd54e93d..add427d4ed1 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5146,7 +5146,8 @@ instantiate_class_template (type) { tree template, args, pattern, t, member; tree typedecl; - + tree pbinfo; + if (type == error_mark_node) return error_mark_node; @@ -5277,10 +5278,13 @@ instantiate_class_template (type) if (ANON_AGGR_TYPE_P (pattern)) SET_ANON_AGGR_TYPE_P (type); - if (TYPE_BINFO_BASETYPES (pattern)) + pbinfo = TYPE_BINFO (pattern); + + if (BINFO_BASETYPES (pbinfo)) { tree base_list = NULL_TREE; - tree pbases = TYPE_BINFO_BASETYPES (pattern); + tree pbases = BINFO_BASETYPES (pbinfo); + tree paccesses = BINFO_BASEACCESSES (pbinfo); int i; /* Substitute into each of the bases to determine the actual @@ -5292,33 +5296,15 @@ instantiate_class_template (type) tree pbase; pbase = TREE_VEC_ELT (pbases, i); + access = TREE_VEC_ELT (paccesses, i); /* Substitute to figure out the base class. */ base = tsubst (BINFO_TYPE (pbase), args, tf_error, NULL_TREE); if (base == error_mark_node) continue; - - /* Calculate the correct access node. */ - if (TREE_VIA_VIRTUAL (pbase)) - { - if (TREE_VIA_PUBLIC (pbase)) - access = access_public_virtual_node; - else if (TREE_VIA_PROTECTED (pbase)) - access = access_protected_virtual_node; - else - access = access_private_virtual_node; - } - else - { - if (TREE_VIA_PUBLIC (pbase)) - access = access_public_node; - else if (TREE_VIA_PROTECTED (pbase)) - access = access_protected_node; - else - access = access_private_node; - } - + base_list = tree_cons (access, base, base_list); + TREE_VIA_VIRTUAL (base_list) = TREE_VIA_VIRTUAL (pbase); } /* The list is now in reverse order; correct that. */ @@ -9161,7 +9147,7 @@ get_template_base_recursive (tparms, targs, parm, /* When searching for a non-virtual, we cannot mark virtually found binfos. */ if (! this_virtual) - SET_BINFO_MARKED (base_binfo); + BINFO_MARKED (base_binfo) = 1; rval = get_template_base_recursive (tparms, targs, parm, diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index e222d25c876..9ebae8b5448 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1039,6 +1039,7 @@ get_pseudo_ti_init (tree type, tree var_desc, bool *non_public_p) tree binfo = TYPE_BINFO (type); int nbases = BINFO_N_BASETYPES (binfo); tree base_binfos = BINFO_BASETYPES (binfo); + tree base_accesses = BINFO_BASEACCESSES (binfo); tree base_inits = NULL_TREE; int ix; @@ -1051,15 +1052,14 @@ get_pseudo_ti_init (tree type, tree var_desc, bool *non_public_p) tree tinfo; tree offset; - if (TREE_PUBLIC (base_binfo)) + if (TREE_VEC_ELT (base_accesses, ix) == access_public_node) flags |= 2; tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo)); if (TREE_VIA_VIRTUAL (base_binfo)) { /* We store the vtable offset at which the virtual base offset can be found. */ - offset = BINFO_VPTR_FIELD - (binfo_for_vbase (BINFO_TYPE (base_binfo), type)); + offset = BINFO_VPTR_FIELD (base_binfo); offset = convert (sizetype, offset); flags |= 1; } @@ -1187,12 +1187,14 @@ get_pseudo_ti_desc (tree type) return class_desc_type_node; else { - tree base_binfo = - TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), 0); - int num_bases = BINFO_N_BASETYPES (TYPE_BINFO (type)); + tree binfo = TYPE_BINFO (type); + tree base_binfos = BINFO_BASETYPES (binfo); + tree base_accesses = BINFO_BASEACCESSES (binfo); + tree base_binfo = TREE_VEC_ELT (base_binfos, 0); + int num_bases = TREE_VEC_LENGTH (base_binfos); if (num_bases == 1 - && TREE_PUBLIC (base_binfo) + && TREE_VEC_ELT (base_accesses, 0) == access_public_node && !TREE_VIA_VIRTUAL (base_binfo) && integer_zerop (BINFO_OFFSET (base_binfo))) /* single non-virtual public. */ diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 395464e0ef9..8fd1ee52e72 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -82,18 +82,15 @@ struct vbase_info }; static tree lookup_field_1 (tree, tree); -static int is_subobject_of_p (tree, tree, tree); -static int is_subobject_of_p_1 (tree, tree, tree); static tree dfs_check_overlap (tree, void *); -static tree dfs_no_overlap_yet (tree, void *); +static tree dfs_no_overlap_yet (tree, int, void *); static base_kind lookup_base_r (tree, tree, base_access, bool, bool, bool, tree *); static int dynamic_cast_base_recurse (tree, tree, bool, tree *); -static tree marked_pushdecls_p (tree, void *); -static tree unmarked_pushdecls_p (tree, void *); -static tree dfs_debug_unmarkedp (tree, void *); +static tree marked_pushdecls_p (tree, int, void *); +static tree unmarked_pushdecls_p (tree, int, void *); +static tree dfs_debug_unmarkedp (tree, int, void *); static tree dfs_debug_mark (tree, void *); -static tree dfs_get_vbase_types (tree, void *); static tree dfs_push_type_decls (tree, void *); static tree dfs_push_decls (tree, void *); static tree dfs_unuse_fields (tree, void *); @@ -104,28 +101,19 @@ static struct search_level *push_search_level (struct stack_level *, static struct search_level *pop_search_level (struct stack_level *); static void grow_bfs_bases (tree **, size_t *, size_t *); static tree bfs_walk (tree, tree (*) (tree, void *), - tree (*) (tree, void *), void *); -static tree lookup_field_queue_p (tree, void *); + tree (*) (tree, int, void *), void *); +static tree lookup_field_queue_p (tree, int, void *); static int shared_member_p (tree); static tree lookup_field_r (tree, void *); -static tree canonical_binfo (tree); -static tree shared_marked_p (tree, void *); -static tree shared_unmarked_p (tree, void *); -static int dependent_base_p (tree); -static tree dfs_accessible_queue_p (tree, void *); +static tree dfs_accessible_queue_p (tree, int, void *); static tree dfs_accessible_p (tree, void *); static tree dfs_access_in_type (tree, void *); static access_kind access_in_type (tree, tree); -static tree dfs_canonical_queue (tree, void *); -static tree dfs_assert_unmarked_p (tree, void *); -static void assert_canonical_unmarked (tree); static int protected_accessible_p (tree, tree, tree); static int friend_accessible_p (tree, tree, tree); static void setup_class_bindings (tree, int); static int template_self_reference_p (tree, tree); -static tree dfs_find_vbase_instance (tree, void *); static tree dfs_get_pure_virtuals (tree, void *); -static tree dfs_build_inheritance_graph_order (tree, void *); /* Allocate a level of searching. */ @@ -183,7 +171,7 @@ lookup_base_r (tree binfo, tree base, base_access access, tree *binfo_ptr) { int i; - tree bases; + tree bases, accesses; base_kind found = bk_not_base; if (access == ba_check @@ -207,8 +195,7 @@ lookup_base_r (tree binfo, tree base, base_access access, if (!*binfo_ptr) *binfo_ptr = binfo; - else if (!is_virtual || !tree_int_cst_equal (BINFO_OFFSET (binfo), - BINFO_OFFSET (*binfo_ptr))) + else if (binfo != *binfo_ptr) { if (access != ba_any) *binfo_ptr = NULL; @@ -222,23 +209,26 @@ lookup_base_r (tree binfo, tree base, base_access access, } bases = BINFO_BASETYPES (binfo); + accesses = BINFO_BASEACCESSES (binfo); if (!bases) return bk_not_base; for (i = TREE_VEC_LENGTH (bases); i--;) { tree base_binfo = TREE_VEC_ELT (bases, i); + tree base_access = TREE_VEC_ELT (accesses, i); + int this_non_public = is_non_public; int this_virtual = is_virtual; base_kind bk; if (access <= ba_ignore) ; /* no change */ - else if (TREE_VIA_PUBLIC (base_binfo)) + else if (base_access == access_public_node) ; /* no change */ else if (access == ba_not_special) this_non_public = 1; - else if (TREE_VIA_PROTECTED (base_binfo) && within_current_scope) + else if (base_access == access_protected_node && within_current_scope) ; /* no change */ else if (is_friend (BINFO_TYPE (binfo), current_scope ())) ; /* no change */ @@ -290,9 +280,9 @@ lookup_base_r (tree binfo, tree base, base_access access, } /* Lookup BASE in the hierarchy dominated by T. Do access checking as - ACCESS specifies. Return the binfo we discover (which might not be - canonical). If KIND_PTR is non-NULL, fill with information about - what kind of base we discovered. + ACCESS specifies. Return the binfo we discover. If KIND_PTR is + non-NULL, fill with information about what kind of base we + discovered. If the base is inaccessible, or ambiguous, and the ba_quiet bit is not set in ACCESS, then an error is issued and error_mark_node is @@ -365,7 +355,7 @@ static int dynamic_cast_base_recurse (tree subtype, tree binfo, bool is_via_virtual, tree *offset_ptr) { - tree binfos; + tree binfos, accesses; int i, n_baselinks; int worst = -2; @@ -381,13 +371,15 @@ dynamic_cast_base_recurse (tree subtype, tree binfo, bool is_via_virtual, } binfos = BINFO_BASETYPES (binfo); + accesses = BINFO_BASEACCESSES (binfo); n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); + tree base_access = TREE_VEC_ELT (accesses, i); int rval; - if (!TREE_VIA_PUBLIC (base_binfo)) + if (base_access != access_public_node) continue; rval = dynamic_cast_base_recurse (subtype, base_binfo, @@ -603,74 +595,17 @@ context_for_name_lookup (tree decl) return context; } -/* Return a canonical BINFO if BINFO is a virtual base, or just BINFO - otherwise. */ - -static tree -canonical_binfo (tree binfo) -{ - return (TREE_VIA_VIRTUAL (binfo) - ? TYPE_BINFO (BINFO_TYPE (binfo)) : binfo); -} - -/* A queue function that simply ensures that we walk into the - canonical versions of virtual bases. */ - -static tree -dfs_canonical_queue (tree binfo, void *data ATTRIBUTE_UNUSED) -{ - return canonical_binfo (binfo); -} - -/* Called via dfs_walk from assert_canonical_unmarked. */ - -static tree -dfs_assert_unmarked_p (tree binfo, void *data ATTRIBUTE_UNUSED) -{ - my_friendly_assert (!BINFO_MARKED (binfo), 0); - return NULL_TREE; -} - -/* Asserts that all the nodes below BINFO (using the canonical - versions of virtual bases) are unmarked. */ - -static void -assert_canonical_unmarked (tree binfo) -{ - dfs_walk (binfo, dfs_assert_unmarked_p, dfs_canonical_queue, 0); -} - -/* If BINFO is marked, return a canonical version of BINFO. - Otherwise, return NULL_TREE. */ - -static tree -shared_marked_p (tree binfo, void *data) -{ - binfo = canonical_binfo (binfo); - return markedp (binfo, data); -} - -/* If BINFO is not marked, return a canonical version of BINFO. - Otherwise, return NULL_TREE. */ - -static tree -shared_unmarked_p (tree binfo, void *data) -{ - binfo = canonical_binfo (binfo); - return unmarkedp (binfo, data); -} - /* The accessibility routines use BINFO_ACCESS for scratch space during the computation of the accssibility of some declaration. */ #define BINFO_ACCESS(NODE) \ - ((access_kind) ((TREE_LANG_FLAG_1 (NODE) << 1) | TREE_LANG_FLAG_6 (NODE))) + ((access_kind) ((TREE_PUBLIC (NODE) << 1) | TREE_PRIVATE (NODE))) /* Set the access associated with NODE to ACCESS. */ #define SET_BINFO_ACCESS(NODE, ACCESS) \ - ((TREE_LANG_FLAG_1 (NODE) = ((ACCESS) & 2) != 0), \ - (TREE_LANG_FLAG_6 (NODE) = ((ACCESS) & 1) != 0)) + ((TREE_PUBLIC (NODE) = ((ACCESS) & 2) != 0), \ + (TREE_PRIVATE (NODE) = ((ACCESS) & 1) != 0)) /* Called from access_in_type via dfs_walk. Calculate the access to DATA (which is really a DECL) in BINFO. */ @@ -702,51 +637,59 @@ dfs_access_in_type (tree binfo, void *data) if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl)) { tree decl_access = purpose_member (type, DECL_ACCESS (decl)); + if (decl_access) - access = ((access_kind) - TREE_INT_CST_LOW (TREE_VALUE (decl_access))); + { + decl_access = TREE_VALUE (decl_access); + + if (decl_access == access_public_node) + access = ak_public; + else if (decl_access == access_protected_node) + access = ak_protected; + else if (decl_access == access_private_node) + access = ak_private; + else + my_friendly_assert (false, 20030217); + } } if (!access) { int i; int n_baselinks; - tree binfos; + tree binfos, accesses; /* Otherwise, scan our baseclasses, and pick the most favorable access. */ binfos = BINFO_BASETYPES (binfo); + accesses = BINFO_BASEACCESSES (binfo); n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; for (i = 0; i < n_baselinks; ++i) { tree base_binfo = TREE_VEC_ELT (binfos, i); - access_kind base_access - = BINFO_ACCESS (canonical_binfo (base_binfo)); + tree base_access = TREE_VEC_ELT (accesses, i); + access_kind base_access_now = BINFO_ACCESS (base_binfo); - if (base_access == ak_none || base_access == ak_private) + if (base_access_now == ak_none || base_access_now == ak_private) /* If it was not accessible in the base, or only accessible as a private member, we can't access it all. */ - base_access = ak_none; - else if (TREE_VIA_PROTECTED (base_binfo)) - /* Public and protected members in the base are + base_access_now = ak_none; + else if (base_access == access_protected_node) + /* Public and protected members in the base become protected here. */ - base_access = ak_protected; - else if (!TREE_VIA_PUBLIC (base_binfo)) - /* Public and protected members in the base are + base_access_now = ak_protected; + else if (base_access == access_private_node) + /* Public and protected members in the base become private here. */ - base_access = ak_private; + base_access_now = ak_private; /* See if the new access, via this base, gives more access than our previous best access. */ - if (base_access != ak_none - && (base_access == ak_public - || (base_access == ak_protected - && access != ak_public) - || (base_access == ak_private - && access == ak_none))) + if (base_access_now != ak_none + && (access == ak_none || base_access_now < access)) { - access = base_access; + access = base_access_now; /* If the new access is public, we can't do better. */ if (access == ak_public) @@ -761,7 +704,7 @@ dfs_access_in_type (tree binfo, void *data) /* Mark TYPE as visited so that if we reach it again we do not duplicate our efforts here. */ - SET_BINFO_MARKED (binfo); + BINFO_MARKED (binfo) = 1; return NULL_TREE; } @@ -784,9 +727,8 @@ access_in_type (tree type, tree decl) The algorithm we use is to make a post-order depth-first traversal of the base-class hierarchy. As we come up the tree, we annotate each node with the most lenient access. */ - dfs_walk_real (binfo, 0, dfs_access_in_type, shared_unmarked_p, decl); - dfs_walk (binfo, dfs_unmark, shared_marked_p, 0); - assert_canonical_unmarked (binfo); + dfs_walk_real (binfo, 0, dfs_access_in_type, unmarkedp, decl); + dfs_walk (binfo, dfs_unmark, markedp, 0); return BINFO_ACCESS (binfo); } @@ -794,19 +736,20 @@ access_in_type (tree type, tree decl) /* Called from dfs_accessible_p via dfs_walk. */ static tree -dfs_accessible_queue_p (tree binfo, void *data ATTRIBUTE_UNUSED) +dfs_accessible_queue_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED) { + tree binfo = BINFO_BASETYPE (derived, ix); + if (BINFO_MARKED (binfo)) return NULL_TREE; /* If this class is inherited via private or protected inheritance, - then we can't see it, unless we are a friend of the subclass. */ - if (!TREE_VIA_PUBLIC (binfo) - && !is_friend (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)), - current_scope ())) + then we can't see it, unless we are a friend of the derived class. */ + if (BINFO_BASEACCESS (derived, ix) != access_public_node + && !is_friend (BINFO_TYPE (derived), current_scope ())) return NULL_TREE; - return canonical_binfo (binfo); + return binfo; } /* Called from dfs_accessible_p via dfs_walk. */ @@ -817,7 +760,7 @@ dfs_accessible_p (tree binfo, void *data) int protected_ok = data != 0; access_kind access; - SET_BINFO_MARKED (binfo); + BINFO_MARKED (binfo) = 1; access = BINFO_ACCESS (binfo); if (access == ak_public || (access == ak_protected && protected_ok)) return binfo; @@ -1015,75 +958,11 @@ accessible_p (tree type, tree decl) /* Clear any mark bits. Note that we have to walk the whole tree here, since we have aborted the previous walk from some point deep in the tree. */ - dfs_walk (binfo, dfs_unmark, dfs_canonical_queue, 0); - assert_canonical_unmarked (binfo); + dfs_walk (binfo, dfs_unmark, 0, 0); return t != NULL_TREE; } -/* Recursive helper funciton for is_subobject_of_p; see that routine - for documentation of the parameters. */ - -static int -is_subobject_of_p_1 (tree parent, tree binfo, tree most_derived) -{ - tree binfos; - int i, n_baselinks; - - if (parent == binfo) - return 1; - - binfos = BINFO_BASETYPES (binfo); - n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Iterate through the base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree base_type; - - base_type = TREE_TYPE (base_binfo); - if (!CLASS_TYPE_P (base_type)) - /* If we see a TEMPLATE_TYPE_PARM, or some such, as a base - class there's no way to descend into it. */ - continue; - - /* Avoid walking into the same virtual base more than once. */ - if (TREE_VIA_VIRTUAL (base_binfo)) - { - if (CLASSTYPE_MARKED4 (base_type)) - continue; - SET_CLASSTYPE_MARKED4 (base_type); - base_binfo = binfo_for_vbase (base_type, most_derived); - } - - if (is_subobject_of_p_1 (parent, base_binfo, most_derived)) - return 1; - } - return 0; -} - -/* Routine to see if the sub-object denoted by the binfo PARENT can be - found as a base class and sub-object of the object denoted by - BINFO. MOST_DERIVED is the most derived type of the hierarchy being - searched. */ - -static int -is_subobject_of_p (tree parent, tree binfo, tree most_derived) -{ - int result; - tree vbase; - - result = is_subobject_of_p_1 (parent, binfo, most_derived); - /* Clear the mark bits on virtual bases. */ - for (vbase = CLASSTYPE_VBASECLASSES (most_derived); - vbase; - vbase = TREE_CHAIN (vbase)) - CLEAR_CLASSTYPE_MARKED4 (TREE_TYPE (TREE_VALUE (vbase))); - - return result; -} - struct lookup_field_info { /* The type in which we're looking. */ tree type; @@ -1098,8 +977,6 @@ struct lookup_field_info { tree ambiguous; /* If nonzero, we are looking for types, not data members. */ int want_type; - /* If nonzero, RVAL was found by looking through a dependent base. */ - int from_dep_base_p; /* If something went wrong, a message indicating what. */ const char *errstr; }; @@ -1110,8 +987,9 @@ struct lookup_field_info { lookup_field via breadth_first_search. */ static tree -lookup_field_queue_p (tree binfo, void *data) +lookup_field_queue_p (tree derived, int ix, void *data) { + tree binfo = BINFO_BASETYPE (derived, ix); struct lookup_field_info *lfi = (struct lookup_field_info *) data; /* Don't look for constructors or destructors in base classes. */ @@ -1120,11 +998,13 @@ lookup_field_queue_p (tree binfo, void *data) /* If this base class is hidden by the best-known value so far, we don't need to look. */ - binfo = CANONICAL_BINFO (binfo, lfi->type); - if (!lfi->from_dep_base_p && lfi->rval_binfo - && is_subobject_of_p (binfo, lfi->rval_binfo, lfi->type)) + if (lfi->rval_binfo && original_binfo (binfo, lfi->rval_binfo)) return NULL_TREE; + /* If this is a dependent base, don't look in it. */ + if (BINFO_DEPENDENT_BASE_P (binfo)) + return NULL_TREE; + return binfo; } @@ -1187,7 +1067,6 @@ lookup_field_r (tree binfo, void *data) struct lookup_field_info *lfi = (struct lookup_field_info *) data; tree type = BINFO_TYPE (binfo); tree nval = NULL_TREE; - int from_dep_base_p; /* First, look for a function. There can't be a function and a data member with the same name, and if there's a function and a type @@ -1241,40 +1120,14 @@ lookup_field_r (tree binfo, void *data) && template_self_reference_p (type, nval)) return NULL_TREE; - from_dep_base_p = dependent_base_p (binfo); - if (lfi->from_dep_base_p && !from_dep_base_p) - { - /* If the new declaration is not found via a dependent base, and - the old one was, then we must prefer the new one. We weren't - really supposed to be able to find the old one, so we don't - want to be affected by a specialization. Consider: - - struct B { typedef int I; }; - template struct D1 : virtual public B {}; - template struct D : - public D1, virtual pubic B { I i; }; - - The `I' in `D' is unambigousuly `B::I', regardless of how - D1 is specialized. */ - lfi->from_dep_base_p = 0; - lfi->rval = NULL_TREE; - lfi->rval_binfo = NULL_TREE; - lfi->ambiguous = NULL_TREE; - lfi->errstr = 0; - } - else if (lfi->rval_binfo && !lfi->from_dep_base_p && from_dep_base_p) - /* Similarly, if the old declaration was not found via a dependent - base, and the new one is, ignore the new one. */ - return NULL_TREE; - /* If the lookup already found a match, and the new value doesn't hide the old one, we might have an ambiguity. */ - if (lfi->rval_binfo && !is_subobject_of_p (lfi->rval_binfo, binfo, lfi->type)) + if (lfi->rval_binfo && !original_binfo (lfi->rval_binfo, binfo)) { if (nval == lfi->rval && shared_member_p (nval)) /* The two things are really the same. */ ; - else if (is_subobject_of_p (binfo, lfi->rval_binfo, lfi->type)) + else if (original_binfo (binfo, lfi->rval_binfo)) /* The previous value hides the new one. */ ; else @@ -1298,18 +1151,7 @@ lookup_field_r (tree binfo, void *data) } else { - if (from_dep_base_p && TREE_CODE (nval) == TYPE_DECL - /* We need to return a member template class so we can - define partial specializations. Is there a better - way? */ - && !DECL_CLASS_TEMPLATE_P (nval)) - /* The thing we're looking for isn't a type, so the implicit - typename extension doesn't apply, so we just pretend we - didn't find anything. */ - return NULL_TREE; - lfi->rval = nval; - lfi->from_dep_base_p = from_dep_base_p; lfi->rval_binfo = binfo; } @@ -1443,11 +1285,6 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type) rval = error_mark_node; } - /* If the thing we found was found via the implicit typename - extension, build the typename type. */ - if (rval && lfi.from_dep_base_p && !DECL_CLASS_TEMPLATE_P (rval)) - abort (); - if (rval && is_overloaded_fn (rval)) rval = build_baselink (rval_binfo, basetype_path, rval, (IDENTIFIER_TYPENAME_P (name) @@ -1679,8 +1516,10 @@ grow_bfs_bases (tree **basep, size_t *sizep, size_t *headp) use do-while for the inner loop. */ static tree -bfs_walk (tree binfo, tree (*fn) (tree, void *), - tree (*qfn) (tree, void *), void *data) +bfs_walk (tree binfo, + tree (*fn) (tree, void *), + tree (*qfn) (tree, int, void *), + void *data) { tree rval = NULL_TREE; @@ -1698,54 +1537,50 @@ bfs_walk (tree binfo, tree (*fn) (tree, void *), return rval; /* If it has no base types, we are also done. */ - if (BINFO_BASETYPES (binfo) == 0 - || TREE_VEC_LENGTH (BINFO_BASETYPES (binfo)) == 0) + if (!BINFO_BASETYPES (binfo)) return 0; /* Otherwise, initialize the queue with its basetypes vector and proceed. */ head = tail = 0; - bfs_bases[tail++] = BINFO_BASETYPES (binfo); + bfs_bases[tail++] = binfo; - do + while (head != tail) { - int i, n_baselinks; - tree binfos; - - binfos = bfs_bases[head++]; + int n_bases, ix; + tree binfo = bfs_bases[head++]; if (head == bfs_bases_size) head = 0; - i = 0; - n_baselinks = TREE_VEC_LENGTH (binfos); - do - { - binfo = TREE_VEC_ELT (binfos, i); - i++; - - if (qfn) - binfo = qfn (binfo, data); - if (!binfo) - continue; + /* Is this the one we're looking for? If so, we're done. */ + rval = fn (binfo, data); + if (rval) + goto done; - rval = fn (binfo, data); - if (rval) - goto done; + n_bases = BINFO_N_BASETYPES (binfo); + if (n_bases) + { + for (ix = 0; ix != n_bases; ix++) + { + tree base_binfo; - if (BINFO_BASETYPES (binfo) == 0 - || TREE_VEC_LENGTH (BINFO_BASETYPES (binfo)) == 0) - continue; + if (qfn) + base_binfo = (*qfn) (binfo, ix, data); + else + base_binfo = BINFO_BASETYPE (binfo, ix); - bfs_bases[tail++] = BINFO_BASETYPES (binfo); - if (tail == bfs_bases_size) - tail = 0; - if (tail == head) - grow_bfs_bases (&bfs_bases, &bfs_bases_size, &head); + if (base_binfo) + { + bfs_bases[tail++] = base_binfo; + if (tail == bfs_bases_size) + tail = 0; + if (tail == head) + grow_bfs_bases (&bfs_bases, &bfs_bases_size, &head); + } + } } - while (i < n_baselinks); } - while (head != tail); done: if (bfs_bases != bfs_bases_initial) @@ -1758,13 +1593,12 @@ bfs_walk (tree binfo, tree (*fn) (tree, void *), in postorder. */ tree -dfs_walk_real (tree binfo, - tree (*prefn) (tree, void *), tree (*postfn) (tree, void *), - tree (*qfn) (tree, void *), void *data) +dfs_walk_real (tree binfo, + tree (*prefn) (tree, void *), + tree (*postfn) (tree, void *), + tree (*qfn) (tree, int, void *), + void *data) { - int i; - int n_baselinks; - tree binfos; tree rval = NULL_TREE; /* Call the pre-order walking function. */ @@ -1776,20 +1610,24 @@ dfs_walk_real (tree binfo, } /* Process the basetypes. */ - binfos = BINFO_BASETYPES (binfo); - n_baselinks = BINFO_N_BASETYPES (binfo); - for (i = 0; i < n_baselinks; i++) + if (BINFO_BASETYPES (binfo)) { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - if (qfn) - base_binfo = (*qfn) (base_binfo, data); - - if (base_binfo) + int i, n = TREE_VEC_LENGTH (BINFO_BASETYPES (binfo)); + for (i = 0; i != n; i++) { - rval = dfs_walk_real (base_binfo, prefn, postfn, qfn, data); - if (rval) - return rval; + tree base_binfo; + + if (qfn) + base_binfo = (*qfn) (binfo, i, data); + else + base_binfo = BINFO_BASETYPE (binfo, i); + + if (base_binfo) + { + rval = dfs_walk_real (base_binfo, prefn, postfn, qfn, data); + if (rval) + return rval; + } } } @@ -1804,8 +1642,10 @@ dfs_walk_real (tree binfo, performed. */ tree -dfs_walk (tree binfo, tree (*fn) (tree, void *), - tree (*qfn) (tree, void *), void *data) +dfs_walk (tree binfo, + tree (*fn) (tree, void *), + tree (*qfn) (tree, int, void *), + void *data) { return dfs_walk_real (binfo, 0, fn, qfn, data); } @@ -2007,59 +1847,6 @@ look_for_overrides_r (tree type, tree fndecl) return look_for_overrides (type, fndecl); } -/* A queue function to use with dfs_walk that only walks into - canonical bases. DATA should be the type of the complete object, - or a TREE_LIST whose TREE_PURPOSE is the type of the complete - object. By using this function as a queue function, you will walk - over exactly those BINFOs that actually exist in the complete - object, including those for virtual base classes. If you - SET_BINFO_MARKED for each binfo you process, you are further - guaranteed that you will walk into each virtual base class exactly - once. */ - -tree -dfs_unmarked_real_bases_queue_p (tree binfo, void *data) -{ - if (TREE_VIA_VIRTUAL (binfo)) - { - tree type = (tree) data; - - if (TREE_CODE (type) == TREE_LIST) - type = TREE_PURPOSE (type); - binfo = binfo_for_vbase (BINFO_TYPE (binfo), type); - } - return unmarkedp (binfo, NULL); -} - -/* Like dfs_unmarked_real_bases_queue_p but walks only into things - that are marked, rather than unmarked. */ - -tree -dfs_marked_real_bases_queue_p (tree binfo, void *data) -{ - if (TREE_VIA_VIRTUAL (binfo)) - { - tree type = (tree) data; - - if (TREE_CODE (type) == TREE_LIST) - type = TREE_PURPOSE (type); - binfo = binfo_for_vbase (BINFO_TYPE (binfo), type); - } - return markedp (binfo, NULL); -} - -/* A queue function that skips all virtual bases (and their - bases). */ - -tree -dfs_skip_vbases (tree binfo, void *data ATTRIBUTE_UNUSED) -{ - if (TREE_VIA_VIRTUAL (binfo)) - return NULL_TREE; - - return binfo; -} - /* Called via dfs_walk from dfs_get_pure_virtuals. */ static tree @@ -2083,7 +1870,7 @@ dfs_get_pure_virtuals (tree binfo, void *data) CLASSTYPE_PURE_VIRTUALS (type)); } - SET_BINFO_MARKED (binfo); + BINFO_MARKED (binfo) = 1; return NULL_TREE; } @@ -2104,10 +1891,8 @@ get_pure_virtuals (tree type) (A primary base is not interesting because the derived class of which it is a primary base will contain vtable entries for the pure virtuals in the base class. */ - dfs_walk (TYPE_BINFO (type), dfs_get_pure_virtuals, - dfs_unmarked_real_bases_queue_p, type); - dfs_walk (TYPE_BINFO (type), dfs_unmark, - dfs_marked_real_bases_queue_p, type); + dfs_walk (TYPE_BINFO (type), dfs_get_pure_virtuals, unmarkedp, type); + dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, type); /* Put the pure virtuals in dfs order. */ CLASSTYPE_PURE_VIRTUALS (type) = nreverse (CLASSTYPE_PURE_VIRTUALS (type)); @@ -2132,42 +1917,36 @@ get_pure_virtuals (tree type) /* DEPTH-FIRST SEARCH ROUTINES. */ tree -markedp (tree binfo, void *data ATTRIBUTE_UNUSED) +markedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED) { + tree binfo = BINFO_BASETYPE (derived, ix); + return BINFO_MARKED (binfo) ? binfo : NULL_TREE; } tree -unmarkedp (tree binfo, void *data ATTRIBUTE_UNUSED) +unmarkedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED) { - return !BINFO_MARKED (binfo) ? binfo : NULL_TREE; -} - -tree -marked_vtable_pathp (tree binfo, void *data ATTRIBUTE_UNUSED) -{ - return BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE; -} - -tree -unmarked_vtable_pathp (tree binfo, void *data ATTRIBUTE_UNUSED) -{ - return !BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE; + tree binfo = BINFO_BASETYPE (derived, ix); + + return !BINFO_MARKED (binfo) ? binfo : NULL_TREE; } static tree -marked_pushdecls_p (tree binfo, void *data ATTRIBUTE_UNUSED) +marked_pushdecls_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED) { - return (CLASS_TYPE_P (BINFO_TYPE (binfo)) - && !dependent_base_p (binfo) + tree binfo = BINFO_BASETYPE (derived, ix); + + return (!BINFO_DEPENDENT_BASE_P (binfo) && BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE; } static tree -unmarked_pushdecls_p (tree binfo, void *data ATTRIBUTE_UNUSED) +unmarked_pushdecls_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED) { - return (CLASS_TYPE_P (BINFO_TYPE (binfo)) - && !dependent_base_p (binfo) + tree binfo = BINFO_BASETYPE (derived, ix); + + return (!BINFO_DEPENDENT_BASE_P (binfo) && !BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE; } @@ -2177,99 +1956,11 @@ unmarked_pushdecls_p (tree binfo, void *data ATTRIBUTE_UNUSED) tree dfs_unmark (tree binfo, void *data ATTRIBUTE_UNUSED) -{ - CLEAR_BINFO_MARKED (binfo); - return NULL_TREE; -} - -/* get virtual base class types. - This adds type to the vbase_types list in reverse dfs order. - Ordering is very important, so don't change it. */ - -static tree -dfs_get_vbase_types (tree binfo, void *data) -{ - tree type = (tree) data; - - if (TREE_VIA_VIRTUAL (binfo)) - CLASSTYPE_VBASECLASSES (type) - = tree_cons (BINFO_TYPE (binfo), - binfo, - CLASSTYPE_VBASECLASSES (type)); - SET_BINFO_MARKED (binfo); - return NULL_TREE; -} - -/* Called via dfs_walk from mark_primary_bases. Builds the - inheritance graph order list of BINFOs. */ - -static tree -dfs_build_inheritance_graph_order (tree binfo, void *data) { - tree *last_binfo = (tree *) data; - - if (*last_binfo) - TREE_CHAIN (*last_binfo) = binfo; - *last_binfo = binfo; - SET_BINFO_MARKED (binfo); + BINFO_MARKED (binfo) = 0; return NULL_TREE; } -/* Set CLASSTYPE_VBASECLASSES for TYPE. */ - -void -get_vbase_types (tree type) -{ - tree last_binfo; - - CLASSTYPE_VBASECLASSES (type) = NULL_TREE; - dfs_walk (TYPE_BINFO (type), dfs_get_vbase_types, unmarkedp, type); - /* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now - reverse it so that we get normal dfs ordering. */ - CLASSTYPE_VBASECLASSES (type) = nreverse (CLASSTYPE_VBASECLASSES (type)); - dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, 0); - /* Thread the BINFOs in inheritance-graph order. */ - last_binfo = NULL; - dfs_walk_real (TYPE_BINFO (type), - dfs_build_inheritance_graph_order, - NULL, - unmarkedp, - &last_binfo); - dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, NULL); -} - -/* Called from find_vbase_instance via dfs_walk. */ - -static tree -dfs_find_vbase_instance (tree binfo, void *data) -{ - tree base = TREE_VALUE ((tree) data); - - if (BINFO_PRIMARY_P (binfo) - && same_type_p (BINFO_TYPE (binfo), base)) - return binfo; - - return NULL_TREE; -} - -/* Find the real occurrence of the virtual BASE (a class type) in the - hierarchy dominated by TYPE. */ - -tree -find_vbase_instance (tree base, tree type) -{ - tree instance; - - instance = binfo_for_vbase (base, type); - if (!BINFO_PRIMARY_P (instance)) - return instance; - - return dfs_walk (TYPE_BINFO (type), - dfs_find_vbase_instance, - NULL, - build_tree_list (type, base)); -} - /* Debug info for C++ classes can get very large; try to avoid emitting it everywhere. @@ -2334,8 +2025,10 @@ dfs_debug_mark (tree binfo, void *data ATTRIBUTE_UNUSED) info for this base class. */ static tree -dfs_debug_unmarkedp (tree binfo, void *data ATTRIBUTE_UNUSED) -{ +dfs_debug_unmarkedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED) +{ + tree binfo = BINFO_BASETYPE (derived, ix); + return (!CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) ? binfo : NULL_TREE); } @@ -2361,22 +2054,6 @@ note_debug_info_needed (tree type) /* Subroutines of push_class_decls (). */ -/* Returns 1 iff BINFO is a base we shouldn't really be able to see into, - because it (or one of the intermediate bases) depends on template parms. */ - -static int -dependent_base_p (tree binfo) -{ - for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo)) - { - if (currently_open_class (TREE_TYPE (binfo))) - break; - if (dependent_type_p (TREE_TYPE (binfo))) - return 1; - } - return 0; -} - static void setup_class_bindings (tree name, int type_binding_p) { @@ -2449,7 +2126,7 @@ dfs_push_type_decls (tree binfo, void *data ATTRIBUTE_UNUSED) /* We can't just use BINFO_MARKED because envelope_add_decl uses DERIVED_FROM_P, which calls get_base_distance. */ - SET_BINFO_PUSHDECLS_MARKED (binfo); + BINFO_PUSHDECLS_MARKED (binfo) = 1; return NULL_TREE; } @@ -2460,46 +2137,39 @@ dfs_push_type_decls (tree binfo, void *data ATTRIBUTE_UNUSED) static tree dfs_push_decls (tree binfo, void *data) { - tree type; + tree type = BINFO_TYPE (binfo); tree method_vec; - int dep_base_p; - - type = BINFO_TYPE (binfo); - dep_base_p = (processing_template_decl && type != current_class_type - && dependent_base_p (binfo)); - if (!dep_base_p) + tree fields; + + for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) + if (DECL_NAME (fields) + && TREE_CODE (fields) != TYPE_DECL + && TREE_CODE (fields) != USING_DECL + && !DECL_ARTIFICIAL (fields)) + setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/0); + else if (TREE_CODE (fields) == FIELD_DECL + && ANON_AGGR_TYPE_P (TREE_TYPE (fields))) + dfs_push_decls (TYPE_BINFO (TREE_TYPE (fields)), data); + + method_vec = (CLASS_TYPE_P (type) + ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE); + + if (method_vec && TREE_VEC_LENGTH (method_vec) >= 3) { - tree fields; - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) - if (DECL_NAME (fields) - && TREE_CODE (fields) != TYPE_DECL - && TREE_CODE (fields) != USING_DECL - && !DECL_ARTIFICIAL (fields)) - setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/0); - else if (TREE_CODE (fields) == FIELD_DECL - && ANON_AGGR_TYPE_P (TREE_TYPE (fields))) - dfs_push_decls (TYPE_BINFO (TREE_TYPE (fields)), data); - - method_vec = (CLASS_TYPE_P (type) - ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE); - - if (method_vec && TREE_VEC_LENGTH (method_vec) >= 3) - { - tree *methods; - tree *end; - - /* Farm out constructors and destructors. */ - end = TREE_VEC_END (method_vec); - - for (methods = &TREE_VEC_ELT (method_vec, 2); - methods < end && *methods; - methods++) - setup_class_bindings (DECL_NAME (OVL_CURRENT (*methods)), - /*type_binding_p=*/0); - } + tree *methods; + tree *end; + + /* Farm out constructors and destructors. */ + end = TREE_VEC_END (method_vec); + + for (methods = &TREE_VEC_ELT (method_vec, 2); + methods < end && *methods; + methods++) + setup_class_bindings (DECL_NAME (OVL_CURRENT (*methods)), + /*type_binding_p=*/0); } - CLEAR_BINFO_PUSHDECLS_MARKED (binfo); + BINFO_PUSHDECLS_MARKED (binfo) = 0; return NULL_TREE; } @@ -2678,9 +2348,11 @@ dfs_check_overlap (tree empty_binfo, void *data) /* Trivial function to stop base traversal when we find something. */ static tree -dfs_no_overlap_yet (tree binfo, void *data) +dfs_no_overlap_yet (tree derived, int ix, void *data) { + tree binfo = BINFO_BASETYPE (derived, ix); struct overlap_info *oi = (struct overlap_info *) data; + return !oi->found_overlap ? binfo : NULL_TREE; } @@ -2759,14 +2431,99 @@ binfo_via_virtual (tree binfo, tree limit) return NULL_TREE; } -/* Returns the BINFO (if any) for the virtual baseclass T of the class - C from the CLASSTYPE_VBASECLASSES list. */ +/* BINFO is a base binfo in the complete type BINFO_TYPE (HERE). + Find the equivalent binfo within whatever graph HERE is located. + This is the inverse of original_binfo. */ tree -binfo_for_vbase (tree basetype, tree classtype) +copied_binfo (tree binfo, tree here) { - tree binfo; + tree result = NULL_TREE; + + if (TREE_VIA_VIRTUAL (binfo)) + { + tree t; - binfo = purpose_member (basetype, CLASSTYPE_VBASECLASSES (classtype)); - return binfo ? TREE_VALUE (binfo) : NULL_TREE; + for (t = here; BINFO_INHERITANCE_CHAIN (t); + t = BINFO_INHERITANCE_CHAIN (t)) + continue; + + result = purpose_member (BINFO_TYPE (binfo), + CLASSTYPE_VBASECLASSES (BINFO_TYPE (t))); + result = TREE_VALUE (result); + } + else if (BINFO_INHERITANCE_CHAIN (binfo)) + { + tree base_binfos; + int ix, n; + + base_binfos = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here); + base_binfos = BINFO_BASETYPES (base_binfos); + n = TREE_VEC_LENGTH (base_binfos); + for (ix = 0; ix != n; ix++) + { + tree base = TREE_VEC_ELT (base_binfos, ix); + + if (BINFO_TYPE (base) == BINFO_TYPE (binfo)) + { + result = base; + break; + } + } + } + else + { + my_friendly_assert (BINFO_TYPE (here) == BINFO_TYPE (binfo), 20030202); + result = here; + } + + my_friendly_assert (result, 20030202); + return result; } + +/* BINFO is some base binfo of HERE, within some other + hierachy. Return the equivalent binfo, but in the hierarchy + dominated by HERE. This is the inverse of copied_binfo. If BINFO + is not a base binfo of HERE, returns NULL_TREE. */ + +tree +original_binfo (tree binfo, tree here) +{ + tree result = NULL; + + if (BINFO_TYPE (binfo) == BINFO_TYPE (here)) + result = here; + else if (TREE_VIA_VIRTUAL (binfo)) + { + result = purpose_member (BINFO_TYPE (binfo), + CLASSTYPE_VBASECLASSES (BINFO_TYPE (here))); + if (result) + result = TREE_VALUE (result); + } + else if (BINFO_INHERITANCE_CHAIN (binfo)) + { + tree base_binfos; + + base_binfos = original_binfo (BINFO_INHERITANCE_CHAIN (binfo), here); + if (base_binfos) + { + int ix, n; + + base_binfos = BINFO_BASETYPES (base_binfos); + n = TREE_VEC_LENGTH (base_binfos); + for (ix = 0; ix != n; ix++) + { + tree base = TREE_VEC_ELT (base_binfos, ix); + + if (BINFO_TYPE (base) == BINFO_TYPE (binfo)) + { + result = base; + break; + } + } + } + } + + return result; +} + diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9c0b28b6b13..cf0bec7249b 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3,7 +3,8 @@ building RTL. These routines are used both during actual parsing and during the instantiation of template functions. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002, + 2003 Free Software Foundation, Inc. Written by Mark Mitchell (mmitchell@usa.net) based on code found formerly in parse.y and pt.c. @@ -2038,27 +2039,26 @@ finish_template_type (name, args, entering_scope) access_{default,public,protected_private}[_virtual]_node.*/ tree -finish_base_specifier (access_specifier, base_class) - tree access_specifier; - tree base_class; +finish_base_specifier (tree base, tree access, bool virtual_p) { tree result; - if (base_class == error_mark_node) + if (base == error_mark_node) { error ("invalid base-class specification"); result = NULL_TREE; } - else if (! is_aggr_type (base_class, 1)) + else if (! is_aggr_type (base, 1)) result = NULL_TREE; else { - if (cp_type_quals (base_class) != 0) + if (cp_type_quals (base) != 0) { - error ("base class `%T' has cv qualifiers", base_class); - base_class = TYPE_MAIN_VARIANT (base_class); + error ("base class `%T' has cv qualifiers", base); + base = TYPE_MAIN_VARIANT (base); } - result = build_tree_list (access_specifier, base_class); + result = build_tree_list (access, base); + TREE_VIA_VIRTUAL (result) = virtual_p; } return result; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 320ea9585c8..520aa164572 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1,6 +1,6 @@ /* Language-dependent node constructors for parse phase of GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -714,37 +714,81 @@ canonical_type_variant (t) return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), cp_type_quals (t)); } -/* Makes new binfos for the indirect bases under BINFO, and updates - BINFO_OFFSET for them and their bases. */ +/* Makes new binfos for the indirect bases under BINFO. T is the most + derived TYPE. PREV is the previous binfo, whose TREE_CHAIN we make + point to this binfo. We return the last BINFO created. -void -unshare_base_binfos (binfo) - tree binfo; + The CLASSTYPE_VBASECLASSES list of T is constructed in reverse + order (pre-order, depth-first, right-to-left). You must nreverse it. + + The BINFO_INHERITANCE of a virtual base class points to the binfo + og the most derived type. + + The binfo's TREE_CHAIN is set to inheritance graph order, but bases + for non-class types are not included (i.e. those which are + dependent bases in non-instantiated templates). */ + +tree +copy_base_binfos (binfo, t, prev) + tree binfo, t, prev; { tree binfos = BINFO_BASETYPES (binfo); - tree new_binfo; - int j; + int n, ix; + if (prev) + TREE_CHAIN (prev) = binfo; + prev = binfo; + if (binfos == NULL_TREE) - return; + return prev; - /* Now unshare the structure beneath BINFO. */ - for (j = TREE_VEC_LENGTH (binfos)-1; - j >= 0; j--) + n = TREE_VEC_LENGTH (binfos); + + /* Now copy the structure beneath BINFO. */ + for (ix = 0; ix != n; ix++) { - tree base_binfo = TREE_VEC_ELT (binfos, j); - new_binfo = TREE_VEC_ELT (binfos, j) - = make_binfo (BINFO_OFFSET (base_binfo), - base_binfo, - BINFO_VTABLE (base_binfo), - BINFO_VIRTUALS (base_binfo)); - TREE_VIA_PUBLIC (new_binfo) = TREE_VIA_PUBLIC (base_binfo); - TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo); - TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo); - BINFO_INHERITANCE_CHAIN (new_binfo) = binfo; - BINFO_PRIMARY_BASE_OF (new_binfo) = NULL_TREE; - unshare_base_binfos (new_binfo); + tree base_binfo = TREE_VEC_ELT (binfos, ix); + tree new_binfo = NULL_TREE; + + if (!CLASS_TYPE_P (BINFO_TYPE (base_binfo))) + { + my_friendly_assert (binfo == TYPE_BINFO (t), 20030204); + + new_binfo = base_binfo; + TREE_CHAIN (prev) = new_binfo; + prev = new_binfo; + BINFO_INHERITANCE_CHAIN (new_binfo) = binfo; + BINFO_DEPENDENT_BASE_P (new_binfo) = 1; + } + else if (TREE_VIA_VIRTUAL (base_binfo)) + { + new_binfo = purpose_member (BINFO_TYPE (base_binfo), + CLASSTYPE_VBASECLASSES (t)); + if (new_binfo) + new_binfo = TREE_VALUE (new_binfo); + } + + if (!new_binfo) + { + new_binfo = make_binfo (BINFO_OFFSET (base_binfo), + base_binfo, NULL_TREE, + BINFO_VIRTUALS (base_binfo)); + prev = copy_base_binfos (new_binfo, t, prev); + if (TREE_VIA_VIRTUAL (base_binfo)) + { + CLASSTYPE_VBASECLASSES (t) + = tree_cons (BINFO_TYPE (new_binfo), new_binfo, + CLASSTYPE_VBASECLASSES (t)); + TREE_VIA_VIRTUAL (new_binfo) = 1; + BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t); + } + else + BINFO_INHERITANCE_CHAIN (new_binfo) = binfo; + } + TREE_VEC_ELT (binfos, ix) = new_binfo; } + + return prev; } @@ -897,11 +941,15 @@ make_binfo (offset, binfo, vtable, virtuals) tree type; if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); + { + type = BINFO_TYPE (binfo); + BINFO_DEPENDENT_BASE_P (new_binfo) = BINFO_DEPENDENT_BASE_P (binfo); + } else { type = binfo; - binfo = CLASS_TYPE_P (type) ? TYPE_BINFO (binfo) : NULL_TREE; + binfo = NULL_TREE; + BINFO_DEPENDENT_BASE_P (new_binfo) = 1; } TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type); @@ -909,31 +957,14 @@ make_binfo (offset, binfo, vtable, virtuals) BINFO_VTABLE (new_binfo) = vtable; BINFO_VIRTUALS (new_binfo) = virtuals; - if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE) - BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo)); - return new_binfo; -} - -/* Return a TREE_LIST whose TREE_VALUE nodes along the - BINFO_INHERITANCE_CHAIN for BINFO, but in the opposite order. In - other words, while the BINFO_INHERITANCE_CHAIN goes from base - classes to derived classes, the reversed path goes from derived - classes to base classes. */ - -tree -reverse_path (binfo) - tree binfo; -{ - tree reversed_path; - - reversed_path = NULL_TREE; - while (binfo) + if (binfo && !BINFO_DEPENDENT_BASE_P (binfo) + && BINFO_BASETYPES (binfo) != NULL_TREE) { - reversed_path = tree_cons (NULL_TREE, binfo, reversed_path); - binfo = BINFO_INHERITANCE_CHAIN (binfo); + BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo)); + /* We do not need to copy the accesses, as they are read only. */ + BINFO_BASEACCESSES (new_binfo) = BINFO_BASEACCESSES (binfo); } - - return reversed_path; + return new_binfo; } void diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 7c6cb57e9a9..06a0b420705 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5720,9 +5720,8 @@ get_delta_difference (from, to, force) if (virt_binfo) { /* This is a reinterpret cast, we choose to do nothing. */ - warning ("pointer to member cast via virtual base `%T' of `%T'", - BINFO_TYPE (virt_binfo), - BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo))); + warning ("pointer to member cast via virtual base `%T'", + BINFO_TYPE (virt_binfo)); return delta; } delta = BINFO_OFFSET (binfo); @@ -5739,13 +5738,11 @@ get_delta_difference (from, to, force) { /* This is a reinterpret cast, we choose to do nothing. */ if (force) - warning ("pointer to member cast via virtual base `%T' of `%T'", - BINFO_TYPE (virt_binfo), - BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo))); + warning ("pointer to member cast via virtual base `%T'", + BINFO_TYPE (virt_binfo)); else - error ("pointer to member conversion via virtual base `%T' of `%T'", - BINFO_TYPE (virt_binfo), - BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo))); + error ("pointer to member conversion via virtual base `%T'", + BINFO_TYPE (virt_binfo)); return delta; } delta = BINFO_OFFSET (binfo); diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 468ee0969d3..683745fc56b 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -1,6 +1,6 @@ /* Output dbx-format symbol table information from GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -1577,15 +1577,19 @@ dbxout_type (type, full) } for (i = 0; i < n_baseclasses; i++) { - tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i); - + tree binfo = TYPE_BINFO (type); + tree child = BINFO_BASETYPE (binfo, i); + tree access = (BINFO_BASEACCESSES (binfo) + ? BINFO_BASEACCESS (binfo, i) : access_public_node); + if (use_gnu_debug_info_extensions) { have_used_extensions = 1; putc (TREE_VIA_VIRTUAL (child) ? '1' : '0', asmfile); - putc (TREE_VIA_PUBLIC (child) ? '2' : '0', asmfile); + putc (access == access_public_node ? '2' : '0', asmfile); CHARS (2); - if (TREE_VIA_VIRTUAL (child) && strcmp (lang_hooks.name, "GNU C++") == 0) + if (TREE_VIA_VIRTUAL (child) + && strcmp (lang_hooks.name, "GNU C++") == 0) /* For a virtual base, print the (negative) offset within the vtable where we must look to find the necessary adjustment. */ diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 435b5c070d8..ff0b8b0bdbb 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3818,7 +3818,7 @@ static void gen_field_die PARAMS ((tree, dw_die_ref)); static void gen_ptr_to_mbr_type_die PARAMS ((tree, dw_die_ref)); static dw_die_ref gen_compile_unit_die PARAMS ((const char *)); static void gen_string_type_die PARAMS ((tree, dw_die_ref)); -static void gen_inheritance_die PARAMS ((tree, dw_die_ref)); +static void gen_inheritance_die PARAMS ((tree, tree, dw_die_ref)); static void gen_member_die PARAMS ((tree, dw_die_ref)); static void gen_struct_or_union_type_die PARAMS ((tree, dw_die_ref)); static void gen_subroutine_type_die PARAMS ((tree, dw_die_ref)); @@ -11363,8 +11363,8 @@ gen_string_type_die (type, context_die) /* Generate the DIE for a base class. */ static void -gen_inheritance_die (binfo, context_die) - tree binfo; +gen_inheritance_die (binfo, access, context_die) + tree binfo, access; dw_die_ref context_die; { dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo); @@ -11375,9 +11375,9 @@ gen_inheritance_die (binfo, context_die) if (TREE_VIA_VIRTUAL (binfo)) add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual); - if (TREE_VIA_PUBLIC (binfo)) + if (access == access_public_node) add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_public); - else if (TREE_VIA_PROTECTED (binfo)) + else if (access == access_protected_node) add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_protected); } @@ -11389,6 +11389,7 @@ gen_member_die (type, context_die) dw_die_ref context_die; { tree member; + tree binfo = TYPE_BINFO (type); dw_die_ref child; /* If this is not an incomplete type, output descriptions of each of its @@ -11404,14 +11405,17 @@ gen_member_die (type, context_die) the TREE node representing the appropriate (containing) type. */ /* First output info about the base classes. */ - if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type)) + if (binfo && BINFO_BASETYPES (binfo)) { - tree bases = TYPE_BINFO_BASETYPES (type); + tree bases = BINFO_BASETYPES (binfo); + tree accesses = BINFO_BASEACCESSES (binfo); int n_bases = TREE_VEC_LENGTH (bases); int i; for (i = 0; i < n_bases; i++) - gen_inheritance_die (TREE_VEC_ELT (bases, i), context_die); + gen_inheritance_die (TREE_VEC_ELT (bases, i), + (accesses ? TREE_VEC_ELT (accesses, i) + : access_public_node), context_die); } /* Now output info about the data members and type members. */ diff --git a/gcc/dwarfout.c b/gcc/dwarfout.c index 07528cda1fc..8f456f7ee7e 100644 --- a/gcc/dwarfout.c +++ b/gcc/dwarfout.c @@ -4179,7 +4179,8 @@ static void output_inheritance_die (arg) void *arg; { - tree binfo = arg; + tree binfo = ((tree *)arg)[0]; + tree access = ((tree *)arg)[1]; ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_inheritance); sibling_attribute (); @@ -4190,12 +4191,12 @@ output_inheritance_die (arg) ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_virtual); ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); } - if (TREE_VIA_PUBLIC (binfo)) + if (access == access_public_node) { ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_public); ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); } - else if (TREE_VIA_PROTECTED (binfo)) + else if (access == access_protected_node) { ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_protected); ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, ""); @@ -4896,18 +4897,25 @@ output_type (type, containing_scope) if (COMPLETE_TYPE_P (type)) { + tree binfo = TYPE_BINFO (type); + /* First output info about the base classes. */ - if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type)) + if (binfo) { - register tree bases = TYPE_BINFO_BASETYPES (type); - register int n_bases = TREE_VEC_LENGTH (bases); + tree bases = BINFO_BASETYPES (binfo); + tree accesses = BINFO_BASEACCESSES (binfo); + register int n_bases = BINFO_N_BASETYPES (binfo); register int i; for (i = 0; i < n_bases; i++) { - tree binfo = TREE_VEC_ELT (bases, i); + tree arg[2]; + + arg[0] = TREE_VEC_ELT (bases, i); + arg[1] = (accesses ? TREE_VEC_ELT (accesses, i) + : access_public_node); output_type (BINFO_TYPE (binfo), containing_scope); - output_die (output_inheritance_die, binfo); + output_die (output_inheritance_die, arg); } } diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 084a704aa62..44dbbce9f88 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,9 @@ +2003-02-20 Nathan Sidwell + + Change base class access representation. + * java/class.c (set_super_info): Don't set TREE_VIA_PUBLIC. + (add_interface_do): Likewise. + 2003-02-12 Ranjit Mathew * decl.c (java_init_decl_processing): Change diff --git a/gcc/java/class.c b/gcc/java/class.c index 43468b32d90..a58f604da35 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -363,7 +363,6 @@ set_super_info (int access_flags, tree this_class, tree super_binfo = make_tree_vec (BINFO_ELTS); BINFO_TYPE (super_binfo) = super_class; BINFO_OFFSET (super_binfo) = integer_zero_node; - TREE_VIA_PUBLIC (super_binfo) = 1; TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (this_class)), 0) = super_binfo; CLASS_HAS_SUPER (this_class) = 1; @@ -497,7 +496,6 @@ add_interface_do (tree basetype_vec, tree interface_class, int i) BINFO_OFFSET (interface_binfo) = integer_zero_node; BINFO_VPTR_FIELD (interface_binfo) = integer_zero_node; TREE_VIA_VIRTUAL (interface_binfo) = 1; - TREE_VIA_PUBLIC (interface_binfo) = 1; TREE_VEC_ELT (basetype_vec, i) = interface_binfo; } diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c index b840611489d..4e360602b05 100644 --- a/gcc/tree-dump.c +++ b/gcc/tree-dump.c @@ -1,5 +1,5 @@ /* Tree-dumping functionality for intermediate representation. - Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. Written by Mark Mitchell This file is part of GCC. @@ -273,18 +273,37 @@ dequeue_and_dump (di) more informative. */ if (dni->binfo_p) { - if (TREE_VIA_PUBLIC (t)) - dump_string (di, "pub"); - else if (TREE_VIA_PROTECTED (t)) - dump_string (di, "prot"); - else if (TREE_VIA_PRIVATE (t)) - dump_string (di, "priv"); + unsigned ix; + tree bases = BINFO_BASETYPES (t); + unsigned n_bases = bases ? TREE_VEC_LENGTH (bases): 0; + tree accesses = BINFO_BASEACCESSES (t); + + dump_child ("type", BINFO_TYPE (t)); + if (TREE_VIA_VIRTUAL (t)) dump_string (di, "virt"); - dump_child ("type", BINFO_TYPE (t)); - dump_child ("base", BINFO_BASETYPES (t)); - + dump_int (di, "bases", n_bases); + for (ix = 0; ix != n_bases; ix++) + { + tree base = TREE_VEC_ELT (bases, ix); + tree access = (accesses ? TREE_VEC_ELT (accesses, ix) + : access_public_node); + const char *string = NULL; + + if (access == access_public_node) + string = "pub"; + else if (access == access_protected_node) + string = "prot"; + else if (access == access_private_node) + string = "priv"; + else + abort (); + + dump_string (di, string); + queue_and_dump_index (di, "binf", base, DUMP_BINFO); + } + goto done; } diff --git a/gcc/tree.h b/gcc/tree.h index e5344782fb8..7b714b17aaf 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1,6 +1,6 @@ /* Front-end tree definitions for GNU compiler. Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002 Free Software Foundation, Inc. + 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -192,15 +192,11 @@ struct tree_common GTY(()) INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST TREE_PUBLIC in VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE - TREE_VIA_PUBLIC in - TREE_LIST or TREE_VEC EXPR_WFL_EMIT_LINE_NOTE in EXPR_WITH_FILE_LOCATION private_flag: - TREE_VIA_PRIVATE in - TREE_LIST or TREE_VEC TREE_PRIVATE in ..._DECL CALL_EXPR_HAS_RETURN_SLOT_ADDR in @@ -208,9 +204,6 @@ struct tree_common GTY(()) protected_flag: - TREE_VIA_PROTECTED in - TREE_LIST - TREE_VEC TREE_PROTECTED in BLOCK ..._DECL @@ -565,20 +558,6 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *, for this name in an inner scope. */ #define TREE_PUBLIC(NODE) ((NODE)->common.public_flag) -/* Nonzero for TREE_LIST or TREE_VEC node means that the path to the - base class is via a `public' declaration, which preserves public - fields from the base class as public. */ -#define TREE_VIA_PUBLIC(NODE) ((NODE)->common.public_flag) - -/* Ditto, for `private' declarations. */ -#define TREE_VIA_PRIVATE(NODE) ((NODE)->common.private_flag) - -/* Nonzero for TREE_LIST or TREE_VEC node means that the path to the - base class is via a `protected' declaration, which preserves - protected fields from the base class as protected. - OVERLOADED. */ -#define TREE_VIA_PROTECTED(NODE) ((NODE)->common.protected_flag) - /* In any expression, nonzero means it has side effects or reevaluation of the whole expression could produce a different value. This is set if any subexpression is a function call, a side effect @@ -1362,7 +1341,16 @@ struct tree_type GTY(()) vtable where the offset to the virtual base can be found. */ #define BINFO_VPTR_FIELD(NODE) TREE_VEC_ELT (NODE, 5) -#define BINFO_ELTS 6 +/* Indicates the accesses this binfo has to its bases. The values are + access_public_node, access_protected_node or access_private_node. + If this array is not present, public access is implied. */ +#define BINFO_BASEACCESSES(NODE) TREE_VEC_ELT ((NODE), 6) +#define BINFO_BASEACCESS(NODE,N) TREE_VEC_ELT (BINFO_BASEACCESSES(NODE), (N)) + +/* Number of language independent elements in a binfo. Languages may + add additional trailing elements. */ + +#define BINFO_ELTS 7 /* Slot used to build a chain that represents a use of inheritance. For example, if X is derived from Y, and Y is derived from Z, @@ -2028,6 +2016,11 @@ extern GTY(()) tree global_trees[TI_MAX]; #define bitsize_one_node global_trees[TI_BITSIZE_ONE] #define bitsize_unit_node global_trees[TI_BITSIZE_UNIT] +/* Base access nodes. */ +#define access_public_node NULL_TREE +#define access_protected_node size_zero_node +#define access_private_node size_one_node + #define null_pointer_node global_trees[TI_NULL_POINTER] #define float_type_node global_trees[TI_FLOAT_TYPE] -- 2.43.5