Commit 37c46b43 by Mike Stump

91th Cygnus<->FSF quick merge

From-SVN: r14134
parent 87c16668
Tue May 27 19:49:19 1997 Mike Stump <mrs@cygnus.com>
* cvt.c (convert): Don't do any extra work, if we can avoid it
easily.
Tue May 27 18:21:47 1997 Mike Stump <mrs@cygnus.com>
* *.[chy]: Change cp_convert to ocp_convert, change convert to
cp_convert. convert is now reserved for the backend, and doesn't
have the semantics a frontend person should ever want.
Fri May 23 10:58:31 1997 Jason Merrill <jason@yorick.cygnus.com>
* lang-specs.h: Define __EXCEPTIONS if exceptions are enabled.
Lose -traditional support.
Thu May 22 15:41:28 1997 Jason Merrill <jason@yorick.cygnus.com>
* rtti.c (get_tinfo_var): Use TYPE_PRECISION (sizetype).
* parse.y (self_reference): Do it for templates, too.
* class.c (pushclass): Don't overload_template_name; the alias
generated by build_self_reference serves the same purpose.
* tree.c (list_hash): Make static, take more args.
(list_hash_lookup): Likewise.
(list_hash_add): Make static.
(list_hash_canon): Lose.
(hash_tree_cons): Only build a new node if one isn't already in the
hashtable.
(hash_tree_chain): Use hash_tree_cons.
* cp-tree.h: Adjust.
* decl.c (grokfndecl): Just check IDENTIFIER_GLOBAL_VALUE instead
of calling lookup_name.
Wed May 21 18:24:19 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_class_template): TYPE_VALUES for an enum
doesn't refer to the CONST_DECLs.
Tue May 20 21:09:32 1997 Bob Manson <manson@charmed.cygnus.com>
* rtti.c (get_tinfo_var): Either INT_TYPE_SIZE or 32, whichever
is bigger.
(expand_class_desc): Convert the last argument to a sizetype.
Tue May 20 13:55:57 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* gxx.gperf (__complex, __complex__, __imag, __imag__, __real,
__real__): Add reswords.
* hash.h: Regenerate.
* lex.h (rid): Add RID_COMPLEX.
(RID_LAST_MODIFIER): Set to RID_COMPLEX.
* lex.c (init_lex): Add building of RID_COMPLEX. Unset reserved
word "complex" if -fno-gnu-keywords.
(real_yylex): General cleanup in line with what c-lex.c also has,
sans the cruft for traditional; add handling of SPEC_IMAG, complex
types, and imaginary numeric constants.
* parse.y (REALPART, IMAGPART): Add tokens.
(unary_expr): Add REALPART and IMAGPART rules.
* cp-tree.h (complex_{integer,float,double,long}_type_node): Declare.
* decl.c (complex_{integer,float,double,long}_type_node): Define
types.
(init_decl_processing): Set up the types.
(grokdeclarator): Add handling of RID_COMPLEX. Set and use
DEFAULTED_INT instead of EXPLICIT_INT when we default to int type.
* call.c (build_new_op): Add REALPART_EXPR and IMAGPART_EXPR cases.
* cvt.c (cp_convert): Handle COMPLEX_TYPE.
* error.c (dump_type_prefix, dump_type, dump_type_suffix): Add
COMPLEX_TYPE case.
* method.c (build_overload_name): Add handling of the different
COMPLEX_TYPEs, prefixing them with `J'.
* pt.c (process_template_parm): Don't let them use a COMPLEX_TYPE
as a template parm.
(uses_template_parms, tsubst, unify): Add COMPLEX_TYPE case.
* tree.c (lvalue_p): Add REALPART_EXPR and IMAGPART_EXPR cases.
(mapcar): Handle COMPLEX_CST.
* typeck.c (build_binary_op_nodefault): Handle COMPLEX_TYPE.
(common_type): Add code for complex types.
(build_unary_op): Add REALPART_EXPR and IMAGPART_EXPR cases.
(convert_for_assignment): Likewise.
(mark_addressable): Add REALPART_EXPR and IMAGPART_EXPR cases.
Mon May 19 12:26:27 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (tsubst): Don't pass the MINUS_EXPR for an array domain to
tsubst_expr, as it might try to do overload resolution.
Sat May 17 10:48:31 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_class_template): Oops.
......@@ -38,10 +126,10 @@ Mon May 5 14:46:53 1997 Jason Merrill <jason@yorick.cygnus.com>
Thu May 1 18:26:37 1997 Mike Stump <mrs@cygnus.com>
* except.c (expand_exception_blocks): Ensure that we flow through
the end of the exception region for the exception specification.
Move exception region for the exception specification in, so that
it doesn't protect the parm cleanup. Remove some obsolete code.
* decl.c (store_parm_decls): Likewise.
the end of the exception region for the exception specification.
Move exception region for the exception specification in, so that
it doesn't protect the parm cleanup. Remove some obsolete code.
* decl.c (store_parm_decls): Likewise.
(finish_function): Likewise.
Tue Apr 29 15:38:54 1997 Jason Merrill <jason@yorick.cygnus.com>
......@@ -64,7 +152,7 @@ Fri Apr 25 11:55:23 1997 Jason Merrill <jason@yorick.cygnus.com>
to -Weffc++.
* decl2.c (finish_prevtable_vardecl): Change NO_LINKAGE_HEURISTICS
to MULTIPLE_SYMBOL_SPACES.
to MULTIPLE_SYMBOL_SPACES.
Wed Apr 23 18:06:50 1997 Jason Merrill <jason@yorick.cygnus.com>
......@@ -89,7 +177,7 @@ Wed Apr 23 14:43:06 1997 Mike Stump <mrs@cygnus.com>
* exception.cc (__default_terminate): Likewise.
* init.c (perform_member_init): Use new method of expr level
cleanups, instead of cleanups_this_call and friends.
cleanups, instead of cleanups_this_call and friends.
(emit_base_init): Likewise.
(expand_aggr_vbase_init_1): Likewise.
(expand_vec_init): Likewise.
......@@ -111,7 +199,7 @@ Wed Apr 23 04:12:06 1997 Jason Merrill <jason@yorick.cygnus.com>
* tree.c (varargs_function_p): New fn.
* method.c (emit_thunk): Replace broken generic code with code to
generate a heavyweight thunk function.
generate a heavyweight thunk function.
Tue Apr 22 02:45:18 1997 Jason Merrill <jason@yorick.cygnus.com>
......@@ -124,28 +212,28 @@ Tue Apr 22 02:45:18 1997 Jason Merrill <jason@yorick.cygnus.com>
Mon Apr 21 15:42:27 1997 Jason Merrill <jason@yorick.cygnus.com>
* class.c (check_for_override): The signature of an overriding
function is not changed.
function is not changed.
* call.c (build_over_call): Move setting of conv into the loop.
Sun Apr 20 16:24:29 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_user_type_conversion_1): Really ignore rvalue
conversions when looking for a REFERENCE_TYPE.
conversions when looking for a REFERENCE_TYPE.
* cvt.c (build_up_reference): Eviscerate, use build_unary_op.
* cp-tree.h (TREE_REFERENCE_EXPR): #if 0.
* typeck.c (decay_conversion): Don't set TREE_REFERENCE_EXPR.
(build_unary_op): Likewise.
* call.c (build_over_call): See through a CONVERT_EXPR around the
ADDR_EXPR for on a temporary.
ADDR_EXPR for on a temporary.
* typeck.c (c_expand_return): See through a CONVERT_EXPR around
the ADDR_EXPR for a local variable.
the ADDR_EXPR for a local variable.
Fri Apr 18 12:11:33 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_user_type_conversion_1): If we're trying to
convert to a REFERENCE_TYPE, only consider lvalue conversions.
convert to a REFERENCE_TYPE, only consider lvalue conversions.
(build_new_function_call): Print candidates.
(implicit_conversion): Try a temp binding if the lvalue conv is BAD.
(reference_binding): Binding a temporary of a reference-related type
......@@ -163,7 +251,7 @@ Mon Apr 14 12:38:17 1997 Jason Merrill <jason@yorick.cygnus.com>
Fri Apr 11 02:18:30 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (implicit_conversion): Try to find a reference conversion
before binding a const reference to a temporary.
before binding a const reference to a temporary.
Wed Apr 2 12:51:36 1997 Mike Stump <mrs@cygnus.com>
......@@ -12223,7 +12311,7 @@ Tue Apr 5 17:48:41 1994 Per Bothner <bothner@kalessin.cygnus.com>
* decl2.c (write_vtable_entries, finish_vtable_typedecl): Removed.
* cp-tree.h, class.c, decl2.c, search.c: Remove -fvtable-hack
and flag_vtable_hack. Use -fvtable-thunks and flag_vtable_thunks
and flag_vtable_hack. Use -fvtable-thunks and flag_vtable_thunks
instead. (The rationale is that these optimizations both break binary
compatibility, but should become the default in a future release.)
......
......@@ -1448,7 +1448,7 @@ build_scoped_method_call (exp, basetype, name, parms)
if (basetype != name && basetype != get_type_value (name))
cp_error ("qualified type `%T' does not match destructor name `~%T'",
basetype, name);
return convert (void_type_node, exp);
return cp_convert (void_type_node, exp);
}
if (! is_aggr_type (basetype, 1))
......@@ -1494,7 +1494,7 @@ build_scoped_method_call (exp, basetype, name, parms)
return error_mark_node;
}
if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
return convert (void_type_node, exp);
return cp_convert (void_type_node, exp);
return build_delete (TREE_TYPE (decl), decl, integer_two_node,
LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
......@@ -1751,11 +1751,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
cp_error ("destructor name `~%D' does not match type `%T' of expression",
name, basetype);
return convert (void_type_node, instance);
return cp_convert (void_type_node, instance);
}
if (! TYPE_HAS_DESTRUCTOR (basetype))
return convert (void_type_node, instance);
return cp_convert (void_type_node, instance);
instance = default_conversion (instance);
instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
return build_delete (build_pointer_type (basetype),
......@@ -1986,7 +1986,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype = inst_ptr_basetype;
else
{
instance_ptr = convert (build_pointer_type (basetype), instance_ptr);
instance_ptr = cp_convert (build_pointer_type (basetype), instance_ptr);
if (instance_ptr == error_mark_node)
return error_mark_node;
}
......@@ -4835,6 +4835,8 @@ builtin:
case POSTINCREMENT_EXPR:
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
return build_unary_op (code, arg1, candidates != 0);
case ARRAY_REF:
......@@ -4972,8 +4974,8 @@ convert_like (convs, expr)
case LVALUE_CONV:
return decay_conversion (expr);
}
return cp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT,
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
return ocp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT,
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
}
static tree
......@@ -5125,7 +5127,7 @@ build_over_call (fn, convs, args, flags)
&& (TYPE_PRECISION (TREE_TYPE (val))
< TYPE_PRECISION (double_type_node)))
/* Convert `float' to `double'. */
val = convert (double_type_node, val);
val = cp_convert (double_type_node, val);
else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val))
&& ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (val)))
cp_warning ("cannot pass objects of type `%T' through `...'",
......
......@@ -322,8 +322,11 @@ build_vbase_path (code, type, expr, path, alias_this)
if (TREE_INT_CST_LOW (offset))
{
/* Bash types to make the backend happy. */
offset = convert (type, offset);
offset = cp_convert (type, offset);
#if 0
/* This shouldn't be necessary. (mrs) */
expr = build1 (NOP_EXPR, type, expr);
#endif
/* For multiple inheritance: if `this' can be set by any
function, then it could be 0 on entry to any function.
......@@ -518,8 +521,8 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
*ptr_to_instptr
= build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
*ptr_to_instptr,
convert (ptrdiff_type_node,
build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
cp_convert (ptrdiff_type_node,
build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
}
return build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
......@@ -4630,8 +4633,10 @@ pushclass (type, modify)
pushlevel_class ();
#if 0
if (CLASSTYPE_TEMPLATE_INFO (type))
overload_template_name (type);
#endif
if (modify)
{
......
......@@ -135,6 +135,12 @@ extern tree unsigned_type_node;
extern tree string_type_node, char_array_type_node, int_array_type_node;
extern tree wchar_array_type_node;
extern tree wchar_type_node, signed_wchar_type_node, unsigned_wchar_type_node;
extern tree complex_integer_type_node;
extern tree complex_float_type_node;
extern tree complex_double_type_node;
extern tree complex_long_double_type_node;
extern tree intQI_type_node, unsigned_intQI_type_node;
extern tree intHI_type_node, unsigned_intHI_type_node;
extern tree intSI_type_node, unsigned_intSI_type_node;
......@@ -1969,7 +1975,8 @@ extern tree convert_from_reference PROTO((tree));
extern tree convert_to_aggr PROTO((tree, tree, char **, int));
extern tree convert_pointer_to_real PROTO((tree, tree));
extern tree convert_pointer_to PROTO((tree, tree));
extern tree cp_convert PROTO((tree, tree, int, int));
extern tree ocp_convert PROTO((tree, tree, int, int));
extern tree cp_convert PROTO((tree, tree));
extern tree convert PROTO((tree, tree));
extern tree convert_force PROTO((tree, tree, int));
extern tree build_type_conversion PROTO((enum tree_code, tree, tree, int));
......@@ -2380,10 +2387,6 @@ extern tree build_cplus_array_type PROTO((tree, tree));
extern void propagate_binfo_offsets PROTO((tree, tree));
extern int layout_vbasetypes PROTO((tree, int));
extern tree layout_basetypes PROTO((tree, tree));
extern int list_hash PROTO((tree));
extern tree list_hash_lookup PROTO((int, tree));
extern void list_hash_add PROTO((int, tree));
extern tree list_hash_canon PROTO((int, tree));
extern tree hash_tree_cons PROTO((int, int, int, tree, tree, tree));
extern tree hash_tree_chain PROTO((tree, tree));
extern tree hash_chainon PROTO((tree, tree));
......
......@@ -283,7 +283,7 @@ cp_convert_to_pointer (type, expr)
{
if (type_precision (intype) == POINTER_SIZE)
return build1 (CONVERT_EXPR, type, expr);
expr = convert (type_for_size (POINTER_SIZE, 0), expr);
expr = cp_convert (type_for_size (POINTER_SIZE, 0), expr);
/* Modes may be different but sizes should be the same. */
if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
!= GET_MODE_SIZE (TYPE_MODE (type)))
......@@ -606,7 +606,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
rval = rval_as_conversion;
else if (! IS_AGGR_TYPE (type) && ! IS_AGGR_TYPE (intype))
{
rval = convert (type, expr);
rval = cp_convert (type, expr);
if (rval == error_mark_node)
return error_mark_node;
......@@ -922,12 +922,21 @@ convert_pointer_to (binfo, expr)
return convert_pointer_to_real (type, expr);
}
/* C++ conversions, preference to static cast conversions. */
tree
cp_convert (type, expr)
tree type, expr;
{
return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);
}
/* Conversion...
FLAGS indicates how we should behave. */
tree
cp_convert (type, expr, convtype, flags)
ocp_convert (type, expr, convtype, flags)
tree type, expr;
int convtype, flags;
{
......@@ -951,7 +960,7 @@ cp_convert (type, expr, convtype, flags)
/* This is incorrect. A truncation can't be stripped this way.
Extensions will be stripped by the use of get_unwidened. */
if (TREE_CODE (e) == NOP_EXPR)
return convert (type, TREE_OPERAND (e, 0));
return cp_convert (type, TREE_OPERAND (e, 0));
#endif
/* Just convert to the type of the member. */
......@@ -1014,7 +1023,7 @@ cp_convert (type, expr, convtype, flags)
if (code == POINTER_TYPE || code == REFERENCE_TYPE
|| TYPE_PTRMEMFUNC_P (type))
return fold (cp_convert_to_pointer (type, e));
if (code == REAL_TYPE)
if (code == REAL_TYPE || code == COMPLEX_TYPE)
{
if (IS_AGGR_TYPE (TREE_TYPE (e)))
{
......@@ -1027,7 +1036,10 @@ cp_convert (type, expr, convtype, flags)
cp_error ("`%#T' used where a floating point value was expected",
TREE_TYPE (e));
}
return fold (convert_to_real (type, e));
if (code == REAL_TYPE)
return fold (convert_to_real (type, e));
else if (code == COMPLEX_TYPE)
return fold (convert_to_complex (type, e));
}
/* New C++ semantics: since assignment is now based on
......@@ -1155,16 +1167,82 @@ cp_convert (type, expr, convtype, flags)
converted to type TYPE. The TREE_TYPE of the value
is always TYPE. This function implements all reasonable
conversions; callers should filter out those that are
not permitted by the language being compiled. */
not permitted by the language being compiled.
Most of this routine is from build_reinterpret_cast.
The backend cannot call cp_convert (what was convert) because
conversions to/from basetypes may involve memory references
(vbases) and adding or subtracting small values (multiple
inheritance), but it calls convert from the constant folding code
on subtrees of already build trees after it has ripped them apart.
Also, if we ever support range variables, we'll probably also have to
do a little bit more work. */
tree
convert (type, expr)
tree type, expr;
{
return cp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);
tree intype;
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
if (TREE_TYPE (expr) == type)
return expr;
if (TREE_CODE (type) != REFERENCE_TYPE)
{
expr = decay_conversion (expr);
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */
if (TREE_CODE (expr) == NOP_EXPR
&& TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
expr = TREE_OPERAND (expr, 0);
}
intype = TREE_TYPE (expr);
if (TREE_CODE (type) == REFERENCE_TYPE)
{
expr = build_unary_op (ADDR_EXPR, expr, 0);
if (expr != error_mark_node)
expr = convert (build_pointer_type (TREE_TYPE (type)), expr);
if (expr != error_mark_node)
expr = build_indirect_ref (expr, 0);
return expr;
}
else if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1))
return build_static_cast (type, expr);
if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE
|| TREE_CODE (intype) == ENUMERAL_TYPE))
/* OK */;
else if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PTR_P (intype))
{
}
else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
{
if (TREE_READONLY_DECL_P (expr))
expr = decl_constant_value (expr);
return fold (build1 (NOP_EXPR, type, expr));
}
else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|| (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
{
if (TREE_READONLY_DECL_P (expr))
expr = decl_constant_value (expr);
return fold (build1 (NOP_EXPR, type, expr));
}
return ocp_convert (type, expr, CONV_OLD_CONVERT,
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
}
/* Like convert, except permit conversions to take place which
/* Like cp_convert, except permit conversions to take place which
are not normally allowed due to access restrictions
(such as conversion from sub-type to private super-type). */
......@@ -1198,7 +1276,7 @@ convert_force (type, expr, convtype)
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1);
}
return cp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);
return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);
}
/* Subroutine of build_type_conversion. */
......@@ -1234,7 +1312,7 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
&& (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))
> TREE_READONLY (TREE_TYPE (xtype))))
warning ("user-defined conversion casting away `const'");
return convert (xtype, rval);
return cp_convert (xtype, rval);
}
/* Convert an aggregate EXPR to type XTYPE. If a conversion
......@@ -1539,8 +1617,8 @@ build_default_binary_type_conversion (code, arg1, arg2)
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
*arg1 = convert (boolean_type_node, *arg1);
*arg2 = convert (boolean_type_node, *arg2);
*arg1 = cp_convert (boolean_type_node, *arg1);
*arg2 = cp_convert (boolean_type_node, *arg2);
break;
default:
......
......@@ -169,6 +169,11 @@ tree float_type_node;
tree double_type_node;
tree long_double_type_node;
tree complex_integer_type_node;
tree complex_float_type_node;
tree complex_double_type_node;
tree complex_long_double_type_node;
tree intQI_type_node;
tree intHI_type_node;
tree intSI_type_node;
......@@ -4805,6 +4810,30 @@ init_decl_processing ()
record_builtin_type (RID_MAX, "long double", long_double_type_node);
layout_type (long_double_type_node);
complex_integer_type_node = make_node (COMPLEX_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
complex_integer_type_node));
TREE_TYPE (complex_integer_type_node) = integer_type_node;
layout_type (complex_integer_type_node);
complex_float_type_node = make_node (COMPLEX_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
complex_float_type_node));
TREE_TYPE (complex_float_type_node) = float_type_node;
layout_type (complex_float_type_node);
complex_double_type_node = make_node (COMPLEX_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
complex_double_type_node));
TREE_TYPE (complex_double_type_node) = double_type_node;
layout_type (complex_double_type_node);
complex_long_double_type_node = make_node (COMPLEX_TYPE);
pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
complex_long_double_type_node));
TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
layout_type (complex_long_double_type_node);
integer_zero_node = build_int_2 (0, 0);
TREE_TYPE (integer_zero_node) = integer_type_node;
integer_one_node = build_int_2 (1, 0);
......@@ -7105,9 +7134,7 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
if (check == 0 && ! current_function_decl)
{
/* FIXME: this should only need to look at
IDENTIFIER_GLOBAL_VALUE. */
tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0);
tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl));
if (tmp == NULL_TREE)
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl;
else if (TREE_CODE (tmp) != TREE_CODE (decl))
......@@ -7379,6 +7406,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
int virtualp, explicitp, friendp, inlinep, staticp;
int explicit_int = 0;
int explicit_char = 0;
int defaulted_int = 0;
int opaque_typedef = 0;
tree typedef_decl = NULL_TREE;
char *name;
......@@ -7808,7 +7836,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
typedef_type = type;
/* No type at all: default to `int', and set EXPLICIT_INT
/* No type at all: default to `int', and set DEFAULTED_INT
because it was not a user-defined typedef.
Except when we have a `typedef' inside a signature, in
which case the type defaults to `unknown type' and is
......@@ -7822,7 +7850,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
/* These imply 'int'. */
type = integer_type_node;
explicit_int = 1;
defaulted_int = 1;
}
if (type == NULL_TREE)
......@@ -7928,7 +7956,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else
{
ok = 1;
if (!explicit_int && !explicit_char && pedantic)
if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
{
pedwarn ("long, short, signed or unsigned used invalidly for `%s'",
name);
......@@ -7948,11 +7976,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
}
if (RIDBIT_SETP (RID_COMPLEX, specbits)
&& TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
{
error ("complex invalid for `%s'", name);
RIDBIT_RESET (RID_COMPLEX, specbits);
}
/* Decide whether an integer type is signed or not.
Optionally treat bitfields as signed by default. */
if (RIDBIT_SETP (RID_UNSIGNED, specbits)
|| (bitfield && ! flag_signed_bitfields
&& (explicit_int || explicit_char
&& (explicit_int || defaulted_int || explicit_char
/* A typedef for plain `int' without `signed'
can be controlled just like plain `int'. */
|| ! (typedef_decl != NULL_TREE
......@@ -7983,6 +8018,31 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else if (RIDBIT_SETP (RID_SHORT, specbits))
type = short_integer_type_node;
if (RIDBIT_SETP (RID_COMPLEX, specbits))
{
/* If we just have "complex", it is equivalent to
"complex double", but if any modifiers at all are specified it is
the complex form of TYPE. E.g, "complex short" is
"complex short int". */
if (defaulted_int && ! longlong
&& ! (RIDBIT_SETP (RID_LONG, specbits)
|| RIDBIT_SETP (RID_SHORT, specbits)
|| RIDBIT_SETP (RID_SIGNED, specbits)
|| RIDBIT_SETP (RID_UNSIGNED, specbits)))
type = complex_double_type_node;
else if (type == integer_type_node)
type = complex_integer_type_node;
else if (type == float_type_node)
type = complex_float_type_node;
else if (type == double_type_node)
type = complex_double_type_node;
else if (type == long_double_type_node)
type = complex_long_double_type_node;
else
type = build_complex_type (type);
}
/* Set CONSTP if this declaration is `const', whether by
explicit specification or via a typedef.
Likewise for VOLATILEP. */
......@@ -8353,9 +8413,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
itype
= fold (build_binary_op (MINUS_EXPR,
convert (index_type, size),
convert (index_type,
integer_one_node), 1));
cp_convert (index_type, size),
cp_convert (index_type,
integer_one_node), 1));
if (! TREE_CONSTANT (itype))
itype = variable_size (itype);
else if (TREE_OVERFLOW (itype))
......
......@@ -197,6 +197,11 @@ dump_type (t, v)
dump_decl (t, v);
break;
case COMPLEX_TYPE:
OB_PUTS ("complex ");
dump_type (TREE_TYPE (t), v);
break;
case INTEGER_TYPE:
if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
OB_PUTS ("unsigned ");
......@@ -435,6 +440,7 @@ dump_type_prefix (t, v)
case UNKNOWN_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
dump_type (t, v);
break;
......@@ -516,6 +522,7 @@ dump_type_suffix (t, v)
case UNKNOWN_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
break;
default:
......
......@@ -9,13 +9,19 @@ __asm, GCC_ASM_KEYWORD, NORID
__asm__, GCC_ASM_KEYWORD, NORID
__attribute, ATTRIBUTE, NORID
__attribute__, ATTRIBUTE, NORID
__complex, TYPESPEC, RID_COMPLEX
__complex__, TYPESPEC, RID_COMPLEX
__const, CV_QUALIFIER, RID_CONST
__const__, CV_QUALIFIER, RID_CONST
__extension__, EXTENSION, NORID
__imag, IMAGPART, NORID
__imag__, IMAGPART, NORID
__inline, SCSPEC, RID_INLINE
__inline__, SCSPEC, RID_INLINE
__label__, LABEL, NORID
__null, CONSTANT, RID_NULL
__real, REALPART, NORID
__real__, REALPART, NORID
__signature__, AGGR, RID_SIGNATURE /* Extension */,
__signed, TYPESPEC, RID_SIGNED
__signed__, TYPESPEC, RID_SIGNED
......
......@@ -1252,7 +1252,7 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags)
via the copy constructor, even if the call is elided. */
if (! (TREE_CODE (exp) == VAR_DECL && DECL_ARTIFICIAL (exp)
&& TREE_CODE (init) == TARGET_EXPR && TREE_TYPE (init) == type))
init = cp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
expand_assignment (exp, init, 0, 0);
return;
......@@ -1512,7 +1512,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
if (init_list && TREE_CHAIN (init_list))
{
warning ("initializer list being treated as compound expression");
init = convert (type, build_compound_expr (init_list));
init = cp_convert (type, build_compound_expr (init_list));
if (init == error_mark_node)
return;
}
......@@ -2101,14 +2101,14 @@ resolve_offset_ref (exp)
basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member));
addr = convert_pointer_to (basetype, addr);
member = convert (ptrdiff_type_node,
build_unary_op (ADDR_EXPR, member, 0));
member = cp_convert (ptrdiff_type_node,
build_unary_op (ADDR_EXPR, member, 0));
/* Pointer to data mebers are offset by one, so that a null
pointer with a real value of 0 is distinguishable from an
offset of the first member of a structure. */
member = build_binary_op (MINUS_EXPR, member,
convert (ptrdiff_type_node, integer_one_node),
cp_convert (ptrdiff_type_node, integer_one_node),
0);
return build1 (INDIRECT_REF, type,
......@@ -2269,7 +2269,7 @@ build_new (placement, decl, init, use_global_new)
}
else
{
this_nelts = save_expr (convert (sizetype, this_nelts));
this_nelts = save_expr (cp_convert (sizetype, this_nelts));
absdcl = TREE_OPERAND (absdcl, 0);
if (this_nelts == integer_zero_node)
{
......@@ -2464,7 +2464,7 @@ build_new (placement, decl, init, use_global_new)
{
rval = build_opfncall (code, LOOKUP_GLOBAL|LOOKUP_COMPLAIN,
ptr_type_node, size, placement);
rval = convert (build_pointer_type (true_type), rval);
rval = cp_convert (build_pointer_type (true_type), rval);
}
else if (! has_array && flag_this_is_variable > 0
&& TYPE_NEEDS_CONSTRUCTING (true_type) && init != void_type_node)
......@@ -2498,8 +2498,8 @@ build_new (placement, decl, init, use_global_new)
{
tree extra = BI_header_size;
tree cookie, exp1;
rval = convert (ptr_type_node, rval); /* convert to void * first */
rval = convert (string_type_node, rval); /* lets not add void* and ints */
rval = cp_convert (ptr_type_node, rval); /* convert to void * first */
rval = cp_convert (string_type_node, rval); /* lets not add void* and ints */
rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1));
/* Store header info. */
cookie = build_indirect_ref (build (MINUS_EXPR, build_pointer_type (BI_header_type),
......@@ -2508,7 +2508,7 @@ build_new (placement, decl, init, use_global_new)
build_component_ref (cookie, nc_nelts_field_id, NULL_TREE, 0),
nelts);
TREE_SIDE_EFFECTS (exp1) = 1;
rval = convert (build_pointer_type (true_type), rval);
rval = cp_convert (build_pointer_type (true_type), rval);
TREE_CALLS_NEW (rval) = 1;
TREE_SIDE_EFFECTS (rval) = 1;
rval = build_compound_expr (tree_cons (NULL_TREE, exp1,
......@@ -2751,11 +2751,11 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
if (auto_delete != integer_zero_node
&& auto_delete != integer_two_node)
{
tree base_tbd = convert (ptype,
build_binary_op (MINUS_EXPR,
convert (ptr_type_node, base),
BI_header_size,
1));
tree base_tbd = cp_convert (ptype,
build_binary_op (MINUS_EXPR,
cp_convert (ptr_type_node, base),
BI_header_size,
1));
/* This is the real size */
virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
body = build_tree_list (NULL_TREE,
......@@ -2808,11 +2808,11 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
base_tbd = base;
else
{
base_tbd = convert (ptype,
build_binary_op (MINUS_EXPR,
convert (string_type_node, base),
BI_header_size,
1));
base_tbd = cp_convert (ptype,
build_binary_op (MINUS_EXPR,
cp_convert (string_type_node, base),
BI_header_size,
1));
/* True size with header. */
virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
}
......@@ -2847,7 +2847,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
return controller;
}
else
return convert (void_type_node, body);
return cp_convert (void_type_node, body);
}
/* Build a tree to cleanup partially built arrays.
......@@ -2891,7 +2891,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
tree type = TREE_TYPE (TREE_TYPE (base));
tree size;
maxindex = convert (ptrdiff_type_node, maxindex);
maxindex = cp_convert (ptrdiff_type_node, maxindex);
if (maxindex == error_mark_node)
return error_mark_node;
......@@ -2909,9 +2909,9 @@ expand_vec_init (decl, base, maxindex, init, from_array)
/* Set to zero in case size is <= 0. Optimizer will delete this if
it is not needed. */
rval = get_temp_regvar (build_pointer_type (type),
convert (build_pointer_type (type), null_pointer_node));
cp_convert (build_pointer_type (type), null_pointer_node));
base = default_conversion (base);
base = convert (build_pointer_type (type), base);
base = cp_convert (build_pointer_type (type), base);
expand_assignment (rval, base, 0, 0);
base = get_temp_regvar (build_pointer_type (type), base);
......
......@@ -33,14 +33,14 @@ Boston, MA 02111-1307, USA. */
%{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\
-undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\
%{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
%c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional} %{trigraphs}\
%{!fno-exceptions:-D__EXCEPTIONS}\
%c %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.ii}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
"%{!M:%{!MM:%{!E:cc1plus %{!pipe:%g.ii} %1 %2\
%{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
%{traditional} %{v:-version} %{pg:-p} %{p}\
%{v:-version} %{pg:-p} %{p}\
%{f*} %{+e*} %{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\
......@@ -51,7 +51,7 @@ Boston, MA 02111-1307, USA. */
{"@c++-cpp-output",
"%{!M:%{!MM:%{!E:cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\
%{traditional} %{v:-version} %{pg:-p} %{p}\
%{v:-version} %{pg:-p} %{p}\
%{f*} %{+e*} %{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\
......
......@@ -62,6 +62,7 @@ enum rid
RID_SIGNED,
RID_AUTO,
RID_MUTABLE,
RID_COMPLEX,
/* This is where grokdeclarator ends its search when setting the
specbits. */
......@@ -81,7 +82,7 @@ enum rid
#define NORID RID_UNUSED
#define RID_FIRST_MODIFIER RID_EXTERN
#define RID_LAST_MODIFIER RID_MUTABLE
#define RID_LAST_MODIFIER RID_COMPLEX
/* The type that can represent all values of RIDBIT. */
/* We assume that we can stick in at least 32 bits into this. */
......
......@@ -895,6 +895,11 @@ build_overload_name (parmtypes, begin, end)
else my_friendly_abort (74);
break;
case COMPLEX_TYPE:
OB_PUTC ('J');
build_overload_name (TREE_TYPE (parmtype), 0, 0);
break;
case VOID_TYPE:
if (! just_one)
{
......
......@@ -140,6 +140,7 @@ empty_parms ()
%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF
%token SIGOF
%token ATTRIBUTE EXTENSION LABEL
%token REALPART IMAGPART
/* the reserved words... C++ extensions */
%token <ttype> AGGR
......@@ -1104,6 +1105,10 @@ unary_expr:
{ $$ = delete_sanity ($5, $3, 2, $1);
if (yychar == YYEMPTY)
yychar = YYLEX; }
| REALPART cast_expr %prec UNARY
{ $$ = build_x_unary_op (REALPART_EXPR, $2); }
| IMAGPART cast_expr %prec UNARY
{ $$ = build_x_unary_op (IMAGPART_EXPR, $2); }
;
new_placement:
......@@ -1542,7 +1547,7 @@ primary:
&& (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3)))))
cp_error ("`%E' is not of type `%T'", $1, $3);
$$ = convert (void_type_node, $1);
$$ = cp_convert (void_type_node, $1);
}
| object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT
{
......@@ -1551,7 +1556,7 @@ primary:
if (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2))))
cp_error ("`%E' is not of type `%T'", $1, $2);
$$ = convert (void_type_node, $1);
$$ = cp_convert (void_type_node, $1);
}
| object error
{
......@@ -2558,9 +2563,6 @@ left_curly:
self_reference:
/* empty */
{
if (CLASSTYPE_TEMPLATE_INFO (current_class_type))
$$ = NULL_TREE;
else
$$ = build_self_reference ();
}
;
......
......@@ -133,7 +133,9 @@ process_template_parm (list, next)
error (" a template type parameter must begin with `class' or `typename'");
TREE_TYPE (parm) = void_type_node;
}
else if (pedantic && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE)
else if (pedantic
&& (TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE
|| TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE))
cp_pedwarn ("`%T' is not a valid type for a template constant parameter",
TREE_TYPE (parm));
tinfo = make_node (TEMPLATE_CONST_PARM);
......@@ -916,6 +918,7 @@ uses_template_parms (t)
return uses_template_parms (TYPE_MAX_VALUE (t));
case REAL_TYPE:
case COMPLEX_TYPE:
case VOID_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
......@@ -1205,12 +1208,13 @@ instantiate_class_template (type)
{
tree e, newtag = tsubst_enum (tag, &TREE_VEC_ELT (args, 0),
TREE_VEC_LENGTH (args));
for (e = TYPE_VALUES (newtag); e; e = TREE_CHAIN (e))
DECL_FIELD_CONTEXT (TREE_VALUE (e)) = type;
*field_chain = grok_enum_decls (newtag, NULL_TREE);
while (*field_chain)
field_chain = &TREE_CHAIN (*field_chain);
{
DECL_FIELD_CONTEXT (*field_chain) = type;
field_chain = &TREE_CHAIN (*field_chain);
}
}
else
tsubst (tag, &TREE_VEC_ELT (args, 0),
......@@ -1387,6 +1391,7 @@ tsubst (t, args, nargs, in_decl)
case OP_IDENTIFIER:
case VOID_TYPE:
case REAL_TYPE:
case COMPLEX_TYPE:
case BOOLEAN_TYPE:
case INTEGER_CST:
case REAL_CST:
......@@ -1413,14 +1418,18 @@ tsubst (t, args, nargs, in_decl)
return t;
{
tree max = tsubst_expr (TYPE_MAX_VALUE (t), args, nargs, in_decl);
tree max = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
max = tsubst_expr (max, args, nargs, in_decl);
if (processing_template_decl)
{
tree itype = make_node (INTEGER_TYPE);
TYPE_MIN_VALUE (itype) = size_zero_node;
TYPE_MAX_VALUE (itype) = max;
TYPE_MAX_VALUE (itype) = build_min (MINUS_EXPR, sizetype, max,
integer_one_node);
return itype;
}
max = fold (build_binary_op (MINUS_EXPR, max, integer_one_node, 1));
return build_index_2_type (size_zero_node, max);
}
......@@ -2796,6 +2805,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
nsubsts, strict);
case REAL_TYPE:
case COMPLEX_TYPE:
case INTEGER_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
......
......@@ -107,7 +107,7 @@ build_headof (exp)
type = build_type_variant (ptr_type_node, TREE_READONLY (exp),
TREE_THIS_VOLATILE (exp));
return build (PLUS_EXPR, type, exp,
convert (ptrdiff_type_node, offset));
cp_convert (ptrdiff_type_node, offset));
}
/* Build a call to a generic entry point taking and returning void. */
......@@ -240,7 +240,7 @@ build_x_typeid (exp)
&& ! nonnull)
{
exp = stabilize_reference (exp);
cond = convert (boolean_type_node, TREE_OPERAND (exp, 0));
cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
}
exp = get_tinfo_fn_dynamic (exp);
......@@ -256,7 +256,7 @@ build_x_typeid (exp)
bad = build_compound_expr
(tree_cons (NULL_TREE, bad, build_tree_list
(NULL_TREE, convert (type, integer_zero_node))));
(NULL_TREE, cp_convert (type, integer_zero_node))));
exp = build (COND_EXPR, type, cond, exp, bad);
}
......@@ -292,7 +292,7 @@ get_tinfo_var (type)
(TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0))))
size = 3 * POINTER_SIZE;
else
size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype);
}
else
size = 2 * POINTER_SIZE;
......@@ -398,7 +398,7 @@ ifnonnull (test, result)
{
return build (COND_EXPR, TREE_TYPE (result),
build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
convert (TREE_TYPE (result), integer_zero_node),
cp_convert (TREE_TYPE (result), integer_zero_node),
result);
}
......@@ -611,15 +611,14 @@ build_dynamic_cast (type, expr)
expr1 = throw_bad_cast ();
expr1 = build_compound_expr
(tree_cons (NULL_TREE, expr1,
build_tree_list (NULL_TREE, convert
(type, integer_zero_node))));
build_tree_list (NULL_TREE, cp_convert (type, integer_zero_node))));
TREE_TYPE (expr1) = type;
result = save_expr (result);
return build (COND_EXPR, type, result, result, expr1);
}
/* Now back to the type we want from a void*. */
result = convert (type, result);
result = cp_convert (type, result);
return ifnonnull (expr, result);
}
}
......@@ -842,7 +841,8 @@ expand_class_desc (tdecl, type)
(NULL_TREE, decay_conversion (tdecl), tree_cons
(NULL_TREE, decay_conversion (name_string), tree_cons
(NULL_TREE, decay_conversion (elts), tree_cons
(NULL_TREE, build_int_2 (base_cnt, 0), NULL_TREE))));
(NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)),
NULL_TREE))));
fn = get_identifier ("__rtti_class");
if (IDENTIFIER_GLOBAL_VALUE (fn))
......@@ -1043,7 +1043,7 @@ synthesize_tinfo_fn (fndecl)
/* If the first word of the array (the vtable) is non-zero, we've already
initialized the object, so don't do it again. */
addr = decay_conversion (tdecl);
tmp = convert (build_pointer_type (ptr_type_node), addr);
tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
tmp = build_indirect_ref (tmp, 0);
tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node, 1);
expand_start_cond (tmp, 0);
......@@ -1084,7 +1084,7 @@ synthesize_tinfo_fn (fndecl)
expand_end_cond ();
/* OK, now return the type_info object. */
tmp = convert (build_pointer_type (type_info_type_node), addr);
tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
tmp = build_indirect_ref (tmp, 0);
c_expand_return (tmp);
finish_function (lineno, 0, 0);
......
......@@ -620,20 +620,20 @@ build_signature_table_constructor (sig_ty, rhs)
pfn_decl = TREE_CHAIN (index_decl);
vt_off_decl = TREE_CHAIN (pfn_decl);
tag = convert (TREE_TYPE (tag_decl), tag);
vb_off = convert (TREE_TYPE (vb_off_decl), vb_off);
delta = convert (TREE_TYPE (delta_decl), delta);
idx = convert (TREE_TYPE (index_decl), idx);
tag = cp_convert (TREE_TYPE (tag_decl), tag);
vb_off = cp_convert (TREE_TYPE (vb_off_decl), vb_off);
delta = cp_convert (TREE_TYPE (delta_decl), delta);
idx = cp_convert (TREE_TYPE (index_decl), idx);
if (DECL_VINDEX (rhs_method))
{
vt_off = convert (TREE_TYPE (vt_off_decl), vt_off);
vt_off = cp_convert (TREE_TYPE (vt_off_decl), vt_off);
tbl_entry = build_tree_list (vt_off_decl, vt_off);
}
else
{
pfn = convert (TREE_TYPE (pfn_decl), pfn);
pfn = cp_convert (TREE_TYPE (pfn_decl), pfn);
tbl_entry = build_tree_list (pfn_decl, pfn);
}
......@@ -956,11 +956,11 @@ build_signature_method_call (function, parms)
}
new_object_ptr = build (PLUS_EXPR, build_pointer_type (basetype),
convert (ptrdiff_type_node, object_ptr),
convert (ptrdiff_type_node, delta));
cp_convert (ptrdiff_type_node, object_ptr),
cp_convert (ptrdiff_type_node, delta));
parms = tree_cons (NULL_TREE,
convert (build_pointer_type (basetype), object_ptr),
cp_convert (build_pointer_type (basetype), object_ptr),
TREE_CHAIN (parms));
new_parms = tree_cons (NULL_TREE, new_object_ptr, TREE_CHAIN (parms));
......@@ -980,8 +980,8 @@ build_signature_method_call (function, parms)
vfld = build (PLUS_EXPR,
build_pointer_type (build_pointer_type (vtbl_type_node)),
convert (ptrdiff_type_node, object_ptr),
convert (ptrdiff_type_node, vt_off));
cp_convert (ptrdiff_type_node, object_ptr),
cp_convert (ptrdiff_type_node, vt_off));
vtbl = build_indirect_ref (build_indirect_ref (vfld, NULL_PTR),
NULL_PTR);
aref = build_array_ref (vtbl, idx);
......
......@@ -129,6 +129,8 @@ lvalue_p (ref)
what they refer to are valid lvals. */
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
case COMPONENT_REF:
case SAVE_EXPR:
return lvalue_p (TREE_OPERAND (ref, 0));
......@@ -925,27 +927,27 @@ struct list_hash
and the hash code is computed differently for each of these. */
#define TYPE_HASH_SIZE 59
struct list_hash *list_hash_table[TYPE_HASH_SIZE];
static struct list_hash *list_hash_table[TYPE_HASH_SIZE];
/* Compute a hash code for a list (chain of TREE_LIST nodes
with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the
TREE_COMMON slots), by adding the hash codes of the individual entries. */
int
list_hash (list)
tree list;
static int
list_hash (purpose, value, chain)
tree purpose, value, chain;
{
register int hashcode = 0;
if (TREE_CHAIN (list))
hashcode += TYPE_HASH (TREE_CHAIN (list));
if (chain)
hashcode += TYPE_HASH (chain);
if (TREE_VALUE (list))
hashcode += TYPE_HASH (TREE_VALUE (list));
if (value)
hashcode += TYPE_HASH (value);
else
hashcode += 1007;
if (TREE_PURPOSE (list))
hashcode += TYPE_HASH (TREE_PURPOSE (list));
if (purpose)
hashcode += TYPE_HASH (purpose);
else
hashcode += 1009;
return hashcode;
......@@ -954,31 +956,30 @@ list_hash (list)
/* Look in the type hash table for a type isomorphic to TYPE.
If one is found, return it. Otherwise return 0. */
tree
list_hash_lookup (hashcode, list)
int hashcode;
tree list;
static tree
list_hash_lookup (hashcode, via_public, via_protected, via_virtual,
purpose, value, chain)
int hashcode, via_public, via_virtual, via_protected;
tree purpose, value, chain;
{
register struct list_hash *h;
for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& TREE_VIA_VIRTUAL (h->list) == TREE_VIA_VIRTUAL (list)
&& TREE_VIA_PUBLIC (h->list) == TREE_VIA_PUBLIC (list)
&& TREE_VIA_PROTECTED (h->list) == TREE_VIA_PROTECTED (list)
&& TREE_PURPOSE (h->list) == TREE_PURPOSE (list)
&& TREE_VALUE (h->list) == TREE_VALUE (list)
&& TREE_CHAIN (h->list) == TREE_CHAIN (list))
{
my_friendly_assert (TREE_TYPE (h->list) == TREE_TYPE (list), 299);
return h->list;
}
&& TREE_VIA_VIRTUAL (h->list) == via_virtual
&& TREE_VIA_PUBLIC (h->list) == via_public
&& TREE_VIA_PROTECTED (h->list) == via_protected
&& TREE_PURPOSE (h->list) == purpose
&& TREE_VALUE (h->list) == value
&& TREE_CHAIN (h->list) == chain)
return h->list;
return 0;
}
/* Add an entry to the list-hash-table
for a list TYPE whose hash code is HASHCODE. */
void
static void
list_hash_add (hashcode, list)
int hashcode;
tree list;
......@@ -1008,29 +1009,6 @@ list_hash_add (hashcode, list)
static int debug_no_list_hash = 0;
tree
list_hash_canon (hashcode, list)
int hashcode;
tree list;
{
tree t1;
if (debug_no_list_hash)
return list;
t1 = list_hash_lookup (hashcode, list);
if (t1 != 0)
{
obstack_free (&class_obstack, list);
return t1;
}
/* If this is a new list, record it for later reuse. */
list_hash_add (hashcode, list);
return list;
}
tree
hash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain)
int via_public, via_virtual, via_protected;
tree purpose, value, chain;
......@@ -1039,13 +1017,26 @@ hash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain)
tree t;
int hashcode;
if (! debug_no_list_hash)
{
hashcode = list_hash (purpose, value, chain);
t = list_hash_lookup (hashcode, via_public, via_protected, via_virtual,
purpose, value, chain);
if (t)
return t;
}
current_obstack = &class_obstack;
t = tree_cons (purpose, value, chain);
TREE_VIA_PUBLIC (t) = via_public;
TREE_VIA_PROTECTED (t) = via_protected;
TREE_VIA_VIRTUAL (t) = via_virtual;
hashcode = list_hash (t);
t = list_hash_canon (hashcode, t);
/* If this is a new list, record it for later reuse. */
if (! debug_no_list_hash)
list_hash_add (hashcode, t);
current_obstack = ambient_obstack;
return t;
}
......@@ -1056,16 +1047,7 @@ tree
hash_tree_chain (value, chain)
tree value, chain;
{
struct obstack *ambient_obstack = current_obstack;
tree t;
int hashcode;
current_obstack = &class_obstack;
t = tree_cons (NULL_TREE, value, chain);
hashcode = list_hash (t);
t = list_hash_canon (hashcode, t);
current_obstack = ambient_obstack;
return t;
return hash_tree_cons (0, 0, 0, NULL_TREE, value, chain);
}
/* Similar, but used for concatenating two lists. */
......@@ -1595,6 +1577,12 @@ mapcar (t, func)
mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
case COMPLEX_CST:
t = copy_node (t);
TREE_REALPART (t) = mapcar (TREE_REALPART (t), func);
TREE_IMAGPART (t) = mapcar (TREE_REALPART (t), func);
return t;
case CONSTRUCTOR:
t = copy_node (t);
CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func);
......
......@@ -816,7 +816,7 @@ digest_init (type, init, tail)
if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
|| code == ENUMERAL_TYPE || code == REFERENCE_TYPE
|| code == BOOLEAN_TYPE
|| code == BOOLEAN_TYPE || code == COMPLEX_TYPE
|| (code == RECORD_TYPE && ! raw_constructor
&& (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))))
{
......
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