Commit b6a10c9f by Richard Stallman

(common_type): Handle complex types.

(lvalue_p): Handle REALPART_EXPR, IMAGPART_EXPR.
(build_binary_op, build_unary_op): Handle complex types.

From-SVN: r3646
parent f0b996c5
...@@ -188,6 +188,24 @@ common_type (t1, t2) ...@@ -188,6 +188,24 @@ common_type (t1, t2)
code1 = TREE_CODE (t1); code1 = TREE_CODE (t1);
code2 = TREE_CODE (t2); code2 = TREE_CODE (t2);
/* If one type is complex, form the common type
of the non-complex components,
then make that complex. */
if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
{
tree subtype1, subtype2, subtype;
if (code1 == COMPLEX_TYPE)
subtype1 = TREE_TYPE (t1);
else
subtype1 = t1;
if (code2 == COMPLEX_TYPE)
subtype2 = TREE_TYPE (t2);
else
subtype2 = t2;
subtype = common_type (subtype1, subtype2);
return build_complex_type (subtype);
}
switch (code1) switch (code1)
{ {
case INTEGER_TYPE: case INTEGER_TYPE:
...@@ -2308,8 +2326,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -2308,8 +2326,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case FLOOR_DIV_EXPR: case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR: case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR: case EXACT_DIV_EXPR:
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) || code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE))
{ {
if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)) if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
resultcode = RDIV_EXPR; resultcode = RDIV_EXPR;
...@@ -2363,8 +2383,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -2363,8 +2383,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case TRUTH_AND_EXPR: case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR: case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR: case TRUTH_XOR_EXPR:
if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE || code0 == REAL_TYPE) if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
&& (code1 == INTEGER_TYPE || code1 == POINTER_TYPE || code1 == REAL_TYPE)) || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
|| code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
{ {
/* Result of these operations is always an int, /* Result of these operations is always an int,
but that does not mean the operands should be but that does not mean the operands should be
...@@ -2473,8 +2495,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -2473,8 +2495,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
but don't convert the args to int! */ but don't convert the args to int! */
result_type = integer_type_node; result_type = integer_type_node;
converted = 1; converted = 1;
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) || code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE))
short_compare = 1; short_compare = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{ {
...@@ -2525,8 +2549,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -2525,8 +2549,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case MAX_EXPR: case MAX_EXPR:
case MIN_EXPR: case MIN_EXPR:
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) || code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE))
shorten = 1; shorten = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{ {
...@@ -2543,8 +2569,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -2543,8 +2569,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case GE_EXPR: case GE_EXPR:
case LT_EXPR: case LT_EXPR:
case GT_EXPR: case GT_EXPR:
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) || code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE))
short_compare = 1; short_compare = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{ {
...@@ -2589,9 +2617,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -2589,9 +2617,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
break; break;
} }
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) &&
(code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
{ {
int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
if (shorten || common || short_compare) if (shorten || common || short_compare)
result_type = common_type (type0, type1); result_type = common_type (type0, type1);
...@@ -2606,7 +2637,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -2606,7 +2637,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
Eg, (short)-1 | (unsigned short)-1 is (int)-1 Eg, (short)-1 | (unsigned short)-1 is (int)-1
but calculated in (unsigned short) it would be (unsigned short)-1. */ but calculated in (unsigned short) it would be (unsigned short)-1. */
if (shorten) if (shorten && none_complex)
{ {
int unsigned0, unsigned1; int unsigned0, unsigned1;
tree arg0 = get_narrower (op0, &unsigned0); tree arg0 = get_narrower (op0, &unsigned0);
...@@ -2708,7 +2739,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -2708,7 +2739,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
/* Comparison operations are shortened too but differently. /* Comparison operations are shortened too but differently.
They identify themselves by setting short_compare = 1. */ They identify themselves by setting short_compare = 1. */
if (short_compare) if (short_compare && none_complex)
{ {
/* Don't write &op0, etc., because that would prevent op0 /* Don't write &op0, etc., because that would prevent op0
from being kept in a register. from being kept in a register.
...@@ -2938,14 +2969,16 @@ build_unary_op (code, xarg, noconvert) ...@@ -2938,14 +2969,16 @@ build_unary_op (code, xarg, noconvert)
/* This is used for unary plus, because a CONVERT_EXPR /* This is used for unary plus, because a CONVERT_EXPR
is enough to prevent anybody from looking inside for is enough to prevent anybody from looking inside for
associativity, but won't generate any code. */ associativity, but won't generate any code. */
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE)) if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
errstring = "wrong type argument to unary plus"; errstring = "wrong type argument to unary plus";
else if (!noconvert) else if (!noconvert)
arg = default_conversion (arg); arg = default_conversion (arg);
break; break;
case NEGATE_EXPR: case NEGATE_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE)) if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
errstring = "wrong type argument to unary minus"; errstring = "wrong type argument to unary minus";
else if (!noconvert) else if (!noconvert)
arg = default_conversion (arg); arg = default_conversion (arg);
...@@ -2959,7 +2992,8 @@ build_unary_op (code, xarg, noconvert) ...@@ -2959,7 +2992,8 @@ build_unary_op (code, xarg, noconvert)
break; break;
case ABS_EXPR: case ABS_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE)) if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
errstring = "wrong type argument to abs"; errstring = "wrong type argument to abs";
else if (!noconvert) else if (!noconvert)
arg = default_conversion (arg); arg = default_conversion (arg);
...@@ -2968,6 +3002,7 @@ build_unary_op (code, xarg, noconvert) ...@@ -2968,6 +3002,7 @@ build_unary_op (code, xarg, noconvert)
case TRUTH_NOT_EXPR: case TRUTH_NOT_EXPR:
if (typecode != INTEGER_TYPE if (typecode != INTEGER_TYPE
&& typecode != REAL_TYPE && typecode != POINTER_TYPE && typecode != REAL_TYPE && typecode != POINTER_TYPE
&& typecode != COMPLEX_TYPE
/* These will convert to a pointer. */ /* These will convert to a pointer. */
&& typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE) && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
{ {
...@@ -2979,6 +3014,22 @@ build_unary_op (code, xarg, noconvert) ...@@ -2979,6 +3014,22 @@ build_unary_op (code, xarg, noconvert)
case NOP_EXPR: case NOP_EXPR:
break; 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 convert (TREE_TYPE (arg), integer_zero_node);
case PREINCREMENT_EXPR: case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR: case POSTINCREMENT_EXPR:
...@@ -2991,6 +3042,19 @@ build_unary_op (code, xarg, noconvert) ...@@ -2991,6 +3042,19 @@ build_unary_op (code, xarg, noconvert)
if (val != 0) if (val != 0)
return val; return val;
/* Increment or decrement the real part of the value,
and don't change the imaginary part. */
if (typecode == 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. */ /* Report invalid types. */
if (typecode != POINTER_TYPE if (typecode != POINTER_TYPE
...@@ -3273,6 +3337,8 @@ lvalue_p (ref) ...@@ -3273,6 +3337,8 @@ lvalue_p (ref)
switch (code) switch (code)
{ {
case REALPART_EXPR:
case IMAGPART_EXPR:
case COMPONENT_REF: case COMPONENT_REF:
return lvalue_p (TREE_OPERAND (ref, 0)); return lvalue_p (TREE_OPERAND (ref, 0));
...@@ -4057,9 +4123,11 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) ...@@ -4057,9 +4123,11 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
return error_mark_node; return error_mark_node;
} }
/* Arithmetic types all interconvert, and enum is treated like int. */ /* Arithmetic types all interconvert, and enum is treated like int. */
if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE) if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE
|| codel == COMPLEX_TYPE)
&& &&
(coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE)) (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
|| codel == COMPLEX_TYPE))
return convert_and_check (type, rhs); return convert_and_check (type, rhs);
/* Conversion to a union from its member types. */ /* Conversion to a union from its member types. */
else if (codel == UNION_TYPE) else if (codel == UNION_TYPE)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment