|
|
1.1 root 1: /* Language-dependent node constructors for parse phase of GNU compiler. 1.1.1.2 ! root 2: Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc. 1.1 root 3: Hacked by Michael Tiemann ([email protected]) 4: 5: This file is part of GNU CC. 6: 7: GNU CC is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU CC is distributed in the hope that it will be useful, 13: but WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: GNU General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU CC; see the file COPYING. If not, write to 1.1.1.2 ! root 19: the Free Software Foundation, 59 Temple Place - Suite 330, ! 20: Boston, MA 02111-1307, USA. */ 1.1 root 21: 22: #include "config.h" 23: #include <stdio.h> 24: #include "obstack.h" 25: #include "tree.h" 26: #include "cp-tree.h" 27: #include "flags.h" 1.1.1.2 ! root 28: #include "rtl.h" 1.1 root 29: 30: #define CEIL(x,y) (((x) + (y) - 1) / (y)) 31: 32: /* Return nonzero if REF is an lvalue valid for this language. 33: Lvalues can be assigned, unless they have TREE_READONLY. 34: Lvalues can have their address taken, unless they have DECL_REGISTER. */ 35: 36: int 1.1.1.2 ! root 37: real_lvalue_p (ref) ! 38: tree ref; ! 39: { ! 40: if (! language_lvalue_valid (ref)) ! 41: return 0; ! 42: ! 43: if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE) ! 44: return 1; ! 45: ! 46: if (ref == current_class_decl && flag_this_is_variable <= 0) ! 47: return 0; ! 48: ! 49: switch (TREE_CODE (ref)) ! 50: { ! 51: /* preincrements and predecrements are valid lvals, provided ! 52: what they refer to are valid lvals. */ ! 53: case PREINCREMENT_EXPR: ! 54: case PREDECREMENT_EXPR: ! 55: case COMPONENT_REF: ! 56: case SAVE_EXPR: ! 57: return real_lvalue_p (TREE_OPERAND (ref, 0)); ! 58: ! 59: case STRING_CST: ! 60: return 1; ! 61: ! 62: case VAR_DECL: ! 63: if (TREE_READONLY (ref) && ! TREE_STATIC (ref) ! 64: && DECL_LANG_SPECIFIC (ref) ! 65: && DECL_IN_AGGR_P (ref)) ! 66: return 0; ! 67: case INDIRECT_REF: ! 68: case ARRAY_REF: ! 69: case PARM_DECL: ! 70: case RESULT_DECL: ! 71: case ERROR_MARK: ! 72: if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE ! 73: && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE) ! 74: return 1; ! 75: break; ! 76: ! 77: case WITH_CLEANUP_EXPR: ! 78: return real_lvalue_p (TREE_OPERAND (ref, 0)); ! 79: ! 80: /* A currently unresolved scope ref. */ ! 81: case SCOPE_REF: ! 82: my_friendly_abort (103); ! 83: case OFFSET_REF: ! 84: if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL) ! 85: return 1; ! 86: return real_lvalue_p (TREE_OPERAND (ref, 0)) ! 87: && real_lvalue_p (TREE_OPERAND (ref, 1)); ! 88: break; ! 89: ! 90: case COND_EXPR: ! 91: return (real_lvalue_p (TREE_OPERAND (ref, 1)) ! 92: && real_lvalue_p (TREE_OPERAND (ref, 2))); ! 93: ! 94: case MODIFY_EXPR: ! 95: return 1; ! 96: ! 97: case COMPOUND_EXPR: ! 98: return real_lvalue_p (TREE_OPERAND (ref, 1)); ! 99: ! 100: case MAX_EXPR: ! 101: case MIN_EXPR: ! 102: return (real_lvalue_p (TREE_OPERAND (ref, 0)) ! 103: && real_lvalue_p (TREE_OPERAND (ref, 1))); ! 104: } ! 105: ! 106: return 0; ! 107: } ! 108: ! 109: int 1.1 root 110: lvalue_p (ref) 111: tree ref; 112: { 113: if (! language_lvalue_valid (ref)) 114: return 0; 115: 116: if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE) 117: return 1; 118: 119: if (ref == current_class_decl && flag_this_is_variable <= 0) 120: return 0; 121: 122: switch (TREE_CODE (ref)) 123: { 124: /* preincrements and predecrements are valid lvals, provided 125: what they refer to are valid lvals. */ 126: case PREINCREMENT_EXPR: 127: case PREDECREMENT_EXPR: 128: case COMPONENT_REF: 129: case SAVE_EXPR: 130: return lvalue_p (TREE_OPERAND (ref, 0)); 131: 132: case STRING_CST: 133: return 1; 134: 135: case VAR_DECL: 136: if (TREE_READONLY (ref) && ! TREE_STATIC (ref) 137: && DECL_LANG_SPECIFIC (ref) 138: && DECL_IN_AGGR_P (ref)) 139: return 0; 140: case INDIRECT_REF: 141: case ARRAY_REF: 142: case PARM_DECL: 143: case RESULT_DECL: 144: case ERROR_MARK: 145: if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE 146: && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE) 147: return 1; 148: break; 149: 150: case WITH_CLEANUP_EXPR: 151: return lvalue_p (TREE_OPERAND (ref, 0)); 152: 153: case TARGET_EXPR: 154: return 1; 155: 156: case CALL_EXPR: 1.1.1.2 ! root 157: if (IS_AGGR_TYPE (TREE_TYPE (ref))) 1.1 root 158: return 1; 159: break; 160: 161: /* A currently unresolved scope ref. */ 162: case SCOPE_REF: 163: my_friendly_abort (103); 164: case OFFSET_REF: 165: if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL) 166: return 1; 167: return lvalue_p (TREE_OPERAND (ref, 0)) 168: && lvalue_p (TREE_OPERAND (ref, 1)); 169: break; 170: 171: case COND_EXPR: 172: return (lvalue_p (TREE_OPERAND (ref, 1)) 173: && lvalue_p (TREE_OPERAND (ref, 2))); 174: 175: case MODIFY_EXPR: 176: return 1; 177: 178: case COMPOUND_EXPR: 179: return lvalue_p (TREE_OPERAND (ref, 1)); 1.1.1.2 ! root 180: ! 181: case MAX_EXPR: ! 182: case MIN_EXPR: ! 183: return (lvalue_p (TREE_OPERAND (ref, 0)) ! 184: && lvalue_p (TREE_OPERAND (ref, 1))); 1.1 root 185: } 186: 187: return 0; 188: } 189: 190: /* Return nonzero if REF is an lvalue valid for this language; 191: otherwise, print an error message and return zero. */ 192: 193: int 194: lvalue_or_else (ref, string) 195: tree ref; 196: char *string; 197: { 198: int win = lvalue_p (ref); 199: if (! win) 200: error ("non-lvalue in %s", string); 201: return win; 202: } 203: 204: /* INIT is a CALL_EXPR which needs info about its target. 205: TYPE is the type that this initialization should appear to have. 206: 207: Build an encapsulation of the initialization to perform 208: and return it so that it can be processed by language-independent 209: and language-specific expression expanders. 210: 211: If WITH_CLEANUP_P is nonzero, we build a cleanup for this expression. 212: Otherwise, cleanups are not built here. For example, when building 213: an initialization for a stack slot, since the called function handles 214: the cleanup, we would not want to do it here. */ 215: tree 216: build_cplus_new (type, init, with_cleanup_p) 217: tree type; 218: tree init; 219: int with_cleanup_p; 220: { 1.1.1.2 ! root 221: tree slot; ! 222: tree rval; ! 223: ! 224: slot = build (VAR_DECL, type); ! 225: layout_decl (slot, 0); ! 226: rval = build (NEW_EXPR, type, ! 227: TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot); 1.1 root 228: TREE_SIDE_EFFECTS (rval) = 1; 229: TREE_ADDRESSABLE (rval) = 1; 230: rval = build (TARGET_EXPR, type, slot, rval, 0); 231: TREE_SIDE_EFFECTS (rval) = 1; 232: TREE_ADDRESSABLE (rval) = 1; 233: 234: #if 0 235: if (with_cleanup_p && TYPE_NEEDS_DESTRUCTOR (type)) 236: { 237: TREE_OPERAND (rval, 2) = error_mark_node; 238: rval = build (WITH_CLEANUP_EXPR, type, rval, 0, 1.1.1.2 ! root 239: build_delete (build_pointer_type (type), 1.1 root 240: build_unary_op (ADDR_EXPR, slot, 0), 241: integer_two_node, 242: LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0)); 243: TREE_SIDE_EFFECTS (rval) = 1; 244: TREE_ADDRESSABLE (rval) = 1; 245: } 246: #endif 247: return rval; 248: } 249: 250: /* Recursively search EXP for CALL_EXPRs that need cleanups and replace 251: these CALL_EXPRs with tree nodes that will perform the cleanups. */ 252: 253: tree 254: break_out_cleanups (exp) 255: tree exp; 256: { 257: tree tmp = exp; 258: 259: if (TREE_CODE (tmp) == CALL_EXPR 260: && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (tmp))) 261: return build_cplus_new (TREE_TYPE (tmp), tmp, 1); 262: 263: while (TREE_CODE (tmp) == NOP_EXPR 264: || TREE_CODE (tmp) == CONVERT_EXPR 265: || TREE_CODE (tmp) == NON_LVALUE_EXPR) 266: { 267: if (TREE_CODE (TREE_OPERAND (tmp, 0)) == CALL_EXPR 268: && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (TREE_OPERAND (tmp, 0)))) 269: { 270: TREE_OPERAND (tmp, 0) 271: = build_cplus_new (TREE_TYPE (TREE_OPERAND (tmp, 0)), 272: TREE_OPERAND (tmp, 0), 1); 273: break; 274: } 275: else 276: tmp = TREE_OPERAND (tmp, 0); 277: } 278: return exp; 279: } 280: 281: /* Recursively perform a preorder search EXP for CALL_EXPRs, making 282: copies where they are found. Returns a deep copy all nodes transitively 283: containing CALL_EXPRs. */ 284: 285: tree 286: break_out_calls (exp) 287: tree exp; 288: { 289: register tree t1, t2; 290: register enum tree_code code; 291: register int changed = 0; 292: register int i; 293: 294: if (exp == NULL_TREE) 295: return exp; 296: 297: code = TREE_CODE (exp); 298: 299: if (code == CALL_EXPR) 300: return copy_node (exp); 301: 302: /* Don't try and defeat a save_expr, as it should only be done once. */ 303: if (code == SAVE_EXPR) 304: return exp; 305: 306: switch (TREE_CODE_CLASS (code)) 307: { 308: default: 309: abort (); 310: 311: case 'c': /* a constant */ 312: case 't': /* a type node */ 313: case 'x': /* something random, like an identifier or an ERROR_MARK. */ 314: return exp; 315: 316: case 'd': /* A decl node */ 317: #if 0 /* This is bogus. jason 9/21/94 */ 318: 319: t1 = break_out_calls (DECL_INITIAL (exp)); 320: if (t1 != DECL_INITIAL (exp)) 321: { 322: exp = copy_node (exp); 323: DECL_INITIAL (exp) = t1; 324: } 325: #endif 326: return exp; 327: 328: case 'b': /* A block node */ 329: { 330: /* Don't know how to handle these correctly yet. Must do a 331: break_out_calls on all DECL_INITIAL values for local variables, 332: and also break_out_calls on all sub-blocks and sub-statements. */ 333: abort (); 334: } 335: return exp; 336: 337: case 'e': /* an expression */ 338: case 'r': /* a reference */ 339: case 's': /* an expression with side effects */ 340: for (i = tree_code_length[(int) code] - 1; i >= 0; i--) 341: { 342: t1 = break_out_calls (TREE_OPERAND (exp, i)); 343: if (t1 != TREE_OPERAND (exp, i)) 344: { 345: exp = copy_node (exp); 346: TREE_OPERAND (exp, i) = t1; 347: } 348: } 349: return exp; 350: 351: case '<': /* a comparison expression */ 352: case '2': /* a binary arithmetic expression */ 353: t2 = break_out_calls (TREE_OPERAND (exp, 1)); 354: if (t2 != TREE_OPERAND (exp, 1)) 355: changed = 1; 356: case '1': /* a unary arithmetic expression */ 357: t1 = break_out_calls (TREE_OPERAND (exp, 0)); 358: if (t1 != TREE_OPERAND (exp, 0)) 359: changed = 1; 360: if (changed) 361: { 362: if (tree_code_length[(int) code] == 1) 363: return build1 (code, TREE_TYPE (exp), t1); 364: else 365: return build (code, TREE_TYPE (exp), t1, t2); 366: } 367: return exp; 368: } 369: 370: } 371: 372: extern struct obstack *current_obstack; 373: extern struct obstack permanent_obstack, class_obstack; 374: extern struct obstack *saveable_obstack; 375: 376: /* Here is how primitive or already-canonicalized types' hash 377: codes are made. MUST BE CONSISTENT WITH tree.c !!! */ 378: #define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777) 379: 380: /* Construct, lay out and return the type of methods belonging to class 381: BASETYPE and whose arguments are described by ARGTYPES and whose values 382: are described by RETTYPE. If each type exists already, reuse it. */ 383: tree 384: build_cplus_method_type (basetype, rettype, argtypes) 385: tree basetype, rettype, argtypes; 386: { 387: register tree t; 388: tree ptype; 389: int hashcode; 390: 391: /* Make a node of the sort we want. */ 392: t = make_node (METHOD_TYPE); 393: 394: TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype); 395: TREE_TYPE (t) = rettype; 396: if (IS_SIGNATURE (basetype)) 397: ptype = build_signature_pointer_type (TYPE_MAIN_VARIANT (basetype), 398: TYPE_READONLY (basetype), 399: TYPE_VOLATILE (basetype)); 400: else 1.1.1.2 ! root 401: ptype = build_pointer_type (basetype); ! 402: 1.1 root 403: /* The actual arglist for this function includes a "hidden" argument 404: which is "this". Put it into the list of argument types. */ 405: 406: argtypes = tree_cons (NULL_TREE, ptype, argtypes); 407: TYPE_ARG_TYPES (t) = argtypes; 408: TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */ 409: 410: /* If we already have such a type, use the old one and free this one. 411: Note that it also frees up the above cons cell if found. */ 412: hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + type_hash_list (argtypes); 413: t = type_hash_canon (hashcode, t); 414: 415: if (TYPE_SIZE (t) == 0) 416: layout_type (t); 417: 418: return t; 419: } 420: 421: tree 422: build_cplus_staticfn_type (basetype, rettype, argtypes) 423: tree basetype, rettype, argtypes; 424: { 425: register tree t; 426: int hashcode; 427: 428: /* Make a node of the sort we want. */ 429: t = make_node (FUNCTION_TYPE); 430: 431: TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype); 432: TREE_TYPE (t) = rettype; 433: 434: TYPE_ARG_TYPES (t) = argtypes; 435: 436: /* If we already have such a type, use the old one and free this one. 437: Note that it also frees up the above cons cell if found. */ 438: hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + type_hash_list (argtypes); 439: t = type_hash_canon (hashcode, t); 440: 441: if (TYPE_SIZE (t) == 0) 442: layout_type (t); 443: 444: return t; 445: } 446: 447: tree 448: build_cplus_array_type (elt_type, index_type) 449: tree elt_type; 450: tree index_type; 451: { 452: register struct obstack *ambient_obstack = current_obstack; 453: register struct obstack *ambient_saveable_obstack = saveable_obstack; 454: tree t; 455: 456: /* We need a new one. If both ELT_TYPE and INDEX_TYPE are permanent, 457: make this permanent too. */ 458: if (TREE_PERMANENT (elt_type) 459: && (index_type == 0 || TREE_PERMANENT (index_type))) 460: { 461: current_obstack = &permanent_obstack; 462: saveable_obstack = &permanent_obstack; 463: } 464: 465: t = build_array_type (elt_type, index_type); 466: 467: /* Push these needs up so that initialization takes place 468: more easily. */ 469: TYPE_NEEDS_CONSTRUCTING (t) = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type)); 470: TYPE_NEEDS_DESTRUCTOR (t) = TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type)); 471: current_obstack = ambient_obstack; 472: saveable_obstack = ambient_saveable_obstack; 473: return t; 474: } 475: 476: /* Make a variant type in the proper way for C/C++, propagating qualifiers 477: down to the element type of an array. */ 478: 479: tree 480: cp_build_type_variant (type, constp, volatilep) 481: tree type; 482: int constp, volatilep; 483: { 484: if (TREE_CODE (type) == ARRAY_TYPE) 485: { 486: tree real_main_variant = TYPE_MAIN_VARIANT (type); 487: 488: push_obstacks (TYPE_OBSTACK (real_main_variant), 489: TYPE_OBSTACK (real_main_variant)); 490: type = build_cplus_array_type (cp_build_type_variant (TREE_TYPE (type), 491: constp, volatilep), 492: TYPE_DOMAIN (type)); 493: 494: /* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not, 495: make a copy. (TYPE might have come from the hash table and 496: REAL_MAIN_VARIANT might be in some function's obstack.) */ 497: 498: if (TYPE_OBSTACK (type) != TYPE_OBSTACK (real_main_variant)) 499: { 500: type = copy_node (type); 501: TYPE_POINTER_TO (type) = TYPE_REFERENCE_TO (type) = 0; 502: } 503: 504: TYPE_MAIN_VARIANT (type) = real_main_variant; 505: pop_obstacks (); 506: } 507: return build_type_variant (type, constp, volatilep); 508: } 509: 510: /* Add OFFSET to all base types of T. 511: 512: OFFSET, which is a type offset, is number of bytes. 513: 514: Note that we don't have to worry about having two paths to the 515: same base type, since this type owns its association list. */ 516: void 517: propagate_binfo_offsets (binfo, offset) 518: tree binfo; 519: tree offset; 520: { 521: tree binfos = BINFO_BASETYPES (binfo); 522: int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; 523: 524: for (i = 0; i < n_baselinks; /* note increment is done in the loop. */) 525: { 526: tree base_binfo = TREE_VEC_ELT (binfos, i); 527: 528: if (TREE_VIA_VIRTUAL (base_binfo)) 529: i += 1; 530: else 531: { 532: int j; 533: tree base_binfos = BINFO_BASETYPES (base_binfo); 534: tree delta; 535: 536: for (j = i+1; j < n_baselinks; j++) 537: if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j))) 538: { 539: /* The next basetype offset must take into account the space 540: between the classes, not just the size of each class. */ 541: delta = size_binop (MINUS_EXPR, 542: BINFO_OFFSET (TREE_VEC_ELT (binfos, j)), 543: BINFO_OFFSET (base_binfo)); 544: break; 545: } 546: 547: #if 0 548: if (BINFO_OFFSET_ZEROP (base_binfo)) 549: BINFO_OFFSET (base_binfo) = offset; 550: else 551: BINFO_OFFSET (base_binfo) 552: = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset); 553: #else 554: BINFO_OFFSET (base_binfo) = offset; 555: #endif 556: if (base_binfos) 557: { 558: int k; 559: tree chain = NULL_TREE; 560: 561: /* Now unshare the structure beneath BASE_BINFO. */ 562: for (k = TREE_VEC_LENGTH (base_binfos)-1; 563: k >= 0; k--) 564: { 565: tree base_base_binfo = TREE_VEC_ELT (base_binfos, k); 566: if (! TREE_VIA_VIRTUAL (base_base_binfo)) 567: TREE_VEC_ELT (base_binfos, k) 568: = make_binfo (BINFO_OFFSET (base_base_binfo), 569: base_base_binfo, 570: BINFO_VTABLE (base_base_binfo), 571: BINFO_VIRTUALS (base_base_binfo), 572: chain); 573: chain = TREE_VEC_ELT (base_binfos, k); 574: TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo); 575: TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo); 1.1.1.2 ! root 576: BINFO_INHERITANCE_CHAIN (chain) = base_binfo; 1.1 root 577: } 578: /* Now propagate the offset to the base types. */ 579: propagate_binfo_offsets (base_binfo, offset); 580: } 581: 582: /* Go to our next class that counts for offset propagation. */ 583: i = j; 584: if (i < n_baselinks) 585: offset = size_binop (PLUS_EXPR, offset, delta); 586: } 587: } 588: } 589: 590: /* Compute the actual offsets that our virtual base classes 591: will have *for this type*. This must be performed after 592: the fields are laid out, since virtual baseclasses must 593: lay down at the end of the record. 594: 595: Returns the maximum number of virtual functions any of the virtual 596: baseclasses provide. */ 597: int 598: layout_vbasetypes (rec, max) 599: tree rec; 600: int max; 601: { 602: /* Get all the virtual base types that this type uses. 603: The TREE_VALUE slot holds the virtual baseclass type. */ 604: tree vbase_types = get_vbase_types (rec); 605: 606: #ifdef STRUCTURE_SIZE_BOUNDARY 607: unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec)); 608: #else 609: unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec)); 610: #endif 611: int desired_align; 612: 613: /* Record size so far is CONST_SIZE + VAR_SIZE bits, 614: where CONST_SIZE is an integer 615: and VAR_SIZE is a tree expression. 616: If VAR_SIZE is null, the size is just CONST_SIZE. 617: Naturally we try to avoid using VAR_SIZE. */ 618: register unsigned const_size = 0; 619: register tree var_size = 0; 620: int nonvirtual_const_size; 621: tree nonvirtual_var_size; 622: 623: CLASSTYPE_VBASECLASSES (rec) = vbase_types; 624: 625: if (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST) 626: const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec)); 627: else 628: var_size = TYPE_SIZE (rec); 629: 630: nonvirtual_const_size = const_size; 631: nonvirtual_var_size = var_size; 632: 633: while (vbase_types) 634: { 635: tree basetype = BINFO_TYPE (vbase_types); 636: tree offset; 637: 638: desired_align = TYPE_ALIGN (basetype); 639: record_align = MAX (record_align, desired_align); 640: 641: if (const_size == 0) 642: offset = integer_zero_node; 643: else 644: { 645: /* Give each virtual base type the alignment it wants. */ 646: const_size = CEIL (const_size, TYPE_ALIGN (basetype)) 647: * TYPE_ALIGN (basetype); 648: offset = size_int (CEIL (const_size, BITS_PER_UNIT)); 649: } 650: 651: if (CLASSTYPE_VSIZE (basetype) > max) 652: max = CLASSTYPE_VSIZE (basetype); 653: BINFO_OFFSET (vbase_types) = offset; 654: 655: if (TREE_CODE (TYPE_SIZE (basetype)) == INTEGER_CST) 1.1.1.2 ! root 656: { ! 657: /* Every virtual baseclass takes a least a UNIT, so that we can ! 658: take it's address and get something different for each base. */ ! 659: const_size += MAX (BITS_PER_UNIT, ! 660: TREE_INT_CST_LOW (TYPE_SIZE (basetype)) ! 661: - TREE_INT_CST_LOW (CLASSTYPE_VBASE_SIZE (basetype))); ! 662: } 1.1 root 663: else if (var_size == 0) 664: var_size = TYPE_SIZE (basetype); 665: else 666: var_size = size_binop (PLUS_EXPR, var_size, TYPE_SIZE (basetype)); 667: 668: vbase_types = TREE_CHAIN (vbase_types); 669: } 670: 1.1.1.2 ! root 671: if (const_size) ! 672: { ! 673: /* Because a virtual base might take a single byte above, ! 674: we have to re-adjust the total size to make sure it it ! 675: a multiple of the alignment. */ ! 676: /* Give the whole object the alignment it wants. */ ! 677: const_size = CEIL (const_size, record_align) * record_align; ! 678: } ! 679: 1.1 root 680: /* Set the alignment in the complete type. We don't set CLASSTYPE_ALIGN 681: here, as that is for this class, without any virtual base classes. */ 682: TYPE_ALIGN (rec) = record_align; 683: if (const_size != nonvirtual_const_size) 684: { 685: CLASSTYPE_VBASE_SIZE (rec) 686: = size_int (const_size - nonvirtual_const_size); 687: TYPE_SIZE (rec) = size_int (const_size); 688: } 689: 690: /* Now propagate offset information throughout the lattice 691: under the vbase type. */ 692: for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types; 693: vbase_types = TREE_CHAIN (vbase_types)) 694: { 695: tree base_binfos = BINFO_BASETYPES (vbase_types); 696: 1.1.1.2 ! root 697: BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec); ! 698: 1.1 root 699: if (base_binfos) 700: { 701: tree chain = NULL_TREE; 702: int j; 703: /* Now unshare the structure beneath BASE_BINFO. */ 704: 705: for (j = TREE_VEC_LENGTH (base_binfos)-1; 706: j >= 0; j--) 707: { 708: tree base_base_binfo = TREE_VEC_ELT (base_binfos, j); 709: if (! TREE_VIA_VIRTUAL (base_base_binfo)) 710: TREE_VEC_ELT (base_binfos, j) 711: = make_binfo (BINFO_OFFSET (base_base_binfo), 712: base_base_binfo, 713: BINFO_VTABLE (base_base_binfo), 714: BINFO_VIRTUALS (base_base_binfo), 715: chain); 716: chain = TREE_VEC_ELT (base_binfos, j); 717: TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo); 718: TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo); 1.1.1.2 ! root 719: BINFO_INHERITANCE_CHAIN (chain) = vbase_types; 1.1 root 720: } 721: 722: propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types)); 723: } 724: } 725: 726: return max; 727: } 728: 729: /* Lay out the base types of a record type, REC. 730: Tentatively set the size and alignment of REC 731: according to the base types alone. 732: 733: Offsets for immediate nonvirtual baseclasses are also computed here. 734: 735: TYPE_BINFO (REC) should be NULL_TREE on entry, and this routine 736: creates a list of base_binfos in TYPE_BINFO (REC) from BINFOS. 737: 738: Returns list of virtual base classes in a FIELD_DECL chain. */ 739: tree 740: layout_basetypes (rec, binfos) 741: tree rec, binfos; 742: { 743: /* Chain to hold all the new FIELD_DECLs which point at virtual 744: base classes. */ 745: tree vbase_decls = NULL_TREE; 746: 747: #ifdef STRUCTURE_SIZE_BOUNDARY 748: unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec)); 749: #else 750: unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec)); 751: #endif 752: 753: /* Record size so far is CONST_SIZE + VAR_SIZE bits, where CONST_SIZE is 754: an integer and VAR_SIZE is a tree expression. If VAR_SIZE is null, 755: the size is just CONST_SIZE. Naturally we try to avoid using 1.1.1.2 ! root 756: VAR_SIZE. And so far, we've been successful. */ 1.1 root 757: #if 0 758: register tree var_size = 0; 759: #endif 760: 761: register unsigned const_size = 0; 762: int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; 763: 764: /* Handle basetypes almost like fields, but record their 765: offsets differently. */ 766: 767: for (i = 0; i < n_baseclasses; i++) 768: { 769: int inc, desired_align, int_vbase_size; 770: register tree base_binfo = TREE_VEC_ELT (binfos, i); 771: register tree basetype = BINFO_TYPE (base_binfo); 772: tree decl, offset; 773: 774: if (TYPE_SIZE (basetype) == 0) 775: { 776: #if 0 777: /* This error is now reported in xref_tag, thus giving better 778: location information. */ 779: error_with_aggr_type (base_binfo, 780: "base class `%s' has incomplete type"); 781: 782: TREE_VIA_PUBLIC (base_binfo) = 1; 783: TREE_VIA_PROTECTED (base_binfo) = 0; 784: TREE_VIA_VIRTUAL (base_binfo) = 0; 785: 786: /* Should handle this better so that 787: 788: class A; 789: class B: private A { virtual void F(); }; 790: 791: does not dump core when compiled. */ 792: my_friendly_abort (121); 793: #endif 794: continue; 795: } 796: 797: /* All basetypes are recorded in the association list of the 798: derived type. */ 799: 800: if (TREE_VIA_VIRTUAL (base_binfo)) 801: { 802: int j; 803: char *name = (char *)alloca (TYPE_NAME_LENGTH (basetype) 804: + sizeof (VBASE_NAME) + 1); 805: 806: /* The offset for a virtual base class is only used in computing 807: virtual function tables and for initializing virtual base 808: pointers. It is built once `get_vbase_types' is called. */ 809: 810: /* If this basetype can come from another vbase pointer 811: without an additional indirection, we will share 812: that pointer. If an indirection is involved, we 813: make our own pointer. */ 814: for (j = 0; j < n_baseclasses; j++) 815: { 816: tree other_base_binfo = TREE_VEC_ELT (binfos, j); 817: if (! TREE_VIA_VIRTUAL (other_base_binfo) 818: && binfo_member (basetype, 819: CLASSTYPE_VBASECLASSES (BINFO_TYPE (other_base_binfo)))) 820: goto got_it; 821: } 822: sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype)); 823: decl = build_lang_decl (FIELD_DECL, get_identifier (name), 824: build_pointer_type (basetype)); 825: /* If you change any of the below, take a look at all the 826: other VFIELD_BASEs and VTABLE_BASEs in the code, and change 827: them too. */ 828: DECL_ASSEMBLER_NAME (decl) = get_identifier (VTABLE_BASE); 829: DECL_VIRTUAL_P (decl) = 1; 830: DECL_FIELD_CONTEXT (decl) = rec; 831: DECL_CLASS_CONTEXT (decl) = rec; 832: DECL_FCONTEXT (decl) = basetype; 1.1.1.2 ! root 833: DECL_SAVED_INSNS (decl) = NULL_RTX; 1.1 root 834: DECL_FIELD_SIZE (decl) = 0; 835: DECL_ALIGN (decl) = TYPE_ALIGN (ptr_type_node); 836: TREE_CHAIN (decl) = vbase_decls; 837: BINFO_VPTR_FIELD (base_binfo) = decl; 838: vbase_decls = decl; 839: 840: if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype) 841: && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE) 842: { 843: warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0), 844: "destructor `%s' non-virtual"); 845: warning ("in inheritance relationship `%s: virtual %s'", 846: TYPE_NAME_STRING (rec), 847: TYPE_NAME_STRING (basetype)); 848: } 849: got_it: 850: /* The space this decl occupies has already been accounted for. */ 851: continue; 852: } 853: 854: if (const_size == 0) 855: offset = integer_zero_node; 856: else 857: { 858: /* Give each base type the alignment it wants. */ 859: const_size = CEIL (const_size, TYPE_ALIGN (basetype)) 860: * TYPE_ALIGN (basetype); 861: offset = size_int ((const_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT); 862: 863: #if 0 864: /* bpk: Disabled this check until someone is willing to 865: claim it as theirs and explain exactly what circumstances 866: warrant the warning. */ 867: if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype) 868: && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE) 869: { 870: warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0), 871: "destructor `%s' non-virtual"); 872: warning ("in inheritance relationship `%s:%s %s'", 873: TYPE_NAME_STRING (rec), 874: TREE_VIA_VIRTUAL (base_binfo) ? " virtual" : "", 875: TYPE_NAME_STRING (basetype)); 876: } 877: #endif 878: } 879: BINFO_OFFSET (base_binfo) = offset; 880: if (CLASSTYPE_VSIZE (basetype)) 881: { 882: BINFO_VTABLE (base_binfo) = TYPE_BINFO_VTABLE (basetype); 883: BINFO_VIRTUALS (base_binfo) = TYPE_BINFO_VIRTUALS (basetype); 884: } 885: TREE_CHAIN (base_binfo) = TYPE_BINFO (rec); 886: TYPE_BINFO (rec) = base_binfo; 887: 888: /* Add only the amount of storage not present in 889: the virtual baseclasses. */ 890: 891: int_vbase_size = TREE_INT_CST_LOW (CLASSTYPE_VBASE_SIZE (basetype)); 892: if (TREE_INT_CST_LOW (TYPE_SIZE (basetype)) > int_vbase_size) 893: { 894: inc = MAX (record_align, 895: (TREE_INT_CST_LOW (TYPE_SIZE (basetype)) 896: - int_vbase_size)); 897: 898: /* Record must have at least as much alignment as any field. */ 899: desired_align = TYPE_ALIGN (basetype); 900: record_align = MAX (record_align, desired_align); 901: 902: const_size += inc; 903: } 904: } 905: 906: if (const_size) 907: CLASSTYPE_SIZE (rec) = size_int (const_size); 908: else 909: CLASSTYPE_SIZE (rec) = integer_zero_node; 910: CLASSTYPE_ALIGN (rec) = record_align; 911: 912: return vbase_decls; 913: } 914: 915: /* Hashing of lists so that we don't make duplicates. 916: The entry point is `list_hash_canon'. */ 917: 918: /* Each hash table slot is a bucket containing a chain 919: of these structures. */ 920: 921: struct list_hash 922: { 923: struct list_hash *next; /* Next structure in the bucket. */ 924: int hashcode; /* Hash code of this list. */ 925: tree list; /* The list recorded here. */ 926: }; 927: 928: /* Now here is the hash table. When recording a list, it is added 929: to the slot whose index is the hash code mod the table size. 930: Note that the hash table is used for several kinds of lists. 931: While all these live in the same table, they are completely independent, 932: and the hash code is computed differently for each of these. */ 933: 934: #define TYPE_HASH_SIZE 59 935: struct list_hash *list_hash_table[TYPE_HASH_SIZE]; 936: 937: /* Compute a hash code for a list (chain of TREE_LIST nodes 938: with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the 939: TREE_COMMON slots), by adding the hash codes of the individual entries. */ 940: 941: int 942: list_hash (list) 943: tree list; 944: { 945: register int hashcode = 0; 946: 947: if (TREE_CHAIN (list)) 948: hashcode += TYPE_HASH (TREE_CHAIN (list)); 949: 950: if (TREE_VALUE (list)) 951: hashcode += TYPE_HASH (TREE_VALUE (list)); 952: else 953: hashcode += 1007; 954: if (TREE_PURPOSE (list)) 955: hashcode += TYPE_HASH (TREE_PURPOSE (list)); 956: else 957: hashcode += 1009; 958: return hashcode; 959: } 960: 961: /* Look in the type hash table for a type isomorphic to TYPE. 962: If one is found, return it. Otherwise return 0. */ 963: 964: tree 965: list_hash_lookup (hashcode, list) 966: int hashcode; 967: tree list; 968: { 969: register struct list_hash *h; 970: for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next) 971: if (h->hashcode == hashcode 972: && TREE_VIA_VIRTUAL (h->list) == TREE_VIA_VIRTUAL (list) 973: && TREE_VIA_PUBLIC (h->list) == TREE_VIA_PUBLIC (list) 974: && TREE_VIA_PROTECTED (h->list) == TREE_VIA_PROTECTED (list) 975: && TREE_PURPOSE (h->list) == TREE_PURPOSE (list) 976: && TREE_VALUE (h->list) == TREE_VALUE (list) 977: && TREE_CHAIN (h->list) == TREE_CHAIN (list)) 978: { 979: my_friendly_assert (TREE_TYPE (h->list) == TREE_TYPE (list), 299); 980: return h->list; 981: } 982: return 0; 983: } 984: 985: /* Add an entry to the list-hash-table 986: for a list TYPE whose hash code is HASHCODE. */ 987: 988: void 989: list_hash_add (hashcode, list) 990: int hashcode; 991: tree list; 992: { 993: register struct list_hash *h; 994: 995: h = (struct list_hash *) obstack_alloc (&class_obstack, sizeof (struct list_hash)); 996: h->hashcode = hashcode; 997: h->list = list; 998: h->next = list_hash_table[hashcode % TYPE_HASH_SIZE]; 999: list_hash_table[hashcode % TYPE_HASH_SIZE] = h; 1000: } 1001: 1002: /* Given TYPE, and HASHCODE its hash code, return the canonical 1003: object for an identical list if one already exists. 1004: Otherwise, return TYPE, and record it as the canonical object 1005: if it is a permanent object. 1006: 1007: To use this function, first create a list of the sort you want. 1008: Then compute its hash code from the fields of the list that 1009: make it different from other similar lists. 1010: Then call this function and use the value. 1011: This function frees the list you pass in if it is a duplicate. */ 1012: 1013: /* Set to 1 to debug without canonicalization. Never set by program. */ 1014: static int debug_no_list_hash = 0; 1015: 1016: tree 1017: list_hash_canon (hashcode, list) 1018: int hashcode; 1019: tree list; 1020: { 1021: tree t1; 1022: 1023: if (debug_no_list_hash) 1024: return list; 1025: 1026: t1 = list_hash_lookup (hashcode, list); 1027: if (t1 != 0) 1028: { 1029: obstack_free (&class_obstack, list); 1030: return t1; 1031: } 1032: 1033: /* If this is a new list, record it for later reuse. */ 1034: list_hash_add (hashcode, list); 1035: 1036: return list; 1037: } 1038: 1039: tree 1040: hash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain) 1041: int via_public, via_virtual, via_protected; 1042: tree purpose, value, chain; 1043: { 1044: struct obstack *ambient_obstack = current_obstack; 1045: tree t; 1046: int hashcode; 1047: 1048: current_obstack = &class_obstack; 1049: t = tree_cons (purpose, value, chain); 1050: TREE_VIA_PUBLIC (t) = via_public; 1051: TREE_VIA_PROTECTED (t) = via_protected; 1052: TREE_VIA_VIRTUAL (t) = via_virtual; 1053: hashcode = list_hash (t); 1054: t = list_hash_canon (hashcode, t); 1055: current_obstack = ambient_obstack; 1056: return t; 1057: } 1058: 1059: /* Constructor for hashed lists. */ 1060: tree 1061: hash_tree_chain (value, chain) 1062: tree value, chain; 1063: { 1064: struct obstack *ambient_obstack = current_obstack; 1065: tree t; 1066: int hashcode; 1067: 1068: current_obstack = &class_obstack; 1069: t = tree_cons (NULL_TREE, value, chain); 1070: hashcode = list_hash (t); 1071: t = list_hash_canon (hashcode, t); 1072: current_obstack = ambient_obstack; 1073: return t; 1074: } 1075: 1076: /* Similar, but used for concatenating two lists. */ 1077: tree 1078: hash_chainon (list1, list2) 1079: tree list1, list2; 1080: { 1081: if (list2 == 0) 1082: return list1; 1083: if (list1 == 0) 1084: return list2; 1085: if (TREE_CHAIN (list1) == NULL_TREE) 1086: return hash_tree_chain (TREE_VALUE (list1), list2); 1087: return hash_tree_chain (TREE_VALUE (list1), 1088: hash_chainon (TREE_CHAIN (list1), list2)); 1089: } 1090: 1091: static tree 1092: get_identifier_list (value) 1093: tree value; 1094: { 1095: tree list = IDENTIFIER_AS_LIST (value); 1096: if (list != NULL_TREE 1097: && (TREE_CODE (list) != TREE_LIST 1098: || TREE_VALUE (list) != value)) 1099: list = NULL_TREE; 1100: else if (IDENTIFIER_HAS_TYPE_VALUE (value) 1101: && TREE_CODE (IDENTIFIER_TYPE_VALUE (value)) == RECORD_TYPE 1102: && IDENTIFIER_TYPE_VALUE (value) 1103: == TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (value))) 1104: { 1105: tree type = IDENTIFIER_TYPE_VALUE (value); 1106: 1107: if (TYPE_PTRMEMFUNC_P (type)) 1108: list = NULL_TREE; 1109: else if (type == current_class_type) 1110: /* Don't mess up the constructor name. */ 1111: list = tree_cons (NULL_TREE, value, NULL_TREE); 1112: else 1113: { 1114: register tree id; 1115: /* This will return the correct thing for regular types, 1116: nested types, and templates. Yay! */ 1117: if (TYPE_NESTED_NAME (type)) 1118: id = TYPE_NESTED_NAME (type); 1119: else 1120: id = TYPE_IDENTIFIER (type); 1121: 1122: if (CLASSTYPE_ID_AS_LIST (type) == NULL_TREE) 1123: CLASSTYPE_ID_AS_LIST (type) 1124: = perm_tree_cons (NULL_TREE, id, NULL_TREE); 1125: list = CLASSTYPE_ID_AS_LIST (type); 1126: } 1127: } 1128: return list; 1129: } 1130: 1131: tree 1132: get_decl_list (value) 1133: tree value; 1134: { 1135: tree list = NULL_TREE; 1136: 1137: if (TREE_CODE (value) == IDENTIFIER_NODE) 1138: list = get_identifier_list (value); 1139: else if (TREE_CODE (value) == RECORD_TYPE 1140: && TYPE_LANG_SPECIFIC (value)) 1141: list = CLASSTYPE_AS_LIST (value); 1142: 1143: if (list != NULL_TREE) 1144: { 1145: my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 301); 1146: return list; 1147: } 1148: 1149: return build_decl_list (NULL_TREE, value); 1150: } 1151: 1152: /* Look in the type hash table for a type isomorphic to 1153: `build_tree_list (NULL_TREE, VALUE)'. 1154: If one is found, return it. Otherwise return 0. */ 1155: 1156: tree 1157: list_hash_lookup_or_cons (value) 1158: tree value; 1159: { 1160: register int hashcode = TYPE_HASH (value); 1161: register struct list_hash *h; 1162: struct obstack *ambient_obstack; 1163: tree list = NULL_TREE; 1164: 1165: if (TREE_CODE (value) == IDENTIFIER_NODE) 1166: list = get_identifier_list (value); 1167: else if (TREE_CODE (value) == TYPE_DECL 1168: && TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE 1169: && TYPE_LANG_SPECIFIC (TREE_TYPE (value))) 1170: list = CLASSTYPE_ID_AS_LIST (TREE_TYPE (value)); 1171: else if (TREE_CODE (value) == RECORD_TYPE 1172: && TYPE_LANG_SPECIFIC (value)) 1173: list = CLASSTYPE_AS_LIST (value); 1174: 1175: if (list != NULL_TREE) 1176: { 1177: my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 302); 1178: return list; 1179: } 1180: 1181: if (debug_no_list_hash) 1182: return hash_tree_chain (value, NULL_TREE); 1183: 1184: for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next) 1185: if (h->hashcode == hashcode 1186: && TREE_VIA_VIRTUAL (h->list) == 0 1187: && TREE_VIA_PUBLIC (h->list) == 0 1188: && TREE_VIA_PROTECTED (h->list) == 0 1189: && TREE_PURPOSE (h->list) == 0 1190: && TREE_VALUE (h->list) == value) 1191: { 1192: my_friendly_assert (TREE_TYPE (h->list) == 0, 303); 1193: my_friendly_assert (TREE_CHAIN (h->list) == 0, 304); 1194: return h->list; 1195: } 1196: 1197: ambient_obstack = current_obstack; 1198: current_obstack = &class_obstack; 1199: list = build_tree_list (NULL_TREE, value); 1200: list_hash_add (hashcode, list); 1201: current_obstack = ambient_obstack; 1202: return list; 1203: } 1204: 1205: /* Build an association between TYPE and some parameters: 1206: 1207: OFFSET is the offset added to `this' to convert it to a pointer 1208: of type `TYPE *' 1209: 1210: BINFO is the base binfo to use, if we are deriving from one. This 1211: is necessary, as we want specialized parent binfos from base 1212: classes, so that the VTABLE_NAMEs of bases are for the most derived 1213: type, instead of of the simple type. 1214: 1215: VTABLE is the virtual function table with which to initialize 1216: sub-objects of type TYPE. 1217: 1218: VIRTUALS are the virtual functions sitting in VTABLE. 1219: 1220: CHAIN are more associations we must retain. */ 1221: 1222: tree 1223: make_binfo (offset, binfo, vtable, virtuals, chain) 1224: tree offset, binfo; 1225: tree vtable, virtuals; 1226: tree chain; 1227: { 1228: tree new_binfo = make_tree_vec (6); 1229: tree type; 1230: 1231: if (TREE_CODE (binfo) == TREE_VEC) 1232: type = BINFO_TYPE (binfo); 1233: else 1234: { 1235: type = binfo; 1236: binfo = TYPE_BINFO (binfo); 1237: } 1238: 1239: TREE_CHAIN (new_binfo) = chain; 1240: if (chain) 1241: TREE_USED (new_binfo) = TREE_USED (chain); 1242: 1243: TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type); 1244: BINFO_OFFSET (new_binfo) = offset; 1245: BINFO_VTABLE (new_binfo) = vtable; 1246: BINFO_VIRTUALS (new_binfo) = virtuals; 1247: BINFO_VPTR_FIELD (new_binfo) = NULL_TREE; 1248: 1249: if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE) 1250: BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo)); 1251: return new_binfo; 1252: } 1253: 1254: /* Return the binfo value for ELEM in TYPE. */ 1255: 1256: tree 1257: binfo_value (elem, type) 1258: tree elem; 1259: tree type; 1260: { 1261: if (get_base_distance (elem, type, 0, (tree *)0) == -2) 1262: compiler_error ("base class `%s' ambiguous in binfo_value", 1263: TYPE_NAME_STRING (elem)); 1264: if (elem == type) 1265: return TYPE_BINFO (type); 1266: if (TREE_CODE (elem) == RECORD_TYPE && TYPE_BINFO (elem) == type) 1267: return type; 1268: return get_binfo (elem, type, 0); 1269: } 1270: 1271: tree 1272: reverse_path (path) 1273: tree path; 1274: { 1275: register tree prev = 0, tmp, next; 1276: for (tmp = path; tmp; tmp = next) 1277: { 1278: next = BINFO_INHERITANCE_CHAIN (tmp); 1279: BINFO_INHERITANCE_CHAIN (tmp) = prev; 1280: prev = tmp; 1281: } 1282: return prev; 1283: } 1284: 1285: tree 1286: virtual_member (elem, list) 1287: tree elem; 1288: tree list; 1289: { 1290: tree t; 1291: tree rval, nval; 1292: 1293: for (t = list; t; t = TREE_CHAIN (t)) 1294: if (elem == BINFO_TYPE (t)) 1295: return t; 1296: rval = 0; 1297: for (t = list; t; t = TREE_CHAIN (t)) 1298: { 1299: tree binfos = BINFO_BASETYPES (t); 1300: int i; 1301: 1302: if (binfos != NULL_TREE) 1303: for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--) 1304: { 1305: nval = binfo_value (elem, BINFO_TYPE (TREE_VEC_ELT (binfos, i))); 1306: if (nval) 1307: { 1308: if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval)) 1309: my_friendly_abort (104); 1310: rval = nval; 1311: } 1312: } 1313: } 1314: return rval; 1315: } 1316: 1317: void 1318: debug_binfo (elem) 1319: tree elem; 1320: { 1.1.1.2 ! root 1321: unsigned HOST_WIDE_INT n; 1.1 root 1322: tree virtuals; 1323: 1324: fprintf (stderr, "type \"%s\"; offset = %d\n", 1325: TYPE_NAME_STRING (BINFO_TYPE (elem)), 1326: TREE_INT_CST_LOW (BINFO_OFFSET (elem))); 1327: fprintf (stderr, "vtable type:\n"); 1328: debug_tree (BINFO_TYPE (elem)); 1329: if (BINFO_VTABLE (elem)) 1330: fprintf (stderr, "vtable decl \"%s\"\n", IDENTIFIER_POINTER (DECL_NAME (BINFO_VTABLE (elem)))); 1331: else 1332: fprintf (stderr, "no vtable decl yet\n"); 1333: fprintf (stderr, "virtuals:\n"); 1334: virtuals = BINFO_VIRTUALS (elem); 1.1.1.2 ! root 1335: ! 1336: n = skip_rtti_stuff (&virtuals); ! 1337: 1.1 root 1338: while (virtuals) 1339: { 1340: tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0); 1341: fprintf (stderr, "%s [%d =? %d]\n", 1342: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)), 1.1.1.2 ! root 1343: n, TREE_INT_CST_LOW (DECL_VINDEX (fndecl))); ! 1344: ++n; 1.1 root 1345: virtuals = TREE_CHAIN (virtuals); 1346: } 1347: } 1348: 1349: /* Return the length of a chain of nodes chained through DECL_CHAIN. 1350: We expect a null pointer to mark the end of the chain. 1351: This is the Lisp primitive `length'. */ 1352: 1353: int 1354: decl_list_length (t) 1355: tree t; 1356: { 1357: register tree tail; 1358: register int len = 0; 1359: 1360: my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL 1361: || TREE_CODE (t) == TEMPLATE_DECL, 300); 1362: for (tail = t; tail; tail = DECL_CHAIN (tail)) 1363: len++; 1364: 1365: return len; 1366: } 1367: 1368: int 1369: count_functions (t) 1370: tree t; 1371: { 1372: if (TREE_CODE (t) == FUNCTION_DECL) 1373: return 1; 1374: else if (TREE_CODE (t) == TREE_LIST) 1375: return decl_list_length (TREE_VALUE (t)); 1376: 1377: my_friendly_abort (359); 1378: return 0; 1379: } 1380: 1381: /* Like value_member, but for DECL_CHAINs. */ 1382: tree 1383: decl_value_member (elem, list) 1384: tree elem, list; 1385: { 1386: while (list) 1387: { 1388: if (elem == list) 1389: return list; 1390: list = DECL_CHAIN (list); 1391: } 1392: return NULL_TREE; 1393: } 1394: 1395: int 1396: is_overloaded_fn (x) 1397: tree x; 1398: { 1399: if (TREE_CODE (x) == FUNCTION_DECL) 1400: return 1; 1401: 1402: if (TREE_CODE (x) == TREE_LIST 1403: && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL 1404: || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL)) 1405: return 1; 1406: 1407: return 0; 1408: } 1409: 1410: int 1411: really_overloaded_fn (x) 1412: tree x; 1413: { 1414: if (TREE_CODE (x) == TREE_LIST 1415: && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL 1416: || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL)) 1417: return 1; 1418: 1419: return 0; 1420: } 1421: 1422: tree 1423: get_first_fn (from) 1424: tree from; 1425: { 1426: if (TREE_CODE (from) == FUNCTION_DECL) 1427: return from; 1428: 1429: my_friendly_assert (TREE_CODE (from) == TREE_LIST, 9); 1430: 1431: return TREE_VALUE (from); 1432: } 1433: 1434: tree 1435: fnaddr_from_vtable_entry (entry) 1436: tree entry; 1437: { 1438: if (flag_vtable_thunks) 1439: { 1440: tree func = entry; 1441: if (TREE_CODE (func) == ADDR_EXPR) 1442: func = TREE_OPERAND (func, 0); 1443: if (TREE_CODE (func) == THUNK_DECL) 1444: return DECL_INITIAL (func); 1445: else 1446: return entry; 1447: } 1448: else 1449: return TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry)))); 1450: } 1451: 1452: void 1453: set_fnaddr_from_vtable_entry (entry, value) 1454: tree entry, value; 1455: { 1456: if (flag_vtable_thunks) 1457: abort (); 1458: else 1459: TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry)))) = value; 1460: } 1461: 1462: tree 1463: function_arg_chain (t) 1464: tree t; 1465: { 1466: return TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (t))); 1467: } 1468: 1469: int 1470: promotes_to_aggr_type (t, code) 1471: tree t; 1472: enum tree_code code; 1473: { 1474: if (TREE_CODE (t) == code) 1475: t = TREE_TYPE (t); 1476: return IS_AGGR_TYPE (t); 1477: } 1478: 1479: int 1480: is_aggr_type_2 (t1, t2) 1481: tree t1, t2; 1482: { 1483: if (TREE_CODE (t1) != TREE_CODE (t2)) 1484: return 0; 1485: return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2); 1486: } 1487: 1488: /* Give message using types TYPE1 and TYPE2 as arguments. 1489: PFN is the function which will print the message; 1490: S is the format string for PFN to use. */ 1491: void 1492: message_2_types (pfn, s, type1, type2) 1493: void (*pfn) (); 1494: char *s; 1495: tree type1, type2; 1496: { 1497: tree name1 = TYPE_NAME (type1); 1498: tree name2 = TYPE_NAME (type2); 1499: if (TREE_CODE (name1) == TYPE_DECL) 1500: name1 = DECL_NAME (name1); 1501: if (TREE_CODE (name2) == TYPE_DECL) 1502: name2 = DECL_NAME (name2); 1503: (*pfn) (s, IDENTIFIER_POINTER (name1), IDENTIFIER_POINTER (name2)); 1504: } 1505: 1506: #define PRINT_RING_SIZE 4 1507: 1508: char * 1509: lang_printable_name (decl) 1510: tree decl; 1511: { 1512: static tree decl_ring[PRINT_RING_SIZE]; 1513: static char *print_ring[PRINT_RING_SIZE]; 1514: static int ring_counter; 1515: int i; 1516: 1517: /* Only cache functions. */ 1518: if (TREE_CODE (decl) != FUNCTION_DECL 1519: || DECL_LANG_SPECIFIC (decl) == 0) 1520: return decl_as_string (decl, 1); 1521: 1522: /* See if this print name is lying around. */ 1523: for (i = 0; i < PRINT_RING_SIZE; i++) 1524: if (decl_ring[i] == decl) 1525: /* yes, so return it. */ 1526: return print_ring[i]; 1527: 1528: if (++ring_counter == PRINT_RING_SIZE) 1529: ring_counter = 0; 1530: 1531: if (current_function_decl != NULL_TREE) 1532: { 1533: if (decl_ring[ring_counter] == current_function_decl) 1534: ring_counter += 1; 1535: if (ring_counter == PRINT_RING_SIZE) 1536: ring_counter = 0; 1537: if (decl_ring[ring_counter] == current_function_decl) 1538: my_friendly_abort (106); 1539: } 1540: 1541: if (print_ring[ring_counter]) 1542: free (print_ring[ring_counter]); 1543: 1544: { 1545: int print_ret_type_p 1546: = (!DECL_CONSTRUCTOR_P (decl) 1547: && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))); 1548: 1549: char *name = (char *)decl_as_string (decl, print_ret_type_p); 1550: print_ring[ring_counter] = (char *)malloc (strlen (name) + 1); 1551: strcpy (print_ring[ring_counter], name); 1552: decl_ring[ring_counter] = decl; 1553: } 1554: return print_ring[ring_counter]; 1555: } 1556: 1557: /* Comparison function for sorting identifiers in RAISES lists. 1558: Note that because IDENTIFIER_NODEs are unique, we can sort 1559: them by address, saving an indirection. */ 1560: static int 1561: id_cmp (p1, p2) 1562: tree *p1, *p2; 1563: { 1564: return (HOST_WIDE_INT)TREE_VALUE (*p1) - (HOST_WIDE_INT)TREE_VALUE (*p2); 1565: } 1566: 1.1.1.2 ! root 1567: /* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions 1.1 root 1568: listed in RAISES. */ 1569: tree 1.1.1.2 ! root 1570: build_exception_variant (type, raises) ! 1571: tree type; 1.1 root 1572: tree raises; 1573: { 1574: int i; 1575: tree v = TYPE_MAIN_VARIANT (type); 1576: tree t, t2, cname; 1577: tree *a = (tree *)alloca ((list_length (raises)+1) * sizeof (tree)); 1578: int constp = TYPE_READONLY (type); 1579: int volatilep = TYPE_VOLATILE (type); 1580: 1581: for (v = TYPE_NEXT_VARIANT (v); v; v = TYPE_NEXT_VARIANT (v)) 1582: { 1583: if (TYPE_READONLY (v) != constp 1584: || TYPE_VOLATILE (v) != volatilep) 1585: continue; 1586: 1.1.1.2 ! root 1587: /* @@ This should do set equality, not exact match. */ ! 1588: if (simple_cst_list_equal (TYPE_RAISES_EXCEPTIONS (v), raises)) ! 1589: /* List of exceptions raised matches previously found list. ! 1590: ! 1591: @@ Nice to free up storage used in consing up the ! 1592: @@ list of exceptions raised. */ ! 1593: return v; 1.1 root 1594: } 1595: 1596: /* Need to build a new variant. */ 1597: v = copy_node (type); 1598: TYPE_NEXT_VARIANT (v) = TYPE_NEXT_VARIANT (type); 1599: TYPE_NEXT_VARIANT (type) = v; 1600: if (raises && ! TREE_PERMANENT (raises)) 1601: { 1602: push_obstacks_nochange (); 1603: end_temporary_allocation (); 1604: raises = copy_list (raises); 1605: pop_obstacks (); 1606: } 1607: TYPE_RAISES_EXCEPTIONS (v) = raises; 1608: return v; 1609: } 1610: 1611: /* Subroutine of copy_to_permanent 1612: 1613: Assuming T is a node build bottom-up, make it all exist on 1614: permanent obstack, if it is not permanent already. */ 1.1.1.2 ! root 1615: ! 1616: tree ! 1617: mapcar (t, func) 1.1 root 1618: tree t; 1.1.1.2 ! root 1619: tree (*func)(); 1.1 root 1620: { 1621: enum tree_code code; 1.1.1.2 ! root 1622: tree tmp; 1.1 root 1623: 1.1.1.2 ! root 1624: if (t == NULL_TREE) 1.1 root 1625: return t; 1626: 1.1.1.2 ! root 1627: if (tmp = func (t), tmp != NULL_TREE) ! 1628: return tmp; ! 1629: 1.1 root 1630: switch (code = TREE_CODE (t)) 1631: { 1632: case ERROR_MARK: 1633: return error_mark_node; 1634: 1635: case VAR_DECL: 1636: case FUNCTION_DECL: 1637: case CONST_DECL: 1638: break; 1639: 1640: case PARM_DECL: 1641: { 1642: tree chain = TREE_CHAIN (t); 1643: t = copy_node (t); 1.1.1.2 ! root 1644: TREE_CHAIN (t) = mapcar (chain, func); ! 1645: TREE_TYPE (t) = mapcar (TREE_TYPE (t), func); ! 1646: DECL_INITIAL (t) = mapcar (DECL_INITIAL (t), func); ! 1647: DECL_SIZE (t) = mapcar (DECL_SIZE (t), func); 1.1 root 1648: return t; 1649: } 1650: 1651: case TREE_LIST: 1652: { 1653: tree chain = TREE_CHAIN (t); 1654: t = copy_node (t); 1.1.1.2 ! root 1655: TREE_PURPOSE (t) = mapcar (TREE_PURPOSE (t), func); ! 1656: TREE_VALUE (t) = mapcar (TREE_VALUE (t), func); ! 1657: TREE_CHAIN (t) = mapcar (chain, func); 1.1 root 1658: return t; 1659: } 1660: 1661: case TREE_VEC: 1662: { 1663: int len = TREE_VEC_LENGTH (t); 1664: 1665: t = copy_node (t); 1666: while (len--) 1.1.1.2 ! root 1667: TREE_VEC_ELT (t, len) = mapcar (TREE_VEC_ELT (t, len), func); 1.1 root 1668: return t; 1669: } 1670: 1671: case INTEGER_CST: 1672: case REAL_CST: 1673: case STRING_CST: 1674: return copy_node (t); 1675: 1676: case COND_EXPR: 1677: case TARGET_EXPR: 1678: case NEW_EXPR: 1679: t = copy_node (t); 1.1.1.2 ! root 1680: TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); ! 1681: TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); ! 1682: TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func); 1.1 root 1683: return t; 1684: 1685: case SAVE_EXPR: 1686: t = copy_node (t); 1.1.1.2 ! root 1687: TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); 1.1 root 1688: return t; 1689: 1690: case MODIFY_EXPR: 1691: case PLUS_EXPR: 1692: case MINUS_EXPR: 1693: case MULT_EXPR: 1694: case TRUNC_DIV_EXPR: 1695: case TRUNC_MOD_EXPR: 1696: case MIN_EXPR: 1697: case MAX_EXPR: 1698: case LSHIFT_EXPR: 1699: case RSHIFT_EXPR: 1700: case BIT_IOR_EXPR: 1701: case BIT_XOR_EXPR: 1702: case BIT_AND_EXPR: 1703: case BIT_ANDTC_EXPR: 1704: case TRUTH_ANDIF_EXPR: 1705: case TRUTH_ORIF_EXPR: 1706: case LT_EXPR: 1707: case LE_EXPR: 1708: case GT_EXPR: 1709: case GE_EXPR: 1710: case EQ_EXPR: 1711: case NE_EXPR: 1712: case CEIL_DIV_EXPR: 1713: case FLOOR_DIV_EXPR: 1714: case ROUND_DIV_EXPR: 1715: case CEIL_MOD_EXPR: 1716: case FLOOR_MOD_EXPR: 1717: case ROUND_MOD_EXPR: 1718: case COMPOUND_EXPR: 1719: case PREDECREMENT_EXPR: 1720: case PREINCREMENT_EXPR: 1721: case POSTDECREMENT_EXPR: 1722: case POSTINCREMENT_EXPR: 1723: case CALL_EXPR: 1724: t = copy_node (t); 1.1.1.2 ! root 1725: TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); ! 1726: TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); 1.1 root 1727: return t; 1728: 1729: case CONVERT_EXPR: 1730: case ADDR_EXPR: 1731: case INDIRECT_REF: 1732: case NEGATE_EXPR: 1733: case BIT_NOT_EXPR: 1734: case TRUTH_NOT_EXPR: 1735: case NOP_EXPR: 1736: case COMPONENT_REF: 1737: t = copy_node (t); 1.1.1.2 ! root 1738: TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); 1.1 root 1739: return t; 1740: 1741: case POINTER_TYPE: 1.1.1.2 ! root 1742: return build_pointer_type (mapcar (TREE_TYPE (t), func)); 1.1 root 1743: case REFERENCE_TYPE: 1.1.1.2 ! root 1744: return build_reference_type (mapcar (TREE_TYPE (t), func)); 1.1 root 1745: case FUNCTION_TYPE: 1.1.1.2 ! root 1746: return build_function_type (mapcar (TREE_TYPE (t), func), ! 1747: mapcar (TYPE_ARG_TYPES (t), func)); 1.1 root 1748: case ARRAY_TYPE: 1.1.1.2 ! root 1749: return build_array_type (mapcar (TREE_TYPE (t), func), ! 1750: mapcar (TYPE_DOMAIN (t), func)); ! 1751: case INTEGER_TYPE: ! 1752: return build_index_type (mapcar (TYPE_MAX_VALUE (t), func)); ! 1753: 1.1 root 1754: case OFFSET_TYPE: 1.1.1.2 ! root 1755: return build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func), ! 1756: mapcar (TREE_TYPE (t), func)); 1.1 root 1757: case METHOD_TYPE: 1758: return build_method_type 1.1.1.2 ! root 1759: (mapcar (TYPE_METHOD_BASETYPE (t), func), 1.1 root 1760: build_function_type 1.1.1.2 ! root 1761: (mapcar (TREE_TYPE (t), func), ! 1762: mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func))); ! 1763: 1.1 root 1764: case RECORD_TYPE: 1765: if (TYPE_PTRMEMFUNC_P (t)) 1766: return build_ptrmemfunc_type 1.1.1.2 ! root 1767: (mapcar (TYPE_PTRMEMFUNC_FN_TYPE (t), func)); 1.1 root 1768: /* else fall through */ 1769: 1770: /* This list is incomplete, but should suffice for now. 1771: It is very important that `sorry' does not call 1772: `report_error_function'. That could cause an infinite loop. */ 1773: default: 1774: sorry ("initializer contains unrecognized tree code"); 1775: return error_mark_node; 1776: 1777: } 1778: my_friendly_abort (107); 1779: /* NOTREACHED */ 1780: return NULL_TREE; 1781: } 1782: 1.1.1.2 ! root 1783: static tree ! 1784: perm_manip (t) ! 1785: tree t; ! 1786: { ! 1787: if (TREE_PERMANENT (t)) ! 1788: return t; ! 1789: return NULL_TREE; ! 1790: } ! 1791: 1.1 root 1792: /* Assuming T is a node built bottom-up, make it all exist on 1793: permanent obstack, if it is not permanent already. */ 1794: tree 1795: copy_to_permanent (t) 1796: tree t; 1797: { 1798: register struct obstack *ambient_obstack = current_obstack; 1799: register struct obstack *ambient_saveable_obstack = saveable_obstack; 1.1.1.2 ! root 1800: int resume; 1.1 root 1801: 1802: if (t == NULL_TREE || TREE_PERMANENT (t)) 1803: return t; 1804: 1805: saveable_obstack = &permanent_obstack; 1806: current_obstack = saveable_obstack; 1.1.1.2 ! root 1807: resume = suspend_momentary (); 1.1 root 1808: 1.1.1.2 ! root 1809: t = mapcar (t, perm_manip); 1.1 root 1810: 1.1.1.2 ! root 1811: resume_momentary (resume); 1.1 root 1812: current_obstack = ambient_obstack; 1813: saveable_obstack = ambient_saveable_obstack; 1814: 1815: return t; 1816: } 1817: 1818: void 1819: print_lang_statistics () 1820: { 1821: extern struct obstack maybepermanent_obstack; 1822: print_obstack_statistics ("class_obstack", &class_obstack); 1823: print_obstack_statistics ("permanent_obstack", &permanent_obstack); 1824: print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack); 1825: print_search_statistics (); 1826: print_class_statistics (); 1827: } 1828: 1829: /* This is used by the `assert' macro. It is provided in libgcc.a, 1830: which `cc' doesn't know how to link. Note that the C++ front-end 1831: no longer actually uses the `assert' macro (instead, it calls 1832: my_friendly_assert). But all of the back-end files still need this. */ 1833: void 1834: __eprintf (string, expression, line, filename) 1835: #ifdef __STDC__ 1836: const char *string; 1837: const char *expression; 1838: unsigned line; 1839: const char *filename; 1840: #else 1841: char *string; 1842: char *expression; 1843: unsigned line; 1844: char *filename; 1845: #endif 1846: { 1847: fprintf (stderr, string, expression, line, filename); 1848: fflush (stderr); 1849: abort (); 1850: } 1851: 1852: /* Return, as an INTEGER_CST node, the number of elements for 1853: TYPE (which is an ARRAY_TYPE). This counts only elements of the top array. */ 1854: 1855: tree 1856: array_type_nelts_top (type) 1857: tree type; 1858: { 1859: return fold (build (PLUS_EXPR, sizetype, 1860: array_type_nelts (type), 1861: integer_one_node)); 1862: } 1863: 1864: /* Return, as an INTEGER_CST node, the number of elements for 1865: TYPE (which is an ARRAY_TYPE). This one is a recursive count of all 1866: ARRAY_TYPEs that are clumped together. */ 1867: 1868: tree 1869: array_type_nelts_total (type) 1870: tree type; 1871: { 1872: tree sz = array_type_nelts_top (type); 1873: type = TREE_TYPE (type); 1874: while (TREE_CODE (type) == ARRAY_TYPE) 1875: { 1876: tree n = array_type_nelts_top (type); 1877: sz = fold (build (MULT_EXPR, sizetype, sz, n)); 1878: type = TREE_TYPE (type); 1879: } 1880: return sz; 1881: } 1.1.1.2 ! root 1882: ! 1883: static ! 1884: tree ! 1885: bot_manip (t) ! 1886: tree t; ! 1887: { ! 1888: if (TREE_CODE (t) != TREE_LIST && ! TREE_SIDE_EFFECTS (t)) ! 1889: return t; ! 1890: else if (TREE_CODE (t) == TARGET_EXPR) ! 1891: return build_cplus_new (TREE_TYPE (t), ! 1892: break_out_target_exprs (TREE_OPERAND (t, 1)), 0); ! 1893: return NULL_TREE; ! 1894: } ! 1895: ! 1896: /* Actually, we'll just clean out the target exprs for the moment. */ ! 1897: tree ! 1898: break_out_target_exprs (t) ! 1899: tree t; ! 1900: { ! 1901: return mapcar (t, bot_manip); ! 1902: } ! 1903: ! 1904: tree ! 1905: unsave_expr (expr) ! 1906: tree expr; ! 1907: { ! 1908: tree t; ! 1909: ! 1910: t = build1 (UNSAVE_EXPR, TREE_TYPE (expr), expr); ! 1911: TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (expr); ! 1912: return t; ! 1913: } ! 1914: ! 1915: /* Modify a tree in place so that all the evaluate only once things ! 1916: are cleared out. Return the EXPR given. */ ! 1917: tree ! 1918: unsave_expr_now (expr) ! 1919: tree expr; ! 1920: { ! 1921: enum tree_code code; ! 1922: register int i; ! 1923: ! 1924: if (expr == NULL_TREE) ! 1925: return expr; ! 1926: ! 1927: code = TREE_CODE (expr); ! 1928: switch (code) ! 1929: { ! 1930: case SAVE_EXPR: ! 1931: SAVE_EXPR_RTL (expr) = NULL_RTX; ! 1932: break; ! 1933: ! 1934: case TARGET_EXPR: ! 1935: sorry ("TARGET_EXPR reused inside UNSAVE_EXPR"); ! 1936: break; ! 1937: ! 1938: case RTL_EXPR: ! 1939: warning ("RTL_EXPR reused inside UNSAVE_EXPR"); ! 1940: RTL_EXPR_SEQUENCE (expr) = NULL_RTX; ! 1941: break; ! 1942: ! 1943: case CALL_EXPR: ! 1944: CALL_EXPR_RTL (expr) = NULL_RTX; ! 1945: if (TREE_OPERAND (expr, 1) ! 1946: && TREE_CODE (TREE_OPERAND (expr, 1)) == TREE_LIST) ! 1947: { ! 1948: tree exp = TREE_OPERAND (expr, 1); ! 1949: while (exp) ! 1950: { ! 1951: unsave_expr_now (TREE_VALUE (exp)); ! 1952: exp = TREE_CHAIN (exp); ! 1953: } ! 1954: } ! 1955: break; ! 1956: ! 1957: case WITH_CLEANUP_EXPR: ! 1958: warning ("WITH_CLEANUP_EXPR reused inside UNSAVE_EXPR"); ! 1959: RTL_EXPR_RTL (expr) = NULL_RTX; ! 1960: break; ! 1961: } ! 1962: ! 1963: switch (TREE_CODE_CLASS (code)) ! 1964: { ! 1965: case 'c': /* a constant */ ! 1966: case 't': /* a type node */ ! 1967: case 'x': /* something random, like an identifier or an ERROR_MARK. */ ! 1968: case 'd': /* A decl node */ ! 1969: case 'b': /* A block node */ ! 1970: return expr; ! 1971: ! 1972: case 'e': /* an expression */ ! 1973: case 'r': /* a reference */ ! 1974: case 's': /* an expression with side effects */ ! 1975: case '<': /* a comparison expression */ ! 1976: case '2': /* a binary arithmetic expression */ ! 1977: case '1': /* a unary arithmetic expression */ ! 1978: for (i = tree_code_length[(int) code] - 1; i >= 0; i--) ! 1979: unsave_expr_now (TREE_OPERAND (expr, i)); ! 1980: return expr; ! 1981: ! 1982: default: ! 1983: my_friendly_abort (999); ! 1984: } ! 1985: } ! 1986: ! 1987: /* Since cleanup may have SAVE_EXPRs in it, we protect it with an ! 1988: UNSAVE_EXPR as the backend cannot yet handle SAVE_EXPRs in cleanups ! 1989: by itself. */ ! 1990: int ! 1991: cp_expand_decl_cleanup (decl, cleanup) ! 1992: tree decl, cleanup; ! 1993: { ! 1994: return expand_decl_cleanup (decl, unsave_expr (cleanup)); ! 1995: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.