+Tue May 27 19:49:19 1997 Mike Stump <mrs@cygnus.com>
+
+ * cvt.c (convert): Don't do any extra work, if we can avoid it
+ easily.
+
+Tue May 27 18:21:47 1997 Mike Stump <mrs@cygnus.com>
+
+ * *.[chy]: Change cp_convert to ocp_convert, change convert to
+ cp_convert. convert is now reserved for the backend, and doesn't
+ have the semantics a frontend person should ever want.
+
+Fri May 23 10:58:31 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * lang-specs.h: Define __EXCEPTIONS if exceptions are enabled.
+ Lose -traditional support.
+
+Thu May 22 15:41:28 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * rtti.c (get_tinfo_var): Use TYPE_PRECISION (sizetype).
+
+ * parse.y (self_reference): Do it for templates, too.
+ * class.c (pushclass): Don't overload_template_name; the alias
+ generated by build_self_reference serves the same purpose.
+
+ * tree.c (list_hash): Make static, take more args.
+ (list_hash_lookup): Likewise.
+ (list_hash_add): Make static.
+ (list_hash_canon): Lose.
+ (hash_tree_cons): Only build a new node if one isn't already in the
+ hashtable.
+ (hash_tree_chain): Use hash_tree_cons.
+ * cp-tree.h: Adjust.
+ * decl.c (grokfndecl): Just check IDENTIFIER_GLOBAL_VALUE instead
+ of calling lookup_name.
+
+Wed May 21 18:24:19 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (instantiate_class_template): TYPE_VALUES for an enum
+ doesn't refer to the CONST_DECLs.
+
+Tue May 20 21:09:32 1997 Bob Manson <manson@charmed.cygnus.com>
+
+ * rtti.c (get_tinfo_var): Either INT_TYPE_SIZE or 32, whichever
+ is bigger.
+ (expand_class_desc): Convert the last argument to a sizetype.
+
+Tue May 20 13:55:57 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
+
+ * gxx.gperf (__complex, __complex__, __imag, __imag__, __real,
+ __real__): Add reswords.
+ * hash.h: Regenerate.
+ * lex.h (rid): Add RID_COMPLEX.
+ (RID_LAST_MODIFIER): Set to RID_COMPLEX.
+ * lex.c (init_lex): Add building of RID_COMPLEX. Unset reserved
+ word "complex" if -fno-gnu-keywords.
+ (real_yylex): General cleanup in line with what c-lex.c also has,
+ sans the cruft for traditional; add handling of SPEC_IMAG, complex
+ types, and imaginary numeric constants.
+ * parse.y (REALPART, IMAGPART): Add tokens.
+ (unary_expr): Add REALPART and IMAGPART rules.
+ * cp-tree.h (complex_{integer,float,double,long}_type_node): Declare.
+ * decl.c (complex_{integer,float,double,long}_type_node): Define
+ types.
+ (init_decl_processing): Set up the types.
+ (grokdeclarator): Add handling of RID_COMPLEX. Set and use
+ DEFAULTED_INT instead of EXPLICIT_INT when we default to int type.
+ * call.c (build_new_op): Add REALPART_EXPR and IMAGPART_EXPR cases.
+ * cvt.c (cp_convert): Handle COMPLEX_TYPE.
+ * error.c (dump_type_prefix, dump_type, dump_type_suffix): Add
+ COMPLEX_TYPE case.
+ * method.c (build_overload_name): Add handling of the different
+ COMPLEX_TYPEs, prefixing them with `J'.
+ * pt.c (process_template_parm): Don't let them use a COMPLEX_TYPE
+ as a template parm.
+ (uses_template_parms, tsubst, unify): Add COMPLEX_TYPE case.
+ * tree.c (lvalue_p): Add REALPART_EXPR and IMAGPART_EXPR cases.
+ (mapcar): Handle COMPLEX_CST.
+ * typeck.c (build_binary_op_nodefault): Handle COMPLEX_TYPE.
+ (common_type): Add code for complex types.
+ (build_unary_op): Add REALPART_EXPR and IMAGPART_EXPR cases.
+ (convert_for_assignment): Likewise.
+ (mark_addressable): Add REALPART_EXPR and IMAGPART_EXPR cases.
+
+Mon May 19 12:26:27 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * pt.c (tsubst): Don't pass the MINUS_EXPR for an array domain to
+ tsubst_expr, as it might try to do overload resolution.
+
Sat May 17 10:48:31 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (instantiate_class_template): Oops.
Thu May 1 18:26:37 1997 Mike Stump <mrs@cygnus.com>
* except.c (expand_exception_blocks): Ensure that we flow through
- the end of the exception region for the exception specification.
- Move exception region for the exception specification in, so that
- it doesn't protect the parm cleanup. Remove some obsolete code.
- * decl.c (store_parm_decls): Likewise.
+ the end of the exception region for the exception specification.
+ Move exception region for the exception specification in, so that
+ it doesn't protect the parm cleanup. Remove some obsolete code.
+ * decl.c (store_parm_decls): Likewise.
(finish_function): Likewise.
Tue Apr 29 15:38:54 1997 Jason Merrill <jason@yorick.cygnus.com>
to -Weffc++.
* decl2.c (finish_prevtable_vardecl): Change NO_LINKAGE_HEURISTICS
- to MULTIPLE_SYMBOL_SPACES.
+ to MULTIPLE_SYMBOL_SPACES.
Wed Apr 23 18:06:50 1997 Jason Merrill <jason@yorick.cygnus.com>
* 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.
* tree.c (varargs_function_p): New fn.
* method.c (emit_thunk): Replace broken generic code with code to
- generate a heavyweight thunk function.
+ generate a heavyweight thunk function.
Tue Apr 22 02:45:18 1997 Jason Merrill <jason@yorick.cygnus.com>
Mon Apr 21 15:42:27 1997 Jason Merrill <jason@yorick.cygnus.com>
* class.c (check_for_override): The signature of an overriding
- function is not changed.
+ function is not changed.
* call.c (build_over_call): Move setting of conv into the loop.
Sun Apr 20 16:24:29 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_user_type_conversion_1): Really ignore rvalue
- conversions when looking for a REFERENCE_TYPE.
+ conversions when looking for a REFERENCE_TYPE.
* cvt.c (build_up_reference): Eviscerate, use build_unary_op.
* cp-tree.h (TREE_REFERENCE_EXPR): #if 0.
* typeck.c (decay_conversion): Don't set TREE_REFERENCE_EXPR.
(build_unary_op): Likewise.
* call.c (build_over_call): See through a CONVERT_EXPR around the
- ADDR_EXPR for on a temporary.
+ ADDR_EXPR for on a temporary.
* typeck.c (c_expand_return): See through a CONVERT_EXPR around
- the ADDR_EXPR for a local variable.
+ the ADDR_EXPR for a local variable.
Fri Apr 18 12:11:33 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_user_type_conversion_1): If we're trying to
- convert to a REFERENCE_TYPE, only consider lvalue conversions.
+ convert to a REFERENCE_TYPE, only consider lvalue conversions.
(build_new_function_call): Print candidates.
(implicit_conversion): Try a temp binding if the lvalue conv is BAD.
(reference_binding): Binding a temporary of a reference-related type
Fri Apr 11 02:18:30 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (implicit_conversion): Try to find a reference conversion
- before binding a const reference to a temporary.
+ before binding a const reference to a temporary.
Wed Apr 2 12:51:36 1997 Mike Stump <mrs@cygnus.com>
* 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.)
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))
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,
{
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),
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;
}
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:
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
&& (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 `...'",
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.
*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);
pushlevel_class ();
+#if 0
if (CLASSTYPE_TEMPLATE_INFO (type))
overload_template_name (type);
+#endif
if (modify)
{
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;
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));
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));
{
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)))
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;
return convert_pointer_to_real (type, expr);
}
\f
+/* 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;
{
/* 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. */
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)))
{
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
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). */
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. */
&& (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
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:
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;
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);
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))
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;
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
{
/* These imply 'int'. */
type = integer_type_node;
- explicit_int = 1;
+ defaulted_int = 1;
}
if (type == NULL_TREE)
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);
}
}
+ 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
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. */
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))
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 ");
case UNKNOWN_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
+ case COMPLEX_TYPE:
dump_type (t, v);
break;
case UNKNOWN_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
+ case COMPLEX_TYPE:
break;
default:
__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
/* 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
{
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;
{
{"",}, {"",}, {"",}, {"",},
{"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)
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;
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;
}
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,
}
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)
{
{
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)
{
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),
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,
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,
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);
}
return controller;
}
else
- return convert (void_type_node, body);
+ return cp_convert (void_type_node, body);
}
/* Build a tree to cleanup partially built arrays.
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;
/* 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);
%{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\
{"@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\
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");
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)
p = extend_token_buffer (p);
*p++ = c;
- c = getc (finput);
+ c = getch (finput);
}
if (linemode && c == '\n')
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 ());
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;
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;
}
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
{
int spec_unsigned = 0;
int spec_long = 0;
int spec_long_long = 0;
+ int spec_imag = 0;
int bytes, warn;
while (1)
}
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
/* 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;
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;
}
RID_SIGNED,
RID_AUTO,
RID_MUTABLE,
+ RID_COMPLEX,
/* This is where grokdeclarator ends its search when setting the
specbits. */
#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. */
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)
{
%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF
%token SIGOF
%token ATTRIBUTE EXTENSION LABEL
+%token REALPART IMAGPART
/* the reserved words... C++ extensions */
%token <ttype> AGGR
{ $$ = 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:
&& (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
{
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
{
self_reference:
/* empty */
{
- if (CLASSTYPE_TEMPLATE_INFO (current_class_type))
- $$ = NULL_TREE;
- else
$$ = build_self_reference ();
}
;
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);
return uses_template_parms (TYPE_MAX_VALUE (t));
case REAL_TYPE:
+ case COMPLEX_TYPE:
case VOID_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_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),
case OP_IDENTIFIER:
case VOID_TYPE:
case REAL_TYPE:
+ case COMPLEX_TYPE:
case BOOLEAN_TYPE:
case INTEGER_CST:
case REAL_CST:
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);
}
nsubsts, strict);
case REAL_TYPE:
+ case COMPLEX_TYPE:
case INTEGER_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
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. */
&& ! 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);
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);
}
(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;
{
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);
}
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);
}
}
(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))
/* 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);
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);
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);
}
}
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));
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);
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));
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;
/* 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;
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;
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;
}
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. */
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);
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:
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)
/* 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;
{
tree t = type_promotes_to (type);
if (t != type)
- return convert (t, exp);
+ return cp_convert (t, exp);
}
return exp;
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);
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,
&& (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)))
{
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);
/* 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;
}
/* 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;
}
/* 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)
{
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);
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);
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;
}
}
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;
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)
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;
}
}
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. */
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)
/* 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)
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;
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;
}
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);
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;
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:
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,
else
inc = integer_one_node;
- inc = convert (argtype, inc);
+ inc = cp_convert (argtype, inc);
/* Handle incrementing a cast-expression. */
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:
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;
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);
}
}
case ADDR_EXPR:
case COMPONENT_REF:
case ARRAY_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
x = TREE_OPERAND (x, 0);
break;
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;
return error_mark_node;
}
- return convert (type, expr);
+ return cp_convert (type, expr);
}
tree
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;
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;
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);
}
}
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);
}
}
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
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,
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)))),
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)
|| (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
return error_mark_node;
}
}
- return convert (type, rhs);
+ return cp_convert (type, rhs);
}
else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
{
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
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
&& (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
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;
&& (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))
{
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))
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))))
{