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:
parent
2401a452d8
commit
3927874dcd
3 changed files with 44 additions and 27 deletions
|
@ -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.
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue