Renamed language to dlt (Delight)
[delight/core.git] / d-convert.cc
blob0329dd949b8db76120e735af3246ce8e59b7fb0a
1 /* GDC -- D front-end for GCC
2 Copyright (C) 2004 David Friedman
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "d-gcc-includes.h"
20 #include "d-lang.h"
22 /* Perform default promotions for C data used in expressions.
23 Arrays and functions are converted to pointers;
24 enumeral types or short or char, to int.
25 In addition, manifest constants symbols are replaced by their values. */
27 extern "C" tree
28 default_conversion (tree exp)
30 #if 0
31 tree orig_exp;
32 tree type = TREE_TYPE (exp);
33 enum tree_code code = TREE_CODE (type);
35 if (code == FUNCTION_TYPE || code == ARRAY_TYPE)
36 return default_function_array_conversion (exp);
38 /* Constants can be used directly unless they're not loadable. */
39 if (TREE_CODE (exp) == CONST_DECL)
40 exp = DECL_INITIAL (exp);
42 /* Replace a nonvolatile const static variable with its value unless
43 it is an array, in which case we must be sure that taking the
44 address of the array produces consistent results. */
45 else if (gcc_optimize() && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE)
47 exp = decl_constant_value_for_broken_optimization (exp);
48 type = TREE_TYPE (exp);
51 /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
52 an lvalue.
54 Do not use STRIP_NOPS here! It will remove conversions from pointer
55 to integer and cause infinite recursion. */
56 orig_exp = exp;
57 while (TREE_CODE (exp) == NON_LVALUE_EXPR
58 || (TREE_CODE (exp) == NOP_EXPR
59 && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
60 exp = TREE_OPERAND (exp, 0);
62 /* Preserve the original expression code. */
63 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (exp))))
64 C_SET_EXP_ORIGINAL_CODE (exp, C_EXP_ORIGINAL_CODE (orig_exp));
66 /* Normally convert enums to int,
67 but convert wide enums to something wider. */
68 if (code == ENUMERAL_TYPE)
70 type = c_common_type_for_size (MAX (TYPE_PRECISION (type),
71 TYPE_PRECISION (integer_type_node)),
72 ((TYPE_PRECISION (type)
73 >= TYPE_PRECISION (integer_type_node))
74 && TREE_UNSIGNED (type)));
76 return convert (type, exp);
79 if (TREE_CODE (exp) == COMPONENT_REF
80 && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))
81 /* If it's thinner than an int, promote it like a
82 c_promoting_integer_type_p, otherwise leave it alone. */
83 && 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
84 TYPE_PRECISION (integer_type_node)))
85 return convert (integer_type_node, exp);
87 if (c_promoting_integer_type_p (type))
89 /* Preserve unsignedness if not really getting any wider. */
90 if (TREE_UNSIGNED (type)
91 && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
92 return convert (unsigned_type_node, exp);
94 return convert (integer_type_node, exp);
97 if (code == VOID_TYPE)
99 error ("void value not ignored as it ought to be");
100 return error_mark_node;
102 return exp;
103 #else
104 return exp;
105 #endif
108 // copied this over just to support d_truthvalue_conversion, so assumes bool
109 static tree
110 build_buul_binary_op(tree_code code, tree orig_op0, tree orig_op1, int convert_p)
112 tree op0, op1;
113 tree result_type = NULL_TREE;
114 if (convert_p)
116 op0 = default_conversion (orig_op0);
117 op1 = default_conversion (orig_op1);
119 else
121 op0 = orig_op0;
122 op1 = orig_op1;
125 /* Also need to convert pointer/int comparison for GCC >= 4.1 */
126 tree type0 = TREE_TYPE (op0);
127 tree type1 = TREE_TYPE (op1);
128 if (POINTER_TYPE_P(type0) && TREE_CODE(op1) == INTEGER_CST
129 && integer_zerop (op1))
131 result_type = type0;
133 else if (POINTER_TYPE_P(type1) && TREE_CODE(op0) == INTEGER_CST
134 && integer_zerop (op0))
136 result_type = type1;
139 if (result_type)
141 if (TREE_TYPE (op0) != result_type)
142 op0 = convert (result_type, op0);
143 if (TREE_TYPE (op1) != result_type)
144 op1 = convert (result_type, op1);
147 return build(code, boolean_type_node, op0, op1);
150 // These functions support calls from the backend. This happens
151 // for build_common_tree_nodes_2 and (anything else?%% if so, can
152 // pare this down or ..just do the work of build_common_tree_nodes_2
153 // OTOH, might want vector extensions some day.
155 // probably can go back into dc-lang.cc
157 // Because this is called by the backend, there may be cases when IRState::converTo
158 // has been bypassed. If we have type.lang_specific set on both args, try using IRState::converTo.
160 // tree convert (tree type, tree expr) is in d-glue.cc to get the current IRState...
162 tree
163 d_convert_basic (tree type, tree expr)
165 // take from c-convert.c
167 tree e = expr;
168 enum tree_code code = TREE_CODE (type);
170 if (type == TREE_TYPE (expr)
171 || TREE_CODE (expr) == ERROR_MARK
172 || code == ERROR_MARK || TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
173 return expr;
175 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
176 return fold (build1 (NOP_EXPR, type, expr));
177 if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
178 return error_mark_node;
179 if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
181 error ("void value not ignored as it ought to be");
182 return error_mark_node;
184 if (code == VOID_TYPE)
185 return build1 (CONVERT_EXPR, type, e);
186 #if 0
187 /* This is incorrect. A truncation can't be stripped this way.
188 Extensions will be stripped by the use of get_unwidened. */
189 if (TREE_CODE (expr) == NOP_EXPR)
190 return convert (type, TREE_OPERAND (expr, 0));
191 #endif
192 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
193 return fold (convert_to_integer (type, e));
194 if (code == BOOLEAN_TYPE)
196 tree t = d_truthvalue_conversion (expr);
197 /* If it returns a NOP_EXPR, we must fold it here to avoid
198 infinite recursion between fold () and convert (). */
199 if (TREE_CODE (t) == NOP_EXPR)
200 return fold (build1 (NOP_EXPR, type, TREE_OPERAND (t, 0)));
201 else
202 return fold (build1 (NOP_EXPR, type, t));
204 if (code == POINTER_TYPE || code == REFERENCE_TYPE)
205 return fold (convert_to_pointer (type, e));
206 if (code == REAL_TYPE)
207 return fold (convert_to_real (type, e));
208 if (code == COMPLEX_TYPE)
209 return fold (convert_to_complex (type, e));
210 if (code == VECTOR_TYPE)
211 return fold (convert_to_vector (type, e));
213 error ("conversion to non-scalar type requested");
214 return error_mark_node;
217 tree
218 d_truthvalue_conversion (tree expr)
220 if (TREE_CODE (expr) == ERROR_MARK)
221 return expr;
223 #if 0 /* This appears to be wrong for C++. */
224 /* These really should return error_mark_node after 2.4 is stable.
225 But not all callers handle ERROR_MARK properly. */
226 switch (TREE_CODE (TREE_TYPE (expr)))
228 case RECORD_TYPE:
229 error ("struct type value used where scalar is required");
230 return boolean_false_node;
232 case UNION_TYPE:
233 error ("union type value used where scalar is required");
234 return boolean_false_node;
236 case ARRAY_TYPE:
237 error ("array type value used where scalar is required");
238 return boolean_false_node;
240 default:
241 break;
243 #endif /* 0 */
245 switch (TREE_CODE (expr))
247 case EQ_EXPR:
248 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
249 case TRUTH_ANDIF_EXPR:
250 case TRUTH_ORIF_EXPR:
251 case TRUTH_AND_EXPR:
252 case TRUTH_OR_EXPR:
253 case TRUTH_XOR_EXPR:
254 case TRUTH_NOT_EXPR:
255 TREE_TYPE (expr) = boolean_type_node;
256 return expr;
258 case ERROR_MARK:
259 return expr;
261 case INTEGER_CST:
262 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
264 case REAL_CST:
265 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
267 case ADDR_EXPR:
268 /* If we are taking the address of an external decl, it might be zero
269 if it is weak, so we cannot optimize. */
270 if (DECL_P (TREE_OPERAND (expr, 0))
271 && DECL_EXTERNAL (TREE_OPERAND (expr, 0)))
272 break;
274 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
275 return build (COMPOUND_EXPR, boolean_type_node,
276 TREE_OPERAND (expr, 0), boolean_true_node);
277 else
278 return boolean_true_node;
280 case COMPLEX_EXPR:
281 return build_buul_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
282 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
283 d_truthvalue_conversion (TREE_OPERAND (expr, 0)),
284 d_truthvalue_conversion (TREE_OPERAND (expr, 1)),
287 case NEGATE_EXPR:
288 case ABS_EXPR:
289 case FLOAT_EXPR:
290 // %% there may be other things wrong...
291 /* These don't change whether an object is nonzero or zero. */
292 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
294 case LROTATE_EXPR:
295 case RROTATE_EXPR:
296 /* These don't change whether an object is zero or nonzero, but
297 we can't ignore them if their second arg has side-effects. */
298 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
299 return build (COMPOUND_EXPR, boolean_type_node, TREE_OPERAND (expr, 1),
300 d_truthvalue_conversion (TREE_OPERAND (expr, 0)));
301 else
302 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
304 case COND_EXPR:
305 /* Distribute the conversion into the arms of a COND_EXPR. */
306 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
307 d_truthvalue_conversion (TREE_OPERAND (expr, 1)),
308 d_truthvalue_conversion (TREE_OPERAND (expr, 2))));
310 case CONVERT_EXPR:
311 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
312 since that affects how `default_conversion' will behave. */
313 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
314 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
315 break;
316 /* fall through... */
317 case NOP_EXPR:
318 /* If this is widening the argument, we can ignore it. */
319 if (TYPE_PRECISION (TREE_TYPE (expr))
320 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
321 return d_truthvalue_conversion (TREE_OPERAND (expr, 0));
322 break;
324 case MINUS_EXPR:
325 /* Perhaps reduce (x - y) != 0 to (x != y). The expressions
326 aren't guaranteed to the be same for modes that can represent
327 infinity, since if x and y are both +infinity, or both
328 -infinity, then x - y is not a number.
330 Note that this transformation is safe when x or y is NaN.
331 (x - y) is then NaN, and both (x - y) != 0 and x != y will
332 be false. */
333 if (HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0)))))
334 break;
335 /* fall through... */
336 case BIT_XOR_EXPR:
337 /* This and MINUS_EXPR can be changed into a comparison of the
338 two objects. */
339 if (TREE_TYPE (TREE_OPERAND (expr, 0))
340 == TREE_TYPE (TREE_OPERAND (expr, 1)))
341 return build_buul_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
342 TREE_OPERAND (expr, 1), 1);
343 return build_buul_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
344 fold (build1 (NOP_EXPR,
345 TREE_TYPE (TREE_OPERAND (expr, 0)),
346 TREE_OPERAND (expr, 1))), 1);
347 case BIT_AND_EXPR:
348 if (integer_onep (TREE_OPERAND (expr, 1))
349 && TREE_TYPE (expr) != boolean_type_node)
350 /* Using convert here would cause infinite recursion. */
351 return build1 (NOP_EXPR, boolean_type_node, expr);
352 break;
354 case MODIFY_EXPR:
356 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
357 warning ("suggest parentheses around assignment used as truth value");
359 break;
361 default:
362 break;
365 tree t_zero = integer_zero_node;
367 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
369 tree t = save_expr (expr);
370 tree compon_type = TREE_TYPE( TREE_TYPE( expr ));
371 return (build_buul_binary_op
372 ((TREE_SIDE_EFFECTS (expr)
373 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
374 d_truthvalue_conversion (build1 (REALPART_EXPR, compon_type, t)),
375 d_truthvalue_conversion (build1 (IMAGPART_EXPR, compon_type, t)),
376 0));
379 #if D_GCC_VER >= 40
380 /* Without this, the backend tries to load a float reg with and integer
381 value with fails (on i386 and rs6000, at least). */
382 else if ( SCALAR_FLOAT_TYPE_P( TREE_TYPE( expr )))
384 t_zero = convert( TREE_TYPE(expr), t_zero );
386 #endif
389 return build_buul_binary_op (NE_EXPR, expr, t_zero, 1);