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