Commit 3c215895 by Jason Merrill

cvt.c, [...]: Clean up more old overloading code, old RTTI code, and some formatting quirks.

	* cvt.c, decl.c, decl2.c, init.c, rtti.c, typeck.c, typeck2.c,
	cp-tree.h: Clean up more old overloading code, old RTTI code, and
	some formatting quirks.

From-SVN: r18391
parent de7987a6
...@@ -2084,7 +2084,6 @@ extern tree convert PROTO((tree, tree)); ...@@ -2084,7 +2084,6 @@ extern tree convert PROTO((tree, tree));
extern tree convert_force PROTO((tree, tree, int)); extern tree convert_force PROTO((tree, tree, int));
extern tree build_type_conversion PROTO((enum tree_code, tree, tree, int)); extern tree build_type_conversion PROTO((enum tree_code, tree, tree, int));
extern tree build_expr_type_conversion PROTO((int, tree, int)); extern tree build_expr_type_conversion PROTO((int, tree, int));
extern int build_default_binary_type_conversion PROTO((enum tree_code, tree *, tree *));
extern tree type_promotes_to PROTO((tree)); extern tree type_promotes_to PROTO((tree));
extern tree perform_qualification_conversions PROTO((tree, tree)); extern tree perform_qualification_conversions PROTO((tree, tree));
......
...@@ -38,8 +38,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -38,8 +38,6 @@ Boston, MA 02111-1307, USA. */
extern tree static_aggregates; extern tree static_aggregates;
static tree build_thunk PROTO((tree, tree));
static tree convert_fn_ptr PROTO((tree, tree));
static tree cp_convert_to_pointer PROTO((tree, tree)); static tree cp_convert_to_pointer PROTO((tree, tree));
static tree convert_to_pointer_force PROTO((tree, tree)); static tree convert_to_pointer_force PROTO((tree, tree));
static tree build_up_reference PROTO((tree, tree, int, int)); static tree build_up_reference PROTO((tree, tree, int, int));
...@@ -68,60 +66,6 @@ static tree build_type_conversion_1 PROTO((tree, tree, tree, tree, ...@@ -68,60 +66,6 @@ static tree build_type_conversion_1 PROTO((tree, tree, tree, tree,
/* Subroutines of `convert'. */ /* Subroutines of `convert'. */
/* Build a thunk. What it is, is an entry point that when called will
adjust the this pointer (the first argument) by offset, and then
goto the real address of the function given by REAL_ADDR that we
would like called. What we return is the address of the thunk. */
static tree
build_thunk (offset, real_addr)
tree offset, real_addr;
{
if (TREE_CODE (real_addr) != ADDR_EXPR
|| TREE_CODE (TREE_OPERAND (real_addr, 0)) != FUNCTION_DECL)
{
sorry ("MI pointer to member conversion too complex");
return error_mark_node;
}
sorry ("MI pointer to member conversion too complex");
return error_mark_node;
}
/* Convert a `pointer to member' (POINTER_TYPE to METHOD_TYPE) into
another `pointer to method'. This may involved the creation of
a thunk to handle the this offset calculation. */
static tree
convert_fn_ptr (type, expr)
tree type, expr;
{
#if 0 /* We don't use thunks for pmfs. */
if (flag_vtable_thunks)
{
tree intype = TREE_TYPE (expr);
tree binfo = get_binfo (TYPE_METHOD_BASETYPE (TREE_TYPE (intype)),
TYPE_METHOD_BASETYPE (TREE_TYPE (type)), 1);
if (binfo == error_mark_node)
{
error (" in pointer to member conversion");
return error_mark_node;
}
if (binfo == NULL_TREE)
{
/* ARM 4.8 restriction. */
error ("invalid pointer to member conversion");
return error_mark_node;
}
if (BINFO_OFFSET_ZEROP (binfo))
return build1 (NOP_EXPR, type, expr);
return build1 (NOP_EXPR, type, build_thunk (BINFO_OFFSET (binfo), expr));
}
else
#endif
return build_ptrmemfunc (type, expr, 1);
}
/* if converting pointer to pointer /* if converting pointer to pointer
if dealing with classes, check for derived->base or vice versa if dealing with classes, check for derived->base or vice versa
else if dealing with method pointers, delegate else if dealing with method pointers, delegate
...@@ -239,9 +183,11 @@ cp_convert_to_pointer (type, expr) ...@@ -239,9 +183,11 @@ cp_convert_to_pointer (type, expr)
tree path; tree path;
if (code == PLUS_EXPR) if (code == PLUS_EXPR)
get_base_distance (TREE_TYPE (type), TREE_TYPE (intype), 0, &path); get_base_distance (TREE_TYPE (type), TREE_TYPE (intype),
0, &path);
else else
get_base_distance (TREE_TYPE (intype), TREE_TYPE (type), 0, &path); get_base_distance (TREE_TYPE (intype), TREE_TYPE (type),
0, &path);
return build_vbase_path (code, type, expr, path, 0); return build_vbase_path (code, type, expr, path, 0);
} }
} }
...@@ -249,7 +195,7 @@ cp_convert_to_pointer (type, expr) ...@@ -249,7 +195,7 @@ cp_convert_to_pointer (type, expr)
if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE
&& TREE_CODE (type) == POINTER_TYPE && TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE) && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
return convert_fn_ptr (type, expr); return build_ptrmemfunc (type, expr, 1);
if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
&& TREE_CODE (TREE_TYPE (intype)) == OFFSET_TYPE) && TREE_CODE (TREE_TYPE (intype)) == OFFSET_TYPE)
...@@ -548,7 +494,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl) ...@@ -548,7 +494,8 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
rval = build_unary_op (ADDR_EXPR, expr, 0); rval = build_unary_op (ADDR_EXPR, expr, 0);
if (rval != error_mark_node) if (rval != error_mark_node)
rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval, 0); rval = convert_force (build_pointer_type (TREE_TYPE (reftype)),
rval, 0);
if (rval != error_mark_node) if (rval != error_mark_node)
rval = build1 (NOP_EXPR, reftype, rval); rval = build1 (NOP_EXPR, reftype, rval);
} }
...@@ -1033,230 +980,39 @@ build_expr_type_conversion (desires, expr, complain) ...@@ -1033,230 +980,39 @@ build_expr_type_conversion (desires, expr, complain)
int complain; int complain;
{ {
tree basetype = TREE_TYPE (expr); tree basetype = TREE_TYPE (expr);
tree conv;
tree winner = NULL_TREE;
if (TREE_CODE (basetype) == OFFSET_TYPE) if (TREE_CODE (basetype) == OFFSET_TYPE)
expr = resolve_offset_ref (expr); expr = resolve_offset_ref (expr);
expr = convert_from_reference (expr); expr = convert_from_reference (expr);
basetype = TREE_TYPE (expr); basetype = TREE_TYPE (expr);
if (! IS_AGGR_TYPE (basetype)) switch (TREE_CODE (basetype))
switch (TREE_CODE (basetype))
{
case INTEGER_TYPE:
if ((desires & WANT_NULL) && TREE_CODE (expr) == INTEGER_CST
&& integer_zerop (expr))
return expr;
/* else fall through... */
case BOOLEAN_TYPE:
return (desires & WANT_INT) ? expr : NULL_TREE;
case ENUMERAL_TYPE:
return (desires & WANT_ENUM) ? expr : NULL_TREE;
case REAL_TYPE:
return (desires & WANT_FLOAT) ? expr : NULL_TREE;
case POINTER_TYPE:
return (desires & WANT_POINTER) ? expr : NULL_TREE;
case FUNCTION_TYPE:
case ARRAY_TYPE:
return (desires & WANT_POINTER) ? default_conversion (expr)
: NULL_TREE;
default:
return NULL_TREE;
}
if (! TYPE_HAS_CONVERSION (basetype))
return NULL_TREE;
for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
{ {
int win = 0; case INTEGER_TYPE:
tree candidate; if ((desires & WANT_NULL) && TREE_CODE (expr) == INTEGER_CST
tree cand = TREE_VALUE (conv); && integer_zerop (expr))
return expr;
if (winner && winner == cand) /* else fall through... */
continue;
case BOOLEAN_TYPE:
candidate = TREE_TYPE (TREE_TYPE (cand)); return (desires & WANT_INT) ? expr : NULL_TREE;
if (TREE_CODE (candidate) == REFERENCE_TYPE) case ENUMERAL_TYPE:
candidate = TREE_TYPE (candidate); return (desires & WANT_ENUM) ? expr : NULL_TREE;
case REAL_TYPE:
switch (TREE_CODE (candidate)) return (desires & WANT_FLOAT) ? expr : NULL_TREE;
{ case POINTER_TYPE:
case BOOLEAN_TYPE: return (desires & WANT_POINTER) ? expr : NULL_TREE;
case INTEGER_TYPE:
win = (desires & WANT_INT); break; case FUNCTION_TYPE:
case ENUMERAL_TYPE: case ARRAY_TYPE:
win = (desires & WANT_ENUM); break; return ((desires & WANT_POINTER) ? default_conversion (expr)
case REAL_TYPE: : NULL_TREE);
win = (desires & WANT_FLOAT); break;
case POINTER_TYPE:
win = (desires & WANT_POINTER); break;
default:
break;
}
if (win)
{
if (winner)
{
if (complain)
{
cp_error ("ambiguous default type conversion from `%T'",
basetype);
cp_error (" candidate conversions include `%D' and `%D'",
winner, cand);
}
return error_mark_node;
}
else
winner = cand;
}
}
if (winner)
{
tree type = TREE_TYPE (TREE_TYPE (winner));
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
return build_type_conversion_1 (type, basetype, expr,
DECL_NAME (winner), 1);
}
return NULL_TREE;
}
/* Must convert two aggregate types to non-aggregate type.
Attempts to find a non-ambiguous, "best" type conversion.
Return 1 on success, 0 on failure.
@@ What are the real semantics of this supposed to be??? */
int
build_default_binary_type_conversion (code, arg1, arg2)
enum tree_code code;
tree *arg1, *arg2;
{
switch (code)
{
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
*arg1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);
*arg2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);
break;
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
case LSHIFT_EXPR:
case RSHIFT_EXPR:
case BIT_AND_EXPR:
case BIT_XOR_EXPR:
case BIT_IOR_EXPR:
*arg1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, *arg1, 0);
*arg2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, *arg2, 0);
break;
case PLUS_EXPR:
{
tree a1, a2, p1, p2;
int wins;
a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);
a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);
p1 = build_expr_type_conversion (WANT_POINTER, *arg1, 0);
p2 = build_expr_type_conversion (WANT_POINTER, *arg2, 0);
wins = (a1 && a2) + (a1 && p2) + (p1 && a2);
if (wins > 1)
error ("ambiguous default type conversion for `operator +'");
if (a1 && a2)
*arg1 = a1, *arg2 = a2;
else if (a1 && p2)
*arg1 = a1, *arg2 = p2;
else
*arg1 = p1, *arg2 = a2;
break;
}
case MINUS_EXPR:
{
tree a1, a2, p1, p2;
int wins;
a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);
a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);
p1 = build_expr_type_conversion (WANT_POINTER, *arg1, 0);
p2 = build_expr_type_conversion (WANT_POINTER, *arg2, 0);
wins = (a1 && a2) + (p1 && p2) + (p1 && a2);
if (wins > 1)
error ("ambiguous default type conversion for `operator -'");
if (a1 && a2)
*arg1 = a1, *arg2 = a2;
else if (p1 && p2)
*arg1 = p1, *arg2 = p2;
else
*arg1 = p1, *arg2 = a2;
break;
}
case GT_EXPR:
case LT_EXPR:
case GE_EXPR:
case LE_EXPR:
case EQ_EXPR:
case NE_EXPR:
{
tree a1, a2, p1, p2;
int wins;
a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);
a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);
p1 = build_expr_type_conversion (WANT_POINTER | WANT_NULL, *arg1, 0);
p2 = build_expr_type_conversion (WANT_POINTER | WANT_NULL, *arg2, 0);
wins = (a1 && a2) + (p1 && p2);
if (wins > 1)
cp_error ("ambiguous default type conversion for `%O'", code);
if (a1 && a2)
*arg1 = a1, *arg2 = a2;
else
*arg1 = p1, *arg2 = p2;
break;
}
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
*arg1 = cp_convert (boolean_type_node, *arg1);
*arg2 = cp_convert (boolean_type_node, *arg2);
break;
default: default:
*arg1 = NULL_TREE; break;
*arg2 = NULL_TREE;
} }
if (*arg1 == error_mark_node || *arg2 == error_mark_node) return NULL_TREE;
cp_error ("ambiguous default type conversion for `%O'", code);
if (*arg1 && *arg2)
return 1;
return 0;
} }
/* Implements integral promotion (4.1) and float->double promotion. */ /* Implements integral promotion (4.1) and float->double promotion. */
......
...@@ -5648,122 +5648,6 @@ init_decl_processing () ...@@ -5648,122 +5648,6 @@ init_decl_processing ()
void_type_node); void_type_node);
pushdecl (std_node); pushdecl (std_node);
#if 0
if (flag_rtti)
{
/* Must build __t_desc type. Currently, type descriptors look like this:
struct __t_desc
{
const char *name;
int size;
int bits;
struct __t_desc *points_to;
int ivars_count, meths_count;
struct __i_desc *ivars[];
struct __m_desc *meths[];
struct __t_desc *parents[];
struct __t_desc *vbases[];
int offsets[];
};
...as per Linton's paper. */
__t_desc_type_node = make_lang_type (RECORD_TYPE);
__i_desc_type_node = make_lang_type (RECORD_TYPE);
__m_desc_type_node = make_lang_type (RECORD_TYPE);
__t_desc_array_type
= build_array_type (build_pointer_type (__t_desc_type_node),
NULL_TREE);
__i_desc_array_type
= build_array_type (build_pointer_type (__i_desc_type_node),
NULL_TREE);
__m_desc_array_type
= build_array_type (build_pointer_type (__m_desc_type_node),
NULL_TREE);
fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"),
string_type_node);
fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("size"),
unsigned_type_node);
fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("bits"),
unsigned_type_node);
fields[3] = build_lang_field_decl (FIELD_DECL,
get_identifier ("points_to"),
build_pointer_type (__t_desc_type_node));
fields[4] = build_lang_field_decl (FIELD_DECL,
get_identifier ("ivars_count"),
integer_type_node);
fields[5] = build_lang_field_decl (FIELD_DECL,
get_identifier ("meths_count"),
integer_type_node);
fields[6] = build_lang_field_decl (FIELD_DECL, get_identifier ("ivars"),
build_pointer_type (__i_desc_array_type));
fields[7] = build_lang_field_decl (FIELD_DECL, get_identifier ("meths"),
build_pointer_type (__m_desc_array_type));
fields[8] = build_lang_field_decl (FIELD_DECL, get_identifier ("parents"),
build_pointer_type (__t_desc_array_type));
fields[9] = build_lang_field_decl (FIELD_DECL, get_identifier ("vbases"),
build_pointer_type (__t_desc_array_type));
fields[10] = build_lang_field_decl (FIELD_DECL, get_identifier ("offsets"),
build_pointer_type (integer_type_node));
finish_builtin_type (__t_desc_type_node, "__t_desc", fields, 10, integer_type_node);
/* ivar descriptors look like this:
struct __i_desc
{
const char *name;
int offset;
struct __t_desc *type;
};
*/
fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"),
string_type_node);
fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("offset"),
integer_type_node);
fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"),
build_pointer_type (__t_desc_type_node));
finish_builtin_type (__i_desc_type_node, "__i_desc", fields, 2,
integer_type_node);
/* method descriptors look like this:
struct __m_desc
{
const char *name;
int vindex;
struct __t_desc *vcontext;
struct __t_desc *return_type;
void (*address)();
short parm_count;
short required_parms;
struct __t_desc *parm_types[];
};
*/
fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("name"),
string_type_node);
fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("vindex"),
integer_type_node);
fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("vcontext"),
build_pointer_type (__t_desc_type_node));
fields[3] = build_lang_field_decl (FIELD_DECL, get_identifier ("return_type"),
build_pointer_type (__t_desc_type_node));
fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("address"),
build_pointer_type (default_function_type));
fields[5] = build_lang_field_decl (FIELD_DECL, get_identifier ("parm_count"),
short_integer_type_node);
fields[6] = build_lang_field_decl (FIELD_DECL, get_identifier ("required_parms"),
short_integer_type_node);
fields[7] = build_lang_field_decl (FIELD_DECL, get_identifier ("parm_types"),
build_pointer_type (build_array_type (build_pointer_type (__t_desc_type_node), NULL_TREE)));
finish_builtin_type (__m_desc_type_node, "__m_desc", fields, 7,
integer_type_node);
}
#endif /*flag_rtti*/
/* Now, C++. */ /* Now, C++. */
current_lang_name = lang_name_cplusplus; current_lang_name = lang_name_cplusplus;
...@@ -5811,76 +5695,6 @@ init_decl_processing () ...@@ -5811,76 +5695,6 @@ init_decl_processing ()
using_eh_for_cleanups (); using_eh_for_cleanups ();
} }
/* initialize type descriptor type node of various rtti type. */
int
init_type_desc()
{
tree tdecl;
tdecl = lookup_name (get_identifier ("type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__t_desc_type_node = TREE_TYPE (tdecl);
#if 0
__tp_desc_type_node = build_pointer_type (__t_desc_type_node);
#endif
#if 0
tdecl = lookup_name (get_identifier ("__baselist_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__baselist_desc_type_node = TREE_TYPE (tdecl);
#endif
tdecl = lookup_name (get_identifier ("__builtin_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__bltn_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__user_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__user_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__class_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__class_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_field (__class_desc_type_node,
get_identifier ("access_mode"), 0, 0);
if (tdecl == NULL_TREE)
return 0;
__access_mode_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__attr_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__attr_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__pointer_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__ptr_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__func_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__func_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__ptmf_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__ptmf_desc_type_node = TREE_TYPE (tdecl);
tdecl = lookup_name (get_identifier ("__ptmd_type_info"), 0);
if (tdecl == NULL_TREE)
return 0;
__ptmd_desc_type_node = TREE_TYPE (tdecl);
return 1;
}
/* Make a definition for a builtin function named NAME and whose data type /* Make a definition for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types. is TYPE. TYPE should be a function type with argument types.
FUNCTION_CODE tells later passes how to compile calls to this function. FUNCTION_CODE tells later passes how to compile calls to this function.
......
...@@ -781,26 +781,6 @@ grok_method_quals (ctype, function, quals) ...@@ -781,26 +781,6 @@ grok_method_quals (ctype, function, quals)
return ctype; return ctype;
} }
#if 0 /* Not used. */
/* This routine replaces cryptic DECL_NAMEs with readable DECL_NAMEs.
It leaves DECL_ASSEMBLER_NAMEs with the correct value. */
/* This does not yet work with user defined conversion operators
It should. */
static void
substitute_nice_name (decl)
tree decl;
{
if (DECL_NAME (decl) && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE)
{
char *n = decl_as_string (DECL_NAME (decl), 1);
if (n[strlen (n) - 1] == ' ')
n[strlen (n) - 1] = 0;
DECL_NAME (decl) = get_identifier (n);
}
}
#endif
/* Warn when -fexternal-templates is used and #pragma /* Warn when -fexternal-templates is used and #pragma
interface/implementation is not used all the times it should be, interface/implementation is not used all the times it should be,
inform the user. */ inform the user. */
...@@ -1051,7 +1031,8 @@ grokclassfn (ctype, cname, function, flags, quals) ...@@ -1051,7 +1031,8 @@ grokclassfn (ctype, cname, function, flags, quals)
if (IDENTIFIER_TYPE_VALUE (cname)) if (IDENTIFIER_TYPE_VALUE (cname))
dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1); dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1);
else if (IDENTIFIER_LOCAL_VALUE (cname)) else if (IDENTIFIER_LOCAL_VALUE (cname))
dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)), 1, 1); dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)),
1, 1);
else else
/* Using ctype fixes the `X::Y::~Y()' crash. The cname has no type when /* Using ctype fixes the `X::Y::~Y()' crash. The cname has no type when
it's defined out of the class definition, since poplevel_class wipes it's defined out of the class definition, since poplevel_class wipes
...@@ -1108,14 +1089,6 @@ grokclassfn (ctype, cname, function, flags, quals) ...@@ -1108,14 +1089,6 @@ grokclassfn (ctype, cname, function, flags, quals)
DECL_ASSEMBLER_NAME (function) DECL_ASSEMBLER_NAME (function)
= build_decl_overload (fn_name, these_arg_types, = build_decl_overload (fn_name, these_arg_types,
1 + DECL_CONSTRUCTOR_P (function)); 1 + DECL_CONSTRUCTOR_P (function));
#if 0
/* This code is going into the compiler, but currently, it makes
libg++/src/Integer.cc not compile. The problem is that the nice name
winds up going into the symbol table, and conversion operations look
for the manged name. */
substitute_nice_name (function);
#endif
} }
DECL_ARGUMENTS (function) = last_function_parms; DECL_ARGUMENTS (function) = last_function_parms;
...@@ -1199,8 +1172,7 @@ grok_array_decl (array_expr, index_exp) ...@@ -1199,8 +1172,7 @@ grok_array_decl (array_expr, index_exp)
type = TREE_TYPE (type); type = TREE_TYPE (type);
/* If they have an `operator[]', use that. */ /* If they have an `operator[]', use that. */
if (TYPE_LANG_SPECIFIC (type) if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
&& TYPE_OVERLOADS_ARRAY_REF (complete_type (type)))
return build_opfncall (ARRAY_REF, LOOKUP_NORMAL, return build_opfncall (ARRAY_REF, LOOKUP_NORMAL,
array_expr, index_exp, NULL_TREE); array_expr, index_exp, NULL_TREE);
...@@ -1596,7 +1568,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) ...@@ -1596,7 +1568,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
if (DECL_NAME (value) != NULL_TREE if (DECL_NAME (value) != NULL_TREE
&& IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_' && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'
&& ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr")) && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))
cp_error ("member `%D' conflicts with virtual function table field name", value); cp_error ("member `%D' conflicts with virtual function table field name",
value);
/* Stash away type declarations. */ /* Stash away type declarations. */
if (TREE_CODE (value) == TYPE_DECL) if (TREE_CODE (value) == TYPE_DECL)
...@@ -1953,33 +1926,6 @@ grok_function_init (decl, init) ...@@ -1953,33 +1926,6 @@ grok_function_init (decl, init)
TYPE_HAS_ABSTRACT_ASSIGN_REF (current_class_type) = 1; TYPE_HAS_ABSTRACT_ASSIGN_REF (current_class_type) = 1;
} }
} }
else if (TREE_CODE (init) == OFFSET_REF
&& TREE_OPERAND (init, 0) == NULL_TREE
&& TREE_CODE (TREE_TYPE (init)) == METHOD_TYPE)
{
tree basetype = DECL_CLASS_CONTEXT (init);
tree basefn = TREE_OPERAND (init, 1);
if (TREE_CODE (basefn) != FUNCTION_DECL)
cp_error ("non-method initializer invalid for method `%D'", decl);
else if (! BINFO_OFFSET_ZEROP (TYPE_BINFO (DECL_CLASS_CONTEXT (basefn))))
sorry ("base member function from other than first base class");
else
{
tree binfo = get_binfo (basetype, TYPE_METHOD_BASETYPE (type), 1);
if (binfo == error_mark_node)
;
else if (binfo == 0)
error_not_base_type (TYPE_METHOD_BASETYPE (TREE_TYPE (init)),
TYPE_METHOD_BASETYPE (type));
else
{
/* Mark this function as being defined,
and give it new rtl. */
DECL_INITIAL (decl) = error_mark_node;
DECL_RTL (decl) = DECL_RTL (basefn);
}
}
}
else else
cp_error ("invalid initializer for virtual method `%D'", decl); cp_error ("invalid initializer for virtual method `%D'", decl);
} }
...@@ -2264,82 +2210,6 @@ finish_anon_union (anon_union_decl) ...@@ -2264,82 +2210,6 @@ finish_anon_union (anon_union_decl)
expand_anon_union_decl (anon_union_decl, NULL_TREE, elems); expand_anon_union_decl (anon_union_decl, NULL_TREE, elems);
} }
/* Finish and output a table which is generated by the compiler.
NAME is the name to give the table.
TYPE is the type of the table entry.
INIT is all the elements in the table.
PUBLICP is non-zero if this table should be given external access. */
tree
finish_table (name, type, init, publicp)
tree name, type, init;
int publicp;
{
tree itype, atype, decl;
static tree empty_table;
int is_empty = 0;
tree asmspec;
itype = build_index_type (size_int (list_length (init) - 1));
atype = build_cplus_array_type (type, itype);
layout_type (atype);
if (TREE_VALUE (init) == integer_zero_node
&& TREE_CHAIN (init) == NULL_TREE)
{
#if 0
if (empty_table == NULL_TREE)
#endif
{
empty_table = get_temp_name (atype, 1);
init = build (CONSTRUCTOR, atype, NULL_TREE, init);
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
DECL_INITIAL (empty_table) = init;
asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (empty_table)),
IDENTIFIER_POINTER (DECL_NAME (empty_table)));
cp_finish_decl (empty_table, NULL_TREE, asmspec, 0, 0);
}
is_empty = 1;
}
if (name == NULL_TREE)
{
if (is_empty)
return empty_table;
decl = get_temp_name (atype, 1);
}
else
{
decl = build_decl (VAR_DECL, name, atype);
decl = pushdecl (decl);
TREE_STATIC (decl) = 1;
}
if (is_empty == 0)
{
TREE_PUBLIC (decl) = publicp;
init = build (CONSTRUCTOR, atype, NULL_TREE, init);
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
DECL_INITIAL (decl) = init;
asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (decl)),
IDENTIFIER_POINTER (DECL_NAME (decl)));
}
else
{
/* This will cause DECL to point to EMPTY_TABLE in rtl-land. */
DECL_EXTERNAL (decl) = 1;
TREE_STATIC (decl) = 0;
init = 0;
asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (empty_table)),
IDENTIFIER_POINTER (DECL_NAME (empty_table)));
}
cp_finish_decl (decl, NULL_TREE, asmspec, 0, 0);
return decl;
}
/* Finish processing a builtin type TYPE. It's name is NAME, /* Finish processing a builtin type TYPE. It's name is NAME,
its fields are in the array FIELDS. LEN is the number of elements its fields are in the array FIELDS. LEN is the number of elements
in FIELDS minus one, or put another way, it is the maximum subscript in FIELDS minus one, or put another way, it is the maximum subscript
......
...@@ -1589,9 +1589,9 @@ build_member_call (type, name, parmlist) ...@@ -1589,9 +1589,9 @@ build_member_call (type, name, parmlist)
cp_error ("invalid use of member `%D'", t); cp_error ("invalid use of member `%D'", t);
return error_mark_node; return error_mark_node;
} }
if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl)) if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl)))
&& TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (decl))) return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl,
return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, parmlist, NULL_TREE); parmlist, NULL_TREE);
return build_function_call (decl, parmlist); return build_function_call (decl, parmlist);
} }
else else
......
...@@ -1108,285 +1108,3 @@ synthesize_tinfo_fn (fndecl) ...@@ -1108,285 +1108,3 @@ synthesize_tinfo_fn (fndecl)
c_expand_return (tmp); c_expand_return (tmp);
finish_function (lineno, 0, 0); finish_function (lineno, 0, 0);
} }
#if 0
/* This is the old dossier type descriptor generation code, it's much
more extended than rtti. It's reserved for later use. */
/* Build an initializer for a __t_desc node. So that we can take advantage
of recursion, we accept NULL for TYPE.
DEFINITION is greater than zero iff we must define the type descriptor
(as opposed to merely referencing it). 1 means treat according to
#pragma interface/#pragma implementation rules. 2 means define as
global and public, no matter what. */
tree
build_t_desc (type, definition)
tree type;
int definition;
{
tree tdecl;
tree tname, name_string;
tree elems, fields;
tree parents, vbases, offsets, ivars, methods, target_type;
int method_count = 0, field_count = 0;
if (type == NULL_TREE)
return NULL_TREE;
tname = build_t_desc_overload (type);
if (IDENTIFIER_AS_DESC (tname)
&& (!definition || TREE_ASM_WRITTEN (IDENTIFIER_AS_DESC (tname))))
return IDENTIFIER_AS_DESC (tname);
tdecl = lookup_name (tname, 0);
if (tdecl == NULL_TREE)
{
tdecl = build_decl (VAR_DECL, tname, __t_desc_type_node);
DECL_EXTERNAL (tdecl) = 1;
TREE_PUBLIC (tdecl) = 1;
tdecl = pushdecl_top_level (tdecl);
}
/* If we previously defined it, return the defined result. */
else if (definition && DECL_INITIAL (tdecl))
return IDENTIFIER_AS_DESC (tname);
if (definition)
{
tree taggr = type;
/* Let T* and T& be written only when T is written (if T is an aggr).
We do this for const, but not for volatile, since volatile
is rare and const is not. */
if (!TYPE_VOLATILE (taggr)
&& (TREE_CODE (taggr) == POINTER_TYPE
|| TREE_CODE (taggr) == REFERENCE_TYPE)
&& IS_AGGR_TYPE (TREE_TYPE (taggr)))
taggr = TREE_TYPE (taggr);
/* If we know that we don't need to write out this type's
vtable, then don't write out it's dossier. Somebody
else will take care of that. */
if (IS_AGGR_TYPE (taggr) && CLASSTYPE_VFIELD (taggr))
{
if (CLASSTYPE_VTABLE_NEEDS_WRITING (taggr))
{
TREE_PUBLIC (tdecl) = ! CLASSTYPE_INTERFACE_ONLY (taggr)
&& CLASSTYPE_INTERFACE_KNOWN (taggr);
DECL_EXTERNAL (tdecl) = 0;
}
else
{
if (write_virtuals != 0)
TREE_PUBLIC (tdecl) = 1;
}
}
else
{
DECL_EXTERNAL (tdecl) = 0;
TREE_PUBLIC (tdecl) = (definition > 1);
}
}
SET_IDENTIFIER_AS_DESC (tname, build_unary_op (ADDR_EXPR, tdecl, 0));
if (!definition || DECL_EXTERNAL (tdecl))
{
/* That's it! */
cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
return IDENTIFIER_AS_DESC (tname);
}
/* Show that we are defining the t_desc for this type. */
DECL_INITIAL (tdecl) = error_mark_node;
parents = build_expr_list (NULL_TREE, integer_zero_node);
vbases = build_expr_list (NULL_TREE, integer_zero_node);
offsets = build_expr_list (NULL_TREE, integer_zero_node);
methods = NULL_TREE;
ivars = NULL_TREE;
if (TYPE_LANG_SPECIFIC (type))
{
int i = CLASSTYPE_N_BASECLASSES (type);
tree method_vec = CLASSTYPE_METHOD_VEC (type);
tree *meth, *end;
tree binfos = TYPE_BINFO_BASETYPES (type);
tree vb = CLASSTYPE_VBASECLASSES (type);
while (--i >= 0)
parents = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (TREE_VEC_ELT (binfos, i)), 0), parents);
while (vb)
{
vbases = tree_cons (NULL_TREE, build_t_desc (BINFO_TYPE (vb), 0), vbases);
offsets = tree_cons (NULL_TREE, BINFO_OFFSET (vb), offsets);
vb = TREE_CHAIN (vb);
}
if (method_vec)
for (meth = TREE_VEC_END (method_vec),
end = &TREE_VEC_ELT (method_vec, 0); meth-- != end; )
if (*meth)
{
methods = tree_cons (NULL_TREE, build_m_desc (*meth), methods);
method_count++;
}
}
if (IS_AGGR_TYPE (type))
{
for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
if (TREE_CODE (fields) == FIELD_DECL
|| TREE_CODE (fields) == VAR_DECL)
{
ivars = tree_cons (NULL_TREE, build_i_desc (fields), ivars);
field_count++;
}
ivars = nreverse (ivars);
}
parents = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), parents, 0);
vbases = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node), vbases, 0);
offsets = finish_table (NULL_TREE, integer_type_node, offsets, 0);
if (methods == NULL_TREE)
methods = null_pointer_node;
else
methods = build_unary_op (ADDR_EXPR,
finish_table (NULL_TREE, __m_desc_type_node, methods, 0),
0);
if (ivars == NULL_TREE)
ivars = null_pointer_node;
else
ivars = build_unary_op (ADDR_EXPR,
finish_table (NULL_TREE, __i_desc_type_node, ivars, 0),
0);
if (TREE_TYPE (type))
target_type = build_t_desc (TREE_TYPE (type), definition);
else
target_type = integer_zero_node;
name_string = combine_strings (build_string (IDENTIFIER_LENGTH (tname)+1, IDENTIFIER_POINTER (tname)));
elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
tree_cons (NULL_TREE,
TYPE_SIZE(type)? size_in_bytes(type) : integer_zero_node,
/* really should use bitfield initialization here. */
tree_cons (NULL_TREE, integer_zero_node,
tree_cons (NULL_TREE, target_type,
tree_cons (NULL_TREE, build_int_2 (field_count, 2),
tree_cons (NULL_TREE, build_int_2 (method_count, 2),
tree_cons (NULL_TREE, ivars,
tree_cons (NULL_TREE, methods,
tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, parents, 0),
tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, vbases, 0),
build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, offsets, 0))))))))))));
return build_generic_desc (tdecl, elems);
}
/* Build an initializer for a __i_desc node. */
tree
build_i_desc (decl)
tree decl;
{
tree elems, name_string;
tree taggr;
name_string = DECL_NAME (decl);
name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));
/* Now decide whether this ivar should cause it's type to get
def'd or ref'd in this file. If the type we are looking at
has a proxy definition, we look at the proxy (i.e., a
`foo *' is equivalent to a `foo'). */
taggr = TREE_TYPE (decl);
if ((TREE_CODE (taggr) == POINTER_TYPE
|| TREE_CODE (taggr) == REFERENCE_TYPE)
&& TYPE_VOLATILE (taggr) == 0)
taggr = TREE_TYPE (taggr);
elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
tree_cons (NULL_TREE, DECL_FIELD_BITPOS (decl),
build_tree_list (NULL_TREE, build_t_desc (TREE_TYPE (decl),
! IS_AGGR_TYPE (taggr)))));
taggr = build (CONSTRUCTOR, __i_desc_type_node, NULL_TREE, elems);
TREE_CONSTANT (taggr) = 1;
TREE_STATIC (taggr) = 1;
TREE_READONLY (taggr) = 1;
return taggr;
}
/* Build an initializer for a __m_desc node. */
tree
build_m_desc (decl)
tree decl;
{
tree taggr, elems, name_string;
tree parm_count, req_count, vindex, vcontext;
tree parms;
int p_count, r_count;
tree parm_types = NULL_TREE;
for (parms = TYPE_ARG_TYPES (TREE_TYPE (decl)), p_count = 0, r_count = 0;
parms != NULL_TREE; parms = TREE_CHAIN (parms), p_count++)
{
taggr = TREE_VALUE (parms);
if ((TREE_CODE (taggr) == POINTER_TYPE
|| TREE_CODE (taggr) == REFERENCE_TYPE)
&& TYPE_VOLATILE (taggr) == 0)
taggr = TREE_TYPE (taggr);
parm_types = tree_cons (NULL_TREE, build_t_desc (TREE_VALUE (parms),
! IS_AGGR_TYPE (taggr)),
parm_types);
if (TREE_PURPOSE (parms) == NULL_TREE)
r_count++;
}
parm_types = finish_table (NULL_TREE, build_pointer_type (__t_desc_type_node),
nreverse (parm_types), 0);
parm_count = build_int_2 (p_count, 0);
req_count = build_int_2 (r_count, 0);
if (DECL_VINDEX (decl))
vindex = DECL_VINDEX (decl);
else
vindex = integer_zero_node;
if (DECL_CONTEXT (decl)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
vcontext = build_t_desc (DECL_CONTEXT (decl), 0);
else
vcontext = integer_zero_node;
name_string = DECL_NAME (decl);
if (name_string == NULL)
name_string = DECL_ASSEMBLER_NAME (decl);
name_string = combine_strings (build_string (IDENTIFIER_LENGTH (name_string)+1, IDENTIFIER_POINTER (name_string)));
/* Now decide whether the return type of this mvar
should cause it's type to get def'd or ref'd in this file.
If the type we are looking at has a proxy definition,
we look at the proxy (i.e., a `foo *' is equivalent to a `foo'). */
taggr = TREE_TYPE (TREE_TYPE (decl));
if ((TREE_CODE (taggr) == POINTER_TYPE
|| TREE_CODE (taggr) == REFERENCE_TYPE)
&& TYPE_VOLATILE (taggr) == 0)
taggr = TREE_TYPE (taggr);
elems = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, name_string, 0),
tree_cons (NULL_TREE, vindex,
tree_cons (NULL_TREE, vcontext,
tree_cons (NULL_TREE, build_t_desc (TREE_TYPE (TREE_TYPE (decl)),
! IS_AGGR_TYPE (taggr)),
tree_cons (NULL_TREE, build_c_cast (build_pointer_type (default_function_type), build_unary_op (ADDR_EXPR, decl, 0)),
tree_cons (NULL_TREE, parm_count,
tree_cons (NULL_TREE, req_count,
build_tree_list (NULL_TREE, build_unary_op (ADDR_EXPR, parm_types, 0)))))))));
taggr = build (CONSTRUCTOR, __m_desc_type_node, NULL_TREE, elems);
TREE_CONSTANT (taggr) = 1;
TREE_STATIC (taggr) = 1;
TREE_READONLY (taggr) = 1;
return taggr;
}
#endif /* dossier */
...@@ -570,10 +570,13 @@ common_type (t1, t2) ...@@ -570,10 +570,13 @@ common_type (t1, t2)
/* If this was a member function type, get back to the /* If this was a member function type, get back to the
original type of type member function (i.e., without original type of type member function (i.e., without
the class instance variable up front. */ the class instance variable up front. */
t1 = build_function_type (TREE_TYPE (t1), TREE_CHAIN (TYPE_ARG_TYPES (t1))); t1 = build_function_type (TREE_TYPE (t1),
t2 = build_function_type (TREE_TYPE (t2), TREE_CHAIN (TYPE_ARG_TYPES (t2))); TREE_CHAIN (TYPE_ARG_TYPES (t1)));
t2 = build_function_type (TREE_TYPE (t2),
TREE_CHAIN (TYPE_ARG_TYPES (t2)));
t3 = common_type (t1, t2); t3 = common_type (t1, t2);
t3 = build_cplus_method_type (basetype, TREE_TYPE (t3), TYPE_ARG_TYPES (t3)); t3 = build_cplus_method_type (basetype, TREE_TYPE (t3),
TYPE_ARG_TYPES (t3));
t1 = build_exception_variant (t3, raises); t1 = build_exception_variant (t3, raises);
} }
else else
...@@ -958,7 +961,8 @@ comp_target_types (ttl, ttr, nptrs) ...@@ -958,7 +961,8 @@ comp_target_types (ttl, ttr, nptrs)
else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE) else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE)
{ {
if (comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), -1)) if (comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), -1))
switch (comp_target_parms (TYPE_ARG_TYPES (ttl), TYPE_ARG_TYPES (ttr), 1)) switch (comp_target_parms (TYPE_ARG_TYPES (ttl),
TYPE_ARG_TYPES (ttr), 1))
{ {
case 0: case 0:
return 0; return 0;
...@@ -978,9 +982,11 @@ comp_target_types (ttl, ttr, nptrs) ...@@ -978,9 +982,11 @@ comp_target_types (ttl, ttr, nptrs)
/* Contravariance: we can assign a pointer to base member to a pointer /* Contravariance: we can assign a pointer to base member to a pointer
to derived member. Note difference from simple pointer case, where to derived member. Note difference from simple pointer case, where
we can pass a pointer to derived to a pointer to base. */ we can pass a pointer to derived to a pointer to base. */
if (comptypes (TYPE_OFFSET_BASETYPE (ttr), TYPE_OFFSET_BASETYPE (ttl), 0)) if (comptypes (TYPE_OFFSET_BASETYPE (ttr),
TYPE_OFFSET_BASETYPE (ttl), 0))
return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs); return comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs);
else if (comptypes (TYPE_OFFSET_BASETYPE (ttl), TYPE_OFFSET_BASETYPE (ttr), 0) else if (comptypes (TYPE_OFFSET_BASETYPE (ttl),
TYPE_OFFSET_BASETYPE (ttr), 0)
&& comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs)) && comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), nptrs))
return -1; return -1;
} }
...@@ -1150,7 +1156,8 @@ comp_target_parms (parms1, parms2, strict) ...@@ -1150,7 +1156,8 @@ comp_target_parms (parms1, parms2, strict)
continue; continue;
if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE) if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)
|| (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE)) || (TREE_CODE (p1) == REFERENCE_TYPE
&& TREE_CODE (p2) == REFERENCE_TYPE))
{ {
if (strict <= 0 if (strict <= 0
&& (TYPE_MAIN_VARIANT (TREE_TYPE (p1)) && (TYPE_MAIN_VARIANT (TREE_TYPE (p1))
...@@ -1571,7 +1578,8 @@ decay_conversion (exp) ...@@ -1571,7 +1578,8 @@ decay_conversion (exp)
if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE) if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE)
{ {
inner = build1 (CONVERT_EXPR, inner = build1 (CONVERT_EXPR,
build_pointer_type (TREE_TYPE (TREE_TYPE (inner))), build_pointer_type (TREE_TYPE
(TREE_TYPE (inner))),
inner); inner);
TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0)); TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0));
} }
...@@ -1604,8 +1612,8 @@ decay_conversion (exp) ...@@ -1604,8 +1612,8 @@ decay_conversion (exp)
if (TYPE_READONLY (type) || TYPE_VOLATILE (type) if (TYPE_READONLY (type) || TYPE_VOLATILE (type)
|| constp || volatilep) || constp || volatilep)
restype = cp_build_type_variant (restype, restype = cp_build_type_variant (restype,
TYPE_READONLY (type) || constp, TYPE_READONLY (type) || constp,
TYPE_VOLATILE (type) || volatilep); TYPE_VOLATILE (type) || volatilep);
ptrtype = build_pointer_type (restype); ptrtype = build_pointer_type (restype);
if (TREE_CODE (exp) == VAR_DECL) if (TREE_CODE (exp) == VAR_DECL)
...@@ -1932,10 +1940,12 @@ build_component_ref (datum, component, basetype_path, protect) ...@@ -1932,10 +1940,12 @@ build_component_ref (datum, component, basetype_path, protect)
tree addr = build_unary_op (ADDR_EXPR, datum, 0); tree addr = build_unary_op (ADDR_EXPR, datum, 0);
tree fntype = TREE_TYPE (fndecl); tree fntype = TREE_TYPE (fndecl);
addr = convert_pointer_to (DECL_CONTEXT (fndecl), addr); addr = convert_pointer_to (DECL_CONTEXT (fndecl),
addr);
datum = build_indirect_ref (addr, NULL_PTR); datum = build_indirect_ref (addr, NULL_PTR);
my_friendly_assert (datum != error_mark_node, 310); my_friendly_assert (datum != error_mark_node, 310);
fndecl = build_vfn_ref (&addr, datum, DECL_VINDEX (fndecl)); fndecl = build_vfn_ref (&addr, datum,
DECL_VINDEX (fndecl));
/* The type of fndecl is a function type, /* The type of fndecl is a function type,
not a pointer-to-function type, since not a pointer-to-function type, since
build_vfn_ref returns not the correct build_vfn_ref returns not the correct
...@@ -1945,7 +1955,8 @@ build_component_ref (datum, component, basetype_path, protect) ...@@ -1945,7 +1955,8 @@ build_component_ref (datum, component, basetype_path, protect)
} }
else else
mark_used (fndecl); mark_used (fndecl);
return build (OFFSET_REF, TREE_TYPE (fndecl), datum, fndecl); return build (OFFSET_REF, TREE_TYPE (fndecl),
datum, fndecl);
} }
if (access == access_protected_node) if (access == access_protected_node)
cp_error ("member function `%D' is protected", fndecl); cp_error ("member function `%D' is protected", fndecl);
...@@ -2079,7 +2090,8 @@ build_x_indirect_ref (ptr, errorstring) ...@@ -2079,7 +2090,8 @@ build_x_indirect_ref (ptr, errorstring)
if (processing_template_decl) if (processing_template_decl)
return build_min_nt (INDIRECT_REF, ptr); return build_min_nt (INDIRECT_REF, ptr);
rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE, NULL_TREE); rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE,
NULL_TREE);
if (rval) if (rval)
return rval; return rval;
return build_indirect_ref (ptr, errorstring); return build_indirect_ref (ptr, errorstring);
...@@ -2102,17 +2114,6 @@ build_indirect_ref (ptr, errorstring) ...@@ -2102,17 +2114,6 @@ build_indirect_ref (ptr, errorstring)
if (ptr == current_class_ptr) if (ptr == current_class_ptr)
return current_class_ref; return current_class_ref;
if (IS_AGGR_TYPE (type))
{
ptr = build_expr_type_conversion (WANT_POINTER, pointer, 1);
if (ptr)
{
pointer = ptr;
type = TREE_TYPE (pointer);
}
}
if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE) if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE)
{ {
if (TREE_CODE (pointer) == ADDR_EXPR if (TREE_CODE (pointer) == ADDR_EXPR
...@@ -2135,7 +2136,8 @@ build_indirect_ref (ptr, errorstring) ...@@ -2135,7 +2136,8 @@ build_indirect_ref (ptr, errorstring)
to assign to. Also, &* is supposed to be a no-op. */ to assign to. Also, &* is supposed to be a no-op. */
TREE_READONLY (ref) = TYPE_READONLY (t); TREE_READONLY (ref) = TYPE_READONLY (t);
TREE_SIDE_EFFECTS (ref) TREE_SIDE_EFFECTS (ref)
= TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile; = (TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer)
|| flag_volatile);
TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t); TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
return ref; return ref;
} }
...@@ -2214,7 +2216,8 @@ build_array_ref (array, idx) ...@@ -2214,7 +2216,8 @@ build_array_ref (array, idx)
Likewise an array of elements of variable size. */ Likewise an array of elements of variable size. */
if (TREE_CODE (idx) != INTEGER_CST if (TREE_CODE (idx) != INTEGER_CST
|| (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0 || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST)) && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
!= INTEGER_CST)))
{ {
if (mark_addressable (array) == 0) if (mark_addressable (array) == 0)
return error_mark_node; return error_mark_node;
...@@ -2292,7 +2295,8 @@ build_array_ref (array, idx) ...@@ -2292,7 +2295,8 @@ build_array_ref (array, idx)
return error_mark_node; return error_mark_node;
} }
return build_indirect_ref (build_binary_op_nodefault (PLUS_EXPR, ar, ind, PLUS_EXPR), return build_indirect_ref (build_binary_op_nodefault (PLUS_EXPR, ar,
ind, PLUS_EXPR),
"array indexing"); "array indexing");
} }
} }
...@@ -2357,12 +2361,14 @@ build_x_function_call (function, params, decl) ...@@ -2357,12 +2361,14 @@ build_x_function_call (function, params, decl)
function = TREE_VALUE (function); function = TREE_VALUE (function);
my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 999); my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 999);
function = DECL_NAME (function); function = DECL_NAME (function);
return build_method_call (decl, function, params, TYPE_BINFO (type), LOOKUP_NORMAL); return build_method_call (decl, function, params,
TYPE_BINFO (type), LOOKUP_NORMAL);
} }
is_method = ((TREE_CODE (function) == TREE_LIST is_method = ((TREE_CODE (function) == TREE_LIST
&& current_class_type != NULL_TREE && current_class_type != NULL_TREE
&& IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function)) == function) && (IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function))
== function))
|| TREE_CODE (function) == IDENTIFIER_NODE || TREE_CODE (function) == IDENTIFIER_NODE
|| TREE_CODE (type) == METHOD_TYPE || TREE_CODE (type) == METHOD_TYPE
|| TYPE_PTRMEMFUNC_P (type)); || TYPE_PTRMEMFUNC_P (type));
...@@ -2395,7 +2401,8 @@ build_x_function_call (function, params, decl) ...@@ -2395,7 +2401,8 @@ build_x_function_call (function, params, decl)
} }
else if (TREE_CODE (function) == TREE_LIST) else if (TREE_CODE (function) == TREE_LIST)
{ {
my_friendly_assert (TREE_CODE (TREE_VALUE (function)) == FUNCTION_DECL, 312); my_friendly_assert (TREE_CODE (TREE_VALUE (function))
== FUNCTION_DECL, 312);
basetype = DECL_CLASS_CONTEXT (TREE_VALUE (function)); basetype = DECL_CLASS_CONTEXT (TREE_VALUE (function));
function = TREE_PURPOSE (function); function = TREE_PURPOSE (function);
} }
...@@ -2416,7 +2423,8 @@ build_x_function_call (function, params, decl) ...@@ -2416,7 +2423,8 @@ build_x_function_call (function, params, decl)
if (TREE_CODE (TREE_TYPE (function)) != POINTER_TYPE if (TREE_CODE (TREE_TYPE (function)) != POINTER_TYPE
&& ! TYPE_PTRMEMFUNC_P (TREE_TYPE (function)) && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (function))
&& TREE_CODE (function) != OFFSET_REF) && TREE_CODE (function) != OFFSET_REF)
function = build (OFFSET_REF, TREE_TYPE (type), NULL_TREE, function); function = build (OFFSET_REF, TREE_TYPE (type), NULL_TREE,
function);
goto do_x_function; goto do_x_function;
} }
...@@ -2519,7 +2527,8 @@ build_x_function_call (function, params, decl) ...@@ -2519,7 +2527,8 @@ build_x_function_call (function, params, decl)
passed in as an argument. */ passed in as an argument. */
else if (TYPE_PTRMEMFUNC_P (fntype)) else if (TYPE_PTRMEMFUNC_P (fntype))
{ {
tree rec = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (fntype))); tree rec = TYPE_METHOD_BASETYPE (TREE_TYPE
(TYPE_PTRMEMFUNC_FN_TYPE (fntype)));
ctypeptr = build_pointer_type (rec); ctypeptr = build_pointer_type (rec);
} }
/* Unexpected node type? */ /* Unexpected node type? */
...@@ -2587,7 +2596,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) ...@@ -2587,7 +2596,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
NULL_TREE, 0))); NULL_TREE, 0)));
e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1); e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1);
delta = cp_convert (ptrdiff_type_node, delta = cp_convert (ptrdiff_type_node,
build_component_ref (function, delta_identifier, NULL_TREE, 0)); build_component_ref (function, delta_identifier,
NULL_TREE, 0));
delta2 = DELTA2_FROM_PTRMEMFUNC (function); delta2 = DELTA2_FROM_PTRMEMFUNC (function);
/* Convert down to the right base, before using the instance. */ /* Convert down to the right base, before using the instance. */
...@@ -2610,9 +2620,13 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) ...@@ -2610,9 +2620,13 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
{ {
aref = save_expr (aref); aref = save_expr (aref);
delta = build_binary_op (PLUS_EXPR, delta = build_binary_op
build_conditional_expr (e1, build_component_ref (aref, delta_identifier, NULL_TREE, 0), integer_zero_node), (PLUS_EXPR,
delta, 1); build_conditional_expr (e1, build_component_ref (aref,
delta_identifier,
NULL_TREE, 0),
integer_zero_node),
delta, 1);
} }
*instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr), *instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr),
...@@ -2666,7 +2680,8 @@ build_function_call_real (function, params, require_complete, flags) ...@@ -2666,7 +2680,8 @@ build_function_call_real (function, params, require_complete, flags)
GNU_xref_call (current_function_decl, GNU_xref_call (current_function_decl,
IDENTIFIER_POINTER (name ? name IDENTIFIER_POINTER (name ? name
: TYPE_IDENTIFIER (DECL_CLASS_CONTEXT (function)))); : TYPE_IDENTIFIER (DECL_CLASS_CONTEXT
(function))));
mark_used (function); mark_used (function);
fndecl = function; fndecl = function;
...@@ -2936,7 +2951,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) ...@@ -2936,7 +2951,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
#ifdef PROMOTE_PROTOTYPES #ifdef PROMOTE_PROTOTYPES
if ((TREE_CODE (type) == INTEGER_TYPE if ((TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == ENUMERAL_TYPE) || TREE_CODE (type) == ENUMERAL_TYPE)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) && (TYPE_PRECISION (type)
< TYPE_PRECISION (integer_type_node)))
parmval = default_conversion (parmval); parmval = default_conversion (parmval);
#endif #endif
} }
...@@ -2955,7 +2971,9 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) ...@@ -2955,7 +2971,9 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
&& (TYPE_PRECISION (TREE_TYPE (val)) && (TYPE_PRECISION (TREE_TYPE (val))
< TYPE_PRECISION (double_type_node))) < TYPE_PRECISION (double_type_node)))
/* Convert `float' to `double'. */ /* Convert `float' to `double'. */
result = expr_tree_cons (NULL_TREE, cp_convert (double_type_node, val), result); result = expr_tree_cons (NULL_TREE,
cp_convert (double_type_node, val),
result);
else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val)) else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val))
&& ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (val))) && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (val)))
{ {
...@@ -2965,7 +2983,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) ...@@ -2965,7 +2983,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
} }
else else
/* Convert `short' and `char' to full-size `int'. */ /* Convert `short' and `char' to full-size `int'. */
result = expr_tree_cons (NULL_TREE, default_conversion (val), result); result = expr_tree_cons (NULL_TREE, default_conversion (val),
result);
} }
if (typetail) if (typetail)
...@@ -2988,8 +3007,10 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) ...@@ -2988,8 +3007,10 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
else if (TREE_CODE (val) == CONSTRUCTOR) else if (TREE_CODE (val) == CONSTRUCTOR)
{ {
parmval = digest_init (type, val, (tree *)0); parmval = digest_init (type, val, (tree *)0);
parmval = convert_for_initialization (return_loc, type, parmval, flags, parmval = convert_for_initialization (return_loc, type,
"default constructor", fndecl, i); parmval, flags,
"default constructor",
fndecl, i);
} }
else else
{ {
...@@ -2997,12 +3018,15 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) ...@@ -2997,12 +3018,15 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
if (TREE_HAS_CONSTRUCTOR (val)) if (TREE_HAS_CONSTRUCTOR (val))
val = copy_node (val); val = copy_node (val);
parmval = convert_for_initialization (return_loc, type, val, flags, parmval = convert_for_initialization (return_loc, type,
"default argument", fndecl, i); val, flags,
"default argument",
fndecl, i);
#ifdef PROMOTE_PROTOTYPES #ifdef PROMOTE_PROTOTYPES
if ((TREE_CODE (type) == INTEGER_TYPE if ((TREE_CODE (type) == INTEGER_TYPE
|| TREE_CODE (type) == ENUMERAL_TYPE) || TREE_CODE (type) == ENUMERAL_TYPE)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) && (TYPE_PRECISION (type)
< TYPE_PRECISION (integer_type_node)))
parmval = default_conversion (parmval); parmval = default_conversion (parmval);
#endif #endif
} }
...@@ -3087,15 +3111,7 @@ build_binary_op (code, arg1, arg2, convert_p) ...@@ -3087,15 +3111,7 @@ build_binary_op (code, arg1, arg2, convert_p)
} }
if (IS_AGGR_TYPE (type0) || IS_AGGR_TYPE (type1)) if (IS_AGGR_TYPE (type0) || IS_AGGR_TYPE (type1))
{ my_friendly_abort (754867);
/* Try to convert this to something reasonable. */
if (! build_default_binary_type_conversion(code, &args[0], &args[1]))
{
cp_error ("no match for `%O(%#T, %#T)'", code,
TREE_TYPE (arg1), TREE_TYPE (arg2));
return error_mark_node;
}
}
} }
return build_binary_op_nodefault (code, args[0], args[1], code); return build_binary_op_nodefault (code, args[0], args[1], code);
} }
...@@ -3279,7 +3295,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3279,7 +3295,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
in the short type, making the entire operation go away. */ in the short type, making the entire operation go away. */
if (TREE_CODE (op0) == INTEGER_CST if (TREE_CODE (op0) == INTEGER_CST
&& TREE_CODE (op1) == NOP_EXPR && TREE_CODE (op1) == NOP_EXPR
&& TYPE_PRECISION (type1) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0))) && (TYPE_PRECISION (type1)
> TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0))))
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0)))) && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0))))
{ {
final_type = result_type; final_type = result_type;
...@@ -3288,7 +3305,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3288,7 +3305,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
} }
if (TREE_CODE (op1) == INTEGER_CST if (TREE_CODE (op1) == INTEGER_CST
&& TREE_CODE (op0) == NOP_EXPR && TREE_CODE (op0) == NOP_EXPR
&& TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))) && (TYPE_PRECISION (type0)
> TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0))))
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
{ {
final_type = result_type; final_type = result_type;
...@@ -3478,18 +3496,23 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3478,18 +3496,23 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
&& ((op1.index != -1 && op0.delta2 == op1.delta2) && ((op1.index != -1 && op0.delta2 == op1.delta2)
|| op0.pfn == op1.pfn)) */ || op0.pfn == op1.pfn)) */
tree index0 = build_component_ref (op0, index_identifier, NULL_TREE, 0); tree index0 = build_component_ref (op0, index_identifier,
tree index1 = save_expr (build_component_ref (op1, index_identifier, NULL_TREE, 0)); NULL_TREE, 0);
tree index1 = save_expr (build_component_ref (op1, index_identifier,
NULL_TREE, 0));
tree pfn0 = PFN_FROM_PTRMEMFUNC (op0); tree pfn0 = PFN_FROM_PTRMEMFUNC (op0);
tree pfn1 = PFN_FROM_PTRMEMFUNC (op1); tree pfn1 = PFN_FROM_PTRMEMFUNC (op1);
tree delta20 = DELTA2_FROM_PTRMEMFUNC (op0); tree delta20 = DELTA2_FROM_PTRMEMFUNC (op0);
tree delta21 = DELTA2_FROM_PTRMEMFUNC (op1); tree delta21 = DELTA2_FROM_PTRMEMFUNC (op1);
tree e1, e2, e3; tree e1, e2, e3;
tree integer_neg_one_node tree integer_neg_one_node
= build_binary_op (MINUS_EXPR, integer_zero_node, integer_one_node, 1); = build_binary_op (MINUS_EXPR, integer_zero_node,
integer_one_node, 1);
e1 = build_binary_op (EQ_EXPR, index0, index1, 1); e1 = build_binary_op (EQ_EXPR, index0, index1, 1);
e2 = build_binary_op (NE_EXPR, index1, integer_neg_one_node, 1); e2 = build_binary_op (NE_EXPR, index1, integer_neg_one_node, 1);
e2 = build_binary_op (TRUTH_ANDIF_EXPR, e2, build_binary_op (EQ_EXPR, delta20, delta21, 1), 1); e2 = build_binary_op (TRUTH_ANDIF_EXPR, e2,
build_binary_op (EQ_EXPR, delta20, delta21, 1),
1);
e3 = build_binary_op (EQ_EXPR, pfn0, pfn1, 1); e3 = build_binary_op (EQ_EXPR, pfn0, pfn1, 1);
e2 = build_binary_op (TRUTH_ORIF_EXPR, e2, e3, 1); e2 = build_binary_op (TRUTH_ORIF_EXPR, e2, e3, 1);
e2 = build_binary_op (TRUTH_ANDIF_EXPR, e1, e2, 1); e2 = build_binary_op (TRUTH_ANDIF_EXPR, e1, e2, 1);
...@@ -3500,7 +3523,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3500,7 +3523,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
else if (TYPE_PTRMEMFUNC_P (type0) else if (TYPE_PTRMEMFUNC_P (type0)
&& TYPE_PTRMEMFUNC_FN_TYPE (type0) == type1) && TYPE_PTRMEMFUNC_FN_TYPE (type0) == type1)
{ {
tree index0 = build_component_ref (op0, index_identifier, NULL_TREE, 0); tree index0 = build_component_ref (op0, index_identifier,
NULL_TREE, 0);
tree index1; tree index1;
tree pfn0 = PFN_FROM_PTRMEMFUNC (op0); tree pfn0 = PFN_FROM_PTRMEMFUNC (op0);
tree delta20 = DELTA2_FROM_PTRMEMFUNC (op0); tree delta20 = DELTA2_FROM_PTRMEMFUNC (op0);
...@@ -3511,26 +3535,32 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3511,26 +3535,32 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
if (TREE_CODE (TREE_OPERAND (op1, 0)) == FUNCTION_DECL if (TREE_CODE (TREE_OPERAND (op1, 0)) == FUNCTION_DECL
&& DECL_VINDEX (TREE_OPERAND (op1, 0))) && DECL_VINDEX (TREE_OPERAND (op1, 0)))
{ {
/* Map everything down one to make room for the null pointer to member. */ /* Map everything down one to make room for
the null pointer to member. */
index1 = size_binop (PLUS_EXPR, index1 = size_binop (PLUS_EXPR,
DECL_VINDEX (TREE_OPERAND (op1, 0)), DECL_VINDEX (TREE_OPERAND (op1, 0)),
integer_one_node); integer_one_node);
op1 = integer_zero_node; op1 = integer_zero_node;
delta21 = CLASSTYPE_VFIELD (TYPE_METHOD_BASETYPE (TREE_TYPE (type1))); delta21 = CLASSTYPE_VFIELD (TYPE_METHOD_BASETYPE
(TREE_TYPE (type1)));
delta21 = DECL_FIELD_BITPOS (delta21); delta21 = DECL_FIELD_BITPOS (delta21);
delta21 = size_binop (FLOOR_DIV_EXPR, delta21, size_int (BITS_PER_UNIT)); delta21 = size_binop (FLOOR_DIV_EXPR, delta21,
size_int (BITS_PER_UNIT));
delta21 = convert (sizetype, delta21); delta21 = convert (sizetype, delta21);
} }
else else
index1 = integer_neg_one_node; index1 = integer_neg_one_node;
{ {
tree nop1 = build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type0), op1); tree nop1 = build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type0),
op1);
TREE_CONSTANT (nop1) = TREE_CONSTANT (op1); TREE_CONSTANT (nop1) = TREE_CONSTANT (op1);
op1 = nop1; op1 = nop1;
} }
e1 = build_binary_op (EQ_EXPR, index0, index1, 1); e1 = build_binary_op (EQ_EXPR, index0, index1, 1);
e2 = build_binary_op (NE_EXPR, index1, integer_neg_one_node, 1); e2 = build_binary_op (NE_EXPR, index1, integer_neg_one_node, 1);
e2 = build_binary_op (TRUTH_ANDIF_EXPR, e2, build_binary_op (EQ_EXPR, delta20, delta21, 1), 1); e2 = build_binary_op (TRUTH_ANDIF_EXPR, e2,
build_binary_op (EQ_EXPR, delta20, delta21, 1),
1);
e3 = build_binary_op (EQ_EXPR, pfn0, op1, 1); e3 = build_binary_op (EQ_EXPR, pfn0, op1, 1);
e2 = build_binary_op (TRUTH_ORIF_EXPR, e2, e3, 1); e2 = build_binary_op (TRUTH_ORIF_EXPR, e2, e3, 1);
e2 = build_binary_op (TRUTH_ANDIF_EXPR, e1, e2, 1); e2 = build_binary_op (TRUTH_ANDIF_EXPR, e1, e2, 1);
...@@ -3665,7 +3695,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3665,7 +3695,8 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
&& (unsigned0 || !uns)) && (unsigned0 || !uns))
result_type result_type
= signed_or_unsigned_type (unsigned0, = signed_or_unsigned_type (unsigned0,
common_type (TREE_TYPE (arg0), TREE_TYPE (arg1))); common_type (TREE_TYPE (arg0),
TREE_TYPE (arg1)));
else if (TREE_CODE (arg0) == INTEGER_CST else if (TREE_CODE (arg0) == INTEGER_CST
&& (unsigned1 || !uns) && (unsigned1 || !uns)
&& (TYPE_PRECISION (TREE_TYPE (arg1)) && (TYPE_PRECISION (TREE_TYPE (arg1))
...@@ -3790,9 +3821,11 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3790,9 +3821,11 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
not use the most significant bit of result_type. */ not use the most significant bit of result_type. */
else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR) else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR)
&& ((op0_signed && TREE_CODE (orig_op1) == INTEGER_CST && ((op0_signed && TREE_CODE (orig_op1) == INTEGER_CST
&& int_fits_type_p (orig_op1, signed_type (result_type)) && int_fits_type_p (orig_op1,
signed_type (result_type))
|| (op1_signed && TREE_CODE (orig_op0) == INTEGER_CST || (op1_signed && TREE_CODE (orig_op0) == INTEGER_CST
&& int_fits_type_p (orig_op0, signed_type (result_type)))))) && int_fits_type_p (orig_op0,
signed_type (result_type))))))
/* OK */; /* OK */;
else else
warning ("comparison between signed and unsigned"); warning ("comparison between signed and unsigned");
...@@ -3970,7 +4003,9 @@ pointer_int_sum (resultcode, ptrop, intop) ...@@ -3970,7 +4003,9 @@ pointer_int_sum (resultcode, ptrop, intop)
intop = cp_convert (result_type, intop = cp_convert (result_type,
build_binary_op (MULT_EXPR, intop, build_binary_op (MULT_EXPR, intop,
cp_convert (TREE_TYPE (intop), size_exp), 1)); cp_convert (TREE_TYPE (intop),
size_exp),
1));
/* Create the sum or difference. */ /* Create the sum or difference. */
...@@ -4009,8 +4044,8 @@ pointer_diff (op0, op1, ptrtype) ...@@ -4009,8 +4044,8 @@ pointer_diff (op0, op1, ptrtype)
/* First do the subtraction as integers; /* First do the subtraction as integers;
then drop through to build the divide operator. */ then drop through to build the divide operator. */
op0 = build_binary_op (MINUS_EXPR, op0 = build_binary_op (MINUS_EXPR, cp_convert (restype, op0),
cp_convert (restype, op0), cp_convert (restype, op1), 1); cp_convert (restype, op1), 1);
/* This generates an error if op1 is a pointer to an incomplete type. */ /* This generates an error if op1 is a pointer to an incomplete type. */
if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0) if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
...@@ -4565,8 +4600,9 @@ build_unary_op (code, xarg, noconvert) ...@@ -4565,8 +4600,9 @@ build_unary_op (code, xarg, noconvert)
tree addr; tree addr;
if (TREE_CODE (arg) == COMPONENT_REF) if (TREE_CODE (arg) == COMPONENT_REF)
addr = build_component_addr (arg, argtype, addr = build_component_addr
"attempt to take address of bit-field structure member `%s'"); (arg, argtype,
"attempt to take address of bit-field structure member `%s'");
else else
addr = build1 (code, argtype, arg); addr = build1 (code, argtype, arg);
...@@ -4689,7 +4725,8 @@ unary_complex_lvalue (code, arg) ...@@ -4689,7 +4725,8 @@ unary_complex_lvalue (code, arg)
t = TREE_OPERAND (arg, 1); t = TREE_OPERAND (arg, 1);
if (TREE_CODE (t) == FUNCTION_DECL) /* Check all this code for right semantics. */ /* Check all this code for right semantics. */
if (TREE_CODE (t) == FUNCTION_DECL)
return build_unary_op (ADDR_EXPR, t, 0); return build_unary_op (ADDR_EXPR, t, 0);
if (TREE_CODE (t) == VAR_DECL) if (TREE_CODE (t) == VAR_DECL)
return build_unary_op (ADDR_EXPR, t, 0); return build_unary_op (ADDR_EXPR, t, 0);
...@@ -4700,7 +4737,8 @@ unary_complex_lvalue (code, arg) ...@@ -4700,7 +4737,8 @@ unary_complex_lvalue (code, arg)
if (TREE_OPERAND (arg, 0) if (TREE_OPERAND (arg, 0)
&& (TREE_CODE (TREE_OPERAND (arg, 0)) != NOP_EXPR && (TREE_CODE (TREE_OPERAND (arg, 0)) != NOP_EXPR
|| TREE_OPERAND (TREE_OPERAND (arg, 0), 0) != error_mark_node)) || (TREE_OPERAND (TREE_OPERAND (arg, 0), 0)
!= error_mark_node)))
if (TREE_CODE (t) != FIELD_DECL) if (TREE_CODE (t) != FIELD_DECL)
{ {
/* Don't know if this should return address to just /* Don't know if this should return address to just
...@@ -4723,7 +4761,8 @@ unary_complex_lvalue (code, arg) ...@@ -4723,7 +4761,8 @@ unary_complex_lvalue (code, arg)
convert (sizetype, convert (sizetype,
size_binop (EASY_DIV_EXPR, size_binop (EASY_DIV_EXPR,
DECL_FIELD_BITPOS (t), DECL_FIELD_BITPOS (t),
size_int (BITS_PER_UNIT)))); size_int (BITS_PER_UNIT))
));
/* We offset all pointer to data members by 1 so that we can /* We offset all pointer to data members by 1 so that we can
distinguish between a null pointer to data member and the first distinguish between a null pointer to data member and the first
...@@ -4808,7 +4847,8 @@ mark_addressable (exp) ...@@ -4808,7 +4847,8 @@ mark_addressable (exp)
TREE_ASM_WRITTEN (x) = 0; TREE_ASM_WRITTEN (x) = 0;
DECL_RTL (x) = 0; DECL_RTL (x) = 0;
rest_of_decl_compilation (x, 0, IDENTIFIER_LOCAL_VALUE (x) == 0, 0); rest_of_decl_compilation (x, 0, IDENTIFIER_LOCAL_VALUE (x) == 0,
0);
TREE_ADDRESSABLE (x) = 1; TREE_ADDRESSABLE (x) = 1;
pop_obstacks (); pop_obstacks ();
...@@ -4977,7 +5017,8 @@ build_conditional_expr (ifexp, op1, op2) ...@@ -4977,7 +5017,8 @@ build_conditional_expr (ifexp, op1, op2)
{ {
if (code2 == ENUMERAL_TYPE) if (code2 == ENUMERAL_TYPE)
{ {
cp_error ("enumeral mismatch in conditional expression: `%T' vs `%T'", type1, type2); cp_error ("enumeral mismatch in conditional expression: `%T' vs `%T'",
type1, type2);
return error_mark_node; return error_mark_node;
} }
else if (extra_warnings && ! IS_AGGR_TYPE_CODE (code2) else if (extra_warnings && ! IS_AGGR_TYPE_CODE (code2)
...@@ -5066,7 +5107,8 @@ build_conditional_expr (ifexp, op1, op2) ...@@ -5066,7 +5107,8 @@ build_conditional_expr (ifexp, op1, op2)
result_type = type2; result_type = type2;
else if (IS_AGGR_TYPE (TREE_TYPE (type1)) else if (IS_AGGR_TYPE (TREE_TYPE (type1))
&& IS_AGGR_TYPE (TREE_TYPE (type2)) && IS_AGGR_TYPE (TREE_TYPE (type2))
&& (result_type = common_base_type (TREE_TYPE (type1), TREE_TYPE (type2)))) && (result_type = common_base_type (TREE_TYPE (type1),
TREE_TYPE (type2))))
{ {
if (result_type == error_mark_node) if (result_type == error_mark_node)
{ {
...@@ -5108,7 +5150,8 @@ build_conditional_expr (ifexp, op1, op2) ...@@ -5108,7 +5150,8 @@ build_conditional_expr (ifexp, op1, op2)
an aggregate value, try converting to a scalar type. */ an aggregate value, try converting to a scalar type. */
if (code1 == RECORD_TYPE && code2 == RECORD_TYPE) if (code1 == RECORD_TYPE && code2 == RECORD_TYPE)
{ {
cp_error ("aggregate mismatch in conditional expression: `%T' vs `%T'", type1, type2); cp_error ("aggregate mismatch in conditional expression: `%T' vs `%T'",
type1, type2);
return error_mark_node; return error_mark_node;
} }
/* Warning: this code assumes that conversion between cv-variants of /* Warning: this code assumes that conversion between cv-variants of
...@@ -5205,7 +5248,8 @@ build_x_compound_expr (list) ...@@ -5205,7 +5248,8 @@ build_x_compound_expr (list)
result = build_opfncall (COMPOUND_EXPR, LOOKUP_NORMAL, result = build_opfncall (COMPOUND_EXPR, LOOKUP_NORMAL,
TREE_VALUE (list), TREE_VALUE (rest), NULL_TREE); TREE_VALUE (list), TREE_VALUE (rest), NULL_TREE);
if (result) if (result)
return build_x_compound_expr (expr_tree_cons (NULL_TREE, result, TREE_CHAIN (rest))); return build_x_compound_expr (expr_tree_cons (NULL_TREE, result,
TREE_CHAIN (rest)));
if (! TREE_SIDE_EFFECTS (TREE_VALUE (list))) if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
{ {
...@@ -5222,8 +5266,10 @@ build_x_compound_expr (list) ...@@ -5222,8 +5266,10 @@ build_x_compound_expr (list)
warn_if_unused_value (TREE_VALUE(list)); warn_if_unused_value (TREE_VALUE(list));
#endif #endif
return build_compound_expr (expr_tree_cons (NULL_TREE, TREE_VALUE (list), return build_compound_expr
build_expr_list (NULL_TREE, build_x_compound_expr (rest)))); (expr_tree_cons (NULL_TREE, TREE_VALUE (list),
build_expr_list (NULL_TREE,
build_x_compound_expr (rest))));
} }
/* Given a list of expressions, return a compound expression /* Given a list of expressions, return a compound expression
...@@ -5878,23 +5924,7 @@ build_modify_expr (lhs, modifycode, rhs) ...@@ -5878,23 +5924,7 @@ build_modify_expr (lhs, modifycode, rhs)
} }
else if (PROMOTES_TO_AGGR_TYPE (lhstype, REFERENCE_TYPE)) else if (PROMOTES_TO_AGGR_TYPE (lhstype, REFERENCE_TYPE))
{ {
/* This case must convert to some sort of lvalue that my_friendly_abort (978652);
can participate in an op= operation. */
tree lhs_tmp = lhs;
tree rhs_tmp = rhs;
if (build_default_binary_type_conversion (modifycode, &lhs_tmp, &rhs_tmp))
{
lhs = stabilize_reference (lhs_tmp);
/* Forget it was ever anything else. */
olhstype = lhstype = TREE_TYPE (lhs);
newrhs = build_binary_op (modifycode, lhs, rhs_tmp, 1);
}
else
{
cp_error ("no match for `%Q(%#T, %#T)'", modifycode,
TREE_TYPE (lhs), TREE_TYPE (rhs));
return error_mark_node;
}
} }
else else
{ {
......
...@@ -1295,9 +1295,10 @@ build_x_arrow (datum) ...@@ -1295,9 +1295,10 @@ build_x_arrow (datum)
type = TREE_TYPE (rval); type = TREE_TYPE (rval);
} }
if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (complete_type (type))) if (IS_AGGR_TYPE (type))
{ {
while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval, NULL_TREE, NULL_TREE))) while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval,
NULL_TREE, NULL_TREE)))
{ {
if (rval == error_mark_node) if (rval == error_mark_node)
return error_mark_node; return error_mark_node;
......
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