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"
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. */
28 default_conversion (tree 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
54 Do not use STRIP_NOPS here! It will remove conversions from pointer
55 to integer and cause infinite recursion. */
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
;
108 // copied this over just to support d_truthvalue_conversion, so assumes bool
110 build_buul_binary_op(tree_code code
, tree orig_op0
, tree orig_op1
, int convert_p
)
113 tree result_type
= NULL_TREE
;
116 op0
= default_conversion (orig_op0
);
117 op1
= default_conversion (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
))
133 else if (POINTER_TYPE_P(type1
) && TREE_CODE(op0
) == INTEGER_CST
134 && integer_zerop (op0
))
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...
163 d_convert_basic (tree type
, tree expr
)
165 // take from c-convert.c
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
)
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
);
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));
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)));
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
;
218 d_truthvalue_conversion (tree expr
)
220 if (TREE_CODE (expr
) == ERROR_MARK
)
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
)))
229 error ("struct type value used where scalar is required");
230 return boolean_false_node
;
233 error ("union type value used where scalar is required");
234 return boolean_false_node
;
237 error ("array type value used where scalar is required");
238 return boolean_false_node
;
245 switch (TREE_CODE (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
:
255 TREE_TYPE (expr
) = boolean_type_node
;
262 return integer_zerop (expr
) ? boolean_false_node
: boolean_true_node
;
265 return real_zerop (expr
) ? boolean_false_node
: boolean_true_node
;
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)))
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
);
278 return boolean_true_node
;
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)),
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));
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)));
302 return d_truthvalue_conversion (TREE_OPERAND (expr
, 0));
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))));
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
)
316 /* fall through... */
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));
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
333 if (HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr
, 0)))))
335 /* fall through... */
337 /* This and MINUS_EXPR can be changed into a comparison of the
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);
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
);
356 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
357 warning ("suggest parentheses around assignment used as truth value");
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
)),
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
);
389 return build_buul_binary_op (NE_EXPR
, expr
, t_zero
, 1);