if (type_precision (intype) == POINTER_SIZE)
return build1 (CONVERT_EXPR, type, expr);
expr = convert (type_for_size (POINTER_SIZE, 0), expr);
- if (TYPE_MODE (TREE_TYPE (expr)) != TYPE_MODE (type))
+ /* 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)))
/* There is supposed to be some integral type
that is the same width as a pointer. */
abort ();
if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
return build1 (FLOAT_EXPR, type, expr);
+ if (form == COMPLEX_TYPE)
+ return convert (type, fold (build1 (REALPART_EXPR,
+ TREE_TYPE (TREE_TYPE (expr)), expr)));
+
if (form == POINTER_TYPE)
error ("pointer value used where a floating point value was expected");
else
{
register tree tem = make_node (REAL_CST);
TREE_TYPE (tem) = type;
- TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0");
+ TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0", TYPE_MODE (type));
return tem;
}
}
switch (ex_form)
{
-#if 0
- case INTEGER_CST:
- if (TREE_UNSIGNED (type))
- {
- if (TREE_INT_CST_LOW (expr) >> outprec)
- warning ("integer constant truncated");
- }
- else
- {
- /* if the sign bit of the low-order part isn't replicated
- through the entire high part, we have overflow */
- int sign = TREE_INT_CST_LOW (expr) & (1 << (outprec - 1));
- if (!sign) /* lower part positive */
- {
- if (TREE_INT_CST_LOW (expr) >> outprec)
- warning ("integer constant truncated");
- }
- else
- {
- if ((TREE_INT_CST_LOW (expr) >> outprec) + 1)
- warning ("integer constant truncated");
- }
- }
- break;
-#endif /* 0 */
-
case RSHIFT_EXPR:
/* We can pass truncation down through right shifting
when the shift count is a nonpositive constant. */
if (form == REAL_TYPE)
return build1 (FIX_TRUNC_EXPR, type, expr);
+ if (form == COMPLEX_TYPE)
+ return convert (type, fold (build1 (REALPART_EXPR,
+ TREE_TYPE (TREE_TYPE (expr)), expr)));
+
error ("aggregate value used where an integer was expected");
{
return tem;
}
}
+
+/* Convert EXPR to the complex type TYPE in the usual ways. */
+
+tree
+convert_to_complex (type, expr)
+ tree type, expr;
+{
+ register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
+ tree subtype = TREE_TYPE (type);
+
+ if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
+ {
+ expr = convert (subtype, expr);
+ return build (COMPLEX_EXPR, type, expr,
+ convert (subtype, integer_zero_node));
+ }
+
+ if (form == COMPLEX_TYPE)
+ {
+ tree elt_type = TREE_TYPE (TREE_TYPE (expr));
+ if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
+ return expr;
+ else if (TREE_CODE (expr) == COMPLEX_EXPR)
+ return fold (build (COMPLEX_EXPR,
+ type,
+ convert (subtype, TREE_OPERAND (expr, 0)),
+ convert (subtype, TREE_OPERAND (expr, 1))));
+ else
+ {
+ expr = save_expr (expr);
+ return fold (build (COMPLEX_EXPR,
+ type,
+ convert (subtype,
+ build_unary_op (REALPART_EXPR, expr, 1)),
+ convert (subtype,
+ build_unary_op (IMAGPART_EXPR, expr, 1))));
+ }
+ }
+
+ if (form == POINTER_TYPE)
+ error ("pointer value used where a complex was expected");
+ else
+ error ("aggregate value used where a complex was expected");
+
+ return build (COMPLEX_EXPR, type,
+ convert (subtype, integer_zero_node),
+ convert (subtype, integer_zero_node));
+}