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