diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-23 00:26:04 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-23 00:26:04 +0000 |
commit | 215e2f1d86a587308fdbde512bb2f228ba224ae9 (patch) | |
tree | 0be6b0f8e11f86590d8a53628df5d2776497a29c /gcc/cp | |
parent | f09f2d78d2d06c18635dec7e3cc6c103fd174eee (diff) | |
download | gcc-215e2f1d86a587308fdbde512bb2f228ba224ae9.tar.gz |
* tree.def (VTABLE_REF): Remove.
(OBJ_TYPE_REF): New.
(TRY_CATCH_EXPR, TRY_FINALLY_EXPR): Set type 's'.
* expr.c (expand_expr_real_1): Replace VTABLE_REF with OBJ_TYPE_REF.
* fold-const.c (non_lvalue): Likewise.
* gimplify.c (gimplify_expr): Likewise.
(gimplify_call_expr): Use is_gimple_call_addr.
* langhooks-def.h (LANG_HOOKS_FOLD_OBJ_TYPE_REF): New.
* langhooks.h (fold_obj_type_ref): New.
* tree-gimple.c (is_gimple_call_addr): New.
* tree-gimple.h (is_gimple_call_addr): Declare.
* tree-inline.c (inlinable_function_p): Fix merge error.
(estimate_num_insns_1): Replace VTABLE_REF with OBJ_TYPE_REF.
* tree-pretty-print.c (dump_generic_node): Likewise.
(print_call_name): Handle OBJ_TYPE_REF.
* tree-ssa-ccp.c (fold_stmt): Fold OBJ_TYPE_REF.
* tree-ssa-operands.c (get_expr_operands): Handle OBJ_TYPE_REF.
* tree.h (OBJ_TYPE_REF_EXPR): New.
(OBJ_TYPE_REF_OBJECT, OBJ_TYPE_REF_TOKEN): New.
* doc/c-tree.texi (VTABLE_REF): Remove.
* objc/objc-act.c (build_objc_method_call): Build an OBJ_TYPE_REF.
cp/
* class.c (build_vfn_ref): Take a pointer not object. Build
an OBJ_TYPE_REF.
(cp_fold_obj_type_ref): New.
* call.c (build_over_call): Update build_vfn_ref call.
* cp-lang.c (LANG_HOOKS_FOLD_OBJ_TYPE_REF): New.
* cp-tree.h (cp_fold_obj_type_ref): Declare.
testsuite/
* g++.dg/opt/devirt1.C: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83531 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/class.c | 41 | ||||
-rw-r--r-- | gcc/cp/cp-lang.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 |
5 files changed, 50 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1f2eda9b6a0..f67eb221408 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2004-06-22 Richard Henderson <rth@redhat.com> + + * class.c (build_vfn_ref): Take a pointer not object. Build + an OBJ_TYPE_REF. + (cp_fold_obj_type_ref): New. + * call.c (build_over_call): Update build_vfn_ref call. + * cp-lang.c (LANG_HOOKS_FOLD_OBJ_TYPE_REF): New. + * cp-tree.h (cp_fold_obj_type_ref): Declare. + 2004-06-21 Jason Merrill <jason@redhat.com> PR c++/16112 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0c247b8127a..2a659cce1ef 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4835,7 +4835,7 @@ build_over_call (struct z_candidate *cand, int flags) if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn))) fn = build_java_interface_fn_ref (fn, *p); else - fn = build_vfn_ref (build_indirect_ref (*p, 0), DECL_VINDEX (fn)); + fn = build_vfn_ref (*p, DECL_VINDEX (fn)); TREE_TYPE (fn) = t; } else if (DECL_INLINE (fn)) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1853d4faadf..d58577f496f 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -542,13 +542,15 @@ build_vtbl_ref (tree instance, tree idx) return aref; } -/* Given an object INSTANCE, return an expression which yields a - function pointer corresponding to vtable element INDEX. */ +/* Given a stable object pointer INSTANCE_PTR, return an expression which + yields a function pointer corresponding to vtable element INDEX. */ tree -build_vfn_ref (tree instance, tree idx) +build_vfn_ref (tree instance_ptr, tree idx) { - tree aref = build_vtbl_ref_1 (instance, idx); + tree aref; + + aref = build_vtbl_ref_1 (build_indirect_ref (instance_ptr, 0), idx); /* When using function descriptors, the address of the vtable entry is treated as a function pointer. */ @@ -556,6 +558,9 @@ build_vfn_ref (tree instance, tree idx) aref = build1 (NOP_EXPR, TREE_TYPE (aref), build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1)); + /* Remember this as a method reference, for later devirtualization. */ + aref = build (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx); + return aref; } @@ -7912,3 +7917,31 @@ build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid) *vid->last_init = build_tree_list (NULL_TREE, init); vid->last_init = &TREE_CHAIN (*vid->last_init); } + +/* Fold a OBJ_TYPE_REF expression to the address of a function. + KNOWN_TYPE carries the true type of OBJ_TYPE_REF_OBJECT(REF). */ + +tree +cp_fold_obj_type_ref (tree ref, tree known_type) +{ + HOST_WIDE_INT index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1); + HOST_WIDE_INT i = 0; + tree v = TYPE_BINFO_VIRTUALS (known_type); + tree fndecl; + + while (i != index) + { + i += (TARGET_VTABLE_USES_DESCRIPTORS + ? TARGET_VTABLE_USES_DESCRIPTORS : 1); + v = TREE_CHAIN (v); + } + + fndecl = BV_FN (v); + +#ifdef ENABLE_CHECKING + if (!tree_int_cst_equal (OBJ_TYPE_REF_TOKEN (ref), DECL_VINDEX (fndecl))) + abort (); +#endif + + return build_address (fndecl); +} diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index 757ca08e845..5af5b97333d 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -182,6 +182,8 @@ static void cxx_initialize_diagnostics (diagnostic_context *); #define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type #undef LANG_HOOKS_GIMPLIFY_EXPR #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr +#undef LANG_HOOKS_FOLD_OBJ_TYPE_REF +#define LANG_HOOKS_FOLD_OBJ_TYPE_REF cp_fold_obj_type_ref /* Each front end provides its own hooks, for toplev.c. */ const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e29e084e0bb..36d98c60195 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3678,6 +3678,7 @@ extern tree get_vtt_name (tree); extern tree get_primary_binfo (tree); extern void debug_class (tree); extern void debug_thunks (tree); +extern tree cp_fold_obj_type_ref (tree, tree); /* in cvt.c */ extern tree convert_to_reference (tree, tree, int, int, tree); |