Updated to libg++ 2.4
[unix-history] / gnu / usr.bin / cc / common / convert.c
CommitLineData
9bf86ebb
PR
1/* Utility routines for data type conversion for GNU C.
2 Copyright (C) 1987, 1988, 1991, 1992 Free Software Foundation, Inc.
3
4This file is part of GNU C.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21/* These routines are somewhat language-independent utility function
22 intended to be called by the language-specific convert () functions. */
23
24#include "config.h"
25#include "tree.h"
26#include "flags.h"
27#include "convert.h"
28
29/* Convert EXPR to some pointer type TYPE.
30
31 EXPR must be pointer, integer, enumeral, or literal zero;
32 in other cases error is called. */
33
34tree
35convert_to_pointer (type, expr)
36 tree type, expr;
37{
38 register tree intype = TREE_TYPE (expr);
39 register enum tree_code form = TREE_CODE (intype);
40
41 if (integer_zerop (expr))
42 {
43 if (type == TREE_TYPE (null_pointer_node))
44 return null_pointer_node;
45 expr = build_int_2 (0, 0);
46 TREE_TYPE (expr) = type;
47 return expr;
48 }
49
50 if (form == POINTER_TYPE)
51 return build1 (NOP_EXPR, type, expr);
52
53
54 if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
55 {
56 if (type_precision (intype) == POINTER_SIZE)
57 return build1 (CONVERT_EXPR, type, expr);
58 expr = convert (type_for_size (POINTER_SIZE, 0), expr);
59 /* Modes may be different but sizes should be the same. */
60 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
61 != GET_MODE_SIZE (TYPE_MODE (type)))
62 /* There is supposed to be some integral type
63 that is the same width as a pointer. */
64 abort ();
65 return convert_to_pointer (type, expr);
66 }
67
68 error ("cannot convert to a pointer type");
69
70 return null_pointer_node;
71}
72
73/* Convert EXPR to some floating-point type TYPE.
74
75 EXPR must be float, integer, or enumeral;
76 in other cases error is called. */
77
78tree
79convert_to_real (type, expr)
80 tree type, expr;
81{
82 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
83
84 if (form == REAL_TYPE)
85 return build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
86 type, expr);
87
88 if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
89 return build1 (FLOAT_EXPR, type, expr);
90
91 if (form == COMPLEX_TYPE)
92 return convert (type, fold (build1 (REALPART_EXPR,
93 TREE_TYPE (TREE_TYPE (expr)), expr)));
94
95 if (form == POINTER_TYPE)
96 error ("pointer value used where a floating point value was expected");
97 else
98 error ("aggregate value used where a float was expected");
99
100 {
101 register tree tem = make_node (REAL_CST);
102 TREE_TYPE (tem) = type;
103 TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0", TYPE_MODE (type));
104 return tem;
105 }
106}
107
108/* Convert EXPR to some integer (or enum) type TYPE.
109
110 EXPR must be pointer, integer, discrete (enum, char, or bool), or float;
111 in other cases error is called.
112
113 The result of this is always supposed to be a newly created tree node
114 not in use in any existing structure. */
115
116tree
117convert_to_integer (type, expr)
118 tree type, expr;
119{
120 register tree intype = TREE_TYPE (expr);
121 register enum tree_code form = TREE_CODE (intype);
122
123 if (form == POINTER_TYPE)
124 {
125 if (integer_zerop (expr))
126 expr = integer_zero_node;
127 else
128 expr = fold (build1 (CONVERT_EXPR,
129 type_for_size (POINTER_SIZE, 0), expr));
130 intype = TREE_TYPE (expr);
131 form = TREE_CODE (intype);
132 if (intype == type)
133 return expr;
134 }
135
136 if (form == INTEGER_TYPE || form == ENUMERAL_TYPE
137 || form == BOOLEAN_TYPE || form == CHAR_TYPE)
138 {
139 register unsigned outprec = TYPE_PRECISION (type);
140 register unsigned inprec = TYPE_PRECISION (intype);
141 register enum tree_code ex_form = TREE_CODE (expr);
142
143 /* If we are widening the type, put in an explicit conversion.
144 Similarly if we are not changing the width. However, if this is
145 a logical operation that just returns 0 or 1, we can change the
146 type of the expression (see below). */
147
148 if (TREE_CODE_CLASS (ex_form) == '<'
149 || ex_form == TRUTH_AND_EXPR || ex_form == TRUTH_ANDIF_EXPR
150 || ex_form == TRUTH_OR_EXPR || ex_form == TRUTH_ORIF_EXPR
151 || ex_form == TRUTH_XOR_EXPR || ex_form == TRUTH_NOT_EXPR)
152 {
153 TREE_TYPE (expr) = type;
154 return expr;
155 }
156 else if (outprec >= inprec)
157 return build1 (NOP_EXPR, type, expr);
158
159/* Here detect when we can distribute the truncation down past some arithmetic.
160 For example, if adding two longs and converting to an int,
161 we can equally well convert both to ints and then add.
162 For the operations handled here, such truncation distribution
163 is always safe.
164 It is desirable in these cases:
165 1) when truncating down to full-word from a larger size
166 2) when truncating takes no work.
167 3) when at least one operand of the arithmetic has been extended
168 (as by C's default conversions). In this case we need two conversions
169 if we do the arithmetic as already requested, so we might as well
170 truncate both and then combine. Perhaps that way we need only one.
171
172 Note that in general we cannot do the arithmetic in a type
173 shorter than the desired result of conversion, even if the operands
174 are both extended from a shorter type, because they might overflow
175 if combined in that type. The exceptions to this--the times when
176 two narrow values can be combined in their narrow type even to
177 make a wider result--are handled by "shorten" in build_binary_op. */
178
179 switch (ex_form)
180 {
181 case RSHIFT_EXPR:
182 /* We can pass truncation down through right shifting
183 when the shift count is a nonpositive constant. */
184 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
185 && tree_int_cst_lt (TREE_OPERAND (expr, 1), integer_one_node))
186 goto trunc1;
187 break;
188
189 case LSHIFT_EXPR:
190 /* We can pass truncation down through left shifting
191 when the shift count is a nonnegative constant. */
192 if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
193 && ! tree_int_cst_lt (TREE_OPERAND (expr, 1), integer_zero_node)
194 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
195 {
196 /* If shift count is less than the width of the truncated type,
197 really shift. */
198 if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
199 /* In this case, shifting is like multiplication. */
200 goto trunc1;
201 else
202 {
203 /* If it is >= that width, result is zero.
204 Handling this with trunc1 would give the wrong result:
205 (int) ((long long) a << 32) is well defined (as 0)
206 but (int) a << 32 is undefined and would get a
207 warning. */
208
209 tree t = convert_to_integer (type, integer_zero_node);
210
211 /* If the original expression had side-effects, we must
212 preserve it. */
213 if (TREE_SIDE_EFFECTS (expr))
214 return build (COMPOUND_EXPR, type, expr, t);
215 else
216 return t;
217 }
218 }
219 break;
220
221 case MAX_EXPR:
222 case MIN_EXPR:
223 case MULT_EXPR:
224 {
225 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
226 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
227
228 /* Don't distribute unless the output precision is at least as big
229 as the actual inputs. Otherwise, the comparison of the
230 truncated values will be wrong. */
231 if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
232 && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
233 /* If signedness of arg0 and arg1 don't match,
234 we can't necessarily find a type to compare them in. */
235 && (TREE_UNSIGNED (TREE_TYPE (arg0))
236 == TREE_UNSIGNED (TREE_TYPE (arg1))))
237 goto trunc1;
238 break;
239 }
240
241 case PLUS_EXPR:
242 case MINUS_EXPR:
243 case BIT_AND_EXPR:
244 case BIT_IOR_EXPR:
245 case BIT_XOR_EXPR:
246 case BIT_ANDTC_EXPR:
247 trunc1:
248 {
249 tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
250 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
251
252 if (outprec >= BITS_PER_WORD
253 || TRULY_NOOP_TRUNCATION (outprec, inprec)
254 || inprec > TYPE_PRECISION (TREE_TYPE (arg0))
255 || inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
256 {
257 /* Do the arithmetic in type TYPEX,
258 then convert result to TYPE. */
259 register tree typex = type;
260
261 /* Can't do arithmetic in enumeral types
262 so use an integer type that will hold the values. */
263 if (TREE_CODE (typex) == ENUMERAL_TYPE)
264 typex = type_for_size (TYPE_PRECISION (typex),
265 TREE_UNSIGNED (typex));
266
267 /* But now perhaps TYPEX is as wide as INPREC.
268 In that case, do nothing special here.
269 (Otherwise would recurse infinitely in convert. */
270 if (TYPE_PRECISION (typex) != inprec)
271 {
272 /* Don't do unsigned arithmetic where signed was wanted,
273 or vice versa.
274 Exception: if either of the original operands were
275 unsigned then can safely do the work as unsigned.
276 And we may need to do it as unsigned
277 if we truncate to the original size. */
278 typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
279 || TREE_UNSIGNED (TREE_TYPE (arg0))
280 || TREE_UNSIGNED (TREE_TYPE (arg1)))
281 ? unsigned_type (typex) : signed_type (typex));
282 return convert (type,
283 fold (build (ex_form, typex,
284 convert (typex, arg0),
285 convert (typex, arg1),
286 0)));
287 }
288 }
289 }
290 break;
291
292 case NEGATE_EXPR:
293 case BIT_NOT_EXPR:
294 case ABS_EXPR:
295 {
296 register tree typex = type;
297
298 /* Can't do arithmetic in enumeral types
299 so use an integer type that will hold the values. */
300 if (TREE_CODE (typex) == ENUMERAL_TYPE)
301 typex = type_for_size (TYPE_PRECISION (typex),
302 TREE_UNSIGNED (typex));
303
304 /* But now perhaps TYPEX is as wide as INPREC.
305 In that case, do nothing special here.
306 (Otherwise would recurse infinitely in convert. */
307 if (TYPE_PRECISION (typex) != inprec)
308 {
309 /* Don't do unsigned arithmetic where signed was wanted,
310 or vice versa. */
311 typex = (TREE_UNSIGNED (TREE_TYPE (expr))
312 ? unsigned_type (typex) : signed_type (typex));
313 return convert (type,
314 fold (build1 (ex_form, typex,
315 convert (typex,
316 TREE_OPERAND (expr, 0)))));
317 }
318 }
319
320 case NOP_EXPR:
321 /* If truncating after truncating, might as well do all at once.
322 If truncating after extending, we may get rid of wasted work. */
323 return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
324
325 case COND_EXPR:
326 /* Can treat the two alternative values like the operands
327 of an arithmetic expression. */
328 {
329 tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
330 tree arg2 = get_unwidened (TREE_OPERAND (expr, 2), type);
331
332 if (outprec >= BITS_PER_WORD
333 || TRULY_NOOP_TRUNCATION (outprec, inprec)
334 || inprec > TYPE_PRECISION (TREE_TYPE (arg1))
335 || inprec > TYPE_PRECISION (TREE_TYPE (arg2)))
336 {
337 /* Do the arithmetic in type TYPEX,
338 then convert result to TYPE. */
339 register tree typex = type;
340
341 /* Can't do arithmetic in enumeral types
342 so use an integer type that will hold the values. */
343 if (TREE_CODE (typex) == ENUMERAL_TYPE)
344 typex = type_for_size (TYPE_PRECISION (typex),
345 TREE_UNSIGNED (typex));
346
347 /* But now perhaps TYPEX is as wide as INPREC.
348 In that case, do nothing special here.
349 (Otherwise would recurse infinitely in convert. */
350 if (TYPE_PRECISION (typex) != inprec)
351 {
352 /* Don't do unsigned arithmetic where signed was wanted,
353 or vice versa. */
354 typex = (TREE_UNSIGNED (TREE_TYPE (expr))
355 ? unsigned_type (typex) : signed_type (typex));
356 return convert (type,
357 fold (build (COND_EXPR, typex,
358 TREE_OPERAND (expr, 0),
359 convert (typex, arg1),
360 convert (typex, arg2))));
361 }
362 else
363 /* It is sometimes worthwhile
364 to push the narrowing down through the conditional. */
365 return fold (build (COND_EXPR, type,
366 TREE_OPERAND (expr, 0),
367 convert (type, TREE_OPERAND (expr, 1)),
368 convert (type, TREE_OPERAND (expr, 2))));
369 }
370 }
371
372 }
373
374 return build1 (NOP_EXPR, type, expr);
375 }
376
377 if (form == REAL_TYPE)
378 return build1 (FIX_TRUNC_EXPR, type, expr);
379
380 if (form == COMPLEX_TYPE)
381 return convert (type, fold (build1 (REALPART_EXPR,
382 TREE_TYPE (TREE_TYPE (expr)), expr)));
383
384 error ("aggregate value used where an integer was expected");
385
386 {
387 register tree tem = build_int_2 (0, 0);
388 TREE_TYPE (tem) = type;
389 return tem;
390 }
391}
392
393/* Convert EXPR to the complex type TYPE in the usual ways. */
394
395tree
396convert_to_complex (type, expr)
397 tree type, expr;
398{
399 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
400 tree subtype = TREE_TYPE (type);
401
402 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
403 {
404 expr = convert (subtype, expr);
405 return build (COMPLEX_EXPR, type, expr,
406 convert (subtype, integer_zero_node));
407 }
408
409 if (form == COMPLEX_TYPE)
410 {
411 tree elt_type = TREE_TYPE (TREE_TYPE (expr));
412 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
413 return expr;
414 else if (TREE_CODE (expr) == COMPLEX_EXPR)
415 return fold (build (COMPLEX_EXPR,
416 type,
417 convert (subtype, TREE_OPERAND (expr, 0)),
418 convert (subtype, TREE_OPERAND (expr, 1))));
419 else
420 {
421 expr = save_expr (expr);
422 return fold (build (COMPLEX_EXPR,
423 type,
424 convert (subtype,
425 fold (build1 (REALPART_EXPR,
426 TREE_TYPE (TREE_TYPE (expr)),
427 expr))),
428 convert (subtype,
429 fold (build1 (IMAGPART_EXPR,
430 TREE_TYPE (TREE_TYPE (expr)),
431 expr)))));
432 }
433 }
434
435 if (form == POINTER_TYPE)
436 error ("pointer value used where a complex was expected");
437 else
438 error ("aggregate value used where a complex was expected");
439
440 return build (COMPLEX_EXPR, type,
441 convert (subtype, integer_zero_node),
442 convert (subtype, integer_zero_node));
443}