cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro.

* cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro.
	* typeck.c (expand_ptrmemfunc_cst): Calculate delta correctly for
	virtual functions and MI.  Simplify.

From-SVN: r28304
This commit is contained in:
Jason Merrill 1999-07-28 00:45:12 +00:00 committed by Jason Merrill
parent 2401a452d8
commit 3927874dcd
3 changed files with 44 additions and 27 deletions

View File

@ -1,5 +1,9 @@
1999-07-27 Jason Merrill <jason@yorick.cygnus.com>
* cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro.
* typeck.c (expand_ptrmemfunc_cst): Calculate delta correctly for
virtual functions and MI. Simplify.
* method.c: Remove prototype for largest_union_member.
* pt.c (determine_specialization): Fix uninitialized warning.
* lex.c (real_yylex): Likewise.

View File

@ -212,12 +212,12 @@ struct tree_overload
indicating a particular base class, and whose TREE_VALUE is a
(possibly overloaded) function from that base class. */
#define BASELINK_P(NODE) \
(TREE_CODE ((NODE)) == TREE_LIST && TREE_LANG_FLAG_1 ((NODE)))
(TREE_CODE (NODE) == TREE_LIST && TREE_LANG_FLAG_1 (NODE))
#define SET_BASELINK_P(NODE) \
(TREE_LANG_FLAG_1 ((NODE)) = 1)
(TREE_LANG_FLAG_1 (NODE) = 1)
#define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr)
#define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i)
#define WRAPPER_PTR(NODE) (((struct tree_wrapper*)(NODE))->u.ptr)
#define WRAPPER_INT(NODE) (((struct tree_wrapper*)(NODE))->u.i)
struct tree_wrapper
{
@ -1404,6 +1404,10 @@ struct lang_decl
(DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace)
#define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE))
/* For a virtual function, the base where we find its vtable entry.
For a non-virtual function, the base where it is defined. */
#define DECL_VIRTUAL_CONTEXT(NODE) DECL_CONTEXT (NODE)
/* 1 iff NODE has namespace scope, including the global namespace. */
#define DECL_NAMESPACE_SCOPE_P(NODE) \
(DECL_CONTEXT (NODE) == NULL_TREE \

View File

@ -6078,7 +6078,12 @@ build_x_modify_expr (lhs, modifycode, rhs)
/* Get difference in deltas for different pointer to member function
types. Return integer_zero_node, if FROM cannot be converted to a
TO type. If FORCE is true, then allow reverse conversions as well. */
TO type. If FORCE is true, then allow reverse conversions as well.
Note that the naming of FROM and TO is kind of backwards; the return
value is what we add to a TO in order to get a FROM. They are named
this way because we call this function to find out how to convert from
a pointer to member of FROM to a pointer to member of TO. */
static tree
get_delta_difference (from, to, force)
@ -6338,37 +6343,41 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
{
tree type = TREE_TYPE (cst);
tree fn = PTRMEM_CST_MEMBER (cst);
tree ptr_class, fn_class;
my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
*delta
= get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)),
TYPE_PTRMEMFUNC_OBJECT_TYPE (type),
/*force=*/0);
/* The class that the function belongs to. */
fn_class = DECL_CLASS_CONTEXT (fn);
/* The class that we're creating a pointer to member of. */
ptr_class = TYPE_PTRMEMFUNC_OBJECT_TYPE (type);
/* First, calculate the adjustment to the function's class. */
*delta = get_delta_difference (fn_class, ptr_class, /*force=*/0);
if (!DECL_VIRTUAL_P (fn))
{
*idx = size_binop (MINUS_EXPR, integer_zero_node,
integer_one_node);
*pfn = build_addr_func (fn);
if (!same_type_p (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)),
TYPE_PTRMEMFUNC_OBJECT_TYPE (type)))
*pfn = build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type),
*pfn);
*idx = size_binop (MINUS_EXPR, integer_zero_node, integer_one_node);
*pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn));
*delta2 = NULL_TREE;
}
else
{
*idx = size_binop (PLUS_EXPR, DECL_VINDEX (fn),
integer_one_node);
/* If we're dealing with a virtual function, we have to adjust 'this'
again, to point to the base which provides the vtable entry for
fn; the call will do the opposite adjustment. */
tree orig_class = DECL_VIRTUAL_CONTEXT (fn);
tree binfo = binfo_or_else (orig_class, fn_class);
*delta = size_binop (PLUS_EXPR, *delta, BINFO_OFFSET (binfo));
/* Map everything down one to make room for the null PMF. */
*idx = size_binop (PLUS_EXPR, DECL_VINDEX (fn), integer_one_node);
*pfn = NULL_TREE;
*delta2 = get_binfo (DECL_CONTEXT (fn),
DECL_CLASS_CONTEXT (fn),
0);
*delta2 = get_vfield_offset (*delta2);
*delta2 = size_binop (PLUS_EXPR, *delta2,
build_binary_op (PLUS_EXPR,
*delta,
integer_zero_node));
/* Offset from an object of PTR_CLASS to the vptr for ORIG_CLASS. */
*delta2 = size_binop (PLUS_EXPR, *delta,
get_vfield_offset (TYPE_BINFO (orig_class)));
}
}