method.c (make_thunk): Use overload machinery to make name.

* method.c (make_thunk): Use overload machinery to make name.
	* search.c (covariant_return_p): New fn.
	(get_matching_virtual): Use it.
	* init.c (build_new_1): Fix check for void.

From-SVN: r20215
This commit is contained in:
Jason Merrill 1998-06-04 00:34:57 +00:00 committed by Jason Merrill
parent ff439b5fee
commit cc600f3318
4 changed files with 83 additions and 37 deletions

View File

@ -1,3 +1,11 @@
1998-06-03 Jason Merrill <jason@yorick.cygnus.com>
* method.c (make_thunk): Use overload machinery to make name.
* search.c (covariant_return_p): New fn.
(get_matching_virtual): Use it.
* init.c (build_new_1): Fix check for void.
1998-06-01 Per Bothner <bothner@cygnus.com>
* cp-tree.h (TYPE_FOR_JAVA): New macro.

View File

@ -2261,7 +2261,7 @@ build_new_1 (exp)
else
size = size_in_bytes (type);
if (true_type == void_type_node)
if (TREE_CODE (true_type) == VOID_TYPE)
{
error ("invalid type `void' for new");
return error_mark_node;

View File

@ -1917,23 +1917,30 @@ make_thunk (function, delta)
tree function;
int delta;
{
char *buffer;
tree thunk_id;
tree thunk;
char *func_name;
tree func_decl;
if (TREE_CODE (function) != ADDR_EXPR)
abort ();
func_decl = TREE_OPERAND (function, 0);
if (TREE_CODE (func_decl) != FUNCTION_DECL)
abort ();
func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl));
buffer = (char *)alloca (strlen (func_name) + 32);
if (delta<=0)
sprintf (buffer, "__thunk_%d_%s", -delta, func_name);
OB_INIT ();
OB_PUTS ("__thunk_");
if (delta > 0)
{
OB_PUTC ('n');
icat (delta);
}
else
sprintf (buffer, "__thunk_n%d_%s", delta, func_name);
thunk_id = get_identifier (buffer);
icat (-delta);
OB_PUTC ('_');
OB_PUTID (DECL_ASSEMBLER_NAME (func_decl));
OB_FINISH ();
thunk_id = get_identifier (obstack_base (&scratch_obstack));
thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
if (thunk && TREE_CODE (thunk) != THUNK_DECL)
{

View File

@ -2133,6 +2133,57 @@ tree_has_any_destructor_p (binfo, i)
return TYPE_NEEDS_DESTRUCTOR (type);
}
/* Returns > 0 if a function with type DRETTYPE overriding a function
with type BRETTYPE is covariant, as defined in [class.virtual].
Returns 1 if trivial covariance, 2 if non-trivial (requiring runtime
adjustment), or -1 if pedantically invalid covariance. */
int
covariant_return_p (brettype, drettype)
tree brettype, drettype;
{
tree binfo;
if (TREE_CODE (brettype) == FUNCTION_DECL
|| TREE_CODE (brettype) == THUNK_DECL)
{
brettype = TREE_TYPE (TREE_TYPE (brettype));
drettype = TREE_TYPE (TREE_TYPE (drettype));
}
else if (TREE_CODE (brettype) == METHOD_TYPE)
{
brettype = TREE_TYPE (brettype);
drettype = TREE_TYPE (drettype);
}
if (comptypes (brettype, drettype, 1))
return 0;
if (! (TREE_CODE (brettype) == TREE_CODE (drettype)
&& (TREE_CODE (brettype) == POINTER_TYPE
|| TREE_CODE (brettype) == REFERENCE_TYPE)
&& TYPE_READONLY (brettype) == TYPE_READONLY (drettype)
&& TYPE_VOLATILE (brettype) == TYPE_VOLATILE (drettype)))
return 0;
if (! can_convert (brettype, drettype))
return 0;
brettype = TREE_TYPE (brettype);
drettype = TREE_TYPE (drettype);
/* If not pedantic, allow any standard pointer conversion. */
if (! IS_AGGR_TYPE (drettype) || ! IS_AGGR_TYPE (brettype))
return -1;
binfo = get_binfo (brettype, drettype, 0);
if (! BINFO_OFFSET_ZEROP (binfo) || TREE_VIA_VIRTUAL (binfo))
return 2;
return 1;
}
/* Given a class type TYPE, and a function decl FNDECL, look for a
virtual function in TYPE's hierarchy which FNDECL could match as a
virtual function. It doesn't matter which one we find.
@ -2146,6 +2197,7 @@ get_matching_virtual (binfo, fndecl, dtorp)
int dtorp;
{
tree tmp = NULL_TREE;
int i;
/* Breadth first search routines start searching basetypes
of TYPE, so we must perform first ply of search here. */
@ -2209,36 +2261,15 @@ get_matching_virtual (binfo, fndecl, dtorp)
tree brettype = TREE_TYPE (TREE_TYPE (tmp));
if (comptypes (brettype, drettype, 1))
/* OK */;
else if
(TREE_CODE (brettype) == TREE_CODE (drettype)
&& (TREE_CODE (brettype) == POINTER_TYPE
|| TREE_CODE (brettype) == REFERENCE_TYPE)
&& comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (brettype)),
TYPE_MAIN_VARIANT (TREE_TYPE (drettype)),
0))
/* covariant return type */
else if ((i = covariant_return_p (brettype, drettype)))
{
tree b = TREE_TYPE (brettype), d = TREE_TYPE (drettype);
if (TYPE_MAIN_VARIANT (b) != TYPE_MAIN_VARIANT (d))
if (i == 2)
sorry ("adjusting pointers for covariant returns");
if (pedantic && i == -1)
{
tree binfo = get_binfo (b, d, 1);
if (binfo != error_mark_node
&& (! BINFO_OFFSET_ZEROP (binfo)
|| TREE_VIA_VIRTUAL (binfo)))
sorry ("adjusting pointers for covariant returns");
}
if (TYPE_READONLY (d) > TYPE_READONLY (b))
{
cp_error_at ("return type of `%#D' adds const", fndecl);
cp_error_at (" overriding definition as `%#D'",
tmp);
}
else if (TYPE_VOLATILE (d) > TYPE_VOLATILE (b))
{
cp_error_at ("return type of `%#D' adds volatile",
fndecl);
cp_error_at (" overriding definition as `%#D'",
tmp);
cp_pedwarn_at ("invalid covariant return type for `%#D' (must be pointer or reference to class)", fndecl);
cp_pedwarn_at (" overriding `%#D'", tmp);
}
}
else if (IS_AGGR_TYPE_2 (brettype, drettype)