summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2001-10-11 11:48:42 -0700
committerRichard Henderson <rth@gcc.gnu.org>2001-10-11 11:48:42 -0700
commit4a8d0c9c68d8ce12453255695bfab8b2111dd772 (patch)
tree36b169e5937e71fb76f555ec055b161e29728e84 /gcc/cp
parent94e091c8336b9ec8ed70f5e0b9b5b31b189f10a4 (diff)
downloadgcc-4a8d0c9c68d8ce12453255695bfab8b2111dd772.tar.gz
rtl.h (REG_VTABLE_REF): New.
* rtl.h (REG_VTABLE_REF): New. * rtl.c (reg_note_name): Add it. * combine.c (distribute_notes): Handle it. * final.c (final_scan_insn): Handle it. * tree.def (VTABLE_REF): New. * expr.c (expand_expr): Handle it. * varasm.c (assemble_vtable_entry, assemble_vtable_inherit): New. * output.h: Declare them. cp/ * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead of an asm statement. (build_vtbl_ref_1): Split out from build_vtbl_ref. (build_vfn_ref): Use it to handle vtable descriptors before calling build_vtable_entry_ref. * decl2.c (output_vtable_inherit): Use assemble_vtable_inherit. testsuite/ * g++.old-deja/g++.other/crash18.C: Add -S to options. From-SVN: r46195
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/class.c76
-rw-r--r--gcc/cp/decl2.c10
3 files changed, 55 insertions, 40 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8d867bbd579..06806fc40f2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2001-10-11 Richard Henderson <rth@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead
+ of an asm statement.
+ (build_vtbl_ref_1): Split out from build_vtbl_ref.
+ (build_vfn_ref): Use it to handle vtable descriptors before
+ calling build_vtable_entry_ref.
+ * decl2.c (output_vtable_inherit): Use assemble_vtable_inherit.
+
2001-10-10 Richard Henderson <rth@redhat.com>
* parse.y (asm_operand): Allow named operands.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 97a35974102..305bde1d7fb 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -134,7 +134,8 @@ static tree add_implicitly_declared_members PARAMS ((tree, int, int, int));
static tree fixed_type_or_null PARAMS ((tree, int *, int *));
static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int,
int, int, tree));
-static void build_vtable_entry_ref PARAMS ((tree, tree));
+static tree build_vtable_entry_ref PARAMS ((tree, tree, tree));
+static tree build_vtbl_ref_1 PARAMS ((tree, tree));
static tree build_vtbl_initializer PARAMS ((tree, tree, tree, tree, int *));
static int count_fields PARAMS ((tree));
static int add_fields_to_vec PARAMS ((tree, tree, int));
@@ -424,38 +425,31 @@ build_vbase_path (code, type, expr, path, nonnull)
/* Virtual function things. */
-/* We want to give the assembler the vtable identifier as well as
- the offset to the function pointer. So we generate
+static tree
+build_vtable_entry_ref (array_ref, instance, idx)
+ tree array_ref, instance, idx;
+{
+ tree i, i2, vtable, first_fn, basetype;
- __asm__ __volatile__ (".vtable_entry %c0, %c1"
- : : "s"(&class_vtable),
- "i"((long)&vtbl[idx].pfn - (long)&vtbl[0])); */
+ basetype = TREE_TYPE (instance);
+ if (TREE_CODE (basetype) == REFERENCE_TYPE)
+ basetype = TREE_TYPE (basetype);
-static void
-build_vtable_entry_ref (basetype, idx)
- tree basetype, idx;
-{
- static const char asm_stmt[] = ".vtable_entry %c0, %c1";
- tree s, i, i2;
- tree vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
- tree first_fn = TYPE_BINFO_VTABLE (basetype);
+ vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
+ first_fn = TYPE_BINFO_VTABLE (basetype);
- s = build_unary_op (ADDR_EXPR, vtable, 0);
- s = build_tree_list (build_string (1, "s"), s);
+ i = fold (build_array_ref (first_fn, idx));
+ i = fold (build_c_cast (ptrdiff_type_node,
+ build_unary_op (ADDR_EXPR, i, 0)));
+ i2 = fold (build_array_ref (vtable, build_int_2 (0,0)));
+ i2 = fold (build_c_cast (ptrdiff_type_node,
+ build_unary_op (ADDR_EXPR, i2, 0)));
+ i = fold (cp_build_binary_op (MINUS_EXPR, i, i2));
- i = build_array_ref (first_fn, idx);
- /* We must not convert to ptrdiff_type node here, since this could widen
- from a partial to an integral node, which would create a
- convert_expression that would be in the way of any simplifications. */
- i = build_c_cast (string_type_node, build_unary_op (ADDR_EXPR, i, 0));
- i2 = build_array_ref (vtable, build_int_2 (0,0));
- i2 = build_c_cast (string_type_node, build_unary_op (ADDR_EXPR, i2, 0));
- i = cp_build_binary_op (MINUS_EXPR, i, i2);
- i = build_tree_list (build_string (1, "i"), i);
+ if (TREE_CODE (i) != INTEGER_CST)
+ abort ();
- finish_asm_stmt (ridpointers[RID_VOLATILE],
- build_string (sizeof(asm_stmt)-1, asm_stmt),
- NULL_TREE, chainon (s, i), NULL_TREE);
+ return build (VTABLE_REF, TREE_TYPE (array_ref), array_ref, vtable, i);
}
/* Given an object INSTANCE, return an expression which yields the
@@ -463,8 +457,8 @@ build_vtable_entry_ref (basetype, idx)
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)
+static tree
+build_vtbl_ref_1 (instance, idx)
tree instance, idx;
{
tree vtbl, aref;
@@ -535,14 +529,23 @@ build_vtbl_ref (instance, idx)
assemble_external (vtbl);
- if (flag_vtable_gc)
- build_vtable_entry_ref (basetype, idx);
-
aref = build_array_ref (vtbl, idx);
return aref;
}
+tree
+build_vtbl_ref (instance, idx)
+ tree instance, idx;
+{
+ tree aref = build_vtbl_ref_1 (instance, idx);
+
+ if (flag_vtable_gc)
+ aref = build_vtable_entry_ref (aref, instance, idx);
+
+ return aref;
+}
+
/* Given an object INSTANCE, return an expression which yields a
function pointer corresponding to vtable element INDEX. */
@@ -550,14 +553,17 @@ tree
build_vfn_ref (instance, idx)
tree instance, idx;
{
- tree aref = build_vtbl_ref (instance, idx);
+ tree aref = build_vtbl_ref_1 (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),
+ aref = build1 (NOP_EXPR, TREE_TYPE (aref),
build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1));
+ if (flag_vtable_gc)
+ aref = build_vtable_entry_ref (aref, instance, idx);
+
return aref;
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 0ab9299244e..8c5dba17507 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2406,23 +2406,23 @@ output_vtable_inherit (vars)
tree vars;
{
tree parent;
- rtx op[2];
+ rtx child_rtx, parent_rtx;
- op[0] = XEXP (DECL_RTL (vars), 0); /* strip the mem ref */
+ child_rtx = XEXP (DECL_RTL (vars), 0); /* strip the mem ref */
parent = binfo_for_vtable (vars);
if (parent == TYPE_BINFO (DECL_CONTEXT (vars)))
- op[1] = const0_rtx;
+ parent_rtx = const0_rtx;
else if (parent)
{
parent = get_vtbl_decl_for_binfo (TYPE_BINFO (BINFO_TYPE (parent)));
- op[1] = XEXP (DECL_RTL (parent), 0); /* strip the mem ref */
+ parent_rtx = XEXP (DECL_RTL (parent), 0); /* strip the mem ref */
}
else
my_friendly_abort (980826);
- output_asm_insn (".vtable_inherit %c0, %c1", op);
+ assemble_vtable_inherit (child_rtx, parent_rtx);
}
static int