aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog30
-rw-r--r--gcc/cp/class.c451
-rw-r--r--gcc/cp/cp-tree.h27
-rw-r--r--gcc/cp/method.c25
-rw-r--r--gcc/cp/search.c3
5 files changed, 446 insertions, 90 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1f621b3..9f63976 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,35 @@
2000-05-21 Mark Mitchell <mark@codesourcery.com>
+ * cp-tree.h (SET_BINFO_NEW_VTABLE_MARKED): Add sanity checks.
+ (VTT_NAME_PREFIX): New macro.
+ (CTOR_VTBL_NAME_PREFIX): Likewise.
+ (get_ctor_vtbl_name): New function.
+ * class.c (get_vtable_name): Simplify.
+ (get_vtt_name): New function.
+ (get_vtable_decl): Don't set IDENTIFIER_GLOBAL_VALUE.
+ (dfs_mark_primary_bases): Update the CLASSTYPE_VBASECLASSES list
+ when a virtual base becomes primary.
+ (finish_struct_1): Set CLASSTYPE_VFIELDS a little earlier. Build
+ VTTs.
+ (finish_vtbls): Adjust calls to accumulate_vtbl_inits to pass in
+ additional parameters.
+ (dfs_finish_vtbls): Don't clear BINFO_NEW_VTABLE_MARKED.
+ (initialize_array): New function.
+ (build_vtt): Likewise.
+ (build_vtt_inits): Likewise.
+ (dfs_build_vtt_inits): Likewise.
+ (dfs_fixup_binfo_vtbls): Likewise.
+ (build_ctor_vtbl_group): Likewise.
+ (initialize_vtable): Use initialize_array.
+ (accumulate_vtbl_inits): Reimplement to handle construction
+ vtables.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (bulid_vtbl_initializer): Adjust parameter name.
+ * method.c (build_typename_overload): Remove #if 0'd code.
+ (get_ctor_vtbl_name): New function.
+ * search.c (dfs_walk_real): Use BINFO_N_BASETYPES.
+ (init_vbase_pointers): Don't mess with the TREE_CHAIN of a binfo.
+
* cp-tree.h (struct lang_type): Remove search_slot.
(CLASSTYPE_SEARCH_SLOT): Remove.
(emit_base_init): Change prototype.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index cc63239..3fcb0f4 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -93,7 +93,8 @@ static tree get_basefndecls PARAMS ((tree, tree));
static int build_primary_vtable PARAMS ((tree, tree));
static int build_secondary_vtable PARAMS ((tree, tree));
static tree dfs_finish_vtbls PARAMS ((tree, void *));
-static tree dfs_accumulate_vtbl_inits PARAMS ((tree, void *));
+static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree,
+ tree));
static void finish_vtbls PARAMS ((tree));
static void modify_vtable_entry PARAMS ((tree, tree, tree, tree, tree *));
static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
@@ -157,6 +158,7 @@ static void dump_class_hierarchy_r PARAMS ((tree, tree, int));
extern void dump_class_hierarchy PARAMS ((tree));
static tree build_vtable PARAMS ((tree, tree, tree));
static void initialize_vtable PARAMS ((tree, tree));
+static void initialize_array PARAMS ((tree, tree));
static void layout_nonempty_base_or_field PARAMS ((record_layout_info,
tree, tree,
varray_type));
@@ -166,7 +168,7 @@ static tree dfs_search_base_offsets PARAMS ((tree, void *));
static int layout_conflict_p PARAMS ((tree, varray_type));
static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
static void layout_empty_base PARAMS ((tree, tree, varray_type));
-static void accumulate_vtbl_inits PARAMS ((tree, tree));
+static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree));
static void set_vindex PARAMS ((tree, tree, int *));
static tree build_rtti_vtbl_entries PARAMS ((tree, tree));
static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree,
@@ -177,6 +179,11 @@ static void clone_constructors_and_destructors PARAMS ((tree));
static tree build_clone PARAMS ((tree, tree));
static void update_vtable_entry_for_fn PARAMS ((tree, tree, tree, tree *));
static tree copy_virtuals PARAMS ((tree));
+static void build_ctor_vtbl_group PARAMS ((tree, tree));
+static void build_vtt PARAMS ((tree));
+static tree *build_vtt_inits PARAMS ((tree, tree, tree *));
+static tree dfs_build_vtt_inits PARAMS ((tree, void *));
+static tree dfs_fixup_binfo_vtbls PARAMS ((tree, void *));
/* Variables shared between class.c and call.c. */
@@ -621,22 +628,19 @@ static tree
get_vtable_name (type)
tree type;
{
- tree type_id = build_typename_overload (type);
- char *buf = (char *) alloca (strlen (VTABLE_NAME_PREFIX)
- + IDENTIFIER_LENGTH (type_id) + 2);
- const char *ptr = IDENTIFIER_POINTER (type_id);
- int i;
- for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
-#if 0
- /* We don't take off the numbers; build_secondary_vtable uses the
- DECL_ASSEMBLER_NAME for the type, which includes the number
- in `3foo'. If we were to pull them off here, we'd end up with
- something like `_vt.foo.3bar', instead of a uniform definition. */
- while (ptr[i] >= '0' && ptr[i] <= '9')
- i += 1;
-#endif
- sprintf (buf, "%s%s", VTABLE_NAME_PREFIX, ptr+i);
- return get_identifier (buf);
+ return build_overload_with_type (get_identifier (VTABLE_NAME_PREFIX),
+ type);
+}
+
+/* Return an IDENTIFIER_NODE for the name of the virtual table table
+ for TYPE. */
+
+static tree
+get_vtt_name (type)
+ tree type;
+{
+ return build_overload_with_type (get_identifier (VTT_NAME_PREFIX),
+ type);
}
/* Return the offset to the main vtable for a given base BINFO. */
@@ -727,7 +731,8 @@ get_vtable_decl (type, complete)
decl = build_vtable (type, name, void_type_node);
decl = pushdecl_top_level (decl);
- SET_IDENTIFIER_GLOBAL_VALUE (name, decl);
+ my_friendly_assert (IDENTIFIER_GLOBAL_VALUE (name) == decl,
+ 20000517);
/* At one time the vtable info was grabbed 2 words at a time. This
fails on sparc unless you have 8-byte alignment. (tiemann) */
@@ -1692,15 +1697,23 @@ dfs_mark_primary_bases (binfo, data)
else
{
tree shared_binfo;
+ tree type;
- shared_binfo
- = binfo_for_vbase (BINFO_TYPE (base_binfo), (tree) data);
+ type = (tree) data;
+ shared_binfo = binfo_for_vbase (BINFO_TYPE (base_binfo), type);
/* If this virtual base is not already primary somewhere else in
the hiearchy, then we'll be using this copy. */
if (!BINFO_VBASE_PRIMARY_P (shared_binfo))
{
- BINFO_VBASE_PRIMARY_P (shared_binfo) = 1;
+ /* Make sure the CLASSTYPE_VBASECLASSES list contains the
+ primary copy; it's the one that really exists. */
+ if (base_binfo != shared_binfo)
+ TREE_VALUE (purpose_member (BINFO_TYPE (base_binfo),
+ CLASSTYPE_VBASECLASSES (type)))
+ = base_binfo;
+
+ BINFO_VBASE_PRIMARY_P (base_binfo) = 1;
BINFO_PRIMARY_MARKED_P (base_binfo) = 1;
}
}
@@ -4900,6 +4913,12 @@ finish_struct_1 (t)
overridden_virtuals
= modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals));
+ /* If we created a new vtbl pointer for this class, add it to the
+ list. */
+ if (TYPE_VFIELD (t) && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
+ CLASSTYPE_VFIELDS (t)
+ = chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
+
/* If necessary, create the primary vtable for this class. */
if (new_virtuals
|| overridden_virtuals
@@ -4962,12 +4981,6 @@ finish_struct_1 (t)
= chainon (TYPE_BINFO_VIRTUALS (t), overridden_virtuals);
}
- /* If we created a new vtbl pointer for this class, add it to the
- list. */
- if (TYPE_VFIELD (t) && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
- CLASSTYPE_VFIELDS (t)
- = chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
-
finish_struct_bits (t);
/* Complete the rtl for any static member objects of the type we're
@@ -5020,6 +5033,8 @@ finish_struct_1 (t)
/* Make the rtl for any new vtables we have created, and unmark
the base types we marked. */
finish_vtbls (t);
+ /* Build the VTT for T. */
+ build_vtt (t);
if (TYPE_VFIELD (t))
{
@@ -6373,16 +6388,16 @@ finish_vtbls (t)
first, followed by the non-virtual secondary vtables in
inheritance graph order. */
list = build_tree_list (TYPE_BINFO_VTABLE (t), NULL_TREE);
- TREE_TYPE (list) = t;
- accumulate_vtbl_inits (TYPE_BINFO (t), list);
+ accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t),
+ TYPE_BINFO (t), t, list);
/* Then come the virtual bases, also in inheritance graph
order. */
for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
{
if (!TREE_VIA_VIRTUAL (vbase))
continue;
- accumulate_vtbl_inits (binfo_for_vbase (BINFO_TYPE (vbase), t),
- list);
+
+ accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), t, list);
}
if (TYPE_BINFO_VTABLE (t))
@@ -6406,14 +6421,11 @@ dfs_finish_vtbls (binfo, data)
{
tree t = (tree) data;
- if (!BINFO_PRIMARY_MARKED_P (binfo)
- && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
- && BINFO_NEW_VTABLE_MARKED (binfo, t))
+ if (BINFO_NEW_VTABLE_MARKED (binfo, t))
initialize_vtable (binfo,
build_vtbl_initializer (binfo, binfo, t,
TYPE_BINFO (t), NULL));
- CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
SET_BINFO_MARKED (binfo);
return NULL_TREE;
@@ -6426,96 +6438,372 @@ initialize_vtable (binfo, inits)
tree binfo;
tree inits;
{
- tree context;
tree decl;
layout_vtable_decl (binfo, list_length (inits));
decl = get_vtbl_decl_for_binfo (binfo);
+ initialize_array (decl, inits);
+}
+
+/* Initialize DECL (a declaration for a namespace-scope array) with
+ the INITS. */
+
+static void
+initialize_array (decl, inits)
+ tree decl;
+ tree inits;
+{
+ tree context;
+
context = DECL_CONTEXT (decl);
- DECL_CONTEXT (decl) = 0;
+ DECL_CONTEXT (decl) = NULL_TREE;
DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits);
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context;
}
+/* Build the VTT (virtual table table) for T. */
+
+static void
+build_vtt (t)
+ tree t;
+{
+ tree inits;
+ tree type;
+ tree vtt;
+
+ /* Under the old ABI, we don't use VTTs. */
+ if (!flag_new_abi)
+ return;
+
+ /* Build up the initializers for the VTT. */
+ inits = NULL_TREE;
+ build_vtt_inits (TYPE_BINFO (t), t, &inits);
+
+ /* If we didn't need a VTT, we're done. */
+ if (!inits)
+ return;
+
+ /* Figure out the type of the VTT. */
+ type = build_index_type (size_int (list_length (inits)));
+ type = build_cplus_array_type (const_ptr_type_node, type);
+
+ /* Now, build the VTT object itself. */
+ vtt = build_vtable (t, get_vtt_name (t), type);
+ pushdecl_top_level (vtt);
+ initialize_array (vtt, inits);
+}
+
+/* Recursively build the VTT-initializer for BINFO (which is in the
+ hierarchy dominated by T). INITS points to the end of the
+ initializer list to date. */
+
+static tree *
+build_vtt_inits (binfo, t, inits)
+ tree binfo;
+ tree t;
+ tree *inits;
+{
+ int i;
+ tree b;
+ tree init;
+ tree secondary_vptrs;
+ int ctor_vtbl_p;
+
+ /* We only need VTTs for subobjects with virtual bases. */
+ if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
+ return inits;
+
+ /* We need to use a construction vtable if this is not the primary
+ VTT. */
+ ctor_vtbl_p = !same_type_p (TREE_TYPE (binfo), t);
+ if (ctor_vtbl_p)
+ build_ctor_vtbl_group (binfo, t);
+
+ /* Add the address of the primary vtable for the complete object. */
+ init = BINFO_VTABLE (binfo);
+ if (TREE_CODE (init) == TREE_LIST)
+ init = TREE_PURPOSE (init);
+ *inits = build_tree_list (NULL_TREE, init);
+ inits = &TREE_CHAIN (*inits);
+
+ /* Recursively add the secondary VTTs for non-virtual bases. */
+ for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
+ {
+ b = BINFO_BASETYPE (binfo, i);
+ if (!TREE_VIA_VIRTUAL (b))
+ inits = build_vtt_inits (BINFO_BASETYPE (binfo, i), t, inits);
+ }
+
+ /* Add secondary virtual pointers for all subobjects of BINFO with
+ either virtual bases or virtual functions overridden along a
+ virtual path between the declaration and D, except subobjects
+ that are non-virtual primary bases. */
+ secondary_vptrs = build_tree_list (BINFO_TYPE (binfo), NULL_TREE);
+ dfs_walk_real (binfo,
+ dfs_build_vtt_inits,
+ NULL,
+ dfs_unmarked_real_bases_queue_p,
+ secondary_vptrs);
+ dfs_walk (binfo, dfs_fixup_binfo_vtbls, dfs_marked_real_bases_queue_p,
+ BINFO_TYPE (binfo));
+
+ /* The secondary vptrs come back in reverse order. After we reverse
+ them, and add the INITS, the last init will be the first element
+ of the chain. */
+ secondary_vptrs = TREE_VALUE (secondary_vptrs);
+ if (secondary_vptrs)
+ {
+ *inits = nreverse (secondary_vptrs);
+ inits = &TREE_CHAIN (secondary_vptrs);
+ my_friendly_assert (*inits == NULL_TREE, 20000517);
+ }
+
+ /* Add the secondary VTTs for virtual bases. */
+ 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);
+ }
+
+ return inits;
+}
+
+/* Called from build_vtt_inits via dfs_walk. */
+
+static tree
+dfs_build_vtt_inits (binfo, data)
+ tree binfo;
+ void *data;
+{
+ tree l;
+ tree t;
+ tree init;
+
+ l = (tree) data;
+ t = TREE_PURPOSE (l);
+
+ SET_BINFO_MARKED (binfo);
+
+ /* We don't care about bases that don't have vtables. */
+ if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
+ return NULL_TREE;
+
+ /* We're only interested in proper subobjects of T. */
+ if (same_type_p (BINFO_TYPE (binfo), t))
+ return NULL_TREE;
+
+ /* We're not interested in non-virtual primary bases. */
+ if (!TREE_VIA_VIRTUAL (binfo) && BINFO_PRIMARY_MARKED_P (binfo))
+ return NULL_TREE;
+
+ /* If BINFO doesn't have virtual bases, then we have to look to see
+ whether or not any virtual functions were overidden along a
+ virtual path between the declaration and T. */
+ if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
+ /* FIXME: Implement this. */
+ ;
+
+ /* Add the initializer for this secondary vptr. */
+ init = BINFO_VTABLE (binfo);
+ if (TREE_CODE (init) == TREE_LIST)
+ init = TREE_PURPOSE (init);
+
+ TREE_VALUE (l) = tree_cons (NULL_TREE, init, TREE_VALUE (l));
+
+ return NULL_TREE;
+}
+
+/* Called from build_vtt_inits via dfs_walk. */
+
+static tree
+dfs_fixup_binfo_vtbls (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ CLEAR_BINFO_MARKED (binfo);
+
+ /* We don't care about bases that don't have vtables. */
+ if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
+ return NULL_TREE;
+
+ /* If we scribbled the construction vtable vptr into BINFO, clear it
+ out now. */
+ if (TREE_CODE (BINFO_VTABLE (binfo)) == TREE_LIST)
+ BINFO_VTABLE (binfo) = TREE_VALUE (BINFO_VTABLE (binfo));
+
+ return NULL_TREE;
+}
+
+/* Build the construction vtable group for BINFO which is in the
+ hierarchy dominated by T. */
+
+static void
+build_ctor_vtbl_group (binfo, t)
+ tree binfo;
+ tree t;
+{
+ tree list;
+ tree type;
+ tree vtbl;
+ tree inits;
+ tree id;
+
+ /* See if we've already create this construction vtable group. */
+ id = get_ctor_vtbl_name (t, binfo);
+ if (IDENTIFIER_GLOBAL_VALUE (id))
+ return;
+
+ /* Build a version of VTBL (with the wrong type) for use in
+ constructing the addresses of secondary vtables in the
+ construction vtable group. */
+ vtbl = build_vtable (BINFO_TYPE (binfo), id, vtable_entry_type);
+ list = build_tree_list (vtbl, NULL_TREE);
+ accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
+ binfo, t, list);
+
+ /* Figure out the type of the construction vtable. */
+ type = build_index_type (size_int (list_length (inits)));
+ type = build_cplus_array_type (vtable_entry_type, type);
+ TREE_TYPE (vtbl) = type;
+
+ /* Initialize the construction vtable. */
+ pushdecl_top_level (vtbl);
+ initialize_array (vtbl, inits);
+}
+
/* Add the vtbl initializers for BINFO (and its non-primary,
- non-virtual bases) to the list of INITS. */
+ non-virtual bases) to the list of INITS. BINFO is in the hierarchy
+ dominated by T. ORIG_BINFO must have the same type as BINFO, but
+ may be different from BINFO if we are building a construction
+ vtable. RTTI_BINFO gives the object that should be used as the
+ complete object for BINFO. */
static void
-accumulate_vtbl_inits (binfo, inits)
+accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, inits)
tree binfo;
+ tree orig_binfo;
+ tree rtti_binfo;
+ tree t;
tree inits;
{
+ int i;
+ int ctor_vtbl_p;
+
+ my_friendly_assert (same_type_p (BINFO_TYPE (binfo),
+ BINFO_TYPE (orig_binfo)),
+ 20000517);
+
+ /* This is a construction vtable if the RTTI type is not the most
+ derived type in the hierarchy. */
+ ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
+
+ /* If we're building a construction vtable, we're not interested in
+ subobjects that don't require construction vtables. */
+ if (ctor_vtbl_p
+ && !TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
+ return;
+
+ /* Build the initializers for the BINFO-in-T vtable. */
+ TREE_VALUE (inits)
+ = chainon (TREE_VALUE (inits),
+ dfs_accumulate_vtbl_inits (binfo, orig_binfo,
+ rtti_binfo, t, inits));
+
/* Walk the BINFO and its bases. We walk in preorder so that as we
initialize each vtable we can figure out at what offset the
- secondary vtable lies from the primary vtable. */
- dfs_walk_real (binfo,
- dfs_accumulate_vtbl_inits,
- NULL,
- dfs_skip_vbases,
- inits);
+ secondary vtable lies from the primary vtable. We can't use
+ dfs_walk here because we need to iterate through bases of BINFO
+ and RTTI_BINFO simultaneously. */
+ for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
+ {
+ tree base_binfo;
+
+ base_binfo = BINFO_BASETYPE (binfo, i);
+ /* Skip virtual bases. */
+ if (TREE_VIA_VIRTUAL (base_binfo))
+ continue;
+ accumulate_vtbl_inits (base_binfo,
+ BINFO_BASETYPE (orig_binfo, i),
+ rtti_binfo,
+ t,
+ inits);
+ }
}
/* Called from finish_vtbls via dfs_walk when using the new ABI.
Accumulates the vtable initializers for all of the vtables into
- TREE_VALUE (DATA). */
+ TREE_VALUE (DATA). Returns the initializers for the BINFO vtable. */
static tree
-dfs_accumulate_vtbl_inits (binfo, data)
+dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
tree binfo;
- void *data;
+ tree orig_binfo;
+ tree rtti_binfo;
+ tree t;
+ tree l;
{
- tree l;
- tree t;
+ tree inits = NULL_TREE;
+ int ctor_vtbl_p;
- l = (tree) data;
- t = TREE_TYPE (l);
+ /* This is a construction vtable if the RTTI type is not the most
+ derived type in the hierarchy. */
+ ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
- if (!BINFO_PRIMARY_MARKED_P (binfo)
- && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
- && BINFO_NEW_VTABLE_MARKED (binfo, t))
+ if (BINFO_NEW_VTABLE_MARKED (binfo, t)
+ /* We need a new vtable, even for a primary base, when we're
+ building a construction vtable. */
+ || (ctor_vtbl_p && orig_binfo == rtti_binfo))
{
- tree inits;
tree vtbl;
tree index;
int non_fn_entries;
/* Compute the initializer for this vtable. */
- inits = build_vtbl_initializer (binfo, binfo, t, TYPE_BINFO (t),
+ inits = build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
&non_fn_entries);
- /* Set BINFO_VTABLE to the address where the VPTR should point. */
+ /* Figure out the position to which the VPTR should point. */
vtbl = TREE_PURPOSE (l);
vtbl = build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (vtbl)),
+ vtbl_ptr_type_node,
vtbl);
index = size_binop (PLUS_EXPR,
size_int (non_fn_entries),
size_int (list_length (TREE_VALUE (l))));
- BINFO_VTABLE (binfo)
- = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
- size_binop (MULT_EXPR,
- TYPE_SIZE_UNIT (TREE_TYPE (vtbl)),
- index));
-
- /* Add the initializers for this vtable to the initializers for
- the other vtables we've already got. */
- TREE_VALUE (l) = chainon (TREE_VALUE (l), inits);
+ index = size_binop (MULT_EXPR,
+ TYPE_SIZE_UNIT (vtable_entry_type),
+ index);
+ vtbl = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
+ TREE_CONSTANT (vtbl) = 1;
+
+ /* For an ordinary vtable, set BINFO_VTABLE. */
+ if (!ctor_vtbl_p)
+ BINFO_VTABLE (binfo) = vtbl;
+ /* For a construction vtable, we can't overwrite BINFO_VTABLE.
+ So, we make a TREE_LIST. Later, dfs_fixup_binfo_vtbls will
+ straighten this out. */
+ else
+ BINFO_VTABLE (binfo) = build_tree_list (vtbl,
+ BINFO_VTABLE (binfo));
}
- CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
-
- return NULL_TREE;
+ return inits;
}
/* Construct the initializer for BINFOs virtual function table. BINFO
is part of the hierarchy dominated by T. If we're building a
- construction vtable, the ORIGINAL_BINFO is the binfo we should use
- to find the actual function pointers to put in the vtable.
- Otherwise, ORIGINAL_BINFO should be the same as BINFO. The
- RTTI_DOMINATOR is the BINFO that should be indicated by the RTTI
- information in the vtable; it will be a base class of T, rather
- than T itself, if we are building a construction vtable.
+ construction vtable, the ORIG_BINFO is the binfo we should use to
+ find the actual function pointers to put in the vtable. Otherwise,
+ ORIG_BINFO should be the same as BINFO. The RTTI_DOMINATOR is the
+ BINFO that should be indicated by the RTTI information in the
+ vtable; it will be a base class of T, rather than T itself, if we
+ are building a construction vtable.
The value returned is a TREE_LIST suitable for wrapping in a
CONSTRUCTOR to use as the DECL_INITIAL for a vtable. If
@@ -6523,10 +6811,9 @@ dfs_accumulate_vtbl_inits (binfo, data)
number of non-function entries in the vtable. */
static tree
-build_vtbl_initializer (binfo, original_binfo, t, rtti_binfo,
- non_fn_entries_p)
+build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
tree binfo;
- tree original_binfo;
+ tree orig_binfo;
tree t;
tree rtti_binfo;
int *non_fn_entries_p;
@@ -6563,7 +6850,7 @@ build_vtbl_initializer (binfo, original_binfo, t, rtti_binfo,
/* Go through all the ordinary virtual functions, building up
initializers. */
vfun_inits = NULL_TREE;
- for (v = BINFO_VIRTUALS (original_binfo); v; v = TREE_CHAIN (v))
+ for (v = BINFO_VIRTUALS (orig_binfo); v; v = TREE_CHAIN (v))
{
tree delta;
tree vcall_index;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 711f614..d21a195 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1597,7 +1597,11 @@ struct lang_type
/* 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.) */
+ 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. */
#define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases)
/* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the
@@ -1721,8 +1725,15 @@ struct lang_type
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 SET_BINFO_NEW_VTABLE_MARKED(B, C) \
- (BINFO_NEW_VTABLE_MARKED (B, C) = 1)
+
+/* Any subobject that needs a new vtable must have a vptr and must not
+ be a primary base (since it would then use the vtable from a
+ derived class.) */
+#define SET_BINFO_NEW_VTABLE_MARKED(B, C) \
+ (BINFO_NEW_VTABLE_MARKED (B, C) = 1, \
+ my_friendly_assert (!BINFO_PRIMARY_MARKED_P (B), 20000517), \
+ my_friendly_assert (CLASSTYPE_VFIELDS (BINFO_TYPE (B)) != NULL_TREE, \
+ 20000517))
#define CLEAR_BINFO_NEW_VTABLE_MARKED(B, C) \
(BINFO_NEW_VTABLE_MARKED (B, C) = 0)
@@ -3438,6 +3449,15 @@ extern tree original_function_name;
#define EXCEPTION_CLEANUP_NAME "exception cleanup"
+/* The name used as a prefix for VTTs. When the new ABI mangling
+ scheme is implemented, this should be removed. */
+
+#define VTT_NAME_PREFIX "__vtt_"
+
+/* The name used as a prefix for construction vtables. */
+
+#define CTOR_VTBL_NAME_PREFIX "__ctorvt_"
+
#define THIS_NAME_P(ID_NODE) (strcmp(IDENTIFIER_POINTER (ID_NODE), "this") == 0)
#if !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL)
@@ -4187,6 +4207,7 @@ extern void emit_thunk PARAMS ((tree));
extern void synthesize_method PARAMS ((tree));
extern tree get_id_2 PARAMS ((const char *, tree));
extern tree implicitly_declare_fn PARAMS ((special_function_kind, tree, int));
+extern tree get_ctor_vtbl_name PARAMS ((tree, tree));
/* In optimize.c */
extern void optimize_function PARAMS ((tree));
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 81df59a..bbb580d 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1766,9 +1766,6 @@ build_typename_overload (type)
build_mangled_name (type, 0, 1);
id = get_identifier (obstack_base (&scratch_obstack));
IDENTIFIER_OPNAME_P (id) = 1;
-#if 0
- IDENTIFIER_GLOBAL_VALUE (id) = TYPE_MAIN_DECL (type);
-#endif
TREE_TYPE (id) = type;
end_squangling ();
return id;
@@ -1800,6 +1797,28 @@ get_id_2 (name, name2)
return get_identifier (obstack_base (&scratch_obstack));
}
+/* Returns the name of a construction vtable group. TYPE is the most
+ derived class in the hierarhcy. BINFO is the most derived class in
+ the construction vtable group. */
+
+tree
+get_ctor_vtbl_name (type, binfo)
+ tree type;
+ tree binfo;
+{
+ start_squangling ();
+ OB_INIT ();
+ OB_PUTCP (CTOR_VTBL_NAME_PREFIX);
+ build_mangled_name (type, 0, 0);
+ OB_PUTC ('_');
+ build_mangled_name (BINFO_TYPE (binfo), 0, 0);
+ OB_PUTC ('_');
+ build_overload_int (BINFO_OFFSET (binfo), mf_none);
+ OB_FINISH ();
+ end_squangling ();
+ return get_identifier (obstack_base (&scratch_obstack));
+}
+
/* Returns a DECL_ASSEMBLER_NAME for the destructor of type TYPE. */
tree
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 4775e48..bebca05 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1859,7 +1859,7 @@ dfs_walk_real (binfo, prefn, postfn, qfn, data)
/* Process the basetypes. */
binfos = BINFO_BASETYPES (binfo);
- n_baselinks = binfos ? TREE_VEC_LENGTH (binfos): 0;
+ n_baselinks = BINFO_N_BASETYPES (binfo);
for (i = 0; i < n_baselinks; i++)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
@@ -2521,7 +2521,6 @@ init_vbase_pointers (type, decl_ptr)
vi.inits = NULL_TREE;
/* Build up a list of the initializers. */
- TREE_CHAIN (binfo) = decl_ptr;
dfs_walk_real (binfo,
dfs_init_vbase_pointers, 0,
unmarked_vtable_pathp,