diff options
author | Richard Henderson <rth@redhat.com> | 2001-10-11 11:48:42 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2001-10-11 11:48:42 -0700 |
commit | 4a8d0c9c68d8ce12453255695bfab8b2111dd772 (patch) | |
tree | 36b169e5937e71fb76f555ec055b161e29728e84 /gcc/cp | |
parent | 94e091c8336b9ec8ed70f5e0b9b5b31b189f10a4 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/class.c | 76 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 10 |
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 |