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