summaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c70
1 files changed, 54 insertions, 16 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b86bac460c0..d865fba5f99 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -181,7 +181,7 @@ 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 *build_vtt_inits PARAMS ((tree, tree, tree *, tree *));
static tree dfs_build_vtt_inits PARAMS ((tree, void *));
static tree dfs_fixup_binfo_vtbls PARAMS ((tree, void *));
@@ -635,7 +635,7 @@ get_vtable_name (type)
/* Return an IDENTIFIER_NODE for the name of the virtual table table
for TYPE. */
-static tree
+tree
get_vtt_name (type)
tree type;
{
@@ -3957,6 +3957,8 @@ build_clone (fn, name)
DECL_PENDING_INLINE_P (clone) = 0;
/* And it hasn't yet been deferred. */
DECL_DEFERRED_FN (clone) = 0;
+ /* There's no magic VTT parameter in the clone. */
+ DECL_VTT_PARM (clone) = NULL_TREE;
/* The base-class destructor is not virtual. */
if (name == base_dtor_identifier)
@@ -3981,6 +3983,10 @@ build_clone (fn, name)
parmtypes = TREE_CHAIN (parmtypes);
/* Skip the in-charge parameter. */
parmtypes = TREE_CHAIN (parmtypes);
+ /* If this is subobject constructor or destructor, add the vtt
+ parameter. */
+ if (DECL_NEEDS_VTT_PARM_P (clone))
+ parmtypes = hash_tree_chain (vtt_parm_type, parmtypes);
TREE_TYPE (clone)
= build_cplus_method_type (basetype,
TREE_TYPE (TREE_TYPE (clone)),
@@ -4002,6 +4008,18 @@ build_clone (fn, name)
= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
}
+
+ /* Add the VTT parameter. */
+ if (DECL_NEEDS_VTT_PARM_P (clone))
+ {
+ tree parm;
+
+ parm = build_artificial_parm (vtt_parm_identifier,
+ vtt_parm_type);
+ TREE_CHAIN (parm) = TREE_CHAIN (DECL_ARGUMENTS (clone));
+ TREE_CHAIN (DECL_ARGUMENTS (clone)) = parm;
+ }
+
for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
{
DECL_CONTEXT (parms) = clone;
@@ -4063,7 +4081,7 @@ clone_function_decl (fn, update_method_vec_p)
{
my_friendly_assert (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn), 20000411);
- /* For each destructor, we need two variants: an in-charge
+ /* For each destructor, we need three variants: an in-charge
version, a not-in-charge version, and an in-charge deleting
version. We clone the deleting version first because that
means it will go second on the TYPE_METHODS list -- and that
@@ -6474,6 +6492,7 @@ build_vtt (t)
tree inits;
tree type;
tree vtt;
+ tree index;
/* Under the old ABI, we don't use VTTs. */
if (!flag_new_abi)
@@ -6481,7 +6500,8 @@ build_vtt (t)
/* Build up the initializers for the VTT. */
inits = NULL_TREE;
- build_vtt_inits (TYPE_BINFO (t), t, &inits);
+ index = size_zero_node;
+ build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);
/* If we didn't need a VTT, we're done. */
if (!inits)
@@ -6499,13 +6519,15 @@ build_vtt (t)
/* 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. */
+ initializer list to date. INDEX is the VTT index where the next
+ element will be placed. */
static tree *
-build_vtt_inits (binfo, t, inits)
+build_vtt_inits (binfo, t, inits, index)
tree binfo;
tree t;
tree *inits;
+ tree *index;
{
int i;
tree b;
@@ -6521,7 +6543,12 @@ build_vtt_inits (binfo, t, inits)
VTT. */
ctor_vtbl_p = !same_type_p (TREE_TYPE (binfo), t);
if (ctor_vtbl_p)
- build_ctor_vtbl_group (binfo, t);
+ {
+ build_ctor_vtbl_group (binfo, t);
+
+ /* Record the offset in the VTT where this sub-VTT can be found. */
+ BINFO_SUBVTT_INDEX (binfo) = *index;
+ }
/* Add the address of the primary vtable for the complete object. */
init = BINFO_VTABLE (binfo);
@@ -6529,20 +6556,24 @@ build_vtt_inits (binfo, t, inits)
init = TREE_PURPOSE (init);
*inits = build_tree_list (NULL_TREE, init);
inits = &TREE_CHAIN (*inits);
-
+ BINFO_VPTR_INDEX (binfo) = *index;
+ *index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));
+
/* 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);
+ inits = build_vtt_inits (BINFO_BASETYPE (binfo, i), t, inits,
+ index);
}
-
+
/* 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);
+ TREE_TYPE (secondary_vptrs) = *index;
dfs_walk_real (binfo,
dfs_build_vtt_inits,
NULL,
@@ -6550,6 +6581,7 @@ build_vtt_inits (binfo, t, inits)
secondary_vptrs);
dfs_walk (binfo, dfs_fixup_binfo_vtbls, dfs_marked_real_bases_queue_p,
BINFO_TYPE (binfo));
+ *index = TREE_TYPE (secondary_vptrs);
/* The secondary vptrs come back in reverse order. After we reverse
them, and add the INITS, the last init will be the first element
@@ -6571,7 +6603,7 @@ build_vtt_inits (binfo, t, inits)
continue;
vbase = binfo_for_vbase (BINFO_TYPE (b), t);
- inits = build_vtt_inits (vbase, t, inits);
+ inits = build_vtt_inits (vbase, t, inits, index);
}
return inits;
@@ -6587,6 +6619,7 @@ dfs_build_vtt_inits (binfo, data)
tree l;
tree t;
tree init;
+ tree index;
l = (tree) data;
t = TREE_PURPOSE (l);
@@ -6612,13 +6645,18 @@ dfs_build_vtt_inits (binfo, data)
/* FIXME: Implement this. */
;
- /* Add the initializer for this secondary vptr. */
+ /* Record the index where this secondary vptr can be found. */
+ index = TREE_TYPE (l);
+ BINFO_VPTR_INDEX (binfo) = index;
+ TREE_TYPE (l) = size_binop (PLUS_EXPR, index,
+ TYPE_SIZE_UNIT (ptr_type_node));
+
+ /* Add the initializer for the secondary vptr itself. */
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;
}
@@ -6665,7 +6703,7 @@ build_ctor_vtbl_group (binfo, t)
/* 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);
+ vtbl = build_vtable (BINFO_TYPE (binfo), id, ptr_type_node);
list = build_tree_list (vtbl, NULL_TREE);
accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
binfo, t, list);
@@ -6762,7 +6800,7 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
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))
+ || (ctor_vtbl_p && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))))
{
tree vtbl;
tree index;