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