|
|
1.1 ! root 1: /* Language-independent node constructors for parse phase of GNU compiler. ! 2: Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 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: /* This file contains the low level primitives for operating on tree nodes, ! 22: including allocation, list operations, interning of identifiers, ! 23: construction of data type nodes and statement nodes, ! 24: and construction of type conversion nodes. It also contains ! 25: tables index by tree code that describe how to take apart ! 26: nodes of that code. ! 27: ! 28: It is intended to be language-independent, but occasionally ! 29: calls language-dependent routines defined (for C) in typecheck.c. ! 30: ! 31: The low-level allocation routines oballoc and permalloc ! 32: are used also for allocating many other kinds of objects ! 33: by all passes of the compiler. */ ! 34: ! 35: #include "config.h" ! 36: #include <stdio.h> ! 37: #include "flags.h" ! 38: #include "function.h" ! 39: #include "tree.h" ! 40: #include "obstack.h" ! 41: #include "gvarargs.h" ! 42: ! 43: #define obstack_chunk_alloc xmalloc ! 44: #define obstack_chunk_free free ! 45: ! 46: extern int xmalloc (); ! 47: extern void free (); ! 48: ! 49: /* Tree nodes of permanent duration are allocated in this obstack. ! 50: They are the identifier nodes, and everything outside of ! 51: the bodies and parameters of function definitions. */ ! 52: ! 53: struct obstack permanent_obstack; ! 54: ! 55: /* The initial RTL, and all ..._TYPE nodes, in a function ! 56: are allocated in this obstack. Usually they are freed at the ! 57: end of the function, but if the function is inline they are saved. ! 58: For top-level functions, this is maybepermanent_obstack. ! 59: Separate obstacks are made for nested functions. */ ! 60: ! 61: struct obstack *function_maybepermanent_obstack; ! 62: ! 63: /* This is the function_maybepermanent_obstack for top-level functions. */ ! 64: ! 65: struct obstack maybepermanent_obstack; ! 66: ! 67: /* The contents of the current function definition are allocated ! 68: in this obstack, and all are freed at the end of the function. ! 69: For top-level functions, this is temporary_obstack. ! 70: Separate obstacks are made for nested functions. */ ! 71: ! 72: struct obstack *function_obstack; ! 73: ! 74: /* This is used for reading initializers of global variables. */ ! 75: ! 76: struct obstack temporary_obstack; ! 77: ! 78: /* The tree nodes of an expression are allocated ! 79: in this obstack, and all are freed at the end of the expression. */ ! 80: ! 81: struct obstack momentary_obstack; ! 82: ! 83: /* The tree nodes of a declarator are allocated ! 84: in this obstack, and all are freed when the declarator ! 85: has been parsed. */ ! 86: ! 87: static struct obstack temp_decl_obstack; ! 88: ! 89: /* This points at either permanent_obstack ! 90: or the current function_maybepermanent_obstack. */ ! 91: ! 92: struct obstack *saveable_obstack; ! 93: ! 94: /* This is same as saveable_obstack during parse and expansion phase; ! 95: it points to the current function's obstack during optimization. ! 96: This is the obstack to be used for creating rtl objects. */ ! 97: ! 98: struct obstack *rtl_obstack; ! 99: ! 100: /* This points at either permanent_obstack or the current function_obstack. */ ! 101: ! 102: struct obstack *current_obstack; ! 103: ! 104: /* This points at either permanent_obstack or the current function_obstack ! 105: or momentary_obstack. */ ! 106: ! 107: struct obstack *expression_obstack; ! 108: ! 109: /* Stack of obstack selections for push_obstacks and pop_obstacks. */ ! 110: ! 111: struct obstack_stack ! 112: { ! 113: struct obstack_stack *next; ! 114: struct obstack *current; ! 115: struct obstack *saveable; ! 116: struct obstack *expression; ! 117: struct obstack *rtl; ! 118: }; ! 119: ! 120: struct obstack_stack *obstack_stack; ! 121: ! 122: /* Obstack for allocating struct obstack_stack entries. */ ! 123: ! 124: static struct obstack obstack_stack_obstack; ! 125: ! 126: /* Addresses of first objects in some obstacks. ! 127: This is for freeing their entire contents. */ ! 128: char *maybepermanent_firstobj; ! 129: char *temporary_firstobj; ! 130: char *momentary_firstobj; ! 131: char *temp_decl_firstobj; ! 132: ! 133: /* Nonzero means all ..._TYPE nodes should be allocated permanently. */ ! 134: ! 135: int all_types_permanent; ! 136: ! 137: /* Stack of places to restore the momentary obstack back to. */ ! 138: ! 139: struct momentary_level ! 140: { ! 141: /* Pointer back to previous such level. */ ! 142: struct momentary_level *prev; ! 143: /* First object allocated within this level. */ ! 144: char *base; ! 145: /* Value of expression_obstack saved at entry to this level. */ ! 146: struct obstack *obstack; ! 147: }; ! 148: ! 149: struct momentary_level *momentary_stack; ! 150: ! 151: /* Table indexed by tree code giving a string containing a character ! 152: classifying the tree code. Possibilities are ! 153: t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */ ! 154: ! 155: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, ! 156: ! 157: char *standard_tree_code_type[] = { ! 158: #include "tree.def" ! 159: }; ! 160: #undef DEFTREECODE ! 161: ! 162: /* Table indexed by tree code giving number of expression ! 163: operands beyond the fixed part of the node structure. ! 164: Not used for types or decls. */ ! 165: ! 166: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, ! 167: ! 168: int standard_tree_code_length[] = { ! 169: #include "tree.def" ! 170: }; ! 171: #undef DEFTREECODE ! 172: ! 173: /* Names of tree components. ! 174: Used for printing out the tree and error messages. */ ! 175: #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, ! 176: ! 177: char *standard_tree_code_name[] = { ! 178: #include "tree.def" ! 179: }; ! 180: #undef DEFTREECODE ! 181: ! 182: /* Table indexed by tree code giving a string containing a character ! 183: classifying the tree code. Possibilities are ! 184: t, d, s, c, r, e, <, 1 and 2. See tree.def for details. */ ! 185: ! 186: char **tree_code_type; ! 187: ! 188: /* Table indexed by tree code giving number of expression ! 189: operands beyond the fixed part of the node structure. ! 190: Not used for types or decls. */ ! 191: ! 192: int *tree_code_length; ! 193: ! 194: /* Table indexed by tree code giving name of tree code, as a string. */ ! 195: ! 196: char **tree_code_name; ! 197: ! 198: /* Statistics-gathering stuff. */ ! 199: typedef enum ! 200: { ! 201: d_kind, t_kind, s_kind, r_kind, e_kind, c_kind, ! 202: id_kind, op_id_kind, perm_list_kind, temp_list_kind, ! 203: vec_kind, x_kind, lang_decl, lang_type, all_kinds ! 204: } tree_node_kind; ! 205: int tree_node_counts[(int)all_kinds]; ! 206: int tree_node_sizes[(int)all_kinds]; ! 207: int id_string_size = 0; ! 208: char *tree_node_kind_names[] = { "decls", "types", "stmts", "refs", "exprs", "constants", ! 209: "identifiers", "op_identifiers", "perm_tree_lists", "temp_tree_lists", ! 210: "vecs", "random kinds", "lang_decl kinds", "lang_type kinds" }; ! 211: ! 212: /* Hash table for uniquizing IDENTIFIER_NODEs by name. */ ! 213: ! 214: #define MAX_HASH_TABLE 1009 ! 215: static tree hash_table[MAX_HASH_TABLE]; /* id hash buckets */ ! 216: ! 217: /* 0 while creating built-in identifiers. */ ! 218: static int do_identifier_warnings; ! 219: ! 220: extern char *mode_name[]; ! 221: ! 222: void gcc_obstack_init (); ! 223: static tree stabilize_reference_1 (); ! 224: ! 225: /* Init the principal obstacks. */ ! 226: ! 227: void ! 228: init_obstacks () ! 229: { ! 230: gcc_obstack_init (&obstack_stack_obstack); ! 231: gcc_obstack_init (&permanent_obstack); ! 232: ! 233: gcc_obstack_init (&temporary_obstack); ! 234: temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0); ! 235: gcc_obstack_init (&momentary_obstack); ! 236: momentary_firstobj = (char *) obstack_alloc (&momentary_obstack, 0); ! 237: gcc_obstack_init (&maybepermanent_obstack); ! 238: maybepermanent_firstobj ! 239: = (char *) obstack_alloc (&maybepermanent_obstack, 0); ! 240: gcc_obstack_init (&temp_decl_obstack); ! 241: temp_decl_firstobj = (char *) obstack_alloc (&temp_decl_obstack, 0); ! 242: ! 243: function_obstack = &temporary_obstack; ! 244: function_maybepermanent_obstack = &maybepermanent_obstack; ! 245: current_obstack = &permanent_obstack; ! 246: expression_obstack = &permanent_obstack; ! 247: rtl_obstack = saveable_obstack = &permanent_obstack; ! 248: ! 249: /* Init the hash table of identifiers. */ ! 250: bzero (hash_table, sizeof hash_table); ! 251: } ! 252: ! 253: void ! 254: gcc_obstack_init (obstack) ! 255: struct obstack *obstack; ! 256: { ! 257: /* Let particular systems override the size of a chunk. */ ! 258: #ifndef OBSTACK_CHUNK_SIZE ! 259: #define OBSTACK_CHUNK_SIZE 0 ! 260: #endif ! 261: /* Let them override the alloc and free routines too. */ ! 262: #ifndef OBSTACK_CHUNK_ALLOC ! 263: #define OBSTACK_CHUNK_ALLOC xmalloc ! 264: #endif ! 265: #ifndef OBSTACK_CHUNK_FREE ! 266: #define OBSTACK_CHUNK_FREE free ! 267: #endif ! 268: _obstack_begin (obstack, OBSTACK_CHUNK_SIZE, 0, ! 269: (void *(*) ()) OBSTACK_CHUNK_ALLOC, ! 270: (void (*) ()) OBSTACK_CHUNK_FREE); ! 271: } ! 272: ! 273: /* Save all variables describing the current status into the structure *P. ! 274: This is used before starting a nested function. */ ! 275: ! 276: void ! 277: save_tree_status (p) ! 278: struct function *p; ! 279: { ! 280: p->all_types_permanent = all_types_permanent; ! 281: p->momentary_stack = momentary_stack; ! 282: p->maybepermanent_firstobj = maybepermanent_firstobj; ! 283: p->momentary_firstobj = momentary_firstobj; ! 284: p->function_obstack = function_obstack; ! 285: p->function_maybepermanent_obstack = function_maybepermanent_obstack; ! 286: p->current_obstack = current_obstack; ! 287: p->expression_obstack = expression_obstack; ! 288: p->saveable_obstack = saveable_obstack; ! 289: p->rtl_obstack = rtl_obstack; ! 290: ! 291: function_obstack = (struct obstack *) xmalloc (sizeof (struct obstack)); ! 292: gcc_obstack_init (function_obstack); ! 293: ! 294: function_maybepermanent_obstack ! 295: = (struct obstack *) xmalloc (sizeof (struct obstack)); ! 296: gcc_obstack_init (function_maybepermanent_obstack); ! 297: ! 298: current_obstack = &permanent_obstack; ! 299: expression_obstack = &permanent_obstack; ! 300: rtl_obstack = saveable_obstack = &permanent_obstack; ! 301: ! 302: momentary_firstobj = (char *) obstack_finish (&momentary_obstack); ! 303: maybepermanent_firstobj ! 304: = (char *) obstack_finish (function_maybepermanent_obstack); ! 305: } ! 306: ! 307: /* Restore all variables describing the current status from the structure *P. ! 308: This is used after a nested function. */ ! 309: ! 310: void ! 311: restore_tree_status (p) ! 312: struct function *p; ! 313: { ! 314: all_types_permanent = p->all_types_permanent; ! 315: momentary_stack = p->momentary_stack; ! 316: ! 317: obstack_free (&momentary_obstack, momentary_firstobj); ! 318: obstack_free (function_obstack, 0); ! 319: obstack_free (function_maybepermanent_obstack, 0); ! 320: free (function_obstack); ! 321: ! 322: momentary_firstobj = p->momentary_firstobj; ! 323: maybepermanent_firstobj = p->maybepermanent_firstobj; ! 324: function_obstack = p->function_obstack; ! 325: function_maybepermanent_obstack = p->function_maybepermanent_obstack; ! 326: current_obstack = p->current_obstack; ! 327: expression_obstack = p->expression_obstack; ! 328: saveable_obstack = p->saveable_obstack; ! 329: rtl_obstack = p->rtl_obstack; ! 330: } ! 331: ! 332: /* Start allocating on the temporary (per function) obstack. ! 333: This is done in start_function before parsing the function body, ! 334: and before each initialization at top level, and to go back ! 335: to temporary allocation after doing end_temporary_allocation. */ ! 336: ! 337: void ! 338: temporary_allocation () ! 339: { ! 340: /* Note that function_obstack at top level points to temporary_obstack. ! 341: But within a nested function context, it is a separate obstack. */ ! 342: current_obstack = function_obstack; ! 343: expression_obstack = function_obstack; ! 344: rtl_obstack = saveable_obstack = function_maybepermanent_obstack; ! 345: momentary_stack = 0; ! 346: } ! 347: ! 348: /* Start allocating on the permanent obstack but don't ! 349: free the temporary data. After calling this, call ! 350: `permanent_allocation' to fully resume permanent allocation status. */ ! 351: ! 352: void ! 353: end_temporary_allocation () ! 354: { ! 355: current_obstack = &permanent_obstack; ! 356: expression_obstack = &permanent_obstack; ! 357: rtl_obstack = saveable_obstack = &permanent_obstack; ! 358: } ! 359: ! 360: /* Resume allocating on the temporary obstack, undoing ! 361: effects of `end_temporary_allocation'. */ ! 362: ! 363: void ! 364: resume_temporary_allocation () ! 365: { ! 366: current_obstack = function_obstack; ! 367: expression_obstack = function_obstack; ! 368: rtl_obstack = saveable_obstack = function_maybepermanent_obstack; ! 369: } ! 370: ! 371: /* While doing temporary allocation, switch to allocating in such a ! 372: way as to save all nodes if the function is inlined. Call ! 373: resume_temporary_allocation to go back to ordinary temporary ! 374: allocation. */ ! 375: ! 376: void ! 377: saveable_allocation () ! 378: { ! 379: /* Note that function_obstack at top level points to temporary_obstack. ! 380: But within a nested function context, it is a separate obstack. */ ! 381: expression_obstack = current_obstack = saveable_obstack; ! 382: } ! 383: ! 384: /* Switch to current obstack CURRENT and maybepermanent obstack SAVEABLE, ! 385: recording the previously current obstacks on a stack. ! 386: This does not free any storage in any obstack. */ ! 387: ! 388: void ! 389: push_obstacks (current, saveable) ! 390: struct obstack *current, *saveable; ! 391: { ! 392: struct obstack_stack *p ! 393: = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack, ! 394: (sizeof (struct obstack_stack))); ! 395: ! 396: p->current = current_obstack; ! 397: p->saveable = saveable_obstack; ! 398: p->expression = expression_obstack; ! 399: p->rtl = rtl_obstack; ! 400: p->next = obstack_stack; ! 401: obstack_stack = p; ! 402: ! 403: current_obstack = current; ! 404: expression_obstack = current; ! 405: rtl_obstack = saveable_obstack = saveable; ! 406: } ! 407: ! 408: /* Save the current set of obstacks, but don't change them. */ ! 409: ! 410: void ! 411: push_obstacks_nochange () ! 412: { ! 413: struct obstack_stack *p ! 414: = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack, ! 415: (sizeof (struct obstack_stack))); ! 416: ! 417: p->current = current_obstack; ! 418: p->saveable = saveable_obstack; ! 419: p->expression = expression_obstack; ! 420: p->rtl = rtl_obstack; ! 421: p->next = obstack_stack; ! 422: obstack_stack = p; ! 423: } ! 424: ! 425: /* Pop the obstack selection stack. */ ! 426: ! 427: void ! 428: pop_obstacks () ! 429: { ! 430: struct obstack_stack *p = obstack_stack; ! 431: obstack_stack = p->next; ! 432: ! 433: current_obstack = p->current; ! 434: saveable_obstack = p->saveable; ! 435: expression_obstack = p->expression; ! 436: rtl_obstack = p->rtl; ! 437: ! 438: obstack_free (&obstack_stack_obstack, p); ! 439: } ! 440: ! 441: /* Nonzero if temporary allocation is currently in effect. ! 442: Zero if currently doing permanent allocation. */ ! 443: ! 444: int ! 445: allocation_temporary_p () ! 446: { ! 447: return current_obstack != &permanent_obstack; ! 448: } ! 449: ! 450: /* Go back to allocating on the permanent obstack ! 451: and free everything in the temporary obstack. ! 452: This is done in finish_function after fully compiling a function. */ ! 453: ! 454: void ! 455: permanent_allocation () ! 456: { ! 457: /* Free up previous temporary obstack data */ ! 458: obstack_free (&temporary_obstack, temporary_firstobj); ! 459: obstack_free (&momentary_obstack, momentary_firstobj); ! 460: obstack_free (&maybepermanent_obstack, maybepermanent_firstobj); ! 461: obstack_free (&temp_decl_obstack, temp_decl_firstobj); ! 462: ! 463: current_obstack = &permanent_obstack; ! 464: expression_obstack = &permanent_obstack; ! 465: rtl_obstack = saveable_obstack = &permanent_obstack; ! 466: } ! 467: ! 468: /* Save permanently everything on the maybepermanent_obstack. */ ! 469: ! 470: void ! 471: preserve_data () ! 472: { ! 473: maybepermanent_firstobj ! 474: = (char *) obstack_alloc (function_maybepermanent_obstack, 0); ! 475: } ! 476: ! 477: void ! 478: preserve_initializer () ! 479: { ! 480: temporary_firstobj ! 481: = (char *) obstack_alloc (&temporary_obstack, 0); ! 482: momentary_firstobj ! 483: = (char *) obstack_alloc (&momentary_obstack, 0); ! 484: maybepermanent_firstobj ! 485: = (char *) obstack_alloc (function_maybepermanent_obstack, 0); ! 486: } ! 487: ! 488: /* Start allocating new rtl in current_obstack. ! 489: Use resume_temporary_allocation ! 490: to go back to allocating rtl in saveable_obstack. */ ! 491: ! 492: void ! 493: rtl_in_current_obstack () ! 494: { ! 495: rtl_obstack = current_obstack; ! 496: } ! 497: ! 498: /* Temporarily allocate rtl from saveable_obstack. Return 1 if we were ! 499: previously allocating it from current_obstack. */ ! 500: ! 501: int ! 502: rtl_in_saveable_obstack () ! 503: { ! 504: if (rtl_obstack == current_obstack) ! 505: { ! 506: rtl_obstack = saveable_obstack; ! 507: return 1; ! 508: } ! 509: else ! 510: return 0; ! 511: } ! 512: ! 513: /* Allocate SIZE bytes in the current obstack ! 514: and return a pointer to them. ! 515: In practice the current obstack is always the temporary one. */ ! 516: ! 517: char * ! 518: oballoc (size) ! 519: int size; ! 520: { ! 521: return (char *) obstack_alloc (current_obstack, size); ! 522: } ! 523: ! 524: /* Free the object PTR in the current obstack ! 525: as well as everything allocated since PTR. ! 526: In practice the current obstack is always the temporary one. */ ! 527: ! 528: void ! 529: obfree (ptr) ! 530: char *ptr; ! 531: { ! 532: obstack_free (current_obstack, ptr); ! 533: } ! 534: ! 535: /* Allocate SIZE bytes in the permanent obstack ! 536: and return a pointer to them. */ ! 537: ! 538: char * ! 539: permalloc (size) ! 540: long size; ! 541: { ! 542: return (char *) obstack_alloc (&permanent_obstack, size); ! 543: } ! 544: ! 545: /* Allocate NELEM items of SIZE bytes in the permanent obstack ! 546: and return a pointer to them. The storage is cleared before ! 547: returning the value. */ ! 548: ! 549: char * ! 550: perm_calloc (nelem, size) ! 551: int nelem; ! 552: long size; ! 553: { ! 554: char *rval = (char *) obstack_alloc (&permanent_obstack, nelem * size); ! 555: bzero (rval, nelem * size); ! 556: return rval; ! 557: } ! 558: ! 559: /* Allocate SIZE bytes in the saveable obstack ! 560: and return a pointer to them. */ ! 561: ! 562: char * ! 563: savealloc (size) ! 564: int size; ! 565: { ! 566: return (char *) obstack_alloc (saveable_obstack, size); ! 567: } ! 568: ! 569: /* Print out which obstack an object is in. */ ! 570: ! 571: void ! 572: debug_obstack (object) ! 573: char *object; ! 574: { ! 575: struct obstack *obstack = NULL; ! 576: char *obstack_name = NULL; ! 577: struct function *p; ! 578: ! 579: for (p = outer_function_chain; p; p = p->next) ! 580: { ! 581: if (_obstack_allocated_p (p->function_obstack, object)) ! 582: { ! 583: obstack = p->function_obstack; ! 584: obstack_name = "containing function obstack"; ! 585: } ! 586: if (_obstack_allocated_p (p->function_maybepermanent_obstack, object)) ! 587: { ! 588: obstack = p->function_maybepermanent_obstack; ! 589: obstack_name = "containing function maybepermanent obstack"; ! 590: } ! 591: } ! 592: ! 593: if (_obstack_allocated_p (&obstack_stack_obstack, object)) ! 594: { ! 595: obstack = &obstack_stack_obstack; ! 596: obstack_name = "obstack_stack_obstack"; ! 597: } ! 598: else if (_obstack_allocated_p (function_obstack, object)) ! 599: { ! 600: obstack = function_obstack; ! 601: obstack_name = "function obstack"; ! 602: } ! 603: else if (_obstack_allocated_p (&permanent_obstack, object)) ! 604: { ! 605: obstack = &permanent_obstack; ! 606: obstack_name = "permanent_obstack"; ! 607: } ! 608: else if (_obstack_allocated_p (&momentary_obstack, object)) ! 609: { ! 610: obstack = &momentary_obstack; ! 611: obstack_name = "momentary_obstack"; ! 612: } ! 613: else if (_obstack_allocated_p (function_maybepermanent_obstack, object)) ! 614: { ! 615: obstack = function_maybepermanent_obstack; ! 616: obstack_name = "function maybepermanent obstack"; ! 617: } ! 618: else if (_obstack_allocated_p (&temp_decl_obstack, object)) ! 619: { ! 620: obstack = &temp_decl_obstack; ! 621: obstack_name = "temp_decl_obstack"; ! 622: } ! 623: ! 624: /* Check to see if the object is in the free area of the obstack. */ ! 625: if (obstack != NULL) ! 626: { ! 627: if (object >= obstack->next_free ! 628: && object < obstack->chunk_limit) ! 629: fprintf (stderr, "object in free portion of obstack %s.\n", ! 630: obstack_name); ! 631: else ! 632: fprintf (stderr, "object allocated from %s.\n", obstack_name); ! 633: } ! 634: else ! 635: fprintf (stderr, "object not allocated from any obstack.\n"); ! 636: } ! 637: ! 638: /* Return 1 if OBJ is in the permanent obstack. ! 639: This is slow, and should be used only for debugging. ! 640: Use TREE_PERMANENT for other purposes. */ ! 641: ! 642: int ! 643: object_permanent_p (obj) ! 644: tree obj; ! 645: { ! 646: return _obstack_allocated_p (&permanent_obstack, obj); ! 647: } ! 648: ! 649: /* Start a level of momentary allocation. ! 650: In C, each compound statement has its own level ! 651: and that level is freed at the end of each statement. ! 652: All expression nodes are allocated in the momentary allocation level. */ ! 653: ! 654: void ! 655: push_momentary () ! 656: { ! 657: struct momentary_level *tem ! 658: = (struct momentary_level *) obstack_alloc (&momentary_obstack, ! 659: sizeof (struct momentary_level)); ! 660: tem->prev = momentary_stack; ! 661: tem->base = (char *) obstack_base (&momentary_obstack); ! 662: tem->obstack = expression_obstack; ! 663: momentary_stack = tem; ! 664: expression_obstack = &momentary_obstack; ! 665: } ! 666: ! 667: /* Free all the storage in the current momentary-allocation level. ! 668: In C, this happens at the end of each statement. */ ! 669: ! 670: void ! 671: clear_momentary () ! 672: { ! 673: obstack_free (&momentary_obstack, momentary_stack->base); ! 674: } ! 675: ! 676: /* Discard a level of momentary allocation. ! 677: In C, this happens at the end of each compound statement. ! 678: Restore the status of expression node allocation ! 679: that was in effect before this level was created. */ ! 680: ! 681: void ! 682: pop_momentary () ! 683: { ! 684: struct momentary_level *tem = momentary_stack; ! 685: momentary_stack = tem->prev; ! 686: expression_obstack = tem->obstack; ! 687: obstack_free (&momentary_obstack, tem); ! 688: } ! 689: ! 690: /* Call when starting to parse a declaration: ! 691: make expressions in the declaration last the length of the function. ! 692: Returns an argument that should be passed to resume_momentary later. */ ! 693: ! 694: int ! 695: suspend_momentary () ! 696: { ! 697: register int tem = expression_obstack == &momentary_obstack; ! 698: expression_obstack = saveable_obstack; ! 699: return tem; ! 700: } ! 701: ! 702: /* Call when finished parsing a declaration: ! 703: restore the treatment of node-allocation that was ! 704: in effect before the suspension. ! 705: YES should be the value previously returned by suspend_momentary. */ ! 706: ! 707: void ! 708: resume_momentary (yes) ! 709: int yes; ! 710: { ! 711: if (yes) ! 712: expression_obstack = &momentary_obstack; ! 713: } ! 714: ! 715: /* Init the tables indexed by tree code. ! 716: Note that languages can add to these tables to define their own codes. */ ! 717: ! 718: void ! 719: init_tree_codes () ! 720: { ! 721: tree_code_type = (char **) xmalloc (sizeof (standard_tree_code_type)); ! 722: tree_code_length = (int *) xmalloc (sizeof (standard_tree_code_length)); ! 723: tree_code_name = (char **) xmalloc (sizeof (standard_tree_code_name)); ! 724: bcopy (standard_tree_code_type, tree_code_type, ! 725: sizeof (standard_tree_code_type)); ! 726: bcopy (standard_tree_code_length, tree_code_length, ! 727: sizeof (standard_tree_code_length)); ! 728: bcopy (standard_tree_code_name, tree_code_name, ! 729: sizeof (standard_tree_code_name)); ! 730: } ! 731: ! 732: /* Return a newly allocated node of code CODE. ! 733: Initialize the node's unique id and its TREE_PERMANENT flag. ! 734: For decl and type nodes, some other fields are initialized. ! 735: The rest of the node is initialized to zero. ! 736: ! 737: Achoo! I got a code in the node. */ ! 738: ! 739: tree ! 740: make_node (code) ! 741: enum tree_code code; ! 742: { ! 743: register tree t; ! 744: register int type = TREE_CODE_CLASS (code); ! 745: register int length; ! 746: register struct obstack *obstack = current_obstack; ! 747: register int i; ! 748: register tree_node_kind kind; ! 749: ! 750: switch (type) ! 751: { ! 752: case 'd': /* A decl node */ ! 753: #ifdef GATHER_STATISTICS ! 754: kind = d_kind; ! 755: #endif ! 756: length = sizeof (struct tree_decl); ! 757: /* All decls in an inline function need to be saved. */ ! 758: if (obstack != &permanent_obstack) ! 759: obstack = saveable_obstack; ! 760: /* PARM_DECLs always go on saveable_obstack, not permanent, ! 761: even though we may make them before the function turns ! 762: on temporary allocation. */ ! 763: else if (code == PARM_DECL) ! 764: obstack = function_maybepermanent_obstack; ! 765: break; ! 766: ! 767: case 't': /* a type node */ ! 768: #ifdef GATHER_STATISTICS ! 769: kind = t_kind; ! 770: #endif ! 771: length = sizeof (struct tree_type); ! 772: /* All data types are put where we can preserve them if nec. */ ! 773: if (obstack != &permanent_obstack) ! 774: obstack = all_types_permanent ? &permanent_obstack : saveable_obstack; ! 775: break; ! 776: ! 777: case 's': /* an expression with side effects */ ! 778: #ifdef GATHER_STATISTICS ! 779: kind = s_kind; ! 780: goto usual_kind; ! 781: #endif ! 782: case 'r': /* a reference */ ! 783: #ifdef GATHER_STATISTICS ! 784: kind = r_kind; ! 785: goto usual_kind; ! 786: #endif ! 787: case 'e': /* an expression */ ! 788: case '<': /* a comparison expression */ ! 789: case '1': /* a unary arithmetic expression */ ! 790: case '2': /* a binary arithmetic expression */ ! 791: #ifdef GATHER_STATISTICS ! 792: kind = e_kind; ! 793: usual_kind: ! 794: #endif ! 795: obstack = expression_obstack; ! 796: /* All BLOCK nodes are put where we can preserve them if nec. ! 797: Also their potential controllers. */ ! 798: if ((code == BLOCK || code == BIND_EXPR) ! 799: && obstack != &permanent_obstack) ! 800: obstack = saveable_obstack; ! 801: length = sizeof (struct tree_exp) ! 802: + (tree_code_length[(int) code] - 1) * sizeof (char *); ! 803: break; ! 804: ! 805: case 'c': /* a constant */ ! 806: #ifdef GATHER_STATISTICS ! 807: kind = c_kind; ! 808: #endif ! 809: obstack = expression_obstack; ! 810: /* We can't use tree_code_length for this, since the number of words ! 811: is machine-dependent due to varying alignment of `double'. */ ! 812: if (code == REAL_CST) ! 813: { ! 814: length = sizeof (struct tree_real_cst); ! 815: break; ! 816: } ! 817: ! 818: case 'x': /* something random, like an identifier. */ ! 819: #ifdef GATHER_STATISTICS ! 820: if (code == IDENTIFIER_NODE) ! 821: kind = id_kind; ! 822: else if (code == OP_IDENTIFIER) ! 823: kind = op_id_kind; ! 824: else if (code == TREE_VEC) ! 825: kind = vec_kind; ! 826: else ! 827: kind = x_kind; ! 828: #endif ! 829: length = sizeof (struct tree_common) ! 830: + tree_code_length[(int) code] * sizeof (char *); ! 831: /* Identifier nodes are always permanent since they are ! 832: unique in a compiler run. */ ! 833: if (code == IDENTIFIER_NODE) obstack = &permanent_obstack; ! 834: } ! 835: ! 836: t = (tree) obstack_alloc (obstack, length); ! 837: ! 838: #ifdef GATHER_STATISTICS ! 839: tree_node_counts[(int)kind]++; ! 840: tree_node_sizes[(int)kind] += length; ! 841: #endif ! 842: ! 843: TREE_TYPE (t) = 0; ! 844: TREE_CHAIN (t) = 0; ! 845: for (i = (length / sizeof (int)) - 1; ! 846: i >= sizeof (struct tree_common) / sizeof (int) - 1; ! 847: i--) ! 848: ((int *) t)[i] = 0; ! 849: ! 850: TREE_SET_CODE (t, code); ! 851: if (obstack == &permanent_obstack) ! 852: TREE_PERMANENT (t) = 1; ! 853: ! 854: switch (type) ! 855: { ! 856: case 's': ! 857: TREE_SIDE_EFFECTS (t) = 1; ! 858: TREE_TYPE (t) = void_type_node; ! 859: break; ! 860: ! 861: case 'd': ! 862: DECL_ALIGN (t) = 1; ! 863: DECL_SOURCE_LINE (t) = lineno; ! 864: DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>"; ! 865: break; ! 866: ! 867: case 't': ! 868: { ! 869: static unsigned next_type_uid = 1; ! 870: ! 871: TYPE_UID (t) = next_type_uid++; ! 872: } ! 873: TYPE_ALIGN (t) = 1; ! 874: TYPE_MAIN_VARIANT (t) = t; ! 875: break; ! 876: ! 877: case 'c': ! 878: TREE_CONSTANT (t) = 1; ! 879: break; ! 880: } ! 881: ! 882: return t; ! 883: } ! 884: ! 885: /* Return a new node with the same contents as NODE ! 886: except that its TREE_CHAIN is zero and it has a fresh uid. */ ! 887: ! 888: tree ! 889: copy_node (node) ! 890: tree node; ! 891: { ! 892: register tree t; ! 893: register enum tree_code code = TREE_CODE (node); ! 894: register int length; ! 895: register int i; ! 896: ! 897: switch (TREE_CODE_CLASS (code)) ! 898: { ! 899: case 'd': /* A decl node */ ! 900: length = sizeof (struct tree_decl); ! 901: break; ! 902: ! 903: case 't': /* a type node */ ! 904: length = sizeof (struct tree_type); ! 905: break; ! 906: ! 907: case 'r': /* a reference */ ! 908: case 'e': /* a expression */ ! 909: case 's': /* an expression with side effects */ ! 910: case '<': /* a comparison expression */ ! 911: case '1': /* a unary arithmetic expression */ ! 912: case '2': /* a binary arithmetic expression */ ! 913: length = sizeof (struct tree_exp) ! 914: + (tree_code_length[(int) code] - 1) * sizeof (char *); ! 915: break; ! 916: ! 917: case 'c': /* a constant */ ! 918: /* We can't use tree_code_length for this, since the number of words ! 919: is machine-dependent due to varying alignment of `double'. */ ! 920: if (code == REAL_CST) ! 921: { ! 922: length = sizeof (struct tree_real_cst); ! 923: break; ! 924: } ! 925: ! 926: case 'x': /* something random, like an identifier. */ ! 927: length = sizeof (struct tree_common) ! 928: + tree_code_length[(int) code] * sizeof (char *); ! 929: if (code == TREE_VEC) ! 930: length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *); ! 931: } ! 932: ! 933: t = (tree) obstack_alloc (current_obstack, length); ! 934: ! 935: for (i = ((length + sizeof (int) - 1) / sizeof (int)) - 1; ! 936: i >= 0; ! 937: i--) ! 938: ((int *) t)[i] = ((int *) node)[i]; ! 939: ! 940: TREE_CHAIN (t) = 0; ! 941: ! 942: TREE_PERMANENT (t) = (current_obstack == &permanent_obstack); ! 943: ! 944: return t; ! 945: } ! 946: ! 947: /* Return a copy of a chain of nodes, chained through the TREE_CHAIN field. ! 948: For example, this can copy a list made of TREE_LIST nodes. */ ! 949: ! 950: tree ! 951: copy_list (list) ! 952: tree list; ! 953: { ! 954: tree head; ! 955: register tree prev, next; ! 956: ! 957: if (list == 0) ! 958: return 0; ! 959: ! 960: head = prev = copy_node (list); ! 961: next = TREE_CHAIN (list); ! 962: while (next) ! 963: { ! 964: TREE_CHAIN (prev) = copy_node (next); ! 965: prev = TREE_CHAIN (prev); ! 966: next = TREE_CHAIN (next); ! 967: } ! 968: return head; ! 969: } ! 970: ! 971: #define HASHBITS 30 ! 972: ! 973: /* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string). ! 974: If an identifier with that name has previously been referred to, ! 975: the same node is returned this time. */ ! 976: ! 977: tree ! 978: get_identifier (text) ! 979: register char *text; ! 980: { ! 981: register int hi; ! 982: register int i; ! 983: register tree idp; ! 984: register int len, hash_len; ! 985: ! 986: /* Compute length of text in len. */ ! 987: for (len = 0; text[len]; len++); ! 988: ! 989: /* Decide how much of that length to hash on */ ! 990: hash_len = len; ! 991: if (warn_id_clash && len > id_clash_len) ! 992: hash_len = id_clash_len; ! 993: ! 994: /* Compute hash code */ ! 995: hi = hash_len * 613 + (unsigned)text[0]; ! 996: for (i = 1; i < hash_len; i += 2) ! 997: hi = ((hi * 613) + (unsigned)(text[i])); ! 998: ! 999: hi &= (1 << HASHBITS) - 1; ! 1000: hi %= MAX_HASH_TABLE; ! 1001: ! 1002: /* Search table for identifier */ ! 1003: for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp)) ! 1004: if (IDENTIFIER_LENGTH (idp) == len ! 1005: && IDENTIFIER_POINTER (idp)[0] == text[0] ! 1006: && !bcmp (IDENTIFIER_POINTER (idp), text, len)) ! 1007: return idp; /* <-- return if found */ ! 1008: ! 1009: /* Not found; optionally warn about a similar identifier */ ! 1010: if (warn_id_clash && do_identifier_warnings && len >= id_clash_len) ! 1011: for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp)) ! 1012: if (!strncmp (IDENTIFIER_POINTER (idp), text, id_clash_len)) ! 1013: { ! 1014: warning ("`%s' and `%s' identical in first %d characters", ! 1015: IDENTIFIER_POINTER (idp), text, id_clash_len); ! 1016: break; ! 1017: } ! 1018: ! 1019: if (tree_code_length[(int) IDENTIFIER_NODE] < 0) ! 1020: abort (); /* set_identifier_size hasn't been called. */ ! 1021: ! 1022: /* Not found, create one, add to chain */ ! 1023: idp = make_node (IDENTIFIER_NODE); ! 1024: IDENTIFIER_LENGTH (idp) = len; ! 1025: #ifdef GATHER_STATISTICS ! 1026: id_string_size += len; ! 1027: #endif ! 1028: ! 1029: IDENTIFIER_POINTER (idp) = obstack_copy0 (&permanent_obstack, text, len); ! 1030: ! 1031: TREE_CHAIN (idp) = hash_table[hi]; ! 1032: hash_table[hi] = idp; ! 1033: return idp; /* <-- return if created */ ! 1034: } ! 1035: ! 1036: /* Enable warnings on similar identifiers (if requested). ! 1037: Done after the built-in identifiers are created. */ ! 1038: ! 1039: void ! 1040: start_identifier_warnings () ! 1041: { ! 1042: do_identifier_warnings = 1; ! 1043: } ! 1044: ! 1045: /* Record the size of an identifier node for the language in use. ! 1046: SIZE is the total size in bytes. ! 1047: This is called by the language-specific files. This must be ! 1048: called before allocating any identifiers. */ ! 1049: ! 1050: void ! 1051: set_identifier_size (size) ! 1052: int size; ! 1053: { ! 1054: tree_code_length[(int) IDENTIFIER_NODE] ! 1055: = (size - sizeof (struct tree_common)) / sizeof (tree); ! 1056: } ! 1057: ! 1058: /* Return a newly constructed INTEGER_CST node whose constant value ! 1059: is specified by the two ints LOW and HI. ! 1060: The TREE_TYPE is set to `int'. */ ! 1061: ! 1062: tree ! 1063: build_int_2 (low, hi) ! 1064: int low, hi; ! 1065: { ! 1066: register tree t = make_node (INTEGER_CST); ! 1067: TREE_INT_CST_LOW (t) = low; ! 1068: TREE_INT_CST_HIGH (t) = hi; ! 1069: TREE_TYPE (t) = integer_type_node; ! 1070: return t; ! 1071: } ! 1072: ! 1073: /* Return a new REAL_CST node whose type is TYPE and value is D. */ ! 1074: ! 1075: tree ! 1076: build_real (type, d) ! 1077: tree type; ! 1078: REAL_VALUE_TYPE d; ! 1079: { ! 1080: tree v; ! 1081: ! 1082: /* Check for valid float value for this type on this target machine; ! 1083: if not, can print error message and store a valid value in D. */ ! 1084: #ifdef CHECK_FLOAT_VALUE ! 1085: CHECK_FLOAT_VALUE (TYPE_MODE (type), d); ! 1086: #endif ! 1087: ! 1088: v = make_node (REAL_CST); ! 1089: TREE_TYPE (v) = type; ! 1090: TREE_REAL_CST (v) = d; ! 1091: return v; ! 1092: } ! 1093: ! 1094: /* Return a new REAL_CST node whose type is TYPE ! 1095: and whose value is the integer value of the INTEGER_CST node I. */ ! 1096: ! 1097: #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC) ! 1098: ! 1099: REAL_VALUE_TYPE ! 1100: real_value_from_int_cst (i) ! 1101: tree i; ! 1102: { ! 1103: REAL_VALUE_TYPE d; ! 1104: #ifdef REAL_ARITHMETIC ! 1105: REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i)); ! 1106: #else /* not REAL_ARITHMETIC */ ! 1107: if (TREE_INT_CST_HIGH (i) < 0) ! 1108: { ! 1109: d = (double) (~ TREE_INT_CST_HIGH (i)); ! 1110: d *= ((double) (1 << (HOST_BITS_PER_INT / 2)) ! 1111: * (double) (1 << (HOST_BITS_PER_INT / 2))); ! 1112: d += (double) (unsigned) (~ TREE_INT_CST_LOW (i)); ! 1113: d = (- d - 1.0); ! 1114: } ! 1115: else ! 1116: { ! 1117: d = (double) TREE_INT_CST_HIGH (i); ! 1118: d *= ((double) (1 << (HOST_BITS_PER_INT / 2)) ! 1119: * (double) (1 << (HOST_BITS_PER_INT / 2))); ! 1120: d += (double) (unsigned) TREE_INT_CST_LOW (i); ! 1121: } ! 1122: #endif /* not REAL_ARITHMETIC */ ! 1123: return d; ! 1124: } ! 1125: ! 1126: /* This function can't be implemented if we can't do arithmetic ! 1127: on the float representation. */ ! 1128: ! 1129: tree ! 1130: build_real_from_int_cst (type, i) ! 1131: tree type; ! 1132: tree i; ! 1133: { ! 1134: tree v; ! 1135: REAL_VALUE_TYPE d; ! 1136: ! 1137: v = make_node (REAL_CST); ! 1138: TREE_TYPE (v) = type; ! 1139: ! 1140: d = real_value_from_int_cst (i); ! 1141: /* Check for valid float value for this type on this target machine; ! 1142: if not, can print error message and store a valid value in D. */ ! 1143: #ifdef CHECK_FLOAT_VALUE ! 1144: CHECK_FLOAT_VALUE (TYPE_MODE (type), d); ! 1145: #endif ! 1146: ! 1147: TREE_REAL_CST (v) = d; ! 1148: return v; ! 1149: } ! 1150: ! 1151: #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */ ! 1152: ! 1153: /* Return a newly constructed STRING_CST node whose value is ! 1154: the LEN characters at STR. ! 1155: The TREE_TYPE is not initialized. */ ! 1156: ! 1157: tree ! 1158: build_string (len, str) ! 1159: int len; ! 1160: char *str; ! 1161: { ! 1162: register tree s = make_node (STRING_CST); ! 1163: TREE_STRING_LENGTH (s) = len; ! 1164: TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len); ! 1165: return s; ! 1166: } ! 1167: ! 1168: /* Return a newly constructed COMPLEX_CST node whose value is ! 1169: specified by the real and imaginary parts REAL and IMAG. ! 1170: Both REAL and IMAG should be constant nodes. ! 1171: The TREE_TYPE is not initialized. */ ! 1172: ! 1173: tree ! 1174: build_complex (real, imag) ! 1175: tree real, imag; ! 1176: { ! 1177: register tree t = make_node (COMPLEX_CST); ! 1178: TREE_REALPART (t) = real; ! 1179: TREE_IMAGPART (t) = imag; ! 1180: return t; ! 1181: } ! 1182: ! 1183: /* Build a newly constructed TREE_VEC node of length LEN. */ ! 1184: tree ! 1185: make_tree_vec (len) ! 1186: int len; ! 1187: { ! 1188: register tree t; ! 1189: register int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec); ! 1190: register struct obstack *obstack = current_obstack; ! 1191: register int i; ! 1192: ! 1193: #ifdef GATHER_STATISTICS ! 1194: tree_node_counts[(int)vec_kind]++; ! 1195: tree_node_sizes[(int)vec_kind] += length; ! 1196: #endif ! 1197: ! 1198: t = (tree) obstack_alloc (obstack, length); ! 1199: ! 1200: TREE_TYPE (t) = 0; ! 1201: TREE_CHAIN (t) = 0; ! 1202: for (i = (length / sizeof (int)) - 1; ! 1203: i >= sizeof (struct tree_common) / sizeof (int) - 1; ! 1204: i--) ! 1205: ((int *) t)[i] = 0; ! 1206: TREE_SET_CODE (t, TREE_VEC); ! 1207: TREE_VEC_LENGTH (t) = len; ! 1208: if (obstack == &permanent_obstack) ! 1209: TREE_PERMANENT (t) = 1; ! 1210: ! 1211: return t; ! 1212: } ! 1213: ! 1214: /* Return 1 if EXPR is the integer constant zero. */ ! 1215: ! 1216: int ! 1217: integer_zerop (expr) ! 1218: tree expr; ! 1219: { ! 1220: while (TREE_CODE (expr) == NON_LVALUE_EXPR) ! 1221: expr = TREE_OPERAND (expr, 0); ! 1222: ! 1223: return (TREE_CODE (expr) == INTEGER_CST ! 1224: && TREE_INT_CST_LOW (expr) == 0 ! 1225: && TREE_INT_CST_HIGH (expr) == 0); ! 1226: } ! 1227: ! 1228: /* Return 1 if EXPR is the integer constant one. */ ! 1229: ! 1230: int ! 1231: integer_onep (expr) ! 1232: tree expr; ! 1233: { ! 1234: while (TREE_CODE (expr) == NON_LVALUE_EXPR) ! 1235: expr = TREE_OPERAND (expr, 0); ! 1236: ! 1237: return (TREE_CODE (expr) == INTEGER_CST ! 1238: && TREE_INT_CST_LOW (expr) == 1 ! 1239: && TREE_INT_CST_HIGH (expr) == 0); ! 1240: } ! 1241: ! 1242: /* Return 1 if EXPR is an integer containing all 1's ! 1243: in as much precision as it contains. */ ! 1244: ! 1245: int ! 1246: integer_all_onesp (expr) ! 1247: tree expr; ! 1248: { ! 1249: register int prec; ! 1250: register int uns; ! 1251: ! 1252: while (TREE_CODE (expr) == NON_LVALUE_EXPR) ! 1253: expr = TREE_OPERAND (expr, 0); ! 1254: ! 1255: if (TREE_CODE (expr) != INTEGER_CST) ! 1256: return 0; ! 1257: ! 1258: uns = TREE_UNSIGNED (TREE_TYPE (expr)); ! 1259: if (!uns) ! 1260: return TREE_INT_CST_LOW (expr) == -1 && TREE_INT_CST_HIGH (expr) == -1; ! 1261: ! 1262: prec = TYPE_PRECISION (TREE_TYPE (expr)); ! 1263: if (prec >= HOST_BITS_PER_INT) ! 1264: { ! 1265: int high_value, shift_amount; ! 1266: ! 1267: shift_amount = prec - HOST_BITS_PER_INT; ! 1268: ! 1269: if (shift_amount > HOST_BITS_PER_INT) ! 1270: /* Can not handle precisions greater than twice the host int size. */ ! 1271: abort (); ! 1272: else if (shift_amount == HOST_BITS_PER_INT) ! 1273: /* Shifting by the host word size is undefined according to the ANSI ! 1274: standard, so we must handle this as a special case. */ ! 1275: high_value = -1; ! 1276: else ! 1277: high_value = (1 << shift_amount) - 1; ! 1278: ! 1279: return TREE_INT_CST_LOW (expr) == -1 ! 1280: && TREE_INT_CST_HIGH (expr) == high_value; ! 1281: } ! 1282: else ! 1283: return TREE_INT_CST_LOW (expr) == (1 << prec) - 1; ! 1284: } ! 1285: ! 1286: /* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only ! 1287: one bit on). */ ! 1288: ! 1289: int ! 1290: integer_pow2p (expr) ! 1291: tree expr; ! 1292: { ! 1293: int high, low; ! 1294: ! 1295: while (TREE_CODE (expr) == NON_LVALUE_EXPR) ! 1296: expr = TREE_OPERAND (expr, 0); ! 1297: ! 1298: if (TREE_CODE (expr) != INTEGER_CST) ! 1299: return 0; ! 1300: ! 1301: high = TREE_INT_CST_HIGH (expr); ! 1302: low = TREE_INT_CST_LOW (expr); ! 1303: ! 1304: if (high == 0 && low == 0) ! 1305: return 0; ! 1306: ! 1307: return ((high == 0 && (low & (low - 1)) == 0) ! 1308: || (low == 0 && (high & (high - 1)) == 0)); ! 1309: } ! 1310: ! 1311: /* Return 1 if EXPR is the real constant zero. */ ! 1312: ! 1313: int ! 1314: real_zerop (expr) ! 1315: tree expr; ! 1316: { ! 1317: while (TREE_CODE (expr) == NON_LVALUE_EXPR) ! 1318: expr = TREE_OPERAND (expr, 0); ! 1319: ! 1320: return (TREE_CODE (expr) == REAL_CST ! 1321: && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0)); ! 1322: } ! 1323: ! 1324: /* Return 1 if EXPR is the real constant one. */ ! 1325: ! 1326: int ! 1327: real_onep (expr) ! 1328: tree expr; ! 1329: { ! 1330: while (TREE_CODE (expr) == NON_LVALUE_EXPR) ! 1331: expr = TREE_OPERAND (expr, 0); ! 1332: ! 1333: return (TREE_CODE (expr) == REAL_CST ! 1334: && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1)); ! 1335: } ! 1336: ! 1337: /* Return 1 if EXPR is the real constant two. */ ! 1338: ! 1339: int ! 1340: real_twop (expr) ! 1341: tree expr; ! 1342: { ! 1343: while (TREE_CODE (expr) == NON_LVALUE_EXPR) ! 1344: expr = TREE_OPERAND (expr, 0); ! 1345: ! 1346: return (TREE_CODE (expr) == REAL_CST ! 1347: && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2)); ! 1348: } ! 1349: ! 1350: /* Nonzero if EXP is a constant or a cast of a constant. */ ! 1351: ! 1352: int ! 1353: really_constant_p (exp) ! 1354: tree exp; ! 1355: { ! 1356: while (TREE_CODE (exp) == NOP_EXPR ! 1357: || TREE_CODE (exp) == CONVERT_EXPR ! 1358: || TREE_CODE (exp) == NON_LVALUE_EXPR) ! 1359: exp = TREE_OPERAND (exp, 0); ! 1360: return TREE_CONSTANT (exp); ! 1361: } ! 1362: ! 1363: /* Return first list element whose TREE_VALUE is ELEM. ! 1364: Return 0 if ELEM is not it LIST. */ ! 1365: ! 1366: tree ! 1367: value_member (elem, list) ! 1368: tree elem, list; ! 1369: { ! 1370: while (list) ! 1371: { ! 1372: if (elem == TREE_VALUE (list)) ! 1373: return list; ! 1374: list = TREE_CHAIN (list); ! 1375: } ! 1376: return NULL_TREE; ! 1377: } ! 1378: ! 1379: /* Return first list element whose TREE_PURPOSE is ELEM. ! 1380: Return 0 if ELEM is not it LIST. */ ! 1381: ! 1382: tree ! 1383: purpose_member (elem, list) ! 1384: tree elem, list; ! 1385: { ! 1386: while (list) ! 1387: { ! 1388: if (elem == TREE_PURPOSE (list)) ! 1389: return list; ! 1390: list = TREE_CHAIN (list); ! 1391: } ! 1392: return NULL_TREE; ! 1393: } ! 1394: ! 1395: /* Return first list element whose BINFO_TYPE is ELEM. ! 1396: Return 0 if ELEM is not it LIST. */ ! 1397: ! 1398: tree ! 1399: binfo_member (elem, list) ! 1400: tree elem, list; ! 1401: { ! 1402: while (list) ! 1403: { ! 1404: if (elem == BINFO_TYPE (list)) ! 1405: return list; ! 1406: list = TREE_CHAIN (list); ! 1407: } ! 1408: return NULL_TREE; ! 1409: } ! 1410: ! 1411: /* Return nonzero if ELEM is part of the chain CHAIN. */ ! 1412: ! 1413: int ! 1414: chain_member (elem, chain) ! 1415: tree elem, chain; ! 1416: { ! 1417: while (chain) ! 1418: { ! 1419: if (elem == chain) ! 1420: return 1; ! 1421: chain = TREE_CHAIN (chain); ! 1422: } ! 1423: ! 1424: return 0; ! 1425: } ! 1426: ! 1427: /* Return the length of a chain of nodes chained through TREE_CHAIN. ! 1428: We expect a null pointer to mark the end of the chain. ! 1429: This is the Lisp primitive `length'. */ ! 1430: ! 1431: int ! 1432: list_length (t) ! 1433: tree t; ! 1434: { ! 1435: register tree tail; ! 1436: register int len = 0; ! 1437: ! 1438: for (tail = t; tail; tail = TREE_CHAIN (tail)) ! 1439: len++; ! 1440: ! 1441: return len; ! 1442: } ! 1443: ! 1444: /* Concatenate two chains of nodes (chained through TREE_CHAIN) ! 1445: by modifying the last node in chain 1 to point to chain 2. ! 1446: This is the Lisp primitive `nconc'. */ ! 1447: ! 1448: tree ! 1449: chainon (op1, op2) ! 1450: tree op1, op2; ! 1451: { ! 1452: tree t; ! 1453: ! 1454: if (op1) ! 1455: { ! 1456: for (t = op1; TREE_CHAIN (t); t = TREE_CHAIN (t)) ! 1457: if (t == op2) abort (); /* Circularity being created */ ! 1458: TREE_CHAIN (t) = op2; ! 1459: return op1; ! 1460: } ! 1461: else return op2; ! 1462: } ! 1463: ! 1464: /* Return the last node in a chain of nodes (chained through TREE_CHAIN). */ ! 1465: ! 1466: tree ! 1467: tree_last (chain) ! 1468: register tree chain; ! 1469: { ! 1470: register tree next; ! 1471: if (chain) ! 1472: while (next = TREE_CHAIN (chain)) ! 1473: chain = next; ! 1474: return chain; ! 1475: } ! 1476: ! 1477: /* Reverse the order of elements in the chain T, ! 1478: and return the new head of the chain (old last element). */ ! 1479: ! 1480: tree ! 1481: nreverse (t) ! 1482: tree t; ! 1483: { ! 1484: register tree prev = 0, decl, next; ! 1485: for (decl = t; decl; decl = next) ! 1486: { ! 1487: next = TREE_CHAIN (decl); ! 1488: TREE_CHAIN (decl) = prev; ! 1489: prev = decl; ! 1490: } ! 1491: return prev; ! 1492: } ! 1493: ! 1494: /* Given a chain CHAIN of tree nodes, ! 1495: construct and return a list of those nodes. */ ! 1496: ! 1497: tree ! 1498: listify (chain) ! 1499: tree chain; ! 1500: { ! 1501: tree result = NULL_TREE; ! 1502: tree in_tail = chain; ! 1503: tree out_tail = NULL_TREE; ! 1504: ! 1505: while (in_tail) ! 1506: { ! 1507: tree next = tree_cons (NULL_TREE, in_tail, NULL_TREE); ! 1508: if (out_tail) ! 1509: TREE_CHAIN (out_tail) = next; ! 1510: else ! 1511: result = next; ! 1512: out_tail = next; ! 1513: in_tail = TREE_CHAIN (in_tail); ! 1514: } ! 1515: ! 1516: return result; ! 1517: } ! 1518: ! 1519: /* Return a newly created TREE_LIST node whose ! 1520: purpose and value fields are PARM and VALUE. */ ! 1521: ! 1522: tree ! 1523: build_tree_list (parm, value) ! 1524: tree parm, value; ! 1525: { ! 1526: register tree t = make_node (TREE_LIST); ! 1527: TREE_PURPOSE (t) = parm; ! 1528: TREE_VALUE (t) = value; ! 1529: return t; ! 1530: } ! 1531: ! 1532: /* Similar, but build on the temp_decl_obstack. */ ! 1533: ! 1534: tree ! 1535: build_decl_list (parm, value) ! 1536: tree parm, value; ! 1537: { ! 1538: register tree node; ! 1539: register struct obstack *ambient_obstack = current_obstack; ! 1540: current_obstack = &temp_decl_obstack; ! 1541: node = build_tree_list (parm, value); ! 1542: current_obstack = ambient_obstack; ! 1543: return node; ! 1544: } ! 1545: ! 1546: /* Return a newly created TREE_LIST node whose ! 1547: purpose and value fields are PARM and VALUE ! 1548: and whose TREE_CHAIN is CHAIN. */ ! 1549: ! 1550: tree ! 1551: tree_cons (purpose, value, chain) ! 1552: tree purpose, value, chain; ! 1553: { ! 1554: #if 0 ! 1555: register tree node = make_node (TREE_LIST); ! 1556: #else ! 1557: register int i; ! 1558: register tree node = (tree) obstack_alloc (current_obstack, sizeof (struct tree_list)); ! 1559: #ifdef GATHER_STATISTICS ! 1560: tree_node_counts[(int)x_kind]++; ! 1561: tree_node_sizes[(int)x_kind] += sizeof (struct tree_list); ! 1562: #endif ! 1563: ! 1564: ((int *)node)[(sizeof (struct tree_common)/sizeof (int)) - 1] = 0; ! 1565: TREE_SET_CODE (node, TREE_LIST); ! 1566: if (current_obstack == &permanent_obstack) ! 1567: TREE_PERMANENT (node) = 1; ! 1568: TREE_TYPE (node) = 0; ! 1569: #endif ! 1570: ! 1571: TREE_CHAIN (node) = chain; ! 1572: TREE_PURPOSE (node) = purpose; ! 1573: TREE_VALUE (node) = value; ! 1574: return node; ! 1575: } ! 1576: ! 1577: /* Similar, but build on the temp_decl_obstack. */ ! 1578: ! 1579: tree ! 1580: decl_tree_cons (purpose, value, chain) ! 1581: tree purpose, value, chain; ! 1582: { ! 1583: register tree node; ! 1584: register struct obstack *ambient_obstack = current_obstack; ! 1585: current_obstack = &temp_decl_obstack; ! 1586: node = tree_cons (purpose, value, chain); ! 1587: current_obstack = ambient_obstack; ! 1588: return node; ! 1589: } ! 1590: ! 1591: /* Same as `tree_cons' but make a permanent object. */ ! 1592: ! 1593: tree ! 1594: perm_tree_cons (purpose, value, chain) ! 1595: tree purpose, value, chain; ! 1596: { ! 1597: register tree node; ! 1598: register struct obstack *ambient_obstack = current_obstack; ! 1599: current_obstack = &permanent_obstack; ! 1600: ! 1601: node = tree_cons (purpose, value, chain); ! 1602: current_obstack = ambient_obstack; ! 1603: return node; ! 1604: } ! 1605: ! 1606: /* Same as `tree_cons', but make this node temporary, regardless. */ ! 1607: ! 1608: tree ! 1609: temp_tree_cons (purpose, value, chain) ! 1610: tree purpose, value, chain; ! 1611: { ! 1612: register tree node; ! 1613: register struct obstack *ambient_obstack = current_obstack; ! 1614: current_obstack = &temporary_obstack; ! 1615: ! 1616: node = tree_cons (purpose, value, chain); ! 1617: current_obstack = ambient_obstack; ! 1618: return node; ! 1619: } ! 1620: ! 1621: /* Same as `tree_cons', but save this node if the function's RTL is saved. */ ! 1622: ! 1623: tree ! 1624: saveable_tree_cons (purpose, value, chain) ! 1625: tree purpose, value, chain; ! 1626: { ! 1627: register tree node; ! 1628: register struct obstack *ambient_obstack = current_obstack; ! 1629: current_obstack = saveable_obstack; ! 1630: ! 1631: node = tree_cons (purpose, value, chain); ! 1632: current_obstack = ambient_obstack; ! 1633: return node; ! 1634: } ! 1635: ! 1636: /* Return the size nominally occupied by an object of type TYPE ! 1637: when it resides in memory. The value is measured in units of bytes, ! 1638: and its data type is that normally used for type sizes ! 1639: (which is the first type created by make_signed_type or ! 1640: make_unsigned_type). */ ! 1641: ! 1642: tree ! 1643: size_in_bytes (type) ! 1644: tree type; ! 1645: { ! 1646: if (type == error_mark_node) ! 1647: return integer_zero_node; ! 1648: type = TYPE_MAIN_VARIANT (type); ! 1649: if (TYPE_SIZE (type) == 0) ! 1650: { ! 1651: incomplete_type_error (0, type); ! 1652: return integer_zero_node; ! 1653: } ! 1654: return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), ! 1655: size_int (BITS_PER_UNIT)); ! 1656: } ! 1657: ! 1658: /* Return the size of TYPE (in bytes) as an integer, ! 1659: or return -1 if the size can vary. */ ! 1660: ! 1661: int ! 1662: int_size_in_bytes (type) ! 1663: tree type; ! 1664: { ! 1665: int size; ! 1666: if (type == error_mark_node) ! 1667: return 0; ! 1668: type = TYPE_MAIN_VARIANT (type); ! 1669: if (TYPE_SIZE (type) == 0) ! 1670: return -1; ! 1671: if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) ! 1672: return -1; ! 1673: size = TREE_INT_CST_LOW (TYPE_SIZE (type)); ! 1674: return (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT; ! 1675: } ! 1676: ! 1677: /* Return, as an INTEGER_CST node, the number of elements for ! 1678: TYPE (which is an ARRAY_TYPE). */ ! 1679: ! 1680: tree ! 1681: array_type_nelts (type) ! 1682: tree type; ! 1683: { ! 1684: tree index_type = TYPE_DOMAIN (type); ! 1685: return (tree_int_cst_equal (TYPE_MIN_VALUE (index_type), integer_zero_node) ! 1686: ? TYPE_MAX_VALUE (index_type) ! 1687: : fold (build (MINUS_EXPR, integer_type_node, ! 1688: TYPE_MAX_VALUE (index_type), ! 1689: TYPE_MIN_VALUE (index_type)))); ! 1690: } ! 1691: ! 1692: /* Return nonzero if arg is static -- a reference to an object in ! 1693: static storage. This is not the same as the C meaning of `static'. */ ! 1694: ! 1695: int ! 1696: staticp (arg) ! 1697: tree arg; ! 1698: { ! 1699: switch (TREE_CODE (arg)) ! 1700: { ! 1701: case VAR_DECL: ! 1702: case FUNCTION_DECL: ! 1703: case CONSTRUCTOR: ! 1704: return TREE_STATIC (arg) || TREE_EXTERNAL (arg); ! 1705: ! 1706: case STRING_CST: ! 1707: return 1; ! 1708: ! 1709: case COMPONENT_REF: ! 1710: case BIT_FIELD_REF: ! 1711: return staticp (TREE_OPERAND (arg, 0)); ! 1712: ! 1713: case INDIRECT_REF: ! 1714: return TREE_CONSTANT (TREE_OPERAND (arg, 0)); ! 1715: ! 1716: case ARRAY_REF: ! 1717: if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST ! 1718: && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST) ! 1719: return staticp (TREE_OPERAND (arg, 0)); ! 1720: } ! 1721: ! 1722: return 0; ! 1723: } ! 1724: ! 1725: /* This should be applied to any node which may be used in more than one place, ! 1726: but must be evaluated only once. Normally, the code generator would ! 1727: reevaluate the node each time; this forces it to compute it once and save ! 1728: the result. This is done by encapsulating the node in a SAVE_EXPR. */ ! 1729: ! 1730: tree ! 1731: save_expr (expr) ! 1732: tree expr; ! 1733: { ! 1734: register tree t = fold (expr); ! 1735: ! 1736: /* We don't care about whether this can be used as an lvalue in this ! 1737: context. */ ! 1738: while (TREE_CODE (t) == NON_LVALUE_EXPR) ! 1739: t = TREE_OPERAND (t, 0); ! 1740: ! 1741: /* If the tree evaluates to a constant, then we don't want to hide that ! 1742: fact (i.e. this allows further folding, and direct checks for constants). ! 1743: Since it is no problem to reevaluate literals, we just return the ! 1744: literal node. */ ! 1745: ! 1746: if (TREE_CONSTANT (t) || TREE_READONLY (t) || TREE_CODE (t) == SAVE_EXPR) ! 1747: return t; ! 1748: ! 1749: t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL); ! 1750: ! 1751: /* This expression might be placed ahead of a jump to ensure that the ! 1752: value was computed on both sides of the jump. So make sure it isn't ! 1753: eliminated as dead. */ ! 1754: TREE_SIDE_EFFECTS (t) = 1; ! 1755: return t; ! 1756: } ! 1757: ! 1758: /* Stabilize a reference so that we can use it any number of times ! 1759: without causing its operands to be evaluated more than once. ! 1760: Returns the stabilized reference. ! 1761: ! 1762: Also allows conversion expressions whose operands are references. ! 1763: Any other kind of expression is returned unchanged. */ ! 1764: ! 1765: tree ! 1766: stabilize_reference (ref) ! 1767: tree ref; ! 1768: { ! 1769: register tree result; ! 1770: register enum tree_code code = TREE_CODE (ref); ! 1771: ! 1772: switch (code) ! 1773: { ! 1774: case VAR_DECL: ! 1775: case PARM_DECL: ! 1776: case RESULT_DECL: ! 1777: /* No action is needed in this case. */ ! 1778: return ref; ! 1779: ! 1780: case NOP_EXPR: ! 1781: case CONVERT_EXPR: ! 1782: case FLOAT_EXPR: ! 1783: case FIX_TRUNC_EXPR: ! 1784: case FIX_FLOOR_EXPR: ! 1785: case FIX_ROUND_EXPR: ! 1786: case FIX_CEIL_EXPR: ! 1787: result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0))); ! 1788: break; ! 1789: ! 1790: case INDIRECT_REF: ! 1791: result = build_nt (INDIRECT_REF, ! 1792: stabilize_reference_1 (TREE_OPERAND (ref, 0))); ! 1793: break; ! 1794: ! 1795: case COMPONENT_REF: ! 1796: result = build_nt (COMPONENT_REF, ! 1797: stabilize_reference (TREE_OPERAND (ref, 0)), ! 1798: TREE_OPERAND (ref, 1)); ! 1799: break; ! 1800: ! 1801: case BIT_FIELD_REF: ! 1802: result = build_nt (BIT_FIELD_REF, ! 1803: stabilize_reference (TREE_OPERAND (ref, 0)), ! 1804: stabilize_reference_1 (TREE_OPERAND (ref, 1)), ! 1805: stabilize_reference_1 (TREE_OPERAND (ref, 2))); ! 1806: break; ! 1807: ! 1808: case ARRAY_REF: ! 1809: result = build_nt (ARRAY_REF, ! 1810: stabilize_reference (TREE_OPERAND (ref, 0)), ! 1811: stabilize_reference_1 (TREE_OPERAND (ref, 1))); ! 1812: break; ! 1813: ! 1814: /* If arg isn't a kind of lvalue we recognize, make no change. ! 1815: Caller should recognize the error for an invalid lvalue. */ ! 1816: default: ! 1817: return ref; ! 1818: ! 1819: case ERROR_MARK: ! 1820: return error_mark_node; ! 1821: } ! 1822: ! 1823: TREE_TYPE (result) = TREE_TYPE (ref); ! 1824: TREE_READONLY (result) = TREE_READONLY (ref); ! 1825: TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref); ! 1826: TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref); ! 1827: TREE_RAISES (result) = TREE_RAISES (ref); ! 1828: ! 1829: return result; ! 1830: } ! 1831: ! 1832: /* Subroutine of stabilize_reference; this is called for subtrees of ! 1833: references. Any expression with side-effects must be put in a SAVE_EXPR ! 1834: to ensure that it is only evaluated once. ! 1835: ! 1836: We don't put SAVE_EXPR nodes around everything, because assigning very ! 1837: simple expressions to temporaries causes us to miss good opportunities ! 1838: for optimizations. Among other things, the opportunity to fold in the ! 1839: addition of a constant into an addressing mode often gets lost, e.g. ! 1840: "y[i+1] += x;". In general, we take the approach that we should not make ! 1841: an assignment unless we are forced into it - i.e., that any non-side effect ! 1842: operator should be allowed, and that cse should take care of coalescing ! 1843: multiple utterances of the same expression should that prove fruitful. */ ! 1844: ! 1845: static tree ! 1846: stabilize_reference_1 (e) ! 1847: tree e; ! 1848: { ! 1849: register tree result; ! 1850: register int length; ! 1851: register enum tree_code code = TREE_CODE (e); ! 1852: ! 1853: if (TREE_CONSTANT (e) || TREE_READONLY (e) || code == SAVE_EXPR) ! 1854: return e; ! 1855: ! 1856: switch (TREE_CODE_CLASS (code)) ! 1857: { ! 1858: case 'x': ! 1859: case 't': ! 1860: case 'd': ! 1861: case '<': ! 1862: case 's': ! 1863: case 'e': ! 1864: case 'r': ! 1865: /* If the expression has side-effects, then encase it in a SAVE_EXPR ! 1866: so that it will only be evaluated once. */ ! 1867: /* The reference (r) and comparison (<) classes could be handled as ! 1868: below, but it is generally faster to only evaluate them once. */ ! 1869: if (TREE_SIDE_EFFECTS (e)) ! 1870: return save_expr (e); ! 1871: return e; ! 1872: ! 1873: case 'c': ! 1874: /* Constants need no processing. In fact, we should never reach ! 1875: here. */ ! 1876: return e; ! 1877: ! 1878: case '2': ! 1879: /* Recursively stabilize each operand. */ ! 1880: result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)), ! 1881: stabilize_reference_1 (TREE_OPERAND (e, 1))); ! 1882: break; ! 1883: ! 1884: case '1': ! 1885: /* Recursively stabilize each operand. */ ! 1886: result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0))); ! 1887: break; ! 1888: } ! 1889: ! 1890: TREE_TYPE (result) = TREE_TYPE (e); ! 1891: TREE_READONLY (result) = TREE_READONLY (e); ! 1892: TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e); ! 1893: TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e); ! 1894: TREE_RAISES (result) = TREE_RAISES (e); ! 1895: ! 1896: return result; ! 1897: } ! 1898: ! 1899: /* Low-level constructors for expressions. */ ! 1900: ! 1901: /* Build an expression of code CODE, data type TYPE, ! 1902: and operands as specified by the arguments ARG1 and following arguments. ! 1903: Expressions and reference nodes can be created this way. ! 1904: Constants, decls, types and misc nodes cannot be. */ ! 1905: ! 1906: tree ! 1907: build (va_alist) ! 1908: va_dcl ! 1909: { ! 1910: va_list p; ! 1911: enum tree_code code; ! 1912: register tree t; ! 1913: register int length; ! 1914: register int i; ! 1915: ! 1916: va_start (p); ! 1917: ! 1918: code = va_arg (p, enum tree_code); ! 1919: t = make_node (code); ! 1920: length = tree_code_length[(int) code]; ! 1921: TREE_TYPE (t) = va_arg (p, tree); ! 1922: ! 1923: if (length == 2) ! 1924: { ! 1925: /* This is equivalent to the loop below, but faster. */ ! 1926: register tree arg0 = va_arg (p, tree); ! 1927: register tree arg1 = va_arg (p, tree); ! 1928: TREE_OPERAND (t, 0) = arg0; ! 1929: TREE_OPERAND (t, 1) = arg1; ! 1930: if ((arg0 && TREE_SIDE_EFFECTS (arg0)) ! 1931: || (arg1 && TREE_SIDE_EFFECTS (arg1))) ! 1932: TREE_SIDE_EFFECTS (t) = 1; ! 1933: TREE_RAISES (t) ! 1934: = (arg0 && TREE_RAISES (arg0)) || (arg1 && TREE_RAISES (arg1)); ! 1935: } ! 1936: else if (length == 1) ! 1937: { ! 1938: register tree arg0 = va_arg (p, tree); ! 1939: ! 1940: /* Call build1 for this! */ ! 1941: if (TREE_CODE_CLASS (code) != 's') ! 1942: abort (); ! 1943: TREE_OPERAND (t, 0) = arg0; ! 1944: if (arg0 && TREE_SIDE_EFFECTS (arg0)) ! 1945: TREE_SIDE_EFFECTS (t) = 1; ! 1946: TREE_RAISES (t) = (arg0 && TREE_RAISES (arg0)); ! 1947: } ! 1948: else ! 1949: { ! 1950: for (i = 0; i < length; i++) ! 1951: { ! 1952: register tree operand = va_arg (p, tree); ! 1953: TREE_OPERAND (t, i) = operand; ! 1954: if (operand) ! 1955: { ! 1956: if (TREE_SIDE_EFFECTS (operand)) ! 1957: TREE_SIDE_EFFECTS (t) = 1; ! 1958: if (TREE_RAISES (operand)) ! 1959: TREE_RAISES (t) = 1; ! 1960: } ! 1961: } ! 1962: } ! 1963: va_end (p); ! 1964: return t; ! 1965: } ! 1966: ! 1967: /* Same as above, but only builds for unary operators. ! 1968: Saves lions share of calls to `build'; cuts down use ! 1969: of varargs, which is expensive for RISC machines. */ ! 1970: tree ! 1971: build1 (code, type, node) ! 1972: enum tree_code code; ! 1973: tree type; ! 1974: tree node; ! 1975: { ! 1976: register struct obstack *obstack = current_obstack; ! 1977: register int i, length; ! 1978: register tree_node_kind kind; ! 1979: register tree t; ! 1980: ! 1981: #ifdef GATHER_STATISTICS ! 1982: if (TREE_CODE_CLASS (code) == 'r') ! 1983: kind = r_kind; ! 1984: else ! 1985: kind = e_kind; ! 1986: #endif ! 1987: ! 1988: obstack = expression_obstack; ! 1989: length = sizeof (struct tree_exp); ! 1990: ! 1991: t = (tree) obstack_alloc (obstack, length); ! 1992: ! 1993: #ifdef GATHER_STATISTICS ! 1994: tree_node_counts[(int)kind]++; ! 1995: tree_node_sizes[(int)kind] += length; ! 1996: #endif ! 1997: ! 1998: TREE_TYPE (t) = type; ! 1999: TREE_CHAIN (t) = 0; ! 2000: ! 2001: for (i = (length / sizeof (int)) - 2; ! 2002: i >= sizeof (struct tree_common) / sizeof (int) - 1; ! 2003: i--) ! 2004: ((int *) t)[i] = 0; ! 2005: TREE_SET_CODE (t, code); ! 2006: ! 2007: if (obstack == &permanent_obstack) ! 2008: TREE_PERMANENT (t) = 1; ! 2009: ! 2010: TREE_OPERAND (t, 0) = node; ! 2011: if (node) ! 2012: { ! 2013: if (TREE_SIDE_EFFECTS (node)) ! 2014: TREE_SIDE_EFFECTS (t) = 1; ! 2015: if (TREE_RAISES (node)) ! 2016: TREE_RAISES (t) = 1; ! 2017: } ! 2018: ! 2019: return t; ! 2020: } ! 2021: ! 2022: /* Similar except don't specify the TREE_TYPE ! 2023: and leave the TREE_SIDE_EFFECTS as 0. ! 2024: It is permissible for arguments to be null, ! 2025: or even garbage if their values do not matter. */ ! 2026: ! 2027: tree ! 2028: build_nt (va_alist) ! 2029: va_dcl ! 2030: { ! 2031: va_list p; ! 2032: register enum tree_code code; ! 2033: register tree t; ! 2034: register int length; ! 2035: register int i; ! 2036: ! 2037: va_start (p); ! 2038: ! 2039: code = va_arg (p, enum tree_code); ! 2040: t = make_node (code); ! 2041: length = tree_code_length[(int) code]; ! 2042: ! 2043: for (i = 0; i < length; i++) ! 2044: TREE_OPERAND (t, i) = va_arg (p, tree); ! 2045: ! 2046: va_end (p); ! 2047: return t; ! 2048: } ! 2049: ! 2050: /* Similar to `build_nt', except we build ! 2051: on the temp_decl_obstack, regardless. */ ! 2052: ! 2053: tree ! 2054: build_parse_node (va_alist) ! 2055: va_dcl ! 2056: { ! 2057: register struct obstack *ambient_obstack = expression_obstack; ! 2058: va_list p; ! 2059: register enum tree_code code; ! 2060: register tree t; ! 2061: register int length; ! 2062: register int i; ! 2063: ! 2064: expression_obstack = &temp_decl_obstack; ! 2065: ! 2066: va_start (p); ! 2067: ! 2068: code = va_arg (p, enum tree_code); ! 2069: t = make_node (code); ! 2070: length = tree_code_length[(int) code]; ! 2071: ! 2072: for (i = 0; i < length; i++) ! 2073: TREE_OPERAND (t, i) = va_arg (p, tree); ! 2074: ! 2075: va_end (p); ! 2076: expression_obstack = ambient_obstack; ! 2077: return t; ! 2078: } ! 2079: ! 2080: #if 0 ! 2081: /* Commented out because this wants to be done very ! 2082: differently. See cp-lex.c. */ ! 2083: tree ! 2084: build_op_identifier (op1, op2) ! 2085: tree op1, op2; ! 2086: { ! 2087: register tree t = make_node (OP_IDENTIFIER); ! 2088: TREE_PURPOSE (t) = op1; ! 2089: TREE_VALUE (t) = op2; ! 2090: return t; ! 2091: } ! 2092: #endif ! 2093: ! 2094: /* Create a DECL_... node of code CODE, name NAME and data type TYPE. ! 2095: We do NOT enter this node in any sort of symbol table. ! 2096: ! 2097: layout_decl is used to set up the decl's storage layout. ! 2098: Other slots are initialized to 0 or null pointers. */ ! 2099: ! 2100: tree ! 2101: build_decl (code, name, type) ! 2102: enum tree_code code; ! 2103: tree name, type; ! 2104: { ! 2105: register tree t; ! 2106: ! 2107: t = make_node (code); ! 2108: ! 2109: /* if (type == error_mark_node) ! 2110: type = integer_type_node; */ ! 2111: /* That is not done, deliberately, so that having error_mark_node ! 2112: as the type can suppress useless errors in the use of this variable. */ ! 2113: ! 2114: DECL_NAME (t) = name; ! 2115: DECL_ASSEMBLER_NAME (t) = name; ! 2116: TREE_TYPE (t) = type; ! 2117: ! 2118: if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL) ! 2119: layout_decl (t, 0); ! 2120: else if (code == FUNCTION_DECL) ! 2121: DECL_MODE (t) = FUNCTION_MODE; ! 2122: ! 2123: return t; ! 2124: } ! 2125: ! 2126: /* BLOCK nodes are used to represent the structure of binding contours ! 2127: and declarations, once those contours have been exited and their contents ! 2128: compiled. This information is used for outputting debugging info. ! 2129: A BLOCK may have a "controller" which is a BIND_EXPR node. ! 2130: Then the BLOCK is ignored unless the controller has the TREE_USED flag. */ ! 2131: ! 2132: tree ! 2133: build_block (vars, tags, subblocks, supercontext, chain) ! 2134: tree vars, tags, subblocks, supercontext, chain; ! 2135: { ! 2136: register tree block = make_node (BLOCK); ! 2137: BLOCK_VARS (block) = vars; ! 2138: BLOCK_TYPE_TAGS (block) = tags; ! 2139: BLOCK_SUBBLOCKS (block) = subblocks; ! 2140: BLOCK_SUPERCONTEXT (block) = supercontext; ! 2141: BLOCK_CHAIN (block) = chain; ! 2142: return block; ! 2143: } ! 2144: ! 2145: /* Return a type like TYPE except that its TYPE_READONLY is CONSTP ! 2146: and its TYPE_VOLATILE is VOLATILEP. ! 2147: ! 2148: Such variant types already made are recorded so that duplicates ! 2149: are not made. ! 2150: ! 2151: A variant types should never be used as the type of an expression. ! 2152: Always copy the variant information into the TREE_READONLY ! 2153: and TREE_THIS_VOLATILE of the expression, and then give the expression ! 2154: as its type the "main variant", the variant whose TYPE_READONLY ! 2155: and TYPE_VOLATILE are zero. Use TYPE_MAIN_VARIANT to find the ! 2156: main variant. */ ! 2157: ! 2158: tree ! 2159: build_type_variant (type, constp, volatilep) ! 2160: tree type; ! 2161: int constp, volatilep; ! 2162: { ! 2163: register tree t, m = TYPE_MAIN_VARIANT (type); ! 2164: register struct obstack *ambient_obstack = current_obstack; ! 2165: ! 2166: /* Treat any nonzero argument as 1. */ ! 2167: constp = !!constp; ! 2168: volatilep = !!volatilep; ! 2169: ! 2170: /* If not generating auxilliary info, search the chain of variants to see ! 2171: if there is already one there just like the one we need to have. If so, ! 2172: use that existing one. ! 2173: ! 2174: We don't do this in the case where we are generating aux info because ! 2175: in that case we want each typedef names to get it's own distinct type ! 2176: node, even if the type of this new typedef is the same as some other ! 2177: (existing) type. */ ! 2178: ! 2179: if (!flag_gen_aux_info) ! 2180: for (t = m; t; t = TYPE_NEXT_VARIANT (t)) ! 2181: if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t)) ! 2182: return t; ! 2183: ! 2184: /* We need a new one. */ ! 2185: current_obstack ! 2186: = TREE_PERMANENT (type) ? &permanent_obstack : saveable_obstack; ! 2187: ! 2188: t = copy_node (type); ! 2189: TYPE_READONLY (t) = constp; ! 2190: TYPE_VOLATILE (t) = volatilep; ! 2191: TYPE_POINTER_TO (t) = 0; ! 2192: TYPE_REFERENCE_TO (t) = 0; ! 2193: ! 2194: /* Add this type to the chain of variants of TYPE. */ ! 2195: TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); ! 2196: TYPE_NEXT_VARIANT (m) = t; ! 2197: ! 2198: current_obstack = ambient_obstack; ! 2199: return t; ! 2200: } ! 2201: ! 2202: /* Hashing of types so that we don't make duplicates. ! 2203: The entry point is `type_hash_canon'. */ ! 2204: ! 2205: /* Each hash table slot is a bucket containing a chain ! 2206: of these structures. */ ! 2207: ! 2208: struct type_hash ! 2209: { ! 2210: struct type_hash *next; /* Next structure in the bucket. */ ! 2211: int hashcode; /* Hash code of this type. */ ! 2212: tree type; /* The type recorded here. */ ! 2213: }; ! 2214: ! 2215: /* Now here is the hash table. When recording a type, it is added ! 2216: to the slot whose index is the hash code mod the table size. ! 2217: Note that the hash table is used for several kinds of types ! 2218: (function types, array types and array index range types, for now). ! 2219: While all these live in the same table, they are completely independent, ! 2220: and the hash code is computed differently for each of these. */ ! 2221: ! 2222: #define TYPE_HASH_SIZE 59 ! 2223: struct type_hash *type_hash_table[TYPE_HASH_SIZE]; ! 2224: ! 2225: /* Here is how primitive or already-canonicalized types' hash ! 2226: codes are made. */ ! 2227: #define TYPE_HASH(TYPE) ((int) (TYPE) & 0777777) ! 2228: ! 2229: /* Compute a hash code for a list of types (chain of TREE_LIST nodes ! 2230: with types in the TREE_VALUE slots), by adding the hash codes ! 2231: of the individual types. */ ! 2232: ! 2233: int ! 2234: type_hash_list (list) ! 2235: tree list; ! 2236: { ! 2237: register int hashcode; ! 2238: register tree tail; ! 2239: for (hashcode = 0, tail = list; tail; tail = TREE_CHAIN (tail)) ! 2240: hashcode += TYPE_HASH (TREE_VALUE (tail)); ! 2241: return hashcode; ! 2242: } ! 2243: ! 2244: /* Look in the type hash table for a type isomorphic to TYPE. ! 2245: If one is found, return it. Otherwise return 0. */ ! 2246: ! 2247: tree ! 2248: type_hash_lookup (hashcode, type) ! 2249: int hashcode; ! 2250: tree type; ! 2251: { ! 2252: register struct type_hash *h; ! 2253: for (h = type_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next) ! 2254: if (h->hashcode == hashcode ! 2255: && TREE_CODE (h->type) == TREE_CODE (type) ! 2256: && TREE_TYPE (h->type) == TREE_TYPE (type) ! 2257: && (TYPE_MAX_VALUE (h->type) == TYPE_MAX_VALUE (type) ! 2258: || tree_int_cst_equal (TYPE_MAX_VALUE (h->type), ! 2259: TYPE_MAX_VALUE (type))) ! 2260: && (TYPE_MIN_VALUE (h->type) == TYPE_MIN_VALUE (type) ! 2261: || tree_int_cst_equal (TYPE_MIN_VALUE (h->type), ! 2262: TYPE_MIN_VALUE (type))) ! 2263: && (TYPE_DOMAIN (h->type) == TYPE_DOMAIN (type) ! 2264: || (TYPE_DOMAIN (h->type) ! 2265: && TREE_CODE (TYPE_DOMAIN (h->type)) == TREE_LIST ! 2266: && TYPE_DOMAIN (type) ! 2267: && TREE_CODE (TYPE_DOMAIN (type)) == TREE_LIST ! 2268: && type_list_equal (TYPE_DOMAIN (h->type), TYPE_DOMAIN (type))))) ! 2269: return h->type; ! 2270: return 0; ! 2271: } ! 2272: ! 2273: /* Add an entry to the type-hash-table ! 2274: for a type TYPE whose hash code is HASHCODE. */ ! 2275: ! 2276: void ! 2277: type_hash_add (hashcode, type) ! 2278: int hashcode; ! 2279: tree type; ! 2280: { ! 2281: register struct type_hash *h; ! 2282: ! 2283: h = (struct type_hash *) oballoc (sizeof (struct type_hash)); ! 2284: h->hashcode = hashcode; ! 2285: h->type = type; ! 2286: h->next = type_hash_table[hashcode % TYPE_HASH_SIZE]; ! 2287: type_hash_table[hashcode % TYPE_HASH_SIZE] = h; ! 2288: } ! 2289: ! 2290: /* Given TYPE, and HASHCODE its hash code, return the canonical ! 2291: object for an identical type if one already exists. ! 2292: Otherwise, return TYPE, and record it as the canonical object ! 2293: if it is a permanent object. ! 2294: ! 2295: To use this function, first create a type of the sort you want. ! 2296: Then compute its hash code from the fields of the type that ! 2297: make it different from other similar types. ! 2298: Then call this function and use the value. ! 2299: This function frees the type you pass in if it is a duplicate. */ ! 2300: ! 2301: /* Set to 1 to debug without canonicalization. Never set by program. */ ! 2302: int debug_no_type_hash = 0; ! 2303: ! 2304: tree ! 2305: type_hash_canon (hashcode, type) ! 2306: int hashcode; ! 2307: tree type; ! 2308: { ! 2309: tree t1; ! 2310: ! 2311: if (debug_no_type_hash) ! 2312: return type; ! 2313: ! 2314: t1 = type_hash_lookup (hashcode, type); ! 2315: if (t1 != 0) ! 2316: { ! 2317: struct obstack *o ! 2318: = TREE_PERMANENT (type) ? &permanent_obstack : saveable_obstack; ! 2319: obstack_free (o, type); ! 2320: #ifdef GATHER_STATISTICS ! 2321: tree_node_counts[(int)t_kind]--; ! 2322: tree_node_sizes[(int)t_kind] -= sizeof (struct tree_type); ! 2323: #endif ! 2324: return t1; ! 2325: } ! 2326: ! 2327: /* If this is a new type, record it for later reuse. */ ! 2328: if (current_obstack == &permanent_obstack) ! 2329: type_hash_add (hashcode, type); ! 2330: ! 2331: return type; ! 2332: } ! 2333: ! 2334: /* Given two lists of types ! 2335: (chains of TREE_LIST nodes with types in the TREE_VALUE slots) ! 2336: return 1 if the lists contain the same types in the same order. ! 2337: Also, the TREE_PURPOSEs must match. */ ! 2338: ! 2339: int ! 2340: type_list_equal (l1, l2) ! 2341: tree l1, l2; ! 2342: { ! 2343: register tree t1, t2; ! 2344: for (t1 = l1, t2 = l2; t1 && t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2)) ! 2345: { ! 2346: if (TREE_VALUE (t1) != TREE_VALUE (t2)) ! 2347: return 0; ! 2348: if (TREE_PURPOSE (t1) != TREE_PURPOSE (t2)) ! 2349: { ! 2350: int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)); ! 2351: if (cmp < 0) ! 2352: abort (); ! 2353: if (cmp == 0) ! 2354: return 0; ! 2355: } ! 2356: } ! 2357: ! 2358: return t1 == t2; ! 2359: } ! 2360: ! 2361: /* Nonzero if integer constants T1 and T2 ! 2362: represent the same constant value. */ ! 2363: ! 2364: int ! 2365: tree_int_cst_equal (t1, t2) ! 2366: tree t1, t2; ! 2367: { ! 2368: if (t1 == t2) ! 2369: return 1; ! 2370: if (t1 == 0 || t2 == 0) ! 2371: return 0; ! 2372: if (TREE_CODE (t1) == INTEGER_CST ! 2373: && TREE_CODE (t2) == INTEGER_CST ! 2374: && TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2) ! 2375: && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2)) ! 2376: return 1; ! 2377: return 0; ! 2378: } ! 2379: ! 2380: /* Nonzero if integer constants T1 and T2 represent values that satisfy <. ! 2381: The precise way of comparison depends on their data type. */ ! 2382: ! 2383: int ! 2384: tree_int_cst_lt (t1, t2) ! 2385: tree t1, t2; ! 2386: { ! 2387: if (t1 == t2) ! 2388: return 0; ! 2389: ! 2390: if (!TREE_UNSIGNED (TREE_TYPE (t1))) ! 2391: return INT_CST_LT (t1, t2); ! 2392: return INT_CST_LT_UNSIGNED (t1, t2); ! 2393: } ! 2394: ! 2395: /* Compare two constructor-element-type constants. */ ! 2396: int ! 2397: simple_cst_list_equal (l1, l2) ! 2398: tree l1, l2; ! 2399: { ! 2400: while (l1 != NULL_TREE && l2 != NULL_TREE) ! 2401: { ! 2402: int cmp = simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2)); ! 2403: if (cmp < 0) ! 2404: abort (); ! 2405: if (cmp == 0) ! 2406: return 0; ! 2407: l1 = TREE_CHAIN (l1); ! 2408: l2 = TREE_CHAIN (l2); ! 2409: } ! 2410: return (l1 == l2); ! 2411: } ! 2412: ! 2413: /* Return truthvalue of whether T1 is the same tree structure as T2. ! 2414: Return 1 if they are the same. ! 2415: Return 0 if they are understandably different. ! 2416: Return -1 if either contains tree structure not understood by ! 2417: this function. */ ! 2418: ! 2419: int ! 2420: simple_cst_equal (t1, t2) ! 2421: tree t1, t2; ! 2422: { ! 2423: register enum tree_code code1, code2; ! 2424: int cmp; ! 2425: ! 2426: if (t1 == t2) ! 2427: return 1; ! 2428: if (t1 == 0 || t2 == 0) ! 2429: return 0; ! 2430: ! 2431: code1 = TREE_CODE (t1); ! 2432: code2 = TREE_CODE (t2); ! 2433: ! 2434: if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR) ! 2435: if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR) ! 2436: return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); ! 2437: else ! 2438: return simple_cst_equal (TREE_OPERAND (t1, 0), t2); ! 2439: else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR ! 2440: || code2 == NON_LVALUE_EXPR) ! 2441: return simple_cst_equal (t1, TREE_OPERAND (t2, 0)); ! 2442: ! 2443: if (code1 != code2) ! 2444: return 0; ! 2445: ! 2446: switch (code1) ! 2447: { ! 2448: case INTEGER_CST: ! 2449: return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2) ! 2450: && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2); ! 2451: ! 2452: case REAL_CST: ! 2453: return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2)); ! 2454: ! 2455: case STRING_CST: ! 2456: return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2) ! 2457: && !bcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2), ! 2458: TREE_STRING_LENGTH (t1)); ! 2459: ! 2460: case CONSTRUCTOR: ! 2461: abort (); ! 2462: ! 2463: case SAVE_EXPR: ! 2464: return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); ! 2465: ! 2466: case CALL_EXPR: ! 2467: cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); ! 2468: if (cmp <= 0) ! 2469: return cmp; ! 2470: return simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); ! 2471: ! 2472: case TARGET_EXPR: ! 2473: /* Special case: if either target is an unallocated VAR_DECL, ! 2474: it means that it's going to be unified with whatever the ! 2475: TARGET_EXPR is really supposed to initialize, so treat it ! 2476: as being equivalent to anything. */ ! 2477: if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL ! 2478: && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE ! 2479: && DECL_RTL (TREE_OPERAND (t1, 0)) == 0) ! 2480: || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL ! 2481: && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE ! 2482: && DECL_RTL (TREE_OPERAND (t2, 0)) == 0)) ! 2483: cmp = 1; ! 2484: else ! 2485: cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); ! 2486: if (cmp <= 0) ! 2487: return cmp; ! 2488: return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); ! 2489: ! 2490: case WITH_CLEANUP_EXPR: ! 2491: cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); ! 2492: if (cmp <= 0) ! 2493: return cmp; ! 2494: return simple_cst_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t1, 2)); ! 2495: ! 2496: case COMPONENT_REF: ! 2497: if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1)) ! 2498: return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); ! 2499: return 0; ! 2500: ! 2501: case BIT_FIELD_REF: ! 2502: return (simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)) ! 2503: && simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)) ! 2504: && simple_cst_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t2, 2))); ! 2505: ! 2506: case VAR_DECL: ! 2507: case PARM_DECL: ! 2508: case CONST_DECL: ! 2509: case FUNCTION_DECL: ! 2510: return 0; ! 2511: ! 2512: case PLUS_EXPR: ! 2513: case MINUS_EXPR: ! 2514: case MULT_EXPR: ! 2515: case TRUNC_DIV_EXPR: ! 2516: case TRUNC_MOD_EXPR: ! 2517: case LSHIFT_EXPR: ! 2518: case RSHIFT_EXPR: ! 2519: cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); ! 2520: if (cmp <= 0) ! 2521: return cmp; ! 2522: return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); ! 2523: ! 2524: case NEGATE_EXPR: ! 2525: case ADDR_EXPR: ! 2526: case REFERENCE_EXPR: ! 2527: case INDIRECT_REF: ! 2528: return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); ! 2529: ! 2530: default: ! 2531: #if 0 ! 2532: return lang_simple_cst_equal (t1, t2); ! 2533: #else ! 2534: return -1; ! 2535: #endif ! 2536: } ! 2537: } ! 2538: ! 2539: /* Constructors for pointer, array and function types. ! 2540: (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are ! 2541: constructed by language-dependent code, not here.) */ ! 2542: ! 2543: /* Construct, lay out and return the type of pointers to TO_TYPE. ! 2544: If such a type has already been constructed, reuse it. */ ! 2545: ! 2546: tree ! 2547: build_pointer_type (to_type) ! 2548: tree to_type; ! 2549: { ! 2550: register tree t = TYPE_POINTER_TO (to_type); ! 2551: register struct obstack *ambient_obstack = current_obstack; ! 2552: register struct obstack *ambient_saveable_obstack = saveable_obstack; ! 2553: ! 2554: /* First, if we already have a type for pointers to TO_TYPE, use it. */ ! 2555: ! 2556: if (t) ! 2557: return t; ! 2558: ! 2559: /* We need a new one. If TO_TYPE is permanent, make this permanent too. */ ! 2560: if (TREE_PERMANENT (to_type)) ! 2561: { ! 2562: current_obstack = &permanent_obstack; ! 2563: saveable_obstack = &permanent_obstack; ! 2564: } ! 2565: ! 2566: t = make_node (POINTER_TYPE); ! 2567: TREE_TYPE (t) = to_type; ! 2568: ! 2569: /* Record this type as the pointer to TO_TYPE. */ ! 2570: TYPE_POINTER_TO (to_type) = t; ! 2571: ! 2572: /* Lay out the type. This function has many callers that are concerned ! 2573: with expression-construction, and this simplifies them all. ! 2574: Also, it guarantees the TYPE_SIZE is permanent if the type is. */ ! 2575: layout_type (t); ! 2576: ! 2577: current_obstack = ambient_obstack; ! 2578: saveable_obstack = ambient_saveable_obstack; ! 2579: return t; ! 2580: } ! 2581: ! 2582: /* Create a type of integers to be the TYPE_DOMAIN of an ARRAY_TYPE. ! 2583: MAXVAL should be the maximum value in the domain ! 2584: (one less than the length of the array). */ ! 2585: ! 2586: tree ! 2587: build_index_type (maxval) ! 2588: tree maxval; ! 2589: { ! 2590: register tree itype = make_node (INTEGER_TYPE); ! 2591: TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype); ! 2592: TYPE_MIN_VALUE (itype) = build_int_2 (0, 0); ! 2593: TREE_TYPE (TYPE_MIN_VALUE (itype)) = sizetype; ! 2594: TYPE_MAX_VALUE (itype) = convert (sizetype, maxval); ! 2595: TYPE_MODE (itype) = TYPE_MODE (sizetype); ! 2596: TYPE_SIZE (itype) = TYPE_SIZE (sizetype); ! 2597: TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype); ! 2598: if (TREE_CODE (maxval) == INTEGER_CST) ! 2599: { ! 2600: int maxint = TREE_INT_CST_LOW (maxval); ! 2601: return type_hash_canon (maxint > 0 ? maxint : - maxint, itype); ! 2602: } ! 2603: else ! 2604: return itype; ! 2605: } ! 2606: ! 2607: /* Just like build_index_type, but takes lowval and highval instead ! 2608: of just highval (maxval). */ ! 2609: ! 2610: tree ! 2611: build_index_2_type (lowval,highval) ! 2612: tree lowval, highval; ! 2613: { ! 2614: register tree itype = make_node (INTEGER_TYPE); ! 2615: TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype); ! 2616: TYPE_MIN_VALUE (itype) = convert (sizetype, lowval); ! 2617: TYPE_MAX_VALUE (itype) = convert (sizetype, highval); ! 2618: TYPE_MODE (itype) = TYPE_MODE (sizetype); ! 2619: TYPE_SIZE (itype) = TYPE_SIZE (sizetype); ! 2620: TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype); ! 2621: if ((TREE_CODE (lowval) == INTEGER_CST) ! 2622: && (TREE_CODE (highval) == INTEGER_CST)) ! 2623: { ! 2624: int highint = TREE_INT_CST_LOW (highval); ! 2625: int lowint = TREE_INT_CST_LOW (lowval); ! 2626: int maxint = highint - lowint; ! 2627: return type_hash_canon (maxint > 0 ? maxint : - maxint, itype); ! 2628: } ! 2629: else ! 2630: return itype; ! 2631: } ! 2632: ! 2633: /* Return nonzero iff ITYPE1 and ITYPE2 are equal (in the LISP sense). ! 2634: Needed because when index types are not hashed, equal index types ! 2635: built at different times appear distinct, even though structurally, ! 2636: they are not. */ ! 2637: ! 2638: int ! 2639: index_type_equal (itype1, itype2) ! 2640: tree itype1, itype2; ! 2641: { ! 2642: if (TREE_CODE (itype1) != TREE_CODE (itype2)) ! 2643: return 0; ! 2644: if (TREE_CODE (itype1) == INTEGER_TYPE) ! 2645: { ! 2646: if (TYPE_PRECISION (itype1) != TYPE_PRECISION (itype2) ! 2647: || TYPE_MODE (itype1) != TYPE_MODE (itype2) ! 2648: || ! simple_cst_equal (TYPE_SIZE (itype1), TYPE_SIZE (itype2)) ! 2649: || TYPE_ALIGN (itype1) != TYPE_ALIGN (itype2)) ! 2650: return 0; ! 2651: if (simple_cst_equal (TYPE_MIN_VALUE (itype1), TYPE_MIN_VALUE (itype2)) ! 2652: && simple_cst_equal (TYPE_MAX_VALUE (itype1), TYPE_MAX_VALUE (itype2))) ! 2653: return 1; ! 2654: } ! 2655: return 0; ! 2656: } ! 2657: ! 2658: /* Construct, lay out and return the type of arrays of elements with ELT_TYPE ! 2659: and number of elements specified by the range of values of INDEX_TYPE. ! 2660: If such a type has already been constructed, reuse it. */ ! 2661: ! 2662: tree ! 2663: build_array_type (elt_type, index_type) ! 2664: tree elt_type, index_type; ! 2665: { ! 2666: register tree t; ! 2667: int hashcode; ! 2668: ! 2669: if (TREE_CODE (elt_type) == FUNCTION_TYPE) ! 2670: { ! 2671: error ("arrays of functions are not meaningful"); ! 2672: elt_type = integer_type_node; ! 2673: } ! 2674: ! 2675: /* Make sure TYPE_POINTER_TO (elt_type) is filled in. */ ! 2676: build_pointer_type (elt_type); ! 2677: ! 2678: /* Allocate the array after the pointer type, ! 2679: in case we free it in type_hash_canon. */ ! 2680: t = make_node (ARRAY_TYPE); ! 2681: TREE_TYPE (t) = elt_type; ! 2682: TYPE_DOMAIN (t) = index_type; ! 2683: ! 2684: if (index_type == 0) ! 2685: return t; ! 2686: ! 2687: hashcode = TYPE_HASH (elt_type) + TYPE_HASH (index_type); ! 2688: t = type_hash_canon (hashcode, t); ! 2689: ! 2690: if (TYPE_SIZE (t) == 0) ! 2691: layout_type (t); ! 2692: return t; ! 2693: } ! 2694: ! 2695: /* Construct, lay out and return ! 2696: the type of functions returning type VALUE_TYPE ! 2697: given arguments of types ARG_TYPES. ! 2698: ARG_TYPES is a chain of TREE_LIST nodes whose TREE_VALUEs ! 2699: are data type nodes for the arguments of the function. ! 2700: If such a type has already been constructed, reuse it. */ ! 2701: ! 2702: tree ! 2703: build_function_type (value_type, arg_types) ! 2704: tree value_type, arg_types; ! 2705: { ! 2706: register tree t; ! 2707: int hashcode; ! 2708: ! 2709: if (TREE_CODE (value_type) == FUNCTION_TYPE ! 2710: || TREE_CODE (value_type) == ARRAY_TYPE) ! 2711: { ! 2712: error ("function return type cannot be function or array"); ! 2713: value_type = integer_type_node; ! 2714: } ! 2715: ! 2716: /* Make a node of the sort we want. */ ! 2717: t = make_node (FUNCTION_TYPE); ! 2718: TREE_TYPE (t) = value_type; ! 2719: TYPE_ARG_TYPES (t) = arg_types; ! 2720: ! 2721: /* If we already have such a type, use the old one and free this one. */ ! 2722: hashcode = TYPE_HASH (value_type) + type_hash_list (arg_types); ! 2723: t = type_hash_canon (hashcode, t); ! 2724: ! 2725: if (TYPE_SIZE (t) == 0) ! 2726: layout_type (t); ! 2727: return t; ! 2728: } ! 2729: ! 2730: /* Build the node for the type of references-to-TO_TYPE. */ ! 2731: ! 2732: tree ! 2733: build_reference_type (to_type) ! 2734: tree to_type; ! 2735: { ! 2736: register tree t = TYPE_REFERENCE_TO (to_type); ! 2737: register struct obstack *ambient_obstack = current_obstack; ! 2738: register struct obstack *ambient_saveable_obstack = saveable_obstack; ! 2739: ! 2740: /* First, if we already have a type for pointers to TO_TYPE, use it. */ ! 2741: ! 2742: if (t) ! 2743: return t; ! 2744: ! 2745: /* We need a new one. If TO_TYPE is permanent, make this permanent too. */ ! 2746: if (TREE_PERMANENT (to_type)) ! 2747: { ! 2748: current_obstack = &permanent_obstack; ! 2749: saveable_obstack = &permanent_obstack; ! 2750: } ! 2751: ! 2752: t = make_node (REFERENCE_TYPE); ! 2753: TREE_TYPE (t) = to_type; ! 2754: ! 2755: /* Record this type as the pointer to TO_TYPE. */ ! 2756: TYPE_REFERENCE_TO (to_type) = t; ! 2757: ! 2758: layout_type (t); ! 2759: ! 2760: current_obstack = ambient_obstack; ! 2761: saveable_obstack = ambient_saveable_obstack; ! 2762: return t; ! 2763: } ! 2764: ! 2765: /* Construct, lay out and return the type of methods belonging to class ! 2766: BASETYPE and whose arguments and values are described by TYPE. ! 2767: If that type exists already, reuse it. ! 2768: TYPE must be a FUNCTION_TYPE node. */ ! 2769: ! 2770: tree ! 2771: build_method_type (basetype, type) ! 2772: tree basetype, type; ! 2773: { ! 2774: register tree t; ! 2775: int hashcode; ! 2776: ! 2777: /* Make a node of the sort we want. */ ! 2778: t = make_node (METHOD_TYPE); ! 2779: ! 2780: if (TREE_CODE (type) != FUNCTION_TYPE) ! 2781: abort (); ! 2782: ! 2783: TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype); ! 2784: TREE_TYPE (t) = TREE_TYPE (type); ! 2785: ! 2786: /* The actual arglist for this function includes a "hidden" argument ! 2787: which is "this". Put it into the list of argument types. */ ! 2788: ! 2789: TYPE_ARG_TYPES (t) ! 2790: = tree_cons (NULL, build_pointer_type (basetype), TYPE_ARG_TYPES (type)); ! 2791: ! 2792: /* If we already have such a type, use the old one and free this one. */ ! 2793: hashcode = TYPE_HASH (basetype) + TYPE_HASH (type); ! 2794: t = type_hash_canon (hashcode, t); ! 2795: ! 2796: if (TYPE_SIZE (t) == 0) ! 2797: layout_type (t); ! 2798: ! 2799: return t; ! 2800: } ! 2801: ! 2802: /* Construct, lay out and return the type of methods belonging to class ! 2803: BASETYPE and whose arguments and values are described by TYPE. ! 2804: If that type exists already, reuse it. ! 2805: TYPE must be a FUNCTION_TYPE node. */ ! 2806: ! 2807: tree ! 2808: build_offset_type (basetype, type) ! 2809: tree basetype, type; ! 2810: { ! 2811: register tree t; ! 2812: int hashcode; ! 2813: ! 2814: /* Make a node of the sort we want. */ ! 2815: t = make_node (OFFSET_TYPE); ! 2816: ! 2817: TYPE_OFFSET_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype); ! 2818: TREE_TYPE (t) = type; ! 2819: ! 2820: /* If we already have such a type, use the old one and free this one. */ ! 2821: hashcode = TYPE_HASH (basetype) + TYPE_HASH (type); ! 2822: t = type_hash_canon (hashcode, t); ! 2823: ! 2824: if (TYPE_SIZE (t) == 0) ! 2825: layout_type (t); ! 2826: ! 2827: return t; ! 2828: } ! 2829: ! 2830: /* Create a complex type whose components are COMPONENT_TYPE. */ ! 2831: ! 2832: tree ! 2833: build_complex_type (component_type) ! 2834: tree component_type; ! 2835: { ! 2836: register tree t; ! 2837: int hashcode; ! 2838: ! 2839: /* Make a node of the sort we want. */ ! 2840: t = make_node (COMPLEX_TYPE); ! 2841: ! 2842: TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type); ! 2843: TYPE_VOLATILE (t) = TYPE_VOLATILE (component_type); ! 2844: TYPE_READONLY (t) = TYPE_READONLY (component_type); ! 2845: ! 2846: /* If we already have such a type, use the old one and free this one. */ ! 2847: hashcode = TYPE_HASH (component_type); ! 2848: t = type_hash_canon (hashcode, t); ! 2849: ! 2850: if (TYPE_SIZE (t) == 0) ! 2851: layout_type (t); ! 2852: ! 2853: return t; ! 2854: } ! 2855: ! 2856: /* Return OP, stripped of any conversions to wider types as much as is safe. ! 2857: Converting the value back to OP's type makes a value equivalent to OP. ! 2858: ! 2859: If FOR_TYPE is nonzero, we return a value which, if converted to ! 2860: type FOR_TYPE, would be equivalent to converting OP to type FOR_TYPE. ! 2861: ! 2862: If FOR_TYPE is nonzero, unaligned bit-field references may be changed to the ! 2863: narrowest type that can hold the value, even if they don't exactly fit. ! 2864: Otherwise, bit-field references are changed to a narrower type ! 2865: only if they can be fetched directly from memory in that type. ! 2866: ! 2867: OP must have integer, real or enumeral type. Pointers are not allowed! ! 2868: ! 2869: There are some cases where the obvious value we could return ! 2870: would regenerate to OP if converted to OP's type, ! 2871: but would not extend like OP to wider types. ! 2872: If FOR_TYPE indicates such extension is contemplated, we eschew such values. ! 2873: For example, if OP is (unsigned short)(signed char)-1, ! 2874: we avoid returning (signed char)-1 if FOR_TYPE is int, ! 2875: even though extending that to an unsigned short would regenerate OP, ! 2876: since the result of extending (signed char)-1 to (int) ! 2877: is different from (int) OP. */ ! 2878: ! 2879: tree ! 2880: get_unwidened (op, for_type) ! 2881: register tree op; ! 2882: tree for_type; ! 2883: { ! 2884: /* Set UNS initially if converting OP to FOR_TYPE is a zero-extension. */ ! 2885: /* TYPE_PRECISION is safe in place of type_precision since ! 2886: pointer types are not allowed. */ ! 2887: register tree type = TREE_TYPE (op); ! 2888: register unsigned final_prec ! 2889: = TYPE_PRECISION (for_type != 0 ? for_type : type); ! 2890: register int uns ! 2891: = (for_type != 0 && for_type != type ! 2892: && final_prec > TYPE_PRECISION (type) ! 2893: && TREE_UNSIGNED (type)); ! 2894: register tree win = op; ! 2895: ! 2896: while (TREE_CODE (op) == NOP_EXPR) ! 2897: { ! 2898: register int bitschange ! 2899: = TYPE_PRECISION (TREE_TYPE (op)) ! 2900: - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0))); ! 2901: ! 2902: /* Truncations are many-one so cannot be removed. ! 2903: Unless we are later going to truncate down even farther. */ ! 2904: if (bitschange < 0 ! 2905: && final_prec > TYPE_PRECISION (TREE_TYPE (op))) ! 2906: break; ! 2907: ! 2908: /* See what's inside this conversion. If we decide to strip it, ! 2909: we will set WIN. */ ! 2910: op = TREE_OPERAND (op, 0); ! 2911: ! 2912: /* If we have not stripped any zero-extensions (uns is 0), ! 2913: we can strip any kind of extension. ! 2914: If we have previously stripped a zero-extension, ! 2915: only zero-extensions can safely be stripped. ! 2916: Any extension can be stripped if the bits it would produce ! 2917: are all going to be discarded later by truncating to FOR_TYPE. */ ! 2918: ! 2919: if (bitschange > 0) ! 2920: { ! 2921: if (! uns || final_prec <= TYPE_PRECISION (TREE_TYPE (op))) ! 2922: win = op; ! 2923: /* TREE_UNSIGNED says whether this is a zero-extension. ! 2924: Let's avoid computing it if it does not affect WIN ! 2925: and if UNS will not be needed again. */ ! 2926: if ((uns || TREE_CODE (op) == NOP_EXPR) ! 2927: && TREE_UNSIGNED (TREE_TYPE (op))) ! 2928: { ! 2929: uns = 1; ! 2930: win = op; ! 2931: } ! 2932: } ! 2933: } ! 2934: ! 2935: if (TREE_CODE (op) == COMPONENT_REF ! 2936: /* Since type_for_size always gives an integer type. */ ! 2937: && TREE_CODE (type) != REAL_TYPE) ! 2938: { ! 2939: unsigned innerprec = TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (op, 1))); ! 2940: type = type_for_size (innerprec, TREE_UNSIGNED (TREE_OPERAND (op, 1))); ! 2941: ! 2942: /* We can get this structure field in the narrowest type it fits in. ! 2943: If FOR_TYPE is 0, do this only for a field that matches the ! 2944: narrower type exactly and is aligned for it ! 2945: The resulting extension to its nominal type (a fullword type) ! 2946: must fit the same conditions as for other extensions. */ ! 2947: ! 2948: if (innerprec < TYPE_PRECISION (TREE_TYPE (op)) ! 2949: && (for_type || ! DECL_BIT_FIELD (TREE_OPERAND (op, 1))) ! 2950: && (! uns || final_prec <= innerprec ! 2951: || TREE_UNSIGNED (TREE_OPERAND (op, 1))) ! 2952: && type != 0) ! 2953: { ! 2954: win = build (COMPONENT_REF, type, TREE_OPERAND (op, 0), ! 2955: TREE_OPERAND (op, 1)); ! 2956: TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op); ! 2957: TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op); ! 2958: TREE_RAISES (win) = TREE_RAISES (op); ! 2959: } ! 2960: } ! 2961: return win; ! 2962: } ! 2963: ! 2964: /* Return OP or a simpler expression for a narrower value ! 2965: which can be sign-extended or zero-extended to give back OP. ! 2966: Store in *UNSIGNEDP_PTR either 1 if the value should be zero-extended ! 2967: or 0 if the value should be sign-extended. */ ! 2968: ! 2969: tree ! 2970: get_narrower (op, unsignedp_ptr) ! 2971: register tree op; ! 2972: int *unsignedp_ptr; ! 2973: { ! 2974: register int uns = 0; ! 2975: int first = 1; ! 2976: register tree win = op; ! 2977: ! 2978: while (TREE_CODE (op) == NOP_EXPR) ! 2979: { ! 2980: register int bitschange ! 2981: = TYPE_PRECISION (TREE_TYPE (op)) ! 2982: - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0))); ! 2983: ! 2984: /* Truncations are many-one so cannot be removed. */ ! 2985: if (bitschange < 0) ! 2986: break; ! 2987: ! 2988: /* See what's inside this conversion. If we decide to strip it, ! 2989: we will set WIN. */ ! 2990: op = TREE_OPERAND (op, 0); ! 2991: ! 2992: if (bitschange > 0) ! 2993: { ! 2994: /* An extension: the outermost one can be stripped, ! 2995: but remember whether it is zero or sign extension. */ ! 2996: if (first) ! 2997: uns = TREE_UNSIGNED (TREE_TYPE (op)); ! 2998: /* Otherwise, if a sign extension has been stripped, ! 2999: only sign extensions can now be stripped; ! 3000: if a zero extension has been stripped, only zero-extensions. */ ! 3001: else if (uns != TREE_UNSIGNED (TREE_TYPE (op))) ! 3002: break; ! 3003: first = 0; ! 3004: } ! 3005: /* A change in nominal type can always be stripped. */ ! 3006: ! 3007: win = op; ! 3008: } ! 3009: ! 3010: if (TREE_CODE (op) == COMPONENT_REF ! 3011: /* Since type_for_size always gives an integer type. */ ! 3012: && TREE_CODE (TREE_TYPE (op)) != REAL_TYPE) ! 3013: { ! 3014: unsigned innerprec = TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (op, 1))); ! 3015: tree type = type_for_size (innerprec, TREE_UNSIGNED (op)); ! 3016: ! 3017: /* We can get this structure field in a narrower type that fits it, ! 3018: but the resulting extension to its nominal type (a fullword type) ! 3019: must satisfy the same conditions as for other extensions. ! 3020: ! 3021: Do this only for fields that are aligned (not bit-fields), ! 3022: because when bit-field insns will be used there is no ! 3023: advantage in doing this. */ ! 3024: ! 3025: if (innerprec < TYPE_PRECISION (TREE_TYPE (op)) ! 3026: && ! DECL_BIT_FIELD (TREE_OPERAND (op, 1)) ! 3027: && (first || uns == TREE_UNSIGNED (TREE_OPERAND (op, 1))) ! 3028: && type != 0) ! 3029: { ! 3030: if (first) ! 3031: uns = TREE_UNSIGNED (TREE_OPERAND (op, 1)); ! 3032: win = build (COMPONENT_REF, type, TREE_OPERAND (op, 0), ! 3033: TREE_OPERAND (op, 1)); ! 3034: TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op); ! 3035: TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op); ! 3036: TREE_RAISES (win) = TREE_RAISES (op); ! 3037: } ! 3038: } ! 3039: *unsignedp_ptr = uns; ! 3040: return win; ! 3041: } ! 3042: ! 3043: /* Return the precision of a type, for arithmetic purposes. ! 3044: Supports all types on which arithmetic is possible ! 3045: (including pointer types). ! 3046: It's not clear yet what will be right for complex types. */ ! 3047: ! 3048: int ! 3049: type_precision (type) ! 3050: register tree type; ! 3051: { ! 3052: return ((TREE_CODE (type) == INTEGER_TYPE ! 3053: || TREE_CODE (type) == ENUMERAL_TYPE ! 3054: || TREE_CODE (type) == REAL_TYPE) ! 3055: ? TYPE_PRECISION (type) : POINTER_SIZE); ! 3056: } ! 3057: ! 3058: /* Nonzero if integer constant C has a value that is permissible ! 3059: for type TYPE (an INTEGER_TYPE). */ ! 3060: ! 3061: int ! 3062: int_fits_type_p (c, type) ! 3063: tree c, type; ! 3064: { ! 3065: if (TREE_UNSIGNED (type)) ! 3066: return (!INT_CST_LT_UNSIGNED (TYPE_MAX_VALUE (type), c) ! 3067: && !INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type))); ! 3068: else ! 3069: return (!INT_CST_LT (TYPE_MAX_VALUE (type), c) ! 3070: && !INT_CST_LT (c, TYPE_MIN_VALUE (type))); ! 3071: } ! 3072: ! 3073: /* Return the innermost context enclosing FNDECL that is ! 3074: a FUNCTION_DECL, or zero if none. */ ! 3075: ! 3076: tree ! 3077: decl_function_context (fndecl) ! 3078: tree fndecl; ! 3079: { ! 3080: tree context; ! 3081: ! 3082: if (TREE_CODE (fndecl) == ERROR_MARK) ! 3083: return 0; ! 3084: ! 3085: if (TREE_CODE (fndecl) == SAVE_EXPR) ! 3086: context = SAVE_EXPR_CONTEXT (fndecl); ! 3087: else ! 3088: context = DECL_CONTEXT (fndecl); ! 3089: ! 3090: while (context && TREE_CODE (context) != FUNCTION_DECL) ! 3091: { ! 3092: if (TREE_CODE (context) == RECORD_TYPE ! 3093: || TREE_CODE (context) == UNION_TYPE) ! 3094: context = TYPE_CONTEXT (context); ! 3095: else if (TREE_CODE (context) == TYPE_DECL) ! 3096: context = DECL_CONTEXT (context); ! 3097: else if (TREE_CODE (context) == BLOCK) ! 3098: context = BLOCK_SUPERCONTEXT (context); ! 3099: else ! 3100: /* Unhandled CONTEXT !? */ ! 3101: abort (); ! 3102: } ! 3103: ! 3104: return context; ! 3105: } ! 3106: ! 3107: /* Return the innermost context enclosing FNDECL that is ! 3108: a RECORD_TYPE or UNION_TYPE, or zero if none. ! 3109: TYPE_DECLs and FUNCTION_DECLs are transparent to this function. */ ! 3110: ! 3111: tree ! 3112: decl_type_context (fndecl) ! 3113: tree fndecl; ! 3114: { ! 3115: tree context = DECL_CONTEXT (fndecl); ! 3116: ! 3117: while (context) ! 3118: { ! 3119: if (TREE_CODE (context) == RECORD_TYPE ! 3120: || TREE_CODE (context) == UNION_TYPE) ! 3121: return context; ! 3122: if (TREE_CODE (context) == TYPE_DECL ! 3123: || TREE_CODE (context) == FUNCTION_DECL) ! 3124: context = DECL_CONTEXT (context); ! 3125: else if (TREE_CODE (context) == BLOCK) ! 3126: context = BLOCK_SUPERCONTEXT (context); ! 3127: else ! 3128: /* Unhandled CONTEXT!? */ ! 3129: abort (); ! 3130: } ! 3131: return NULL_TREE; ! 3132: } ! 3133: ! 3134: void ! 3135: print_obstack_statistics (str, o) ! 3136: char *str; ! 3137: struct obstack *o; ! 3138: { ! 3139: struct _obstack_chunk *chunk = o->chunk; ! 3140: int n_chunks = 0; ! 3141: int n_alloc = 0; ! 3142: ! 3143: while (chunk) ! 3144: { ! 3145: n_chunks += 1; ! 3146: n_alloc += chunk->limit - &chunk->contents[0]; ! 3147: chunk = chunk->prev; ! 3148: } ! 3149: fprintf (stderr, "obstack %s: %d bytes, %d chunks\n", ! 3150: str, n_alloc, n_chunks); ! 3151: } ! 3152: void ! 3153: dump_tree_statistics () ! 3154: { ! 3155: int i; ! 3156: int total_nodes, total_bytes; ! 3157: ! 3158: fprintf (stderr, "\n??? tree nodes created\n\n"); ! 3159: #ifdef GATHER_STATISTICS ! 3160: fprintf (stderr, "Kind Nodes Bytes\n"); ! 3161: fprintf (stderr, "-------------------------------------\n"); ! 3162: total_nodes = total_bytes = 0; ! 3163: for (i = 0; i < (int) all_kinds; i++) ! 3164: { ! 3165: fprintf (stderr, "%-20s %6d %9d\n", tree_node_kind_names[i], ! 3166: tree_node_counts[i], tree_node_sizes[i]); ! 3167: total_nodes += tree_node_counts[i]; ! 3168: total_bytes += tree_node_sizes[i]; ! 3169: } ! 3170: fprintf (stderr, "%-20s %9d\n", "identifier names", id_string_size); ! 3171: fprintf (stderr, "-------------------------------------\n"); ! 3172: fprintf (stderr, "%-20s %6d %9d\n", "Total", total_nodes, total_bytes); ! 3173: fprintf (stderr, "-------------------------------------\n"); ! 3174: #else ! 3175: fprintf (stderr, "(No per-node statistics)\n"); ! 3176: #endif ! 3177: print_lang_statistics (); ! 3178: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.