From c4a8ac95f11001ad17f362625258990fb816ead7 Mon Sep 17 00:00:00 2001 From: mrs Date: Wed, 28 May 1997 23:20:02 +0000 Subject: [PATCH] 91th Cygnus<->FSF quick merge git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14134 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 116 ++++++++++++++++++++++---- gcc/cp/call.c | 18 ++-- gcc/cp/class.c | 11 ++- gcc/cp/cp-tree.h | 13 +-- gcc/cp/cvt.c | 104 ++++++++++++++++++++--- gcc/cp/decl.c | 80 +++++++++++++++--- gcc/cp/error.c | 7 ++ gcc/cp/gxx.gperf | 6 ++ gcc/cp/hash.h | 234 ++++++++++++++++++++++++++++------------------------ gcc/cp/init.c | 48 +++++------ gcc/cp/lang-specs.h | 8 +- gcc/cp/lex.c | 225 +++++++++++++++++++++++++++++++------------------- gcc/cp/lex.h | 3 +- gcc/cp/method.c | 5 ++ gcc/cp/parse.y | 12 +-- gcc/cp/pt.c | 22 +++-- gcc/cp/rtti.c | 22 ++--- gcc/cp/sig.c | 22 ++--- gcc/cp/tree.c | 108 +++++++++++------------- gcc/cp/typeck.c | 209 +++++++++++++++++++++++++++++++--------------- gcc/cp/typeck2.c | 2 +- 21 files changed, 835 insertions(+), 440 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 79e655cebde..a61f4ee9158 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,91 @@ +Tue May 27 19:49:19 1997 Mike Stump + + * cvt.c (convert): Don't do any extra work, if we can avoid it + easily. + +Tue May 27 18:21:47 1997 Mike Stump + + * *.[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 + + * lang-specs.h: Define __EXCEPTIONS if exceptions are enabled. + Lose -traditional support. + +Thu May 22 15:41:28 1997 Jason Merrill + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 * pt.c (instantiate_class_template): Oops. @@ -38,10 +126,10 @@ Mon May 5 14:46:53 1997 Jason Merrill Thu May 1 18:26:37 1997 Mike Stump * 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 @@ -64,7 +152,7 @@ Fri Apr 25 11:55:23 1997 Jason Merrill 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 @@ -89,7 +177,7 @@ Wed Apr 23 14:43:06 1997 Mike Stump * 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 * 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 @@ -124,28 +212,28 @@ Tue Apr 22 02:45:18 1997 Jason Merrill Mon Apr 21 15:42:27 1997 Jason Merrill * 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 * 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 * 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 Fri Apr 11 02:18:30 1997 Jason Merrill * 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 @@ -12223,7 +12311,7 @@ Tue Apr 5 17:48:41 1994 Per Bothner * 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.) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a469e04b616..0e368075060 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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 `...'", diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 44483c0b9d1..37cdb6b994a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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) { diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 96dd1470a35..677c0fa9969 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index e9054c26b9a..26e388d7d37 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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: diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 0ed77d49cfa..41e6c150744 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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)) diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 8d9ade45fcf..e8eac164e1e 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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: diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf index 6cb2a97abe4..d9cad4a6255 100644 --- a/gcc/cp/gxx.gperf +++ b/gcc/cp/gxx.gperf @@ -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 diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h index d3f6be7330d..720890fd4c8 100644 --- a/gcc/cp/hash.h +++ b/gcc/cp/hash.h @@ -1,14 +1,13 @@ /* C code produced by gperf version 2.5 (GNU C++ version) */ -/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../devo/gcc/cp/gxx.gperf */ -/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ +/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gxx.gperf */ struct resword { char *name; short token; enum rid rid;}; -#define TOTAL_KEYWORDS 97 +#define TOTAL_KEYWORDS 103 #define MIN_WORD_LENGTH 2 #define MAX_WORD_LENGTH 16 #define MIN_HASH_VALUE 4 -#define MAX_HASH_VALUE 202 -/* maximum key range = 199, duplicates = 0 */ +#define MAX_HASH_VALUE 195 +/* maximum key range = 192, duplicates = 0 */ #ifdef __GNUC__ inline @@ -20,19 +19,19 @@ hash (str, len) { static unsigned char asso_values[] = { - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 0, 203, 29, 22, 32, - 35, 0, 73, 8, 19, 48, 203, 0, 7, 15, - 11, 66, 9, 11, 19, 58, 1, 7, 83, 21, - 89, 5, 203, 203, 203, 203, 203, 203, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 0, 196, 80, 26, 28, + 44, 0, 49, 38, 6, 81, 196, 2, 0, 41, + 16, 47, 4, 31, 32, 5, 6, 62, 20, 96, + 17, 25, 196, 196, 196, 196, 196, 196, }; register int hval = len; @@ -66,133 +65,148 @@ is_reserved_word (str, len) { {"",}, {"",}, {"",}, {"",}, {"else", ELSE, NORID,}, + {"",}, + {"__real", REALPART, NORID}, + {"",}, + {"__real__", REALPART, NORID}, + {"",}, {"true", CXX_TRUE, NORID,}, - {"",}, {"",}, {"",}, - {"try", TRY, NORID,}, - {"",}, {"",}, {"",}, {"",}, {"",}, - {"not", '!', NORID,}, {"",}, - {"extern", SCSPEC, RID_EXTERN,}, + {"__asm__", GCC_ASM_KEYWORD, NORID}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"this", THIS, NORID,}, {"",}, + {"extern", SCSPEC, RID_EXTERN,}, + {"switch", SWITCH, NORID,}, {"template", TEMPLATE, RID_TEMPLATE,}, - {"__null", CONSTANT, RID_NULL}, - {"",}, {"",}, {"",}, - {"typename", TYPENAME_KEYWORD, NORID,}, - {"",}, {"",}, - {"long", TYPESPEC, RID_LONG,}, - {"not_eq", EQCOMPARE, NORID,}, + {"not", '!', NORID,}, + {"",}, {"__alignof__", ALIGNOF, NORID}, + {"static_cast", STATIC_CAST, NORID,}, + {"",}, + {"bool", TYPESPEC, RID_BOOL,}, + {"private", VISSPEC, RID_PRIVATE,}, + {"case", CASE, NORID,}, + {"virtual", SCSPEC, RID_VIRTUAL,}, + {"try", TRY, NORID,}, + {"",}, {"",}, + {"compl", '~', NORID,}, + {"public", VISSPEC, RID_PUBLIC,}, + {"",}, {"__inline", SCSPEC, RID_INLINE}, - {"using", USING, NORID,}, + {"",}, {"__inline__", SCSPEC, RID_INLINE}, - {"while", WHILE, NORID,}, - {"enum", ENUM, NORID,}, - {"new", NEW, NORID,}, - {"case", CASE, NORID,}, - {"",}, {"",}, {"",}, - {"bool", TYPESPEC, RID_BOOL,}, + {"class", AGGR, RID_CLASS,}, + {"const", CV_QUALIFIER, RID_CONST,}, + {"static", SCSPEC, RID_STATIC,}, + {"__extension__", EXTENSION, NORID}, + {"",}, + {"short", TYPESPEC, RID_SHORT,}, + {"__imag__", IMAGPART, NORID}, {"delete", DELETE, NORID,}, + {"__asm", GCC_ASM_KEYWORD, NORID}, + {"xor", '^', NORID,}, + {"not_eq", EQCOMPARE, NORID,}, + {"xor_eq", ASSIGN, NORID,}, + {"typename", TYPENAME_KEYWORD, NORID,}, {"typeid", TYPEID, NORID,}, - {"return", RETURN, NORID,}, {"",}, - {"__label__", LABEL, NORID}, - {"and_eq", ASSIGN, NORID,}, - {"asm", ASM_KEYWORD, NORID,}, - {"continue", CONTINUE, NORID,}, - {"namespace", NAMESPACE, NORID,}, + {"__complex__", TYPESPEC, RID_COMPLEX}, + {"false", CXX_FALSE, NORID,}, + {"sizeof", SIZEOF, NORID,}, + {"typeof", TYPEOF, NORID,}, + {"__const__", CV_QUALIFIER, RID_CONST}, + {"__volatile", CV_QUALIFIER, RID_VOLATILE}, {"",}, - {"mutable", SCSPEC, RID_MUTABLE,}, - {"int", TYPESPEC, RID_INT,}, - {"compl", '~', NORID,}, - {"public", VISSPEC, RID_PUBLIC,}, + {"__volatile__", CV_QUALIFIER, RID_VOLATILE}, + {"__const", CV_QUALIFIER, RID_CONST}, + {"catch", CATCH, NORID,}, + {"__null", CONSTANT, RID_NULL}, {"protected", VISSPEC, RID_PROTECTED,}, - {"break", BREAK, NORID,}, {"",}, - {"__signed__", TYPESPEC, RID_SIGNED}, + {"signed", TYPESPEC, RID_SIGNED,}, {"",}, - {"__attribute", ATTRIBUTE, NORID}, + {"__complex", TYPESPEC, RID_COMPLEX}, + {"__alignof", ALIGNOF, NORID}, {"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,}, - {"__attribute__", ATTRIBUTE, NORID}, {"double", TYPESPEC, RID_DOUBLE,}, - {"explicit", SCSPEC, RID_EXPLICIT,}, - {"__asm__", GCC_ASM_KEYWORD, NORID}, - {"reinterpret_cast", REINTERPRET_CAST, NORID,}, - {"and", ANDAND, NORID,}, - {"",}, {"",}, {"",}, - {"static_cast", STATIC_CAST, NORID,}, + {"const_cast", CONST_CAST, NORID,}, + {"",}, {"struct", AGGR, RID_RECORD,}, - {"default", DEFAULT, NORID,}, - {"char", TYPESPEC, RID_CHAR,}, - {"__const", CV_QUALIFIER, RID_CONST}, - {"__const__", CV_QUALIFIER, RID_CONST}, - {"__volatile", CV_QUALIFIER, RID_VOLATILE}, - {"__asm", GCC_ASM_KEYWORD, NORID}, - {"__volatile__", CV_QUALIFIER, RID_VOLATILE}, - {"typeof", TYPEOF, NORID,}, + {"long", TYPESPEC, RID_LONG,}, + {"or", OROR, NORID,}, {"__typeof__", TYPEOF, NORID}, {"or_eq", ASSIGN, NORID,}, - {"short", TYPESPEC, RID_SHORT,}, - {"switch", SWITCH, NORID,}, + {"for", FOR, NORID,}, + {"__imag", IMAGPART, NORID}, + {"enum", ENUM, NORID,}, + {"",}, {"",}, + {"__label__", LABEL, NORID}, + {"int", TYPESPEC, RID_INT,}, + {"__signed__", TYPESPEC, RID_SIGNED}, {"signature", AGGR, RID_SIGNATURE /* Extension */,}, + {"do", DO, NORID,}, {"",}, - {"or", OROR, NORID,}, - {"catch", CATCH, NORID,}, - {"union", AGGR, RID_UNION,}, - {"__signature__", AGGR, RID_SIGNATURE /* Extension */,}, - {"__signed", TYPESPEC, RID_SIGNED}, - {"bitand", '&', NORID,}, - {"throw", THROW, NORID,}, - {"register", SCSPEC, RID_REGISTER,}, - {"for", FOR, NORID,}, - {"const", CV_QUALIFIER, RID_CONST,}, - {"static", SCSPEC, RID_STATIC,}, - {"unsigned", TYPESPEC, RID_UNSIGNED,}, - {"private", VISSPEC, RID_PRIVATE,}, - {"__alignof", ALIGNOF, NORID}, + {"explicit", SCSPEC, RID_EXPLICIT,}, + {"char", TYPESPEC, RID_CHAR,}, {"",}, - {"inline", SCSPEC, RID_INLINE,}, - {"do", DO, NORID,}, + {"__attribute", ATTRIBUTE, NORID}, + {"friend", SCSPEC, RID_FRIEND,}, + {"__attribute__", ATTRIBUTE, NORID}, + {"while", WHILE, NORID,}, + {"reinterpret_cast", REINTERPRET_CAST, NORID,}, {"",}, - {"virtual", SCSPEC, RID_VIRTUAL,}, - {"xor_eq", ASSIGN, NORID,}, + {"continue", CONTINUE, NORID,}, + {"namespace", NAMESPACE, NORID,}, + {"sigof", SIGOF, NORID /* Extension */,}, + {"",}, + {"volatile", CV_QUALIFIER, RID_VOLATILE,}, {"",}, - {"float", TYPESPEC, RID_FLOAT,}, - {"dynamic_cast", DYNAMIC_CAST, NORID,}, - {"signed", TYPESPEC, RID_SIGNED,}, - {"xor", '^', NORID,}, {"bitor", '|', NORID,}, - {"__extension__", EXTENSION, NORID}, - {"friend", SCSPEC, RID_FRIEND,}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"this", THIS, NORID,}, + {"typedef", SCSPEC, RID_TYPEDEF,}, + {"void", TYPESPEC, RID_VOID,}, + {"break", BREAK, NORID,}, {"",}, - {"if", IF, NORID,}, + {"new", NEW, NORID,}, + {"return", RETURN, NORID,}, + {"and_eq", ASSIGN, NORID,}, {"",}, {"",}, {"",}, - {"volatile", CV_QUALIFIER, RID_VOLATILE,}, + {"using", USING, NORID,}, {"",}, {"",}, - {"__sigof__", SIGOF, NORID /* Extension */,}, + {"asm", ASM_KEYWORD, NORID,}, {"",}, {"",}, - {"const_cast", CONST_CAST, NORID,}, + {"and", ANDAND, NORID,}, + {"mutable", SCSPEC, RID_MUTABLE,}, + {"__typeof", TYPEOF, NORID}, + {"union", AGGR, RID_UNION,}, + {"",}, + {"if", IF, NORID,}, + {"__signed", TYPESPEC, RID_SIGNED}, {"",}, {"",}, - {"false", CXX_FALSE, NORID,}, - {"sizeof", SIZEOF, NORID,}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"goto", GOTO, NORID,}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"__typeof", TYPEOF, NORID}, - {"class", AGGR, RID_CLASS,}, - {"typedef", SCSPEC, RID_TYPEDEF,}, {"",}, {"",}, - {"void", TYPESPEC, RID_VOID,}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"auto", SCSPEC, RID_AUTO,}, + {"__sigof__", SIGOF, NORID /* Extension */,}, + {"float", TYPESPEC, RID_FLOAT,}, + {"",}, {"",}, + {"default", DEFAULT, NORID,}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"",}, {"",}, {"",}, - {"operator", OPERATOR, NORID,}, + {"register", SCSPEC, RID_REGISTER,}, + {"throw", THROW, NORID,}, + {"",}, + {"bitand", '&', NORID,}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"operator", OPERATOR, NORID,}, + {"",}, + {"inline", SCSPEC, RID_INLINE,}, + {"",}, + {"dynamic_cast", DYNAMIC_CAST, NORID,}, + {"",}, {"",}, {"",}, + {"__signature__", AGGR, RID_SIGNATURE /* Extension */,}, + {"",}, {"",}, {"",}, + {"auto", SCSPEC, RID_AUTO,}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"",}, {"",}, {"",}, {"",}, {"",}, - {"sigof", SIGOF, NORID /* Extension */,}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"unsigned", TYPESPEC, RID_UNSIGNED,}, }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 5c882566275..378629c7847 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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); diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h index b3b6c0b6833..11f0db28cb8 100644 --- a/gcc/cp/lang-specs.h +++ b/gcc/cp/lang-specs.h @@ -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\ diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index befb5a15211..39f41cbc5e0 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -639,6 +639,9 @@ init_lex () ridpointers[(int) RID_REGISTER] = get_identifier ("register"); SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER], build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER])); + ridpointers[(int) RID_COMPLEX] = get_identifier ("complex"); + SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_COMPLEX], + build_tree_list (NULL_TREE, ridpointers[(int) RID_COMPLEX])); /* C++ extensions. These are probably not correctly named. */ ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t"); @@ -806,6 +809,8 @@ init_lex () UNSET_RESERVED_WORD ("signature"); UNSET_RESERVED_WORD ("sigof"); } + if (flag_no_gnu_keywords) + UNSET_RESERVED_WORD ("complex"); if (flag_no_asm || flag_no_gnu_keywords) UNSET_RESERVED_WORD ("typeof"); if (! flag_operator_names) @@ -2861,7 +2866,7 @@ real_yylex () p = extend_token_buffer (p); *p++ = c; - c = getc (finput); + c = getch (finput); } if (linemode && c == '\n') @@ -3148,12 +3153,12 @@ real_yylex () enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag = NOT_FLOAT; - p = token_buffer; - *p++ = c; - for (count = 0; count < TOTAL_PARTS; count++) parts[count] = 0; + p = token_buffer; + *p++ = c; + if (c == '0') { *p++ = (c = getch ()); @@ -3177,16 +3182,23 @@ real_yylex () while (c == '.' || (isalnum (c) && (c != 'l') && (c != 'L') && (c != 'u') && (c != 'U') + && c != 'i' && c != 'I' && c != 'j' && c != 'J' && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) { if (c == '.') { if (base == 16) error ("floating constant may not be in radix 16"); - if (floatflag == AFTER_POINT) + if (floatflag == TOO_MANY_POINTS) + /* We have already emitted an error. Don't need another. */ + ; + else if (floatflag == AFTER_POINT) { error ("malformed floating constant"); floatflag = TOO_MANY_POINTS; + /* Avoid another error from atof by forcing all characters + from here on to be ignored. */ + p[-1] = '\0'; } else floatflag = AFTER_POINT; @@ -3286,9 +3298,8 @@ real_yylex () if (floatflag != NOT_FLOAT) { tree type = double_type_node; - char f_seen = 0; - char l_seen = 0; - int garbage_chars = 0; + int exceeds_double = 0; + int imag = 0; REAL_VALUE_TYPE value; jmp_buf handler; @@ -3327,76 +3338,117 @@ real_yylex () } else { + int fflag = 0, lflag = 0; + /* Copy token_buffer now, while it has just the number + and not the suffixes; once we add `f' or `i', + REAL_VALUE_ATOF may not work any more. */ + char *copy = (char *) alloca (p - token_buffer + 1); + bcopy (token_buffer, copy, p - token_buffer + 1); + set_float_handler (handler); - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result of - decimal-to-binary conversion. */ - /* Read the suffixes to choose a data type. */ - switch (c) + while (1) { - case 'f': case 'F': - type = float_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - garbage_chars = -1; - break; + int lose = 0; - case 'l': case 'L': - type = long_double_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - garbage_chars = -1; - break; + /* Read the suffixes to choose a data type. */ + switch (c) + { + case 'f': case 'F': + if (fflag) + error ("more than one `f' in numeric constant"); + fflag = 1; + break; + + case 'l': case 'L': + if (lflag) + error ("more than one `l' in numeric constant"); + lflag = 1; + break; + + case 'i': case 'I': + if (imag) + error ("more than one `i' or `j' in numeric constant"); + else if (pedantic) + pedwarn ("ANSI C++ forbids imaginary numeric constants"); + imag = 1; + break; + + default: + lose = 1; + } - default: - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); + if (lose) + break; + + if (p >= token_buffer + maxtoken - 3) + p = extend_token_buffer (p); + *p++ = c; + *p = 0; + c = getch (finput); + } + + /* The second argument, machine_mode, of REAL_VALUE_ATOF + tells the desired precision of the binary result + of decimal-to-binary conversion. */ + + if (fflag) + { + if (lflag) + error ("both `f' and `l' in floating constant"); + + type = float_type_node; + value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); + /* A diagnostic is required here by some ANSI C testsuites. + This is not pedwarn, become some people don't want + an error for this. */ + if (REAL_VALUE_ISINF (value) && pedantic) + warning ("floating point number exceeds range of `float'"); + } + else if (lflag) + { + type = long_double_type_node; + value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); + if (REAL_VALUE_ISINF (value) && pedantic) + warning ("floating point number exceeds range of `long double'"); + } + else + { + value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); + if (REAL_VALUE_ISINF (value) && pedantic) + warning ("floating point number exceeds range of `double'"); } + set_float_handler (NULL_PTR); } - if (pedantic - && (REAL_VALUE_ISINF (value) #ifdef ERANGE - || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && errno == ERANGE - /* ERANGE is also reported for underflow, so test the - value to distinguish overflow from that. */ - && (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1))) -#endif - )) + if (errno == ERANGE && pedantic) { - pedwarn ("floating point number exceeds range of `%s'", - IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))); - } - /* Note: garbage_chars is -1 if first char is *not* garbage. */ - while (isalnum (c)) - { - if (c == 'f' || c == 'F') - { - if (f_seen) - error ("two `f's in floating constant"); - f_seen = 1; - } - if (c == 'l' || c == 'L') + /* ERANGE is also reported for underflow, + so test the value to distinguish overflow from that. */ + if (REAL_VALUES_LESS (dconst1, value) + || REAL_VALUES_LESS (value, dconstm1)) { - if (l_seen) - error ("two `l's in floating constant"); - l_seen = 1; + pedwarn ("floating point number exceeds range of `%s'", + IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))); + exceeds_double = 1; } - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - garbage_chars++; } +#endif - if (garbage_chars > 0) - error ("garbage at end of number"); + /* If the result is not a number, assume it must have been + due to some error message above, so silently convert + it to a zero. */ + if (REAL_VALUE_ISNAN (value)) + value = dconst0; /* Create a node with determined type and value. */ - yylval.ttype = build_real (type, value); - - put_back (c); - *p = 0; + if (imag) + yylval.ttype = build_complex (NULL_TREE, + cp_convert (type, integer_zero_node), + build_real (type, value)); + else + yylval.ttype = build_real (type, value); } else { @@ -3405,6 +3457,7 @@ real_yylex () int spec_unsigned = 0; int spec_long = 0; int spec_long_long = 0; + int spec_imag = 0; int bytes, warn; while (1) @@ -3427,29 +3480,22 @@ real_yylex () } spec_long = 1; } - else + else if (c == 'i' || c == 'j' || c == 'I' || c == 'J') { - if (isalnum (c)) - { - error ("garbage at end of number"); - while (isalnum (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - } - } - break; + if (spec_imag) + error ("more than one `i' or `j' in numeric constant"); + else if (pedantic) + pedwarn ("ANSI C++ forbids imaginary numeric constants"); + spec_imag = 1; } + else + break; if (p >= token_buffer + maxtoken - 3) p = extend_token_buffer (p); *p++ = c; - c = getch (); + c = getch (finput); } - put_back (c); - /* If the constant is not long long and it won't fit in an unsigned long, or if the constant is long long and won't fit in an unsigned long long, then warn that the constant is out @@ -3499,23 +3545,17 @@ real_yylex () /* Nondecimal constants try unsigned even in traditional C. */ type = unsigned_type_node; } - else if (!spec_unsigned && !spec_long_long && int_fits_type_p (yylval.ttype, long_integer_type_node)) type = long_integer_type_node; - - else if (! spec_long_long - && int_fits_type_p (yylval.ttype, - long_unsigned_type_node)) + else if (! spec_long_long) type = long_unsigned_type_node; - else if (! spec_unsigned /* Verify value does not overflow into sign bit. */ && TREE_INT_CST_HIGH (yylval.ttype) >= 0 && int_fits_type_p (yylval.ttype, long_long_integer_type_node)) type = long_long_integer_type_node; - else if (int_fits_type_p (yylval.ttype, long_long_unsigned_type_node)) type = long_long_unsigned_type_node; @@ -3527,12 +3567,25 @@ real_yylex () if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) warning ("decimal integer constant is so large that it is unsigned"); + if (spec_imag) + { + if (TYPE_PRECISION (type) + <= TYPE_PRECISION (integer_type_node)) + yylval.ttype + = build_complex (NULL_TREE, integer_zero_node, + cp_convert (integer_type_node, + yylval.ttype)); + else + error ("complex integer constant is too wide for `complex int'"); + } } TREE_TYPE (yylval.ttype) = type; - *p = 0; } + put_back (c); + *p = 0; + value = CONSTANT; break; } diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h index 4a2c7d133d2..fcea57af7a4 100644 --- a/gcc/cp/lex.h +++ b/gcc/cp/lex.h @@ -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. */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 640b1bfa903..09acad46831 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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) { diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 720c041eef4..8a1ae5d530c 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -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 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 (); } ; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 823116ca18c..e06fa40768c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index c1afbd69197..92b2c579f72 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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); diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c index 9d2322d2a53..c52b1d62cd6 100644 --- a/gcc/cp/sig.c +++ b/gcc/cp/sig.c @@ -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); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index de9128fd7f5..a0605306d91 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index f3779df79e6..dd6415bac9c 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -355,6 +355,24 @@ common_type (t1, t2) code1 = TREE_CODE (t1); code2 = TREE_CODE (t2); + /* If one type is complex, form the common type of the non-complex + components, then make that complex. Use T1 or T2 if it is the + required type. */ + if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) + { + tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1; + tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2; + tree subtype = common_type (subtype1, subtype2); + + if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) + return build_type_attribute_variant (t1, attributes); + else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) + return build_type_attribute_variant (t2, attributes); + else + return build_type_attribute_variant (build_complex_type (subtype), + attributes); + } + switch (code1) { case INTEGER_TYPE: @@ -1509,7 +1527,7 @@ decay_conversion (exp) inner); TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0)); } - return convert (build_pointer_type (TREE_TYPE (type)), inner); + return cp_convert (build_pointer_type (TREE_TYPE (type)), inner); } if (TREE_CODE (exp) == COMPOUND_EXPR) @@ -1558,7 +1576,7 @@ decay_conversion (exp) /* This way is better for a COMPONENT_REF since it can simplify the offset for a component. */ adr = build_unary_op (ADDR_EXPR, exp, 1); - return convert (ptrtype, adr); + return cp_convert (ptrtype, adr); } return exp; @@ -1580,7 +1598,7 @@ default_conversion (exp) { tree t = type_promotes_to (type); if (t != type) - return convert (t, exp); + return cp_convert (t, exp); } return exp; @@ -2469,12 +2487,12 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) index_identifier, NULL_TREE, 0)); e1 = fold (build (GT_EXPR, boolean_type_node, idx, - convert (delta_type_node, integer_zero_node))); - delta = convert (ptrdiff_type_node, - build_component_ref (function, delta_identifier, NULL_TREE, 0)); + cp_convert (delta_type_node, integer_zero_node))); + delta = cp_convert (ptrdiff_type_node, + build_component_ref (function, delta_identifier, NULL_TREE, 0)); delta2 = DELTA2_FROM_PTRMEMFUNC (function); - /* convert down to the right base, before using the instance. */ + /* Convert down to the right base, before using the instance. */ instance = convert_pointer_to_real (TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)), instance_ptr); @@ -2485,7 +2503,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) vtbl = build (PLUS_EXPR, build_pointer_type (build_pointer_type (vtable_entry_type)), - vtbl, convert (ptrdiff_type_node, delta2)); + vtbl, cp_convert (ptrdiff_type_node, delta2)); vtbl = build_indirect_ref (vtbl, NULL_PTR); aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR, idx, @@ -2845,7 +2863,7 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) && (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (double_type_node))) /* Convert `float' to `double'. */ - result = tree_cons (NULL_TREE, convert (double_type_node, val), result); + result = tree_cons (NULL_TREE, cp_convert (double_type_node, val), result); else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val)) && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (val))) { @@ -3139,8 +3157,10 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: case EXACT_DIV_EXPR: - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) + if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE + || code0 == COMPLEX_TYPE) + && (code1 == INTEGER_TYPE || code1 == REAL_TYPE + || code1 == COMPLEX_TYPE)) { if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1)) cp_warning ("division by zero in `%E / 0'", op0); @@ -3249,7 +3269,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1); /* Avoid converting op1 to result_type later. */ converted = 1; } @@ -3271,7 +3291,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1); /* Avoid converting op1 to result_type later. */ converted = 1; } @@ -3296,15 +3316,17 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = convert (integer_type_node, op1); + op1 = cp_convert (integer_type_node, op1); } break; case EQ_EXPR: case NE_EXPR: build_type = boolean_type_node; - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) + if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE + || code0 == COMPLEX_TYPE) + && (code1 == INTEGER_TYPE || code1 == REAL_TYPE + || code1 == COMPLEX_TYPE)) short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { @@ -3496,9 +3518,12 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) break; } - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) + if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) + && + (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) { + int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE); + if (shorten || common || short_compare) result_type = common_type (type0, type1); @@ -3513,7 +3538,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) Eg, (short)-1 | (unsigned short)-1 is (int)-1 but calculated in (unsigned short) it would be (unsigned short)-1. */ - if (shorten) + if (shorten && none_complex) { int unsigned0, unsigned1; tree arg0 = get_narrower (op0, &unsigned0); @@ -3608,7 +3633,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) TREE_TYPE (arg0)); /* Convert value-to-be-shifted to that type. */ if (TREE_TYPE (op0) != result_type) - op0 = convert (result_type, op0); + op0 = cp_convert (result_type, op0); converted = 1; } } @@ -3627,7 +3652,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) tree val = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); if (val != 0) - return convert (boolean_type_node, val); + return cp_convert (boolean_type_node, val); op0 = xop0, op1 = xop1; converted = 1; resultcode = xresultcode; @@ -3758,9 +3783,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) if (! converted) { if (TREE_TYPE (op0) != result_type) - op0 = convert (result_type, op0); + op0 = cp_convert (result_type, op0); if (TREE_TYPE (op1) != result_type) - op1 = convert (result_type, op1); + op1 = cp_convert (result_type, op1); } if (build_type == NULL_TREE) @@ -3774,7 +3799,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) if (folded == result) TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); if (final_type != 0) - return convert (final_type, folded); + return cp_convert (final_type, folded); return folded; } } @@ -3851,15 +3876,15 @@ pointer_int_sum (resultcode, ptrop, intop) so the multiply won't overflow spuriously. */ if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)) - intop = convert (type_for_size (TYPE_PRECISION (sizetype), 0), intop); + intop = cp_convert (type_for_size (TYPE_PRECISION (sizetype), 0), intop); /* Replace the integer argument with a suitable product by the object size. Do this multiplication as signed, then convert to the appropriate pointer type (actually unsigned integral). */ - intop = convert (result_type, - build_binary_op (MULT_EXPR, intop, - convert (TREE_TYPE (intop), size_exp), 1)); + intop = cp_convert (result_type, + build_binary_op (MULT_EXPR, intop, + cp_convert (TREE_TYPE (intop), size_exp), 1)); /* Create the sum or difference. */ @@ -3898,7 +3923,7 @@ pointer_diff (op0, op1) then drop through to build the divide operator. */ op0 = build_binary_op (MINUS_EXPR, - convert (restype, op0), convert (restype, op1), 1); + cp_convert (restype, op0), cp_convert (restype, op1), 1); /* This generates an error if op1 is a pointer to an incomplete type. */ if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0) @@ -3913,7 +3938,7 @@ pointer_diff (op0, op1) /* Do the division. */ - result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1)); + result = build (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1)); folded = fold (result); if (folded == result) @@ -3964,7 +3989,7 @@ build_component_addr (arg, argtype, msg) size_int (BITS_PER_UNIT)); int flag = TREE_CONSTANT (rval); rval = fold (build (PLUS_EXPR, argtype, - rval, convert (argtype, offset))); + rval, cp_convert (argtype, offset))); TREE_CONSTANT (rval) = flag; } return rval; @@ -4028,7 +4053,7 @@ condition_conversion (expr) tree t; if (processing_template_decl) return expr; - t = convert (boolean_type_node, expr); + t = cp_convert (boolean_type_node, expr); t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t)); return t; } @@ -4082,7 +4107,14 @@ build_unary_op (code, xarg, noconvert) break; case BIT_NOT_EXPR: - if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM, arg, 1))) + if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) + { + code = CONJ_EXPR; + if (!noconvert) + arg = default_conversion (arg); + } + else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM, + arg, 1))) errstring = "wrong type argument to bit-complement"; else if (!noconvert) arg = default_conversion (arg); @@ -4095,8 +4127,16 @@ build_unary_op (code, xarg, noconvert) arg = default_conversion (arg); break; + case CONJ_EXPR: + /* Conjugating a real value is a no-op, but allow it anyway. */ + if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1))) + errstring = "wrong type argument to conjugation"; + else if (!noconvert) + arg = default_conversion (arg); + break; + case TRUTH_NOT_EXPR: - arg = convert (boolean_type_node, arg); + arg = cp_convert (boolean_type_node, arg); val = invert_truthvalue (arg); if (arg != error_mark_node) return val; @@ -4106,6 +4146,22 @@ build_unary_op (code, xarg, noconvert) case NOP_EXPR: break; + case REALPART_EXPR: + if (TREE_CODE (arg) == COMPLEX_CST) + return TREE_REALPART (arg); + else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) + return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); + else + return arg; + + case IMAGPART_EXPR: + if (TREE_CODE (arg) == COMPLEX_CST) + return TREE_IMAGPART (arg); + else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) + return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); + else + return cp_convert (TREE_TYPE (arg), integer_zero_node); + case PREINCREMENT_EXPR: case POSTINCREMENT_EXPR: case PREDECREMENT_EXPR: @@ -4117,6 +4173,19 @@ build_unary_op (code, xarg, noconvert) if (val != 0) return val; + /* Increment or decrement the real part of the value, + and don't change the imaginary part. */ + if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) + { + tree real, imag; + + arg = stabilize_reference (arg); + real = build_unary_op (REALPART_EXPR, arg, 1); + imag = build_unary_op (IMAGPART_EXPR, arg, 1); + return build (COMPLEX_EXPR, TREE_TYPE (arg), + build_unary_op (code, real, 1), imag); + } + /* Report invalid types. */ if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER, @@ -4176,7 +4245,7 @@ build_unary_op (code, xarg, noconvert) else inc = integer_one_node; - inc = convert (argtype, inc); + inc = cp_convert (argtype, inc); /* Handle incrementing a cast-expression. */ @@ -4251,7 +4320,7 @@ build_unary_op (code, xarg, noconvert) val = build (code, TREE_TYPE (arg), arg, inc); TREE_SIDE_EFFECTS (val) = 1; - return convert (result_type, val); + return cp_convert (result_type, val); } case ADDR_EXPR: @@ -4438,9 +4507,9 @@ convert_sequence (conversions, arg) case FIX_FLOOR_EXPR: case FIX_ROUND_EXPR: case FIX_CEIL_EXPR: - return convert (TREE_TYPE (conversions), - convert_sequence (TREE_OPERAND (conversions, 0), - arg)); + return cp_convert (TREE_TYPE (conversions), + convert_sequence (TREE_OPERAND (conversions, 0), + arg)); default: return arg; @@ -4556,7 +4625,7 @@ unary_complex_lvalue (code, arg) data member of a structure. */ offset = size_binop (PLUS_EXPR, offset, size_int (1)); - return convert (build_pointer_type (TREE_TYPE (arg)), offset); + return cp_convert (build_pointer_type (TREE_TYPE (arg)), offset); } } @@ -4608,6 +4677,8 @@ mark_addressable (exp) case ADDR_EXPR: case COMPONENT_REF: case ARRAY_REF: + case REALPART_EXPR: + case IMAGPART_EXPR: x = TREE_OPERAND (x, 0); break; @@ -4731,7 +4802,7 @@ build_conditional_expr (ifexp, op1, op2) ifexp = op1 = save_expr (ifexp); } - ifexp = convert (boolean_type_node, ifexp); + ifexp = cp_convert (boolean_type_node, ifexp); if (TREE_CODE (ifexp) == ERROR_MARK) return error_mark_node; @@ -5280,7 +5351,7 @@ build_reinterpret_cast (type, expr) return error_mark_node; } - return convert (type, expr); + return cp_convert (type, expr); } tree @@ -5339,7 +5410,7 @@ build_const_cast (type, expr) else if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (intype) == POINTER_TYPE && comp_ptr_ttypes_const (TREE_TYPE (type), TREE_TYPE (intype))) - return convert (type, expr); + return cp_convert (type, expr); cp_error ("const_cast from `%T' to `%T'", intype, type); return error_mark_node; @@ -5621,9 +5692,9 @@ build_modify_expr (lhs, modifycode, rhs) so the code to compute it is only emitted once. */ tree cond = build_conditional_expr (TREE_OPERAND (lhs, 0), - build_modify_expr (convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 1)), + build_modify_expr (cp_convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 1)), modifycode, rhs), - build_modify_expr (convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 2)), + build_modify_expr (cp_convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 2)), modifycode, rhs)); if (cond == error_mark_node) return cond; @@ -5632,7 +5703,7 @@ build_modify_expr (lhs, modifycode, rhs) return build (COMPOUND_EXPR, TREE_TYPE (lhs), /* Case to void to suppress warning from warn_if_unused_value. */ - convert (void_type_node, rhs), cond); + cp_convert (void_type_node, rhs), cond); } } @@ -5779,11 +5850,11 @@ build_modify_expr (lhs, modifycode, rhs) pedwarn ("ANSI C++ forbids cast to non-reference type used as lvalue"); result = build_modify_expr (inner_lhs, NOP_EXPR, - convert (TREE_TYPE (inner_lhs), - convert (lhstype, newrhs))); + cp_convert (TREE_TYPE (inner_lhs), + cp_convert (lhstype, newrhs))); if (result == error_mark_node) return result; - return convert (TREE_TYPE (lhs), result); + return cp_convert (TREE_TYPE (lhs), result); } } @@ -5999,11 +6070,11 @@ build_modify_expr (lhs, modifycode, rhs) result = build (COND_EXPR, result_type, cond, build_modify_expr (lhs, modifycode, - convert (result_type, - TREE_OPERAND (newrhs, 1))), + cp_convert (result_type, + TREE_OPERAND (newrhs, 1))), build_modify_expr (lhs1, modifycode, - convert (result_type, - TREE_OPERAND (newrhs, 2)))); + cp_convert (result_type, + TREE_OPERAND (newrhs, 2)))); } } else @@ -6116,7 +6187,7 @@ get_delta_difference (from, to, force) warning ("pointer to member conversion to virtual base class will only work if you are very careful"); } delta = BINFO_OFFSET (binfo); - delta = convert (ptrdiff_type_node, delta); + delta = cp_convert (ptrdiff_type_node, delta); return build_binary_op (MINUS_EXPR, integer_zero_node, @@ -6234,8 +6305,8 @@ build_ptrmemfunc (type, pfn, force) if (type == TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn))) return pfn; - ndelta = convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0)); - ndelta2 = convert (ptrdiff_type_node, DELTA2_FROM_PTRMEMFUNC (pfn)); + ndelta = cp_convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0)); + ndelta2 = cp_convert (ptrdiff_type_node, DELTA2_FROM_PTRMEMFUNC (pfn)); idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0); n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)))), @@ -6405,8 +6476,10 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) return error_mark_node; } /* Arithmetic types all interconvert. */ - if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == BOOLEAN_TYPE) - && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == BOOLEAN_TYPE)) + if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == BOOLEAN_TYPE + || codel == COMPLEX_TYPE) + && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == BOOLEAN_TYPE + || coder == COMPLEX_TYPE)) { /* But we should warn if assigning REAL_TYPE to INTEGER_TYPE. */ if (coder == REAL_TYPE && codel == INTEGER_TYPE) @@ -6444,7 +6517,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) || (coder == ENUMERAL_TYPE && (INTEGRAL_CODE_P (codel) || codel == REAL_TYPE))) { - return cp_convert (type, rhs, CONV_IMPLICIT, LOOKUP_NORMAL); + return ocp_convert (type, rhs, CONV_IMPLICIT, LOOKUP_NORMAL); } /* Conversions among pointers */ else if (codel == POINTER_TYPE @@ -6678,7 +6751,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) return error_mark_node; } } - return convert (type, rhs); + return cp_convert (type, rhs); } else if (codel == POINTER_TYPE && coder == INTEGER_TYPE) { @@ -6693,7 +6766,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) cp_pedwarn ("%s to `%T' from `%T' lacks a cast", errtype, type, rhstype); } - return convert (type, rhs); + return cp_convert (type, rhs); } else if (codel == INTEGER_TYPE && (coder == POINTER_TYPE @@ -6708,7 +6781,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) else cp_pedwarn ("%s to `%T' from `%T' lacks a cast", errtype, type, rhstype); - return convert (type, rhs); + return cp_convert (type, rhs); } else if (codel == BOOLEAN_TYPE && (coder == POINTER_TYPE @@ -6716,7 +6789,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) && (IS_SIGNATURE_POINTER (rhstype) || TYPE_PTRMEMFUNC_FLAG (rhstype) || IS_SIGNATURE_REFERENCE (rhstype))))) - return convert (type, rhs); + return cp_convert (type, rhs); /* C++ */ else if (((coder == POINTER_TYPE @@ -6754,14 +6827,14 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) return nrhs; } else if (TYPE_HAS_CONSTRUCTOR (type) || IS_AGGR_TYPE (TREE_TYPE (rhs))) - return convert (type, rhs); + return cp_convert (type, rhs); /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */ else if (TREE_CODE (type) == POINTER_TYPE && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE || TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node) && TREE_TYPE (rhs) && TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs))) - return convert (type, rhs); + return cp_convert (type, rhs); cp_error ("%s to `%T' from `%T'", errtype, type, rhstype); return error_mark_node; @@ -6881,7 +6954,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) && (TYPE_NEEDS_CONSTRUCTING (type) || TREE_HAS_CONSTRUCTOR (rhs))) { if (flag_ansi_overloading) - return cp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); + return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) { @@ -6952,8 +7025,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) return rhs; } - return cp_convert (type, rhs, CONV_OLD_CONVERT, - flags | LOOKUP_NO_CONVERSION); + return ocp_convert (type, rhs, CONV_OLD_CONVERT, + flags | LOOKUP_NO_CONVERSION); } if (type == TREE_TYPE (rhs)) diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index d499846c5a4..afd4cd8f205 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -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)))) { -- 2.11.0