aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0c106c3..ac71fc5 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -459,9 +459,9 @@ build_vtable_entry_ref (basetype, idx)
}
/* Given an object INSTANCE, return an expression which yields the
- virtual function vtable element corresponding to INDEX. There are
- many special cases for INSTANCE which we take care of here, mainly
- to avoid creating extra tree nodes when we don't have to. */
+ vtable element corresponding to INDEX. There are many special
+ cases for INSTANCE which we take care of here, mainly to avoid
+ creating extra tree nodes when we don't have to. */
tree
build_vtbl_ref (instance, idx)
@@ -543,6 +543,24 @@ build_vtbl_ref (instance, idx)
return aref;
}
+/* Given an object INSTANCE, return an expression which yields a
+ function pointer corresponding to vtable element INDEX. */
+
+tree
+build_vfn_ref (instance, idx)
+ tree instance, idx;
+{
+ tree aref = build_vtbl_ref (instance, idx);
+
+ /* When using function descriptors, the address of the
+ vtable entry is treated as a function pointer. */
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ return build1 (NOP_EXPR, TREE_TYPE (aref),
+ build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1));
+
+ return aref;
+}
+
/* Return the name of the virtual function table (as an IDENTIFIER_NODE)
for the given TYPE. */
@@ -823,7 +841,9 @@ set_vindex (decl, vfuns_p)
{
int vindex;
- vindex = (*vfuns_p)++;
+ vindex = *vfuns_p;
+ *vfuns_p += (TARGET_VTABLE_USES_DESCRIPTORS
+ ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
DECL_VINDEX (decl) = build_shared_int_cst (vindex);
}
@@ -7587,7 +7607,25 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
}
/* And add it to the chain of initializers. */
- vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ {
+ int i;
+ if (init == size_zero_node)
+ for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
+ vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
+ else
+ for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
+ {
+ tree fdesc = build (FDESC_EXPR, vfunc_ptr_type_node,
+ TREE_OPERAND (init, 0),
+ build_int_2 (i, 0));
+ TREE_CONSTANT (fdesc) = 1;
+
+ vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits);
+ }
+ }
+ else
+ vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
}
/* The initializers for virtual functions were built up in reverse