|
|
1.1 ! root 1: /* Utility routines for data type conversion for GNU C. ! 2: Copyright (C) 1987, 1988, 1991, 1992 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, 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: ! 34: tree ! 35: convert_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: ! 78: tree ! 79: convert_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: ! 116: tree ! 117: convert_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: /* This is not correct for ABS_EXPR, ! 295: since we must test the sign before truncation. */ ! 296: { ! 297: register tree typex = type; ! 298: ! 299: /* Can't do arithmetic in enumeral types ! 300: so use an integer type that will hold the values. */ ! 301: if (TREE_CODE (typex) == ENUMERAL_TYPE) ! 302: typex = type_for_size (TYPE_PRECISION (typex), ! 303: TREE_UNSIGNED (typex)); ! 304: ! 305: /* But now perhaps TYPEX is as wide as INPREC. ! 306: In that case, do nothing special here. ! 307: (Otherwise would recurse infinitely in convert. */ ! 308: if (TYPE_PRECISION (typex) != inprec) ! 309: { ! 310: /* Don't do unsigned arithmetic where signed was wanted, ! 311: or vice versa. */ ! 312: typex = (TREE_UNSIGNED (TREE_TYPE (expr)) ! 313: ? unsigned_type (typex) : signed_type (typex)); ! 314: return convert (type, ! 315: fold (build1 (ex_form, typex, ! 316: convert (typex, ! 317: TREE_OPERAND (expr, 0))))); ! 318: } ! 319: } ! 320: ! 321: case NOP_EXPR: ! 322: /* If truncating after truncating, might as well do all at once. ! 323: If truncating after extending, we may get rid of wasted work. */ ! 324: return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type)); ! 325: ! 326: case COND_EXPR: ! 327: /* Can treat the two alternative values like the operands ! 328: of an arithmetic expression. */ ! 329: { ! 330: tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); ! 331: tree arg2 = get_unwidened (TREE_OPERAND (expr, 2), type); ! 332: ! 333: if (outprec >= BITS_PER_WORD ! 334: || TRULY_NOOP_TRUNCATION (outprec, inprec) ! 335: || inprec > TYPE_PRECISION (TREE_TYPE (arg1)) ! 336: || inprec > TYPE_PRECISION (TREE_TYPE (arg2))) ! 337: { ! 338: /* Do the arithmetic in type TYPEX, ! 339: then convert result to TYPE. */ ! 340: register tree typex = type; ! 341: ! 342: /* Can't do arithmetic in enumeral types ! 343: so use an integer type that will hold the values. */ ! 344: if (TREE_CODE (typex) == ENUMERAL_TYPE) ! 345: typex = type_for_size (TYPE_PRECISION (typex), ! 346: TREE_UNSIGNED (typex)); ! 347: ! 348: /* But now perhaps TYPEX is as wide as INPREC. ! 349: In that case, do nothing special here. ! 350: (Otherwise would recurse infinitely in convert. */ ! 351: if (TYPE_PRECISION (typex) != inprec) ! 352: { ! 353: /* Don't do unsigned arithmetic where signed was wanted, ! 354: or vice versa. */ ! 355: typex = (TREE_UNSIGNED (TREE_TYPE (expr)) ! 356: ? unsigned_type (typex) : signed_type (typex)); ! 357: return convert (type, ! 358: fold (build (COND_EXPR, typex, ! 359: TREE_OPERAND (expr, 0), ! 360: convert (typex, arg1), ! 361: convert (typex, arg2)))); ! 362: } ! 363: else ! 364: /* It is sometimes worthwhile ! 365: to push the narrowing down through the conditional. */ ! 366: return fold (build (COND_EXPR, type, ! 367: TREE_OPERAND (expr, 0), ! 368: convert (type, TREE_OPERAND (expr, 1)), ! 369: convert (type, TREE_OPERAND (expr, 2)))); ! 370: } ! 371: } ! 372: ! 373: } ! 374: ! 375: return build1 (NOP_EXPR, type, expr); ! 376: } ! 377: ! 378: if (form == REAL_TYPE) ! 379: return build1 (FIX_TRUNC_EXPR, type, expr); ! 380: ! 381: if (form == COMPLEX_TYPE) ! 382: return convert (type, fold (build1 (REALPART_EXPR, ! 383: TREE_TYPE (TREE_TYPE (expr)), expr))); ! 384: ! 385: error ("aggregate value used where an integer was expected"); ! 386: ! 387: { ! 388: register tree tem = build_int_2 (0, 0); ! 389: TREE_TYPE (tem) = type; ! 390: return tem; ! 391: } ! 392: } ! 393: ! 394: /* Convert EXPR to the complex type TYPE in the usual ways. */ ! 395: ! 396: tree ! 397: convert_to_complex (type, expr) ! 398: tree type, expr; ! 399: { ! 400: register enum tree_code form = TREE_CODE (TREE_TYPE (expr)); ! 401: tree subtype = TREE_TYPE (type); ! 402: ! 403: if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE) ! 404: { ! 405: expr = convert (subtype, expr); ! 406: return build (COMPLEX_EXPR, type, expr, ! 407: convert (subtype, integer_zero_node)); ! 408: } ! 409: ! 410: if (form == COMPLEX_TYPE) ! 411: { ! 412: tree elt_type = TREE_TYPE (TREE_TYPE (expr)); ! 413: if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype)) ! 414: return expr; ! 415: else if (TREE_CODE (expr) == COMPLEX_EXPR) ! 416: return fold (build (COMPLEX_EXPR, ! 417: type, ! 418: convert (subtype, TREE_OPERAND (expr, 0)), ! 419: convert (subtype, TREE_OPERAND (expr, 1)))); ! 420: else ! 421: { ! 422: expr = save_expr (expr); ! 423: return fold (build (COMPLEX_EXPR, ! 424: type, ! 425: convert (subtype, ! 426: fold (build1 (REALPART_EXPR, ! 427: TREE_TYPE (TREE_TYPE (expr)), ! 428: expr))), ! 429: convert (subtype, ! 430: fold (build1 (IMAGPART_EXPR, ! 431: TREE_TYPE (TREE_TYPE (expr)), ! 432: expr))))); ! 433: } ! 434: } ! 435: ! 436: if (form == POINTER_TYPE) ! 437: error ("pointer value used where a complex was expected"); ! 438: else ! 439: error ("aggregate value used where a complex was expected"); ! 440: ! 441: return build (COMPLEX_EXPR, type, ! 442: convert (subtype, integer_zero_node), ! 443: convert (subtype, integer_zero_node)); ! 444: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.