]> gcc.gnu.org Git - gcc.git/commitdiff
Change base class access representation.
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 20 Feb 2003 17:51:46 +0000 (17:51 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 20 Feb 2003 17:51:46 +0000 (17:51 +0000)
* 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

21 files changed:
gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/dbxout.c
gcc/dwarf2out.c
gcc/dwarfout.c
gcc/java/ChangeLog
gcc/java/class.c
gcc/tree-dump.c
gcc/tree.h

index 0bdc28dd7a6689417ac3f9c2a279225eef37599c..9a3464e924a586756ff387e658db334b4b70fbf3 100644 (file)
@@ -1,3 +1,155 @@
+2003-02-20  Nathan Sidwell  <nathan@codesourcery.com>
+
+       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  <edelsohn@gnu.org>
 
         * config/rs6000/sysv4.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Define.
index 3006cfdd2a9180ab91618061dbcd512ba3a8c0d8..e013cf02e191efd96ced14c0256e6de2af026ba0 100644 (file)
@@ -1,3 +1,134 @@
+2003-02-20  Nathan Sidwell  <nathan@codesourcery.com>
+
+       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  <zack@codesourcery.com>
 
        * cp/search.c (grow_bfs_bases): New subroutine of bfs_walk.
index 0aa2d5360a5c5c2724d0dbd89c6a232217498901..98b60a10a535803f2dfda31779311e64cc641e46 100644 (file)
@@ -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));
index 5ee67bca7809c66be8151d49898aae7c67077f7f..89c11e653a002af6e9078a56d056cb9b1de28951 100644 (file)
@@ -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, 
-                     treevirtuals)
+                     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),
index 02a724d89f6f32511d2d9fae9272e1719cc0502c..e463fb4b68c5f7a76c348ce2c3a320171dd786ad 100644 (file)
@@ -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);
index 94cd4c3e7d2bf52d7dcaa8bec5216f57b79460fb..3f22b748618b2be598dba8214669093cf4d3f5c1 100644 (file)
@@ -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);
 }
 
 \f
index bb387ce1b0134c877a79c6be792a0d031688734b..7036aa02fb6475617a08bf0dc3afe264eeb560b3 100644 (file)
@@ -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
     {
index c81c3df5e94018f272e7c0297f91037d374cf83a..79ec8be641790196cdad2d081a8bec948394b800 100644 (file)
@@ -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] */
index 959bd54e93d032c9348fab289433dd218de5e4c9..add427d4ed1b8b541ef57a0856340d67863d7968 100644 (file)
@@ -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,
index e222d25c8764d4d398a4b9862aa995b0edef787f..9ebae8b5448e302429faf4e1c75db84cfd3daae5 100644 (file)
@@ -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.  */
index 395464e0ef967602b8942298e2033adb69ed5021..8fd1ee52e72ad846f1d0aef897735341f00f249f 100644 (file)
@@ -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 <typename T> struct D1 : virtual public B {}; 
-          template <typename T> struct D :
-          public D1, virtual pubic B { I i; };
-
-        The `I' in `D<T>' 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));
-}
-
 \f
 /* 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)
 \f
 /* 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;
+}
+
index 9c0b28b6b13fd54acc2d9e6017ee29359a1fbfb8..cf0bec7249bf96ad2b88e7cba4c70385e09d860c 100644 (file)
@@ -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;
index 320ea9585c8bf56d34f9cc5c257c006c8cdb7bb5..520aa164572126143fb5eb1cd24328592b52a002 100644 (file)
@@ -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));
 }
 \f
-/* 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;
 }
 
 \f
@@ -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
index 7c6cb57e9a9fae72389556e54ce6d9b84dcb2557..06a0b420705b5eae348aa0b352f3a60fb72e783f 100644 (file)
@@ -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);
index 468ee0969d386c01aacab024776c1be26e75c823..683745fc56b54c899a350254f4a5a2c7ea7959d8 100644 (file)
@@ -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.  */
index 435b5c070d814d71468b30b1c6b159f86ad8887b..ff0b8b0bdbbe21a2026f3859cb6d71faccacc96b 100644 (file)
@@ -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.  */
index 07528cda1fc19a205fa822be063acbe206077ff7..8f456f7ee7e6b6f4c6e058a0b5de0bb3fe2d743f 100644 (file)
@@ -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);
                  }
              }
 
index 084a704aa621afa4bb46f60282716dbf386d0f7e..44dbbce9f881716013a22f0026b6c45c2ed8bcc6 100644 (file)
@@ -1,3 +1,9 @@
+2003-02-20  Nathan Sidwell  <nathan@codesourcery.com>
+
+       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  <rmathew@hotmail.com>
 
        * decl.c (java_init_decl_processing): Change 
index 43468b32d90a703789798c559924910bdd3b584e..a58f604da35bc614721f5f160bbfb19cd58ca88b 100644 (file)
@@ -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;
 }
 
index b840611489d81438f74a6b0de22cf3fb0b563947..4e360602b058da1bef263c76c29ea86465d26319 100644 (file)
@@ -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 <mark@codesourcery.com>
 
 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;
     }
 
index e5344782fb8bbeb315407821bccb5f092bd14536..7b714b17aafa601e2d6e9eaea3c6a3bd7a2a66cb 100644 (file)
@@ -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]
This page took 0.193813 seconds and 5 git commands to generate.