Commit cb7fdde2 by Alexandre Oliva Committed by Alexandre Oliva

cp-tree.h (ptrmemfunc_vbit_where_t): Declare type.

* cp-tree.h (ptrmemfunc_vbit_where_t): Declare type.
* typeck.c (get_member_function_from_ptrfunc,
build_ptrmemfunc, expand_ptrmemfunc_cst): Take
TARGET_PTRMEMFUNC_VBIT_LOCATION into account.

From-SVN: r41990
parent f3c55c97
2001-05-11 Alexandre Oliva <aoliva@redhat.com> 2001-05-12 Alexandre Oliva <aoliva@redhat.com>
* cp-tree.h (ptrmemfunc_vbit_where_t): Declare type.
* typeck.c (get_member_function_from_ptrfunc,
build_ptrmemfunc, expand_ptrmemfunc_cst): Take
TARGET_PTRMEMFUNC_VBIT_LOCATION into account.
Reverted Geoff Keating's 2001-05-03's patch. Reverted Geoff Keating's 2001-05-03's patch.
......
...@@ -2673,7 +2673,19 @@ extern int flag_new_for_scope; ...@@ -2673,7 +2673,19 @@ extern int flag_new_for_scope;
(We don't need DELTA2, because the vtable is always the first thing (We don't need DELTA2, because the vtable is always the first thing
in the object.) If the function is virtual, then PFN is one plus in the object.) If the function is virtual, then PFN is one plus
twice the index into the vtable; otherwise, it is just a pointer to twice the index into the vtable; otherwise, it is just a pointer to
the function. */ the function.
Unfortunately, using the lowest bit of PFN doesn't work in
architectures that don't impose alignment requirements on function
addresses, or that use the lowest bit to tell one ISA from another,
for example. For such architectures, we use the lowest bit of
DELTA instead of the lowest bit of the PFN, and DELTA will be
multiplied by 2. */
enum ptrmemfunc_vbit_where_t
{
ptrmemfunc_vbit_in_pfn,
ptrmemfunc_vbit_in_delta
};
/* Get the POINTER_TYPE to the METHOD_TYPE associated with this /* Get the POINTER_TYPE to the METHOD_TYPE associated with this
pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true, pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true,
......
...@@ -2894,6 +2894,11 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) ...@@ -2894,6 +2894,11 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
e3 = PFN_FROM_PTRMEMFUNC (function); e3 = PFN_FROM_PTRMEMFUNC (function);
vtbl = convert_pointer_to (ptr_type_node, instance);
delta = cp_convert (ptrdiff_type_node,
build_component_ref (function, delta_identifier,
NULL_TREE, 0));
/* This used to avoid checking for virtual functions if basetype /* This used to avoid checking for virtual functions if basetype
has no virtual functions, according to an earlier ANSI draft. has no virtual functions, according to an earlier ANSI draft.
With the final ISO C++ rules, such an optimization is With the final ISO C++ rules, such an optimization is
...@@ -2906,14 +2911,31 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) ...@@ -2906,14 +2911,31 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
load-with-sign-extend, while the second used normal load then load-with-sign-extend, while the second used normal load then
shift to sign-extend. An optimizer flaw, perhaps, but it's shift to sign-extend. An optimizer flaw, perhaps, but it's
easier to make this change. */ easier to make this change. */
idx = cp_build_binary_op (TRUNC_DIV_EXPR, switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
build1 (NOP_EXPR, vtable_index_type, e3), {
TYPE_SIZE_UNIT (vtable_entry_type)); case ptrmemfunc_vbit_in_pfn:
e1 = cp_build_binary_op (BIT_AND_EXPR, idx = cp_build_binary_op (TRUNC_DIV_EXPR,
build1 (NOP_EXPR, vtable_index_type, e3), build1 (NOP_EXPR, vtable_index_type, e3),
integer_one_node); TYPE_SIZE_UNIT (vtable_entry_type));
e1 = cp_build_binary_op (BIT_AND_EXPR,
build1 (NOP_EXPR, vtable_index_type, e3),
integer_one_node);
break;
case ptrmemfunc_vbit_in_delta:
idx = build1 (NOP_EXPR, vtable_index_type, e3);
e1 = cp_build_binary_op (BIT_AND_EXPR,
delta, integer_one_node);
delta = cp_build_binary_op (RSHIFT_EXPR,
build1 (NOP_EXPR, vtable_index_type,
delta),
integer_one_node);
break;
default:
abort ();
}
vtbl = convert_pointer_to (ptr_type_node, instance);
delta = cp_convert (ptrdiff_type_node, delta = cp_convert (ptrdiff_type_node,
build_component_ref (function, delta_identifier, build_component_ref (function, delta_identifier,
NULL_TREE, 0)); NULL_TREE, 0));
...@@ -6085,6 +6107,8 @@ build_ptrmemfunc (type, pfn, force) ...@@ -6085,6 +6107,8 @@ build_ptrmemfunc (type, pfn, force)
/* Under the new ABI, the conversion is easy. Just adjust /* Under the new ABI, the conversion is easy. Just adjust
the DELTA field. */ the DELTA field. */
delta = cp_convert (ptrdiff_type_node, delta); delta = cp_convert (ptrdiff_type_node, delta);
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
delta = cp_build_binary_op (PLUS_EXPR, delta, n); delta = cp_build_binary_op (PLUS_EXPR, delta, n);
return build_ptrmemfunc1 (to_type, delta, npfn); return build_ptrmemfunc1 (to_type, delta, npfn);
} }
...@@ -6146,13 +6170,32 @@ expand_ptrmemfunc_cst (cst, delta, pfn) ...@@ -6146,13 +6170,32 @@ expand_ptrmemfunc_cst (cst, delta, pfn)
*delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta), *delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta),
*delta, BINFO_OFFSET (binfo))); *delta, BINFO_OFFSET (binfo)));
/* Under the new ABI, we set PFN to the vtable offset, plus /* Under the new ABI, we set PFN to the vtable offset at
one, at which the function can be found. */ which the function can be found, plus one (unless
*pfn = fold (build (MULT_EXPR, integer_type_node, ptrmemfunc_vbit_in_delta, in which case delta is shifted
DECL_VINDEX (fn), left, and then incremented). */
TYPE_SIZE_UNIT (vtable_entry_type))); *pfn = DECL_VINDEX (fn);
*pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn,
integer_one_node)); switch (TARGET_PTRMEMFUNC_VBIT_LOCATION)
{
case ptrmemfunc_vbit_in_pfn:
*pfn = fold (build (MULT_EXPR, integer_type_node, *pfn,
TYPE_SIZE_UNIT (vtable_entry_type)));
*pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn,
integer_one_node));
break;
case ptrmemfunc_vbit_in_delta:
*delta = fold (build (LSHIFT_EXPR, TREE_TYPE (*delta),
*delta, integer_one_node));
*delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta),
*delta, integer_one_node));
break;
default:
abort ();
}
*pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
*pfn)); *pfn));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment