|
|
1.1 ! root 1: /* Language-indepednent node constructors for parse phase of GNU compiler. ! 2: Copyright (C) 1987 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU CC General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU CC, but only under the conditions described in the ! 15: GNU CC General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU CC so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: ! 22: /* This file contains the low level primitives for operating on tree nodes, ! 23: including allocation, list operations, interning of identifiers, ! 24: construction of data type nodes and statement nodes, ! 25: and construction of type conversion nodes. It also contains ! 26: tables index by tree code that describe how to take apart ! 27: nodes of that code. ! 28: ! 29: It is intended to be language-independent, but occasionally ! 30: calls language-dependent routines defined (for C) in typecheck.c. ! 31: ! 32: The low-level allocation routines oballoc and permalloc ! 33: are used also for allocating many other kinds of objects ! 34: by all passes of the compiler. */ ! 35: ! 36: #include "config.h" ! 37: #include <stdio.h> ! 38: #include "tree.h" ! 39: #include "obstack.h" ! 40: ! 41: #define obstack_chunk_alloc xmalloc ! 42: #define obstack_chunk_free free ! 43: ! 44: extern int xmalloc (); ! 45: extern void free (); ! 46: ! 47: /* Tree nodes of permanent duration are allocated in this obstack. ! 48: They are the identifier nodes, and everything outside of ! 49: the bodies and parameters of function definitions. */ ! 50: ! 51: struct obstack permanent_obstack; ! 52: ! 53: /* The contents of the current function definition are allocated ! 54: in this obstack, and all are freed at the end of the function. */ ! 55: ! 56: struct obstack temporary_obstack; ! 57: ! 58: /* This points at either permanent_obstack or temporary_obstack. */ ! 59: ! 60: struct obstack *current_obstack; ! 61: ! 62: /* Table indexed by tree code giving a string containing a character ! 63: classifying the tree code. Possibilities are ! 64: t, d, s, c, r and e. See tree.def for details. */ ! 65: ! 66: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, ! 67: ! 68: char *tree_code_type[] = { ! 69: #include "tree.def" ! 70: }; ! 71: #undef DEFTREECODE ! 72: ! 73: /* Table indexed by tree code giving number of expression ! 74: operands beyond the fixed part of the node structure. ! 75: Not used for types or decls. */ ! 76: ! 77: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, ! 78: ! 79: int tree_code_length[] = { ! 80: #include "tree.def" ! 81: }; ! 82: #undef DEFTREECODE ! 83: ! 84: /* Counter for assigning unique ids to all tree nodes. */ ! 85: ! 86: int tree_node_counter = 0; ! 87: ! 88: /* Hash table for uniquizing IDENTIFIER_NODEs by name. */ ! 89: ! 90: #define MAX_HASH_TABLE 1008 ! 91: static tree hash_table[MAX_HASH_TABLE]; /* id hash buckets */ ! 92: ! 93: /* Init data for node creation, at the beginning of compilation. */ ! 94: ! 95: void ! 96: init_tree () ! 97: { ! 98: obstack_init (&permanent_obstack); ! 99: current_obstack = &permanent_obstack; ! 100: tree_node_counter = 1; ! 101: bzero (hash_table, sizeof hash_table); ! 102: } ! 103: ! 104: /* Start allocating on the temporary (per function) obstack. ! 105: This is done in start_function before parsing the function body. */ ! 106: ! 107: temporary_allocation () ! 108: { ! 109: /* Set up the obstack: */ ! 110: obstack_init (&temporary_obstack); ! 111: ! 112: current_obstack = &temporary_obstack; ! 113: } ! 114: ! 115: /* Go back to allocating on the permanent obstack ! 116: and free everything in the temporary obstack. ! 117: This is done in finish_function after fully compiling a function. */ ! 118: ! 119: permanent_allocation () ! 120: { ! 121: /* Free up previous temporary obstack data */ ! 122: obstack_free (&temporary_obstack, NULL); ! 123: ! 124: current_obstack = &permanent_obstack; ! 125: } ! 126: ! 127: /* Allocate SIZE bytes in the current obstack ! 128: and return a pointer to them. ! 129: In practice the current obstack is always the temporary one. */ ! 130: ! 131: char * ! 132: oballoc (size) ! 133: int size; ! 134: { ! 135: return (char *) obstack_alloc (current_obstack, size); ! 136: } ! 137: ! 138: /* Free the object PTR in the current obstack ! 139: as well as everything allocated since PTR. ! 140: In practice the current obstack is always the temporary one. */ ! 141: ! 142: void ! 143: obfree (ptr) ! 144: char *ptr; ! 145: { ! 146: obstack_free (current_obstack, ptr); ! 147: } ! 148: ! 149: /* Allocate SIZE bytes in the permanent obstack ! 150: and return a pointer to them. */ ! 151: ! 152: char * ! 153: permalloc (size) ! 154: long size; ! 155: { ! 156: char *object; ! 157: ! 158: return (char *) obstack_alloc (&permanent_obstack, size); ! 159: } ! 160: ! 161: /* Return a newly allocated node of code CODE. ! 162: Initialize the node's unique id and its TREE_PERMANENT flag. ! 163: For decl and type nodes, some other fields are initialized. ! 164: The rest of the node is initialized to zero. ! 165: ! 166: Achoo! I got a code in the node. */ ! 167: ! 168: tree ! 169: make_node (code) ! 170: enum tree_code code; ! 171: { ! 172: register tree t; ! 173: register int type = *tree_code_type[(int) code]; ! 174: register int length; ! 175: register struct obstack *obstack; ! 176: register int i; ! 177: ! 178: switch (type) ! 179: { ! 180: case 'd': /* A decl node */ ! 181: length = sizeof (struct tree_decl); ! 182: break; ! 183: ! 184: case 't': /* a type node */ ! 185: length = sizeof (struct tree_type); ! 186: break; ! 187: ! 188: case 's': /* a stmt node */ ! 189: length = sizeof (struct tree_shared) ! 190: + 2 * sizeof (int) ! 191: + tree_code_length[(int) code] * sizeof (char *); ! 192: break; ! 193: ! 194: default: /* an expression or constant. */ ! 195: length = sizeof (struct tree_shared) ! 196: + tree_code_length[(int) code] * sizeof (char *); ! 197: } ! 198: ! 199: obstack = (code != IDENTIFIER_NODE) ? current_obstack : &permanent_obstack; ! 200: ! 201: t = (tree) obstack_alloc (obstack, length); ! 202: ! 203: TREE_UID (t) = tree_node_counter++; ! 204: TREE_TYPE (t) = 0; ! 205: TREE_CHAIN (t) = 0; ! 206: for (i = (length / sizeof (int)) - 1; ! 207: i >= sizeof (struct tree_shared) / sizeof (int) - 1; ! 208: i--) ! 209: ((int *) t)[i] = 0; ! 210: ! 211: TREE_SET_CODE (t, code); ! 212: if (obstack == &permanent_obstack) ! 213: TREE_PERMANENT (t) = 1; ! 214: ! 215: if (type == 'd') ! 216: { ! 217: extern int lineno; ! 218: ! 219: DECL_ALIGN (t) = 1; ! 220: DECL_SIZE_UNIT (t) = 1; ! 221: DECL_VOFFSET_UNIT (t) = 1; ! 222: DECL_SOURCE_LINE (t) = lineno; ! 223: DECL_SOURCE_FILE (t) = input_filename; ! 224: } ! 225: ! 226: if (type == 't') ! 227: { ! 228: TYPE_ALIGN (t) = 1; ! 229: TYPE_SIZE_UNIT (t) = 1; ! 230: TYPE_SEP_UNIT (t) = 1; ! 231: TYPE_MAIN_VARIANT (t) = t; ! 232: } ! 233: ! 234: if (type == 'c') ! 235: { ! 236: TREE_LITERAL (t) = 1; ! 237: } ! 238: ! 239: return t; ! 240: } ! 241: ! 242: /* Return a new node with the same contents as NODE ! 243: except that its TREE_CHAIN is zero and it has a fresh uid. */ ! 244: ! 245: tree ! 246: copy_node (node) ! 247: tree node; ! 248: { ! 249: register tree t; ! 250: register enum tree_code code = TREE_CODE (node); ! 251: register int length; ! 252: register int i; ! 253: ! 254: switch (*tree_code_type[(int) code]) ! 255: { ! 256: case 'd': /* A decl node */ ! 257: length = sizeof (struct tree_decl); ! 258: break; ! 259: ! 260: case 't': /* a type node */ ! 261: length = sizeof (struct tree_type); ! 262: break; ! 263: ! 264: case 's': ! 265: length = sizeof (struct tree_shared) ! 266: + 2 * sizeof (int) ! 267: + tree_code_length[(int) code] * sizeof (char *); ! 268: break; ! 269: ! 270: default: /* a statement, expression or constant. */ ! 271: length = sizeof (struct tree_shared) ! 272: + tree_code_length[(int) code] * sizeof (char *); ! 273: } ! 274: ! 275: t = (tree) obstack_alloc (current_obstack, length); ! 276: ! 277: for (i = (length / sizeof (int)) - 1; ! 278: i >= 0; ! 279: i--) ! 280: ((int *) t)[i] = ((int *) node)[i]; ! 281: ! 282: TREE_UID (t) = tree_node_counter++; ! 283: TREE_CHAIN (t) = 0; ! 284: ! 285: TREE_PERMANENT (t) = (current_obstack == &permanent_obstack); ! 286: ! 287: return t; ! 288: } ! 289: ! 290: #define HASHBITS 30 ! 291: ! 292: /* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string). ! 293: If an identifier with that name has previously been referred to, ! 294: the same node is returned this time. */ ! 295: ! 296: tree ! 297: get_identifier (text) ! 298: register char *text; ! 299: { ! 300: register int hi; ! 301: register int i; ! 302: register tree idp; ! 303: register int len; ! 304: ! 305: /* Compute length of text in len. */ ! 306: for (len = 0; text[len]; len++); ! 307: ! 308: /* Compute hash code */ ! 309: hi = len; ! 310: for (i = 0; i < len; i++) ! 311: hi = ((hi * 613) + (unsigned)(text[i])); ! 312: ! 313: hi &= (1 << HASHBITS) - 1; ! 314: hi %= MAX_HASH_TABLE; ! 315: ! 316: /* Search table for identifier */ ! 317: for (idp = hash_table[hi]; idp!=NULL; idp = TREE_CHAIN (idp)) ! 318: if (IDENTIFIER_LENGTH (idp) == len && ! 319: !strcmp (IDENTIFIER_POINTER (idp), text)) ! 320: return idp; /* <-- return if found */ ! 321: ! 322: /* Not found, create one, add to chain */ ! 323: idp = make_node (IDENTIFIER_NODE); ! 324: IDENTIFIER_LENGTH (idp) = len; ! 325: ! 326: IDENTIFIER_POINTER (idp) = obstack_copy0 (&permanent_obstack, text, len); ! 327: ! 328: TREE_CHAIN (idp) = hash_table[hi]; ! 329: hash_table[hi] = idp; ! 330: return idp; /* <-- return if created */ ! 331: } ! 332: ! 333: /* Return a newly constructed INTEGER_CST node whose constant value ! 334: is specified by the two ints LOW and HI. ! 335: The TREE_TYPE is not initialized. */ ! 336: ! 337: tree ! 338: build_int_2 (low, hi) ! 339: int low, hi; ! 340: { ! 341: register tree t = make_node (INTEGER_CST); ! 342: TREE_INT_CST_LOW (t) = low; ! 343: TREE_INT_CST_HIGH (t) = hi; ! 344: TREE_TYPE (t) = integer_type_node; ! 345: return t; ! 346: } ! 347: ! 348: /* Return a REAL_CST node containing a value atoi (STR) * 10**EX. ! 349: The TREE_TYPE is not initialized. */ ! 350: ! 351: tree ! 352: build_real_from_string (str, ex) ! 353: char *str; ! 354: int ex; ! 355: { ! 356: double r; ! 357: int i; ! 358: tree t; ! 359: ! 360: t = make_node (REAL_CST); ! 361: /* ??? This conversion code is not good. ! 362: Use the new atof once it is done. */ ! 363: sscanf (str, "%lf", &r); ! 364: if (0 < ex) ! 365: for (i = 0; i < ex; i++) ! 366: r = r * 10; ! 367: else ! 368: for (i = 0; i < -ex; i++) ! 369: r = r / 10; ! 370: ! 371: TREE_REAL_CST (t) = r; ! 372: return (t); ! 373: } ! 374: ! 375: /* Return a newly constructed REAL_CST node whose value is D. ! 376: The TREE_TYPE is not initialized. */ ! 377: ! 378: tree ! 379: build_real (d) ! 380: double d; ! 381: { ! 382: tree v; ! 383: ! 384: v = make_node (REAL_CST); ! 385: TREE_REAL_CST (v) = d; ! 386: return v; ! 387: } ! 388: ! 389: /* Return a newly constructed REAL_CST node whose value ! 390: is the integer value of the INTEGER_CST node I. ! 391: The TREE_TYPE is not initialized. */ ! 392: ! 393: tree ! 394: build_real_from_int_cst (i) ! 395: tree i; ! 396: { ! 397: tree v; ! 398: ! 399: v = make_node (REAL_CST); ! 400: TREE_REAL_CST (v) ! 401: = (double) TREE_INT_CST_LOW (i) ! 402: + ((double) (1 << (HOST_BITS_PER_INT / 2)) ! 403: * (double) (1 << (HOST_BITS_PER_INT / 2)) ! 404: * (double) TREE_INT_CST_HIGH (i)); ! 405: return v; ! 406: } ! 407: ! 408: /* Return a newly constructed STRING_CST node whose value is ! 409: the LEN characters at STR. ! 410: The TREE_TYPE is not initialized. */ ! 411: ! 412: tree ! 413: build_string (len, str) ! 414: int len; ! 415: char *str; ! 416: { ! 417: register tree s = make_node (STRING_CST); ! 418: TREE_STRING_LENGTH (s) = len; ! 419: TREE_STRING_POINTER (s) = obstack_copy0 (current_obstack, str, len); ! 420: return s; ! 421: } ! 422: ! 423: /* Return a newly constructed COMPLEX_CST node whose value is ! 424: specified by the real and imaginary parts REAL and IMAG. ! 425: Both REAL and IMAG should be constant nodes. ! 426: The TREE_TYPE is not initialized. */ ! 427: ! 428: tree ! 429: build_complex (real, imag) ! 430: tree real, imag; ! 431: { ! 432: register tree t = make_node (COMPLEX_CST); ! 433: TREE_REALPART (t) = real; ! 434: TREE_IMAGPART (t) = imag; ! 435: return t; ! 436: } ! 437: ! 438: /* Return nonzero if the type FTYPE is unsigned (all possible values >= 0). ! 439: Nonscalar types are considered unsigned; real types considered signed. */ ! 440: ! 441: int ! 442: type_unsigned_p (ftype) ! 443: tree ftype; ! 444: { ! 445: register tree type = ftype; ! 446: register tree t; ! 447: ! 448: if (TREE_CODE (ftype) == POINTER_TYPE) ! 449: return 1; ! 450: if (TREE_CODE (ftype) == REAL_TYPE) ! 451: return 0; ! 452: if (TREE_CODE (ftype) != INTEGER_TYPE ! 453: && TREE_CODE (ftype) != ENUMERAL_TYPE) ! 454: return 1; ! 455: ! 456: while (1) ! 457: { ! 458: t = TYPE_MIN_VALUE (type); ! 459: if (TREE_CODE (t) == INTEGER_CST) ! 460: return TREE_INT_CST_HIGH (t) >= 0; ! 461: ! 462: type = TREE_TYPE (type); ! 463: if (type == 0) ! 464: return 0; ! 465: } ! 466: } ! 467: ! 468: /* Return 1 if EXPR is the integer constant zero. */ ! 469: ! 470: int ! 471: integer_zerop (expr) ! 472: tree expr; ! 473: { ! 474: return TREE_CODE (expr) == INTEGER_CST ! 475: && TREE_INT_CST_LOW (expr) == 0 ! 476: && TREE_INT_CST_HIGH (expr) == 0; ! 477: } ! 478: ! 479: /* Return 1 if EXPR is the integer constant one. */ ! 480: ! 481: int ! 482: integer_onep (expr) ! 483: tree expr; ! 484: { ! 485: return TREE_CODE (expr) == INTEGER_CST ! 486: && TREE_INT_CST_LOW (expr) == 1 ! 487: && TREE_INT_CST_HIGH (expr) == 0; ! 488: } ! 489: ! 490: /* Return 1 if EXPR is an integer containing all 1's ! 491: in as much precision as it contains. */ ! 492: ! 493: int ! 494: integer_all_onesp (expr) ! 495: tree expr; ! 496: { ! 497: register int prec; ! 498: register int uns; ! 499: ! 500: if (TREE_CODE (expr) != INTEGER_CST) ! 501: return 0; ! 502: ! 503: uns = type_unsigned_p (TREE_TYPE (expr)); ! 504: if (!uns) ! 505: return TREE_INT_CST_LOW (expr) == -1 && TREE_INT_CST_HIGH (expr) == -1; ! 506: ! 507: prec = TYPE_PRECISION (TREE_TYPE (expr)); ! 508: if (prec >= HOST_BITS_PER_INT) ! 509: return TREE_INT_CST_LOW (expr) == -1 ! 510: && TREE_INT_CST_HIGH (expr) == (1 << (prec - HOST_BITS_PER_INT)) - 1; ! 511: else ! 512: return TREE_INT_CST_LOW (expr) == (1 << prec) - 1; ! 513: } ! 514: ! 515: /* Return the length of a chain of nodes chained through TREE_CHAIN. ! 516: We expect a null pointer to mark the end of the chain. ! 517: This is the Lisp primitive `length'. */ ! 518: ! 519: int ! 520: list_length (t) ! 521: tree t; ! 522: { ! 523: register tree tail; ! 524: register int len = 0; ! 525: ! 526: for (tail = t; tail; tail = TREE_CHAIN (tail)) ! 527: len++; ! 528: ! 529: return len; ! 530: } ! 531: ! 532: /* Concatenate two chains of nodes (chained through TREE_CHAIN) ! 533: by modifying the last node in chain 1 to point to chain 2. ! 534: This is the Lisp primitive `nconc'. */ ! 535: ! 536: tree ! 537: chainon (op1, op2) ! 538: tree op1, op2; ! 539: { ! 540: tree t; ! 541: ! 542: if (op1) ! 543: { ! 544: for (t = op1; TREE_CHAIN (t); t = TREE_CHAIN (t)) ! 545: if (t == op2) abort (); /* Circularity being created */ ! 546: TREE_CHAIN (t) = op2; ! 547: return op1; ! 548: } ! 549: else return op2; ! 550: } ! 551: ! 552: /* Return a newly created TREE_LIST node whose ! 553: purpose and value fields are PARM and VALUE. */ ! 554: ! 555: tree ! 556: build_tree_list (parm, value) ! 557: tree parm, value; ! 558: { ! 559: register tree t = make_node (TREE_LIST); ! 560: TREE_PURPOSE (t) = parm; ! 561: TREE_VALUE (t) = value; ! 562: return t; ! 563: } ! 564: ! 565: /* Return a newly created TREE_LIST node whose ! 566: purpose and value fields are PARM and VALUE ! 567: and whose TREE_CHAIN is CHAIN. */ ! 568: ! 569: tree ! 570: tree_cons (purpose, value, chain) ! 571: tree purpose, value, chain; ! 572: { ! 573: register tree node = make_node (TREE_LIST); ! 574: TREE_CHAIN (node) = chain; ! 575: TREE_PURPOSE (node) = purpose; ! 576: TREE_VALUE (node) = value; ! 577: return node; ! 578: } ! 579: ! 580: /* Return the last node in a chain of nodes (chained through TREE_CHAIN). */ ! 581: ! 582: tree ! 583: tree_last (chain) ! 584: register tree chain; ! 585: { ! 586: register tree next; ! 587: if (chain) ! 588: while (next = TREE_CHAIN (chain)) ! 589: chain = next; ! 590: return chain; ! 591: } ! 592: ! 593: /* Reverse the order of elements in the chain T, ! 594: and return the new head of the chain (old last element). */ ! 595: ! 596: tree ! 597: nreverse (t) ! 598: tree t; ! 599: { ! 600: register tree prev = 0, decl, next; ! 601: for (decl = t; decl; decl = next) ! 602: { ! 603: next = TREE_CHAIN (decl); ! 604: TREE_CHAIN (decl) = prev; ! 605: prev = decl; ! 606: } ! 607: return prev; ! 608: } ! 609: ! 610: /* Return the size nominally occupied by an object of type TYPE ! 611: when it resides in memory. The value is measured in units of bytes, ! 612: and its data type is that normally used for type sizes ! 613: (which is the first type created by make_signed_type or ! 614: make_unsigned_type). */ ! 615: ! 616: tree ! 617: size_in_bytes (type) ! 618: tree type; ! 619: { ! 620: if (type == error_mark_node) ! 621: return integer_zero_node; ! 622: return convert_units (TYPE_SIZE (type), TYPE_SIZE_UNIT (type), ! 623: BITS_PER_UNIT); ! 624: } ! 625: ! 626: /* Return nonzero if arg is static -- a reference to an object in ! 627: static storage. This is not the same as the C meaning of `static'. */ ! 628: ! 629: int ! 630: staticp (arg) ! 631: tree arg; ! 632: { ! 633: register enum tree_code code = TREE_CODE (arg); ! 634: ! 635: if ((code == VAR_DECL || code == FUNCTION_DECL) ! 636: && (TREE_STATIC (arg) || TREE_EXTERNAL (arg))) ! 637: return 1; ! 638: ! 639: if (code == COMPONENT_REF) ! 640: return staticp (TREE_OPERAND (arg, 0)); ! 641: ! 642: return 0; ! 643: } ! 644: ! 645: /* Verify that an expression, REF, is a reference to data that makes sense ! 646: to modify or take the address of ! 647: (i.e., for processing the argument to unary & or the left arg to =). ! 648: Error if REF is some other kind of expression. ! 649: ! 650: We can safely ignore the difference between "makes sense to modify" ! 651: and "makes sense to take the address of", because attempting to ! 652: take the address of a variable will force it into memory anyway. */ ! 653: ! 654: int ! 655: lvalue_or_else (ref) ! 656: tree ref; ! 657: { ! 658: register enum tree_code code = TREE_CODE (ref); ! 659: ! 660: if (code == COMPONENT_REF) ! 661: return lvalue_or_else (TREE_OPERAND (ref, 0)); ! 662: else if (code == INDIRECT_REF || code == ARRAY_REF || code == VAR_DECL ! 663: || code == FUNCTION_DECL || code == PARM_DECL || code == RESULT_DECL ! 664: || code == ERROR_MARK) ! 665: return 1; ! 666: yyerror ("invalid lvalue (not a reference to data in memory)"); ! 667: return 0; ! 668: } ! 669: ! 670: /* This should be applied to any node which may be used in more than one place, ! 671: but must be evaluated only once. Normally, the code generator would ! 672: reevaluate the node each time; this forces it to compute it once and save ! 673: the result. This is done by encapsulating the node in a SAVE_EXPR. */ ! 674: ! 675: tree ! 676: save_expr (expr) ! 677: tree expr; ! 678: { ! 679: register tree t = fold (expr); ! 680: ! 681: /* If the tree evaluates to a constant, then we don't what to hide that ! 682: fact (i.e. this allows further folding, and direct checks for constants). ! 683: Since it is no problem to reevaluate literals, we just return the ! 684: literal node. */ ! 685: ! 686: if (TREE_LITERAL (t) || TREE_READONLY (t) || TREE_CODE (t) == SAVE_EXPR) ! 687: return t; ! 688: ! 689: t = build2 (SAVE_EXPR, t, NULL); ! 690: TREE_TYPE (t) = TREE_TYPE (expr); ! 691: TREE_VOLATILE (t) = TREE_VOLATILE (expr); ! 692: return t; ! 693: } ! 694: ! 695: /* Stabilize a reference so that we can use it any number of times ! 696: without causing its operands to be evaluated more than once. ! 697: Returns the stabilized reference. */ ! 698: ! 699: tree ! 700: stabilize_reference (ref) ! 701: tree ref; ! 702: { ! 703: register tree result; ! 704: register enum tree_code code = TREE_CODE (ref); ! 705: ! 706: if (code == INDIRECT_REF) ! 707: { ! 708: result = build1 (INDIRECT_REF, save_expr (TREE_OPERAND (ref, 0))); ! 709: } ! 710: else if (code == COMPONENT_REF) ! 711: { ! 712: result = build2 (COMPONENT_REF, ! 713: stabilize_reference (TREE_OPERAND (ref, 0)), ! 714: TREE_OPERAND (ref, 1)); ! 715: } ! 716: else if (code == ARRAY_REF) ! 717: { ! 718: result = build2 (ARRAY_REF, save_expr (TREE_OPERAND (ref, 0)), ! 719: save_expr (TREE_OPERAND (ref, 1))); ! 720: } ! 721: else if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL) ! 722: { ! 723: result = ref; ! 724: } ! 725: else ! 726: { ! 727: if (code != ERROR_MARK) ! 728: yyerror ("invalid lvalue (not a reference to data in memory)"); ! 729: return error_mark_node; ! 730: } ! 731: ! 732: TREE_TYPE (result) = TREE_TYPE (ref); ! 733: TREE_VOLATILE (result) = TREE_VOLATILE (ref); ! 734: ! 735: return result; ! 736: } ! 737: ! 738: /* Low-level constructors for expressions. */ ! 739: ! 740: /* Return a newly created expression-node of code SC and operand ARG1. ! 741: Used for codes that want one operand. ! 742: The TREE_TYPE is not initialized. */ ! 743: ! 744: tree ! 745: build1 (sc, arg1) ! 746: enum tree_code sc; ! 747: tree arg1; ! 748: { ! 749: register tree t = make_node (sc); ! 750: ! 751: TREE_OPERAND (t, 0) = arg1; ! 752: return t; ! 753: } ! 754: ! 755: /* Return a newly created expression-node of code SC ! 756: and operands ARG1 and ARG2. ! 757: Used for codes that want two operands. ! 758: The TREE_TYPE is not initialized. */ ! 759: ! 760: tree ! 761: build2 (sc, arg1, arg2) ! 762: enum tree_code sc; ! 763: tree arg1, arg2; ! 764: { ! 765: register tree t = make_node (sc); ! 766: ! 767: TREE_OPERAND (t, 0) = arg1; ! 768: TREE_OPERAND (t, 1) = arg2; ! 769: return t; ! 770: } ! 771: ! 772: /* Return a newly created expression-node of code SC ! 773: and operands ARG1, ARG2 and ARG3. ! 774: Used for codes that want three operands. ! 775: The TREE_TYPE is not initialized. */ ! 776: ! 777: tree ! 778: build3 (sc, arg1, arg2, arg3) ! 779: int sc; ! 780: tree arg1, arg2, arg3; ! 781: { ! 782: register tree t = make_node (sc); ! 783: ! 784: TREE_OPERAND (t, 0) = arg1; ! 785: TREE_OPERAND (t, 1) = arg2; ! 786: TREE_OPERAND (t, 2) = arg3; ! 787: return t; ! 788: } ! 789: ! 790: /* Low-level constructors for statements. ! 791: These constructors all expect source file name and line number ! 792: as arguments, as well as enough arguments to fill in the data ! 793: in the statement node. */ ! 794: ! 795: tree ! 796: build_goto (filename, line, label) ! 797: char *filename; ! 798: int line; ! 799: tree label; ! 800: { ! 801: register tree t = make_node (GOTO_STMT); ! 802: STMT_SOURCE_FILE (t) = filename; ! 803: STMT_SOURCE_LINE (t) = line; ! 804: STMT_BODY (t) = label; ! 805: return t; ! 806: } ! 807: ! 808: tree ! 809: build_return (filename, line, arg) ! 810: char *filename; ! 811: int line; ! 812: tree arg; ! 813: { ! 814: register tree t = make_node (RETURN_STMT); ! 815: ! 816: STMT_SOURCE_FILE (t) = filename; ! 817: STMT_SOURCE_LINE (t) = line; ! 818: STMT_BODY (t) = arg; ! 819: return t; ! 820: } ! 821: ! 822: tree ! 823: build_expr_stmt (filename, line, expr) ! 824: char *filename; ! 825: int line; ! 826: tree expr; ! 827: { ! 828: register tree t = make_node (EXPR_STMT); ! 829: ! 830: STMT_SOURCE_FILE (t) = filename; ! 831: STMT_SOURCE_LINE (t) = line; ! 832: STMT_BODY (t) = expr; ! 833: return t; ! 834: } ! 835: ! 836: tree ! 837: build_if (filename, line, cond, thenclause, elseclause) ! 838: char *filename; ! 839: int line; ! 840: tree cond, thenclause, elseclause; ! 841: { ! 842: register tree t = make_node (IF_STMT); ! 843: ! 844: STMT_SOURCE_FILE (t) = filename; ! 845: STMT_SOURCE_LINE (t) = line; ! 846: STMT_COND (t) = cond; ! 847: STMT_THEN (t) = thenclause; ! 848: STMT_ELSE (t) = elseclause; ! 849: return t; ! 850: } ! 851: ! 852: tree ! 853: build_exit (filename, line, cond) ! 854: char *filename; ! 855: int line; ! 856: tree cond; ! 857: { ! 858: register tree t = make_node (EXIT_STMT); ! 859: STMT_SOURCE_FILE (t) = filename; ! 860: STMT_SOURCE_LINE (t) = line; ! 861: STMT_BODY (t) = cond; ! 862: return t; ! 863: } ! 864: ! 865: tree ! 866: build_asm_stmt (filename, line, asmcode) ! 867: char *filename; ! 868: int line; ! 869: tree asmcode; ! 870: { ! 871: register tree t = make_node (ASM_STMT); ! 872: STMT_SOURCE_FILE (t) = filename; ! 873: STMT_SOURCE_LINE (t) = line; ! 874: STMT_BODY (t) = asmcode; ! 875: return t; ! 876: } ! 877: ! 878: tree ! 879: build_case (filename, line, object, cases) ! 880: char *filename; ! 881: int line; ! 882: tree object, cases; ! 883: { ! 884: register tree t = make_node (CASE_STMT); ! 885: STMT_SOURCE_FILE (t) = filename; ! 886: STMT_SOURCE_LINE (t) = line; ! 887: STMT_CASE_INDEX (t) = object; ! 888: STMT_CASE_LIST (t) = cases; ! 889: return t; ! 890: } ! 891: ! 892: tree ! 893: build_let (filename, line, vars, body, supercontext, tags) ! 894: char *filename; ! 895: int line; ! 896: tree vars, body, supercontext, tags; ! 897: { ! 898: register tree t = make_node (LET_STMT); ! 899: STMT_SOURCE_FILE (t) = filename; ! 900: STMT_SOURCE_LINE (t) = line; ! 901: STMT_VARS (t) = vars; ! 902: STMT_BODY (t) = body; ! 903: STMT_SUPERCONTEXT (t) = supercontext; ! 904: STMT_BIND_SIZE (t) = 0; ! 905: STMT_TYPE_TAGS (t) = tags; ! 906: return t; ! 907: } ! 908: ! 909: tree ! 910: build_loop (filename, line, body) ! 911: char *filename; ! 912: int line; ! 913: tree body; ! 914: { ! 915: register tree t = make_node (LOOP_STMT); ! 916: STMT_SOURCE_FILE (t) = filename; ! 917: STMT_SOURCE_LINE (t) = line; ! 918: STMT_BODY (t) = body; ! 919: return t; ! 920: } ! 921: ! 922: tree ! 923: build_compound (filename, line, body) ! 924: char *filename; ! 925: int line; ! 926: tree body; ! 927: { ! 928: register tree t = make_node (COMPOUND_STMT); ! 929: STMT_SOURCE_FILE (t) = filename; ! 930: STMT_SOURCE_LINE (t) = line; ! 931: STMT_BODY (t) = body; ! 932: return t; ! 933: } ! 934: ! 935: /* Return a type like TYPE except that its TREE_READONLY is CONSTP ! 936: and its TREE_VOLATILE is VOLATILEP. ! 937: ! 938: Such variant types already made are recorded so that duplicates ! 939: are not made. ! 940: ! 941: A variant types should never be used as the type of an expression. ! 942: Always copy the variant information into the TREE_READONLY ! 943: and TREE_VOLATILE of the expression, and then give the expression ! 944: as its type the "main variant", the variant whose TREE_READONLY ! 945: and TREE_VOLATILE are zero. Use TYPE_MAIN_VARIANT to find the ! 946: main variant. */ ! 947: ! 948: tree ! 949: build_type_variant (type, constp, volatilep) ! 950: tree type; ! 951: int constp, volatilep; ! 952: { ! 953: register tree t, m = TYPE_MAIN_VARIANT (type); ! 954: register struct obstack *ambient_obstack = current_obstack; ! 955: ! 956: /* Treat any nonzero argument as 1. */ ! 957: constp = !!constp; ! 958: volatilep = !!volatilep; ! 959: ! 960: /* First search the chain variants for one that is what we want. */ ! 961: ! 962: for (t = m; t; t = TYPE_NEXT_VARIANT (t)) ! 963: if (constp == TREE_READONLY (t) ! 964: && volatilep == TREE_VOLATILE (t)) ! 965: return t; ! 966: ! 967: /* We need a new one. */ ! 968: current_obstack = TREE_PERMANENT (type) ? &permanent_obstack : &temporary_obstack; ! 969: ! 970: t = copy_node (type); ! 971: TREE_READONLY (t) = constp; ! 972: TREE_VOLATILE (t) = volatilep; ! 973: TYPE_POINTER_TO (t) = 0; ! 974: ! 975: /* Add this type to the chain of variants of TYPE. */ ! 976: TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); ! 977: TYPE_NEXT_VARIANT (m) = t; ! 978: ! 979: current_obstack = ambient_obstack; ! 980: return t; ! 981: } ! 982: ! 983: /* Constructors for pointer, array and function types. ! 984: (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are ! 985: constructed by language-dependent code, not here.) */ ! 986: ! 987: tree ! 988: build_pointer_type (to_type) ! 989: tree to_type; ! 990: { ! 991: register tree t = TYPE_POINTER_TO (to_type); ! 992: register struct obstack *ambient_obstack = current_obstack; ! 993: ! 994: /* First, if we already have a type for pointers to TO_TYPE, use it. */ ! 995: ! 996: if (t) ! 997: return t; ! 998: ! 999: /* We need a new one. If TO_TYPE is permanent, make this permanent too. */ ! 1000: current_obstack = (TREE_PERMANENT (to_type) ! 1001: ? &permanent_obstack ! 1002: : &temporary_obstack); ! 1003: ! 1004: t = make_node (POINTER_TYPE); ! 1005: TREE_TYPE (t) = to_type; ! 1006: ! 1007: /* Record this type as the pointer to TO_TYPE. */ ! 1008: TYPE_POINTER_TO (to_type) = t; ! 1009: ! 1010: /* If this type is permanent but we are really inside a function, ! 1011: lay it out now, so that the size, etc. are permanent too. */ ! 1012: if (current_obstack != ambient_obstack) ! 1013: layout_type (t); ! 1014: ! 1015: current_obstack = ambient_obstack; ! 1016: return t; ! 1017: } ! 1018: ! 1019: tree ! 1020: build_array_type (elt_type, index_type) ! 1021: tree elt_type, index_type; ! 1022: { ! 1023: register tree t = make_node (ARRAY_TYPE); ! 1024: ! 1025: if (TREE_CODE (elt_type) == FUNCTION_TYPE) ! 1026: { ! 1027: yyerror ("arrays of functions are not meaningful"); ! 1028: elt_type = integer_type_node; ! 1029: } ! 1030: ! 1031: TREE_TYPE (t) = elt_type; ! 1032: TYPE_DOMAIN (t) = index_type; ! 1033: /* Make sure TYPE_POINTER_TO (elt_type) is filled in. */ ! 1034: build_pointer_type (elt_type); ! 1035: return t; ! 1036: } ! 1037: ! 1038: /* Build a function type, which is a FUNCTION_TYPE node. ! 1039: The TREE_TYPE of this node is the type of the value returned. ! 1040: If no value is returned, the TREE_TYPE may be 0 or it ! 1041: may be a node for a void type. ! 1042: ARG_TYPES is a chain of TREE_LIST nodes whose TREE_VALUEs ! 1043: are data type nodes for the arguments of the function. */ ! 1044: ! 1045: tree ! 1046: build_function_type (value_type, arg_types) ! 1047: tree value_type, arg_types; ! 1048: { ! 1049: register tree t; ! 1050: ! 1051: if (TREE_CODE (value_type) == FUNCTION_DECL ! 1052: || TREE_CODE (value_type) == ARRAY_TYPE) ! 1053: { ! 1054: yyerror ("function return type cannot be function or array"); ! 1055: value_type = integer_type_node; ! 1056: } ! 1057: ! 1058: t = make_node (FUNCTION_TYPE); ! 1059: TREE_TYPE (t) = value_type; ! 1060: TYPE_ARG_TYPES (t) = arg_types; ! 1061: return t; ! 1062: } ! 1063: ! 1064: /* Return OP, stripped of any conversions to wider types as much as is safe. ! 1065: Converting the value back to OP's type makes a value equivalent to OP. ! 1066: ! 1067: If FOR_TYPE is nonzero, we return a value which, if converted to ! 1068: type FOR_TYPE, would be equivalent to converting OP to type FOR_TYPE. ! 1069: ! 1070: OP must have integer, real or enumeral type. Pointers are not allowed! ! 1071: ! 1072: There are some cases where the obvious value we could return ! 1073: would regenerate to OP if converted to OP's type, ! 1074: but would not extend like OP to wider types. ! 1075: If FOR_TYPE indicates such extension is contemplated, we eschew such values. ! 1076: For example, if OP is (unsigned short)(signed char)-1, ! 1077: we avoid returning (signed char)-1 if FOR_TYPE is int, ! 1078: even though extending that to an unsigned short would regenerate OP, ! 1079: since the result of extending (signed char)-1 to (int) ! 1080: is different from (int) OP. */ ! 1081: ! 1082: tree ! 1083: get_unwidened (op, for_type) ! 1084: register tree op; ! 1085: tree for_type; ! 1086: { ! 1087: /* Set UNS initially if converting OP to FOR_TYPE is a zero-extension. */ ! 1088: /* TYPE_PRECISION is safe in place of type_precision since ! 1089: pointer types are not allowed. */ ! 1090: register tree type = TREE_TYPE (op); ! 1091: register int final_prec = TYPE_PRECISION (for_type != 0 ? for_type : type); ! 1092: register int uns ! 1093: = (for_type != 0 && for_type != type ! 1094: && final_prec > TYPE_PRECISION (type) ! 1095: && type_unsigned_p (type)); ! 1096: register tree win = op; ! 1097: ! 1098: while (TREE_CODE (op) == NOP_EXPR) ! 1099: { ! 1100: register int bitschange ! 1101: = TYPE_PRECISION (TREE_TYPE (op)) ! 1102: - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0))); ! 1103: ! 1104: /* Truncations are many-one so cannot be removed. ! 1105: Unless we are later going to truncate down even farther. */ ! 1106: if (bitschange < 0 ! 1107: && final_prec > TYPE_PRECISION (TREE_TYPE (op))) ! 1108: break; ! 1109: ! 1110: /* See what's inside this conversion. If we decide to strip it, ! 1111: we will set WIN. */ ! 1112: op = TREE_OPERAND (op, 0); ! 1113: ! 1114: /* If we have not stripped any zero-extensions (uns is 0), ! 1115: we can strip any kind of extension. ! 1116: If we have previously stripped a zero-extension, ! 1117: only zero-extensions can safely be stripped. ! 1118: Any extension can be stripped if the bits it would produce ! 1119: are all going to be discarded later by truncating to FOR_TYPE. */ ! 1120: ! 1121: if (bitschange > 0) ! 1122: { ! 1123: if (! uns || final_prec <= TYPE_PRECISION (TREE_TYPE (op))) ! 1124: win = op; ! 1125: /* type_unsigned_p says whether this is a zero-extension. ! 1126: Let's avoid computing it if it does not affect WIN ! 1127: and if UNS will not be needed again. */ ! 1128: if ((uns || TREE_CODE (op) == NOP_EXPR) ! 1129: && type_unsigned_p (TREE_TYPE (op))) ! 1130: { ! 1131: uns = 1; ! 1132: win = op; ! 1133: } ! 1134: } ! 1135: } ! 1136: ! 1137: if (TREE_CODE (op) == COMPONENT_REF) ! 1138: { ! 1139: int innerprec = (TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (op, 1))) ! 1140: * DECL_SIZE_UNIT (TREE_OPERAND (op, 1))); ! 1141: type = type_for_size (innerprec, type_unsigned_p (TREE_TYPE (op))); ! 1142: ! 1143: /* We can get this structure field in the narrowest type it fits in ! 1144: but the resulting extension to its nominal type (a fullword type) ! 1145: must fit the same conditions as for other extensions. */ ! 1146: ! 1147: if (innerprec < TYPE_PRECISION (TREE_TYPE (op)) ! 1148: && (! uns || final_prec <= innerprec ! 1149: || type_unsigned_p (TREE_TYPE (op)))) ! 1150: { ! 1151: if (type != 0) ! 1152: { ! 1153: win = build2 (COMPONENT_REF, TREE_OPERAND (op, 0), ! 1154: TREE_OPERAND (op, 1)); ! 1155: TREE_TYPE (win) = type; ! 1156: } ! 1157: } ! 1158: } ! 1159: return win; ! 1160: } ! 1161: ! 1162: /* Return OP or a simpler expression for a narrower value ! 1163: which can be sign-extended or zero-extended to give back OP. ! 1164: Store in *UNSIGNEDP_PTR either 1 if the value should be zero-extended ! 1165: or 0 if the value should be sign-extended. */ ! 1166: ! 1167: tree ! 1168: get_narrower (op, unsignedp_ptr) ! 1169: register tree op; ! 1170: int *unsignedp_ptr; ! 1171: { ! 1172: register int uns = 0; ! 1173: int first = 1; ! 1174: register tree win = op; ! 1175: ! 1176: while (TREE_CODE (op) == NOP_EXPR) ! 1177: { ! 1178: register int bitschange ! 1179: = TYPE_PRECISION (TREE_TYPE (op)) ! 1180: - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0))); ! 1181: ! 1182: /* Truncations are many-one so cannot be removed. */ ! 1183: if (bitschange < 0) ! 1184: break; ! 1185: ! 1186: /* See what's inside this conversion. If we decide to strip it, ! 1187: we will set WIN. */ ! 1188: op = TREE_OPERAND (op, 0); ! 1189: ! 1190: if (bitschange > 0) ! 1191: { ! 1192: /* An extension: the outermost one can be stripped, ! 1193: but remember whether it is zero or sign extension. */ ! 1194: if (first) ! 1195: uns = type_unsigned_p (TREE_TYPE (op)); ! 1196: /* Otherwise, if a sign extension has been stripped, ! 1197: only sign extensions can now be stripped; ! 1198: if a zero extension has been stripped, only zero-extensions. */ ! 1199: else if (uns != type_unsigned_p (TREE_TYPE (op))) ! 1200: break; ! 1201: first = 0; ! 1202: } ! 1203: /* A change in nominal type can always be stripped. */ ! 1204: ! 1205: win = op; ! 1206: } ! 1207: ! 1208: if (TREE_CODE (op) == COMPONENT_REF) ! 1209: { ! 1210: int innerprec = (TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (op, 1))) ! 1211: * DECL_SIZE_UNIT (TREE_OPERAND (op, 1))); ! 1212: tree type = type_for_size (innerprec, type_unsigned_p (TREE_TYPE (op))); ! 1213: ! 1214: /* We can get this structure field in a narrower type that fits it, ! 1215: but the resulting extension to its nominal type (a fullword type) ! 1216: must satisfy the same conditions as for other extensions. */ ! 1217: ! 1218: if (innerprec < TYPE_PRECISION (TREE_TYPE (op)) ! 1219: && (first || uns == type_unsigned_p (TREE_TYPE (op))) ! 1220: && type != 0) ! 1221: { ! 1222: win = build2 (COMPONENT_REF, TREE_OPERAND (op, 0), ! 1223: TREE_OPERAND (op, 1)); ! 1224: TREE_TYPE (win) = type; ! 1225: } ! 1226: } ! 1227: *unsignedp_ptr = uns; ! 1228: return win; ! 1229: } ! 1230: ! 1231: /* Return the precision of a type, for arithmetic purposes. ! 1232: Supports all types on which arithmetic is possible ! 1233: (including pointer types). ! 1234: It's not clear yet what will be right for complex types. */ ! 1235: ! 1236: int ! 1237: type_precision (type) ! 1238: register tree type; ! 1239: { ! 1240: return ((TREE_CODE (type) == INTEGER_TYPE ! 1241: || TREE_CODE (type) == ENUMERAL_TYPE ! 1242: || TREE_CODE (type) == REAL_TYPE) ! 1243: ? TYPE_PRECISION (type) : BITS_PER_WORD); ! 1244: } ! 1245: ! 1246: /* Nonzero if integer constant C has a value that is permissible ! 1247: for type TYPE (an INTEGER_TYPE). */ ! 1248: ! 1249: int ! 1250: int_fits_type_p (c, type) ! 1251: tree c, type; ! 1252: { ! 1253: if (type_unsigned_p (type)) ! 1254: return (!INT_CST_LT_UNSIGNED (TYPE_MAX_VALUE (type), c) ! 1255: && !INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type))); ! 1256: else ! 1257: return (!INT_CST_LT (TYPE_MAX_VALUE (type), c) ! 1258: && !INT_CST_LT (c, TYPE_MIN_VALUE (type))); ! 1259: } ! 1260: ! 1261: /* Subroutines of `convert'. */ ! 1262: ! 1263: /* Change of width--truncation and extension of integers or reals-- ! 1264: is represented with NOP_EXPR. Proper functioning of many things ! 1265: assumes that no other conversions can be NOP_EXPRs. ! 1266: ! 1267: Conversion between integer and pointer is represented with CONVERT_EXPR. ! 1268: Converting integer to real uses FLOAT_EXPR ! 1269: and real to integer uses FIX_TRUNC_EXPR. */ ! 1270: ! 1271: /* Generate an expression for a conversion using expression code CODE. ! 1272: It will convert EXPR to type TYPE. */ ! 1273: ! 1274: static tree ! 1275: build_convert (code, type, expr) ! 1276: enum tree_code code; ! 1277: tree type, expr; ! 1278: { ! 1279: register tree tem = build1 (code, expr); ! 1280: ! 1281: TREE_TYPE (tem) = type; ! 1282: TREE_VOLATILE (tem) = TREE_VOLATILE (expr); ! 1283: return tem; ! 1284: } ! 1285: ! 1286: static tree ! 1287: convert_to_pointer (type, expr) ! 1288: tree type, expr; ! 1289: { ! 1290: register tree intype = TREE_TYPE (expr); ! 1291: register enum tree_code form = TREE_CODE (intype); ! 1292: ! 1293: if (integer_zerop (expr)) ! 1294: { ! 1295: if (type == TREE_TYPE (null_pointer_node)) ! 1296: return null_pointer_node; ! 1297: expr = build_int_2 (0, 0); ! 1298: TREE_TYPE (expr) = type; ! 1299: return expr; ! 1300: } ! 1301: ! 1302: if (form == POINTER_TYPE) ! 1303: return build_convert (NOP_EXPR, type, expr); ! 1304: ! 1305: if (intype == integer_type_node) ! 1306: return build_convert (CONVERT_EXPR, type, expr); ! 1307: ! 1308: if (form == INTEGER_TYPE || form == ENUMERAL_TYPE) ! 1309: return convert_to_pointer (type, convert (integer_type_node, expr)); ! 1310: ! 1311: yyerror ("cannot convert to a pointer type"); ! 1312: ! 1313: return null_pointer_node; ! 1314: } ! 1315: ! 1316: /* The result of this is always supposed to be a newly created tree node ! 1317: not in use in any existing structure. */ ! 1318: ! 1319: static tree ! 1320: convert_to_integer (type, expr) ! 1321: tree type, expr; ! 1322: { ! 1323: register tree intype = TREE_TYPE (expr); ! 1324: register enum tree_code form = TREE_CODE (intype); ! 1325: extern tree build_binary_op_nodefault (); ! 1326: extern tree build_unary_op (); ! 1327: ! 1328: if (form == POINTER_TYPE) ! 1329: { ! 1330: if (integer_zerop (expr)) ! 1331: expr = integer_zero_node; ! 1332: else ! 1333: expr = fold (build_convert (CONVERT_EXPR, integer_type_node, expr)); ! 1334: intype = TREE_TYPE (expr); ! 1335: form = TREE_CODE (intype); ! 1336: } ! 1337: ! 1338: if (form == INTEGER_TYPE || form == ENUMERAL_TYPE) ! 1339: { ! 1340: register int outprec = TYPE_PRECISION (type); ! 1341: register int inprec = TYPE_PRECISION (intype); ! 1342: register enum tree_code ex_form = TREE_CODE (expr); ! 1343: ! 1344: if (outprec >= inprec) ! 1345: return build_convert (NOP_EXPR, type, expr); ! 1346: ! 1347: /* Here detect when we can distribute the truncation down past some arithmetic. ! 1348: For example, if adding two longs and converting to an int, ! 1349: we can equally well convert both to ints and then add. ! 1350: For the operations handled here, such truncation distribution ! 1351: is always safe. ! 1352: It is desirable in these cases: ! 1353: 1) when truncating down to full-word from a larger size ! 1354: 2) when truncating takes no work. ! 1355: 3) when at least one operand of the arithmetic has been extended ! 1356: (as by C's default conversions). In this case we need two conversions ! 1357: if we do the arithmetic as already requested, so we might as well ! 1358: truncate both and then combine. Perhaps that way we need only one. ! 1359: ! 1360: Note that in general we cannot do the arithmetic in a type ! 1361: shorter than the desired result of conversion, even if the operands ! 1362: are both extended from a shorter type, because they might overflow ! 1363: if combined in that type. The exceptions to this--the times when ! 1364: two narrow values can be combined in their narrow type even to ! 1365: make a wider result--are handled by "shorten" in build_binary_op. */ ! 1366: ! 1367: switch (ex_form) ! 1368: { ! 1369: case RSHIFT_EXPR: ! 1370: /* We can pass truncation down through right shifting ! 1371: when the shift count is a negative constant. */ ! 1372: if (TREE_CODE (TREE_OPERAND (expr, 1)) != INTEGER_CST ! 1373: || TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)) > 0) ! 1374: break; ! 1375: goto trunc1; ! 1376: ! 1377: case LSHIFT_EXPR: ! 1378: /* We can pass truncation down through left shifting ! 1379: when the shift count is a positive constant. */ ! 1380: if (TREE_CODE (TREE_OPERAND (expr, 1)) != INTEGER_CST ! 1381: || TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)) < 0) ! 1382: break; ! 1383: /* In this case, shifting is like multiplication. */ ! 1384: ! 1385: case PLUS_EXPR: ! 1386: case MINUS_EXPR: ! 1387: case MULT_EXPR: ! 1388: case MAX_EXPR: ! 1389: case MIN_EXPR: ! 1390: case BIT_AND_EXPR: ! 1391: case BIT_IOR_EXPR: ! 1392: case BIT_XOR_EXPR: ! 1393: case BIT_ANDTC_EXPR: ! 1394: trunc1: ! 1395: { ! 1396: tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type); ! 1397: tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type); ! 1398: ! 1399: if (outprec >= BITS_PER_WORD ! 1400: || TRULY_NOOP_TRUNCATION (outprec, inprec) ! 1401: || inprec > TYPE_PRECISION (TREE_TYPE (arg0)) ! 1402: || inprec > TYPE_PRECISION (TREE_TYPE (arg1))) ! 1403: { ! 1404: /* Do the arithmetic in type TYPEX, ! 1405: then convert result to TYPE. */ ! 1406: register tree typex = type; ! 1407: ! 1408: /* Can't do arithmetic in enumeral types ! 1409: so use an integer type that will hold the values. */ ! 1410: if (TREE_CODE (typex) == ENUMERAL_TYPE) ! 1411: typex = type_for_size (TYPE_PRECISION (typex)); ! 1412: ! 1413: /* But now perhaps TYPEX is as wide as INPREC. ! 1414: In that case, do nothing special here. ! 1415: (Otherwise would recurse infinitely in convert. */ ! 1416: if (TYPE_PRECISION (typex) != inprec) ! 1417: { ! 1418: /* Don't do unsigned arithmetic where signed was wanted, ! 1419: or vice versa. */ ! 1420: typex = (type_unsigned_p (TREE_TYPE (expr)) ! 1421: ? unsigned_type (typex) : signed_type (typex)); ! 1422: return convert (type, ! 1423: build_binary_op_nodefault (ex_form, ! 1424: convert (typex, arg0), ! 1425: convert (typex, arg1))); ! 1426: } ! 1427: } ! 1428: } ! 1429: break; ! 1430: ! 1431: case EQ_EXPR: ! 1432: case NE_EXPR: ! 1433: case GT_EXPR: ! 1434: case GE_EXPR: ! 1435: case LT_EXPR: ! 1436: case LE_EXPR: ! 1437: case TRUTH_AND_EXPR: ! 1438: case TRUTH_OR_EXPR: ! 1439: case TRUTH_NOT_EXPR: ! 1440: /* If we want result of comparison converted to a byte, ! 1441: we can just regard it as a byte, since it is 0 or 1. */ ! 1442: TREE_TYPE (expr) = type; ! 1443: return expr; ! 1444: ! 1445: case NEGATE_EXPR: ! 1446: case BIT_NOT_EXPR: ! 1447: case ABS_EXPR: ! 1448: { ! 1449: register tree typex = type; ! 1450: ! 1451: /* Can't do arithmetic in enumeral types ! 1452: so use an integer type that will hold the values. */ ! 1453: if (TREE_CODE (typex) == ENUMERAL_TYPE) ! 1454: typex = type_for_size (TYPE_PRECISION (typex)); ! 1455: ! 1456: /* But now perhaps TYPEX is as wide as INPREC. ! 1457: In that case, do nothing special here. ! 1458: (Otherwise would recurse infinitely in convert. */ ! 1459: if (TYPE_PRECISION (typex) != inprec) ! 1460: { ! 1461: /* Don't do unsigned arithmetic where signed was wanted, ! 1462: or vice versa. */ ! 1463: typex = (type_unsigned_p (TREE_TYPE (expr)) ! 1464: ? unsigned_type (typex) : signed_type (typex)); ! 1465: return convert (type, ! 1466: build_unary_op (ex_form, ! 1467: convert (typex, TREE_OPERAND (expr, 0)), ! 1468: 1)); ! 1469: } ! 1470: } ! 1471: ! 1472: case NOP_EXPR: ! 1473: /* If truncating after truncating, might as well do all at once. ! 1474: If truncating after extending, we may get rid of wasted work. */ ! 1475: return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type)); ! 1476: } ! 1477: ! 1478: return build_convert (NOP_EXPR, type, expr); ! 1479: } ! 1480: ! 1481: if (form == REAL_TYPE) ! 1482: return build_convert (FIX_TRUNC_EXPR, type, expr); ! 1483: ! 1484: yyerror ("aggregate value used where an integer was expected"); ! 1485: ! 1486: { ! 1487: register tree tem = build_int_2 (0, 0); ! 1488: TREE_TYPE (tem) = type; ! 1489: return tem; ! 1490: } ! 1491: } ! 1492: ! 1493: static tree ! 1494: convert_to_real (type, expr) ! 1495: tree type, expr; ! 1496: { ! 1497: register enum tree_code form = TREE_CODE (TREE_TYPE (expr)); ! 1498: ! 1499: if (form == REAL_TYPE) ! 1500: return build_convert (NOP_EXPR, type, expr); ! 1501: ! 1502: if (form == INTEGER_TYPE || form == ENUMERAL_TYPE) ! 1503: return build_convert (FLOAT_EXPR, type, expr); ! 1504: ! 1505: if (form == POINTER_TYPE) ! 1506: yyerror ("pointer value used where a float was expected"); ! 1507: else ! 1508: yyerror ("aggregate value used where a float was expected"); ! 1509: ! 1510: { ! 1511: register tree tem = make_node (REAL_CST); ! 1512: TREE_TYPE (tem) = type; ! 1513: TREE_REAL_CST (tem) = 0; ! 1514: return tem; ! 1515: } ! 1516: } ! 1517: ! 1518: /* Create an expression whose value is that of EXPR, ! 1519: converted to type TYPE. The TREE_TYPE of the value ! 1520: is always TYPE. This function implements all reasonable ! 1521: conversions; callers should filter out those that are ! 1522: not permitted by the language being compiled. */ ! 1523: ! 1524: tree ! 1525: convert (type, expr) ! 1526: tree type, expr; ! 1527: { ! 1528: register tree e = expr; ! 1529: register enum tree_code code = TREE_CODE (type); ! 1530: ! 1531: if (type == TREE_TYPE (expr) || TREE_CODE (expr) == ERROR_MARK) ! 1532: return expr; ! 1533: if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE) ! 1534: { ! 1535: yyerror ("void value not ignored as it ought to be"); ! 1536: return error_mark_node; ! 1537: } ! 1538: if (code == VOID_TYPE) ! 1539: return build_convert (CONVERT_EXPR, type, e); ! 1540: #if 0 ! 1541: /* This is incorrect. A truncation can't be stripped this way. ! 1542: Extensions will be stripped by the use of get_unwidened. */ ! 1543: if (TREE_CODE (expr) == NOP_EXPR) ! 1544: return convert (type, TREE_OPERAND (expr, 0)); ! 1545: #endif ! 1546: if (code == INTEGER_TYPE || code == ENUMERAL_TYPE) ! 1547: return fold (convert_to_integer (type, e)); ! 1548: if (code == POINTER_TYPE) ! 1549: return fold (convert_to_pointer (type, e)); ! 1550: if (code == REAL_TYPE) ! 1551: return fold (convert_to_real (type, e)); ! 1552: ! 1553: yyerror ("conversion to non-scalar type requested"); ! 1554: return error_mark_node; ! 1555: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.