|
|
1.1 ! root 1: /* Handle initialization things in C++. ! 2: Copyright (C) 1987, 1989, 1992, 1993, 1994 Free Software Foundation, Inc. ! 3: Contributed 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: ! 22: /* High-level class interface. */ ! 23: ! 24: #include "config.h" ! 25: #include "tree.h" ! 26: #include "rtl.h" ! 27: #include "cp-tree.h" ! 28: #include "flags.h" ! 29: ! 30: #undef NULL ! 31: #define NULL 0 ! 32: ! 33: /* In C++, structures with well-defined constructors are initialized by ! 34: those constructors, unasked. CURRENT_BASE_INIT_LIST ! 35: holds a list of stmts for a BASE_INIT term in the grammar. ! 36: This list has one element for each base class which must be ! 37: initialized. The list elements are [basename, init], with ! 38: type basetype. This allows the possibly anachronistic form ! 39: (assuming d : a, b, c) "d (int a) : c(a+5), b (a-4), a (a+3)" ! 40: where each successive term can be handed down the constructor ! 41: line. Perhaps this was not intended. */ ! 42: tree current_base_init_list, current_member_init_list; ! 43: ! 44: void emit_base_init (); ! 45: void check_base_init (); ! 46: static void expand_aggr_vbase_init (); ! 47: void expand_member_init (); ! 48: void expand_aggr_init (); ! 49: ! 50: static void expand_aggr_init_1 (); ! 51: static void expand_recursive_init_1 (); ! 52: static void expand_recursive_init (); ! 53: static void expand_virtual_init PROTO((tree, tree)); ! 54: tree expand_vec_init (); ! 55: ! 56: static void add_friend (), add_friends (); ! 57: ! 58: /* Cache _builtin_new and _builtin_delete exprs. */ ! 59: static tree BIN, BID, BIVN, BIVD; ! 60: ! 61: /* Cache the identifier nodes for the two magic field of a new cookie. */ ! 62: static tree nc_nelts_field_id; ! 63: #if 0 ! 64: static tree nc_ptr_2comp_field_id; ! 65: #endif ! 66: ! 67: static tree minus_one; ! 68: ! 69: /* Set up local variable for this file. MUST BE CALLED AFTER ! 70: INIT_DECL_PROCESSING. */ ! 71: ! 72: tree BI_header_type, BI_header_size; ! 73: ! 74: void init_init_processing () ! 75: { ! 76: tree fields[1]; ! 77: ! 78: /* Define implicit `operator new' and `operator delete' functions. */ ! 79: BIN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) NEW_EXPR]))); ! 80: TREE_USED (TREE_OPERAND (BIN, 0)) = 0; ! 81: BID = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) DELETE_EXPR]))); ! 82: TREE_USED (TREE_OPERAND (BID, 0)) = 0; ! 83: BIVN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_NEW_EXPR]))); ! 84: TREE_USED (TREE_OPERAND (BIVN, 0)) = 0; ! 85: BIVD = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_DELETE_EXPR]))); ! 86: TREE_USED (TREE_OPERAND (BIVD, 0)) = 0; ! 87: minus_one = build_int_2 (-1, -1); ! 88: ! 89: /* Define the structure that holds header information for ! 90: arrays allocated via operator new. */ ! 91: BI_header_type = make_lang_type (RECORD_TYPE); ! 92: nc_nelts_field_id = get_identifier ("nelts"); ! 93: fields[0] = build_lang_field_decl (FIELD_DECL, nc_nelts_field_id, sizetype); ! 94: finish_builtin_type (BI_header_type, "__new_cookie", fields, ! 95: 0, double_type_node); ! 96: BI_header_size = size_in_bytes (BI_header_type); ! 97: } ! 98: ! 99: /* Subroutine of emit_base_init. For BINFO, initialize all the ! 100: virtual function table pointers, except those that come from ! 101: virtual base classes. Initialize binfo's vtable pointer, if ! 102: INIT_SELF is true. CAN_ELIDE is true when we know that all virtual ! 103: function table pointers in all bases have been initialized already, ! 104: probably because their constructors have just be run. ADDR is the ! 105: pointer to the object whos vtables we are going to initialize. ! 106: ! 107: REAL_BINFO is usually the same as BINFO, except when addr is not of ! 108: pointer to the type of the real derived type that we want to ! 109: initialize for. This is the case when addr is a pointer to a sub ! 110: object of a complete object, and we only want to do part of the ! 111: complete object's initiailzation of vtable pointers. This is done ! 112: for all virtual table pointers in virtual base classes. REAL_BINFO ! 113: is used to find the BINFO_VTABLE that we initialize with. BINFO is ! 114: used for conversions of addr to subobjects. ! 115: ! 116: BINFO_TYPE (real_binfo) must be BINFO_TYPE (binfo). ! 117: ! 118: Relies upon binfo being inside TYPE_BINFO (TREE_TYPE (TREE_TYPE ! 119: (addr))). */ ! 120: void ! 121: expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr) ! 122: tree real_binfo, binfo, addr; ! 123: int init_self, can_elide; ! 124: { ! 125: tree real_binfos = BINFO_BASETYPES (real_binfo); ! 126: tree binfos = BINFO_BASETYPES (binfo); ! 127: int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0; ! 128: ! 129: for (i = 0; i < n_baselinks; i++) ! 130: { ! 131: tree real_base_binfo = TREE_VEC_ELT (real_binfos, i); ! 132: tree base_binfo = TREE_VEC_ELT (binfos, i); ! 133: int is_not_base_vtable = ! 134: i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo)); ! 135: if (! TREE_VIA_VIRTUAL (real_base_binfo)) ! 136: expand_direct_vtbls_init (real_base_binfo, base_binfo, ! 137: is_not_base_vtable, can_elide, addr); ! 138: } ! 139: #if 0 ! 140: /* Before turning this on, make sure it is correct. */ ! 141: if (can_elide && ! BINFO_MODIFIED (binfo)) ! 142: return; ! 143: #endif ! 144: /* Should we use something besides CLASSTYPE_VFIELDS? */ ! 145: if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo))) ! 146: { ! 147: tree base_ptr = convert_pointer_to_real (binfo, addr); ! 148: expand_virtual_init (real_binfo, base_ptr); ! 149: } ! 150: } ! 151: ! 152: /* 348 - 351 */ ! 153: /* Subroutine of emit_base_init. */ ! 154: static void ! 155: perform_member_init (member, name, init, explicit) ! 156: tree member, name, init; ! 157: int explicit; ! 158: { ! 159: tree decl; ! 160: tree type = TREE_TYPE (member); ! 161: ! 162: if (TYPE_NEEDS_CONSTRUCTING (type) ! 163: || (init && TYPE_HAS_CONSTRUCTOR (type))) ! 164: { ! 165: /* Since `init' is already a TREE_LIST on the current_member_init_list, ! 166: only build it into one if we aren't already a list. */ ! 167: if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST) ! 168: init = build_tree_list (NULL_TREE, init); ! 169: ! 170: decl = build_component_ref (C_C_D, name, 0, explicit); ! 171: ! 172: if (explicit ! 173: && TREE_CODE (type) == ARRAY_TYPE ! 174: && init != NULL_TREE ! 175: && TREE_CHAIN (init) == NULL_TREE ! 176: && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE) ! 177: { ! 178: /* Initialization of one array from another. */ ! 179: expand_vec_init (TREE_OPERAND (decl, 1), decl, ! 180: array_type_nelts (type), TREE_VALUE (init), 1); ! 181: } ! 182: else ! 183: expand_aggr_init (decl, init, 0); ! 184: } ! 185: else ! 186: { ! 187: if (init == NULL_TREE) ! 188: { ! 189: if (explicit) ! 190: { ! 191: cp_error ("incomplete initializer for member `%D' of class `%T' which has no constructor", ! 192: member, current_class_type); ! 193: init = error_mark_node; ! 194: } ! 195: /* member traversal: note it leaves init NULL */ ! 196: else if (TREE_CODE (TREE_TYPE (member)) == REFERENCE_TYPE) ! 197: cp_pedwarn ("uninitialized reference member `%D'", member); ! 198: } ! 199: else if (TREE_CODE (init) == TREE_LIST) ! 200: { ! 201: /* There was an explicit member initialization. Do some ! 202: work in that case. */ ! 203: if (TREE_CHAIN (init)) ! 204: { ! 205: warning ("initializer list treated as compound expression"); ! 206: init = build_compound_expr (init); ! 207: } ! 208: else ! 209: init = TREE_VALUE (init); ! 210: } ! 211: ! 212: /* We only build this with a null init if we got it from the ! 213: current_member_init_list. */ ! 214: if (init || explicit) ! 215: { ! 216: decl = build_component_ref (C_C_D, name, 0, explicit); ! 217: expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); ! 218: } ! 219: } ! 220: expand_cleanups_to (NULL_TREE); ! 221: if (flag_handle_exceptions && TYPE_NEEDS_DESTRUCTOR (type)) ! 222: cp_warning ("caution, member `%D' may not be destroyed in the presense of an exception during construction", member); ! 223: } ! 224: ! 225: /* Subroutine of emit_member_init. */ ! 226: static tree ! 227: sort_member_init (t) ! 228: tree t; ! 229: { ! 230: extern int warn_reorder; ! 231: tree x, member, name, field, init; ! 232: tree init_list = NULL_TREE; ! 233: tree fields_to_unmark = NULL_TREE; ! 234: int found; ! 235: int last_pos = 0; ! 236: tree last_field; ! 237: ! 238: for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member)) ! 239: { ! 240: int pos; ! 241: found = 0; ! 242: for (x = current_member_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos) ! 243: { ! 244: /* If we cleared this out, then pay no attention to it. */ ! 245: if (TREE_PURPOSE (x) == NULL_TREE) ! 246: continue; ! 247: name = TREE_PURPOSE (x); ! 248: ! 249: #if 0 ! 250: field = (TREE_CODE (name) == COMPONENT_REF ! 251: ? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name)); ! 252: #else ! 253: /* Let's find out when this happens. */ ! 254: my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 348); ! 255: field = IDENTIFIER_CLASS_VALUE (name); ! 256: #endif ! 257: ! 258: /* If one member shadows another, get the outermost one. */ ! 259: if (TREE_CODE (field) == TREE_LIST) ! 260: field = TREE_VALUE (field); ! 261: ! 262: if (field == member) ! 263: { ! 264: /* See if we already found an initializer for this field. */ ! 265: if (found) ! 266: { ! 267: if (DECL_NAME (field)) ! 268: cp_error ("multiple initializations given for member `%D'", ! 269: field); ! 270: continue; ! 271: } ! 272: else ! 273: { ! 274: if (pos < last_pos && warn_reorder) ! 275: { ! 276: cp_warning_at ("member initializers for `%#D'", last_field); ! 277: cp_warning_at (" and `%#D'", field); ! 278: warning (" will be re-ordered to match declaration order"); ! 279: } ! 280: last_pos = pos; ! 281: last_field = field; ! 282: } ! 283: ! 284: init_list = chainon (init_list, ! 285: build_tree_list (name, TREE_VALUE (x))); ! 286: /* Make sure we won't try to work on this init again. */ ! 287: TREE_PURPOSE (x) = NULL_TREE; ! 288: found = 1; ! 289: break; ! 290: } ! 291: } ! 292: ! 293: /* If we didn't find MEMBER in the list, create a dummy entry ! 294: so the two lists (INIT_LIST and the list of members) will be ! 295: symmetrical. */ ! 296: if (! found) ! 297: init_list = chainon (init_list, build_tree_list (NULL_TREE, NULL_TREE)); ! 298: } ! 299: ! 300: for (x = current_member_init_list ; x ; x = TREE_CHAIN (x)) ! 301: { ! 302: if (TREE_PURPOSE (x)) ! 303: { ! 304: name = TREE_PURPOSE (x); ! 305: init = TREE_VALUE (x); ! 306: /* XXX: this may need the COMPONENT_REF operand 0 check if ! 307: it turns out we actually get them. */ ! 308: field = IDENTIFIER_CLASS_VALUE (name); ! 309: ! 310: /* If one member shadows another, get the outermost one. */ ! 311: if (TREE_CODE (field) == TREE_LIST) ! 312: { ! 313: field = TREE_VALUE (field); ! 314: if (decl_type_context (field) != current_class_type) ! 315: cp_error ("field `%D' not in immediate context", field); ! 316: } ! 317: ! 318: #if 0 ! 319: /* It turns out if you have an anonymous union in the ! 320: class, a member from it can end up not being on the ! 321: list of fields (rather, the type is), and therefore ! 322: won't be seen by the for loop above. */ ! 323: ! 324: /* The code in this for loop is derived from a general loop ! 325: which had this check in it. Theoretically, we've hit ! 326: every initialization for the list of members in T, so ! 327: we shouldn't have anything but these left in this list. */ ! 328: my_friendly_assert (DECL_FIELD_CONTEXT (field) != t, 351); ! 329: #endif ! 330: ! 331: if (TREE_HAS_CONSTRUCTOR (field)) ! 332: { ! 333: if (DECL_NAME (field)) ! 334: error ("multiple initializations given for member `%s'", ! 335: IDENTIFIER_POINTER (DECL_NAME (field))); ! 336: continue; ! 337: } ! 338: ! 339: TREE_HAS_CONSTRUCTOR (field) = 1; ! 340: fields_to_unmark = tree_cons (NULL_TREE, field, fields_to_unmark); ! 341: ! 342: perform_member_init (field, name, init, 1); ! 343: TREE_PURPOSE (x) = NULL_TREE; ! 344: } ! 345: } ! 346: ! 347: /* Unmark fields which are initialized for the base class. */ ! 348: while (fields_to_unmark) ! 349: { ! 350: TREE_HAS_CONSTRUCTOR (TREE_VALUE (fields_to_unmark)) = 0; ! 351: /* XXX is this a memory leak? */ ! 352: fields_to_unmark = TREE_CHAIN (fields_to_unmark); ! 353: } ! 354: ! 355: return init_list; ! 356: } ! 357: ! 358: /* Perform whatever initializations have yet to be done on the base ! 359: class of the class variable. These actions are in the global ! 360: variable CURRENT_BASE_INIT_LIST. Such an action could be ! 361: NULL_TREE, meaning that the user has explicitly called the base ! 362: class constructor with no arguments. ! 363: ! 364: If there is a need for a call to a constructor, we must surround ! 365: that call with a pushlevel/poplevel pair, since we are technically ! 366: at the PARM level of scope. ! 367: ! 368: Argument IMMEDIATELY, if zero, forces a new sequence to be ! 369: generated to contain these new insns, so it can be emitted later. ! 370: This sequence is saved in the global variable BASE_INIT_INSNS. ! 371: Otherwise, the insns are emitted into the current sequence. ! 372: ! 373: Note that emit_base_init does *not* initialize virtual base ! 374: classes. That is done specially, elsewhere. */ ! 375: ! 376: void ! 377: emit_base_init (t, immediately) ! 378: tree t; ! 379: int immediately; ! 380: { ! 381: extern tree in_charge_identifier; ! 382: ! 383: tree member, vbases; ! 384: tree init_list; ! 385: int pass, start; ! 386: tree t_binfo = TYPE_BINFO (t); ! 387: tree binfos = BINFO_BASETYPES (t_binfo); ! 388: int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; ! 389: int have_init_list = 0, from_init_list; ! 390: ! 391: if (! immediately) ! 392: { ! 393: do_pending_stack_adjust (); ! 394: start_sequence (); ! 395: } ! 396: ! 397: if (write_symbols == NO_DEBUG) ! 398: /* As a matter of principle, `start_sequence' should do this. */ ! 399: emit_note (0, -1); ! 400: else ! 401: /* Always emit a line number note so we can step into constructors. */ ! 402: emit_line_note_force (DECL_SOURCE_FILE (current_function_decl), ! 403: DECL_SOURCE_LINE (current_function_decl)); ! 404: ! 405: start = ! TYPE_USES_VIRTUAL_BASECLASSES (t); ! 406: for (pass = start; pass < 2; pass++) ! 407: { ! 408: tree vbase_init_list = NULL_TREE; ! 409: ! 410: for (init_list = current_base_init_list; init_list; ! 411: init_list = TREE_CHAIN (init_list)) ! 412: { ! 413: tree basename = TREE_PURPOSE (init_list); ! 414: tree binfo; ! 415: tree init = TREE_VALUE (init_list); ! 416: ! 417: if (basename == NULL_TREE) ! 418: { ! 419: /* Initializer for single base class. Must not ! 420: use multiple inheritance or this is ambiguous. */ ! 421: switch (n_baseclasses) ! 422: { ! 423: case 0: ! 424: error ("type `%s' does not have a base class to initialize", ! 425: IDENTIFIER_POINTER (current_class_name)); ! 426: return; ! 427: case 1: ! 428: break; ! 429: default: ! 430: error ("unnamed initializer ambiguous for type `%s' which uses multiple inheritance", IDENTIFIER_POINTER (current_class_name)); ! 431: return; ! 432: } ! 433: binfo = TREE_VEC_ELT (binfos, 0); ! 434: } ! 435: else if (is_aggr_typedef (basename, 1)) ! 436: { ! 437: binfo = binfo_or_else (IDENTIFIER_TYPE_VALUE (basename), t); ! 438: if (binfo == NULL_TREE) ! 439: continue; ! 440: ! 441: /* Virtual base classes are special cases. Their initializers ! 442: are recorded with this constructor, and they are used when ! 443: this constructor is the top-level constructor called. */ ! 444: if (! TREE_VIA_VIRTUAL (binfo)) ! 445: { ! 446: /* Otherwise, if it is not an immediate base class, complain. */ ! 447: for (i = n_baseclasses-1; i >= 0; i--) ! 448: if (BINFO_TYPE (binfo) == BINFO_TYPE (TREE_VEC_ELT (binfos, i))) ! 449: break; ! 450: if (i < 0) ! 451: { ! 452: error ("type `%s' is not an immediate base class of type `%s'", ! 453: IDENTIFIER_POINTER (basename), ! 454: IDENTIFIER_POINTER (current_class_name)); ! 455: continue; ! 456: } ! 457: } ! 458: } ! 459: else ! 460: continue; ! 461: ! 462: /* The base initialization list goes up to the first ! 463: base class which can actually use it. */ ! 464: ! 465: if (pass == start) ! 466: { ! 467: char *msgp = (! TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (binfo))) ! 468: ? "cannot pass initialization up to class `%s'" : 0; ! 469: ! 470: while (! TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (binfo)) ! 471: && BINFO_BASETYPES (binfo) != NULL_TREE ! 472: && TREE_VEC_LENGTH (BINFO_BASETYPES (binfo)) == 1) ! 473: { ! 474: /* ?? This should be fixed in RENO by forcing ! 475: default constructors to exist. */ ! 476: SET_BINFO_BASEINIT_MARKED (binfo); ! 477: binfo = BINFO_BASETYPE (binfo, 0); ! 478: } ! 479: ! 480: /* We used to give an error if this wasn't true, saying that ! 481: there's no constructor for the initialization of basename. ! 482: This turned out to be incorrect---it should use the ! 483: default constructor, since a user could try to initialize ! 484: the class in a derived class's base initializer list. */ ! 485: if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (binfo))) ! 486: { ! 487: if (msgp) ! 488: { ! 489: if (pedantic) ! 490: error_with_aggr_type (binfo, msgp); ! 491: else ! 492: msgp = NULL; ! 493: } ! 494: } ! 495: ! 496: if (BINFO_BASEINIT_MARKED (binfo)) ! 497: { ! 498: msgp = "class `%s' initializer already specified"; ! 499: error (msgp, IDENTIFIER_POINTER (basename)); ! 500: } ! 501: ! 502: if (msgp) ! 503: continue; ! 504: ! 505: SET_BINFO_BASEINIT_MARKED (binfo); ! 506: if (TREE_VIA_VIRTUAL (binfo)) ! 507: { ! 508: vbase_init_list = tree_cons (init, BINFO_TYPE (binfo), ! 509: vbase_init_list); ! 510: continue; ! 511: } ! 512: if (pass == 0) ! 513: continue; ! 514: } ! 515: else if (TREE_VIA_VIRTUAL (binfo)) ! 516: continue; ! 517: ! 518: member = convert_pointer_to (binfo, current_class_decl); ! 519: expand_aggr_init_1 (binfo, 0, ! 520: build_indirect_ref (member, NULL_PTR), init, ! 521: BINFO_OFFSET_ZEROP (binfo), LOOKUP_NORMAL); ! 522: expand_cleanups_to (NULL_TREE); ! 523: } ! 524: ! 525: if (pass == 0) ! 526: { ! 527: tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); ! 528: tree vbases; ! 529: ! 530: if (DECL_NAME (current_function_decl) == NULL_TREE ! 531: && TREE_CHAIN (first_arg) != NULL_TREE) ! 532: { ! 533: /* If there are virtual baseclasses without initialization ! 534: specified, and this is a default X(X&) constructor, ! 535: build the initialization list so that each virtual baseclass ! 536: of the new object is initialized from the virtual baseclass ! 537: of the incoming arg. */ ! 538: tree init_arg = build_unary_op (ADDR_EXPR, TREE_CHAIN (first_arg), 0); ! 539: for (vbases = CLASSTYPE_VBASECLASSES (t); ! 540: vbases; vbases = TREE_CHAIN (vbases)) ! 541: { ! 542: if (BINFO_BASEINIT_MARKED (vbases) == 0) ! 543: { ! 544: member = convert_pointer_to (vbases, init_arg); ! 545: if (member == init_arg) ! 546: member = TREE_CHAIN (first_arg); ! 547: else ! 548: TREE_TYPE (member) = build_reference_type (BINFO_TYPE (vbases)); ! 549: vbase_init_list = tree_cons (convert_from_reference (member), ! 550: vbases, vbase_init_list); ! 551: SET_BINFO_BASEINIT_MARKED (vbases); ! 552: } ! 553: } ! 554: } ! 555: expand_start_cond (first_arg, 0); ! 556: expand_aggr_vbase_init (t_binfo, C_C_D, current_class_decl, ! 557: vbase_init_list); ! 558: expand_end_cond (); ! 559: } ! 560: } ! 561: current_base_init_list = NULL_TREE; ! 562: ! 563: /* Now, perform default initialization of all base classes which ! 564: have not yet been initialized, and unmark baseclasses which ! 565: have been initialized. */ ! 566: for (i = 0; i < n_baseclasses; i++) ! 567: { ! 568: tree base = current_class_decl; ! 569: tree base_binfo = TREE_VEC_ELT (binfos, i); ! 570: ! 571: if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo))) ! 572: { ! 573: if (! TREE_VIA_VIRTUAL (base_binfo) ! 574: && ! BINFO_BASEINIT_MARKED (base_binfo)) ! 575: { ! 576: tree ref; ! 577: ! 578: if (BINFO_OFFSET_ZEROP (base_binfo)) ! 579: base = build1 (NOP_EXPR, ! 580: TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), ! 581: current_class_decl); ! 582: else ! 583: base = build (PLUS_EXPR, ! 584: TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), ! 585: current_class_decl, BINFO_OFFSET (base_binfo)); ! 586: ! 587: ref = build_indirect_ref (base, NULL_PTR); ! 588: expand_aggr_init_1 (base_binfo, 0, ref, NULL_TREE, ! 589: BINFO_OFFSET_ZEROP (base_binfo), ! 590: LOOKUP_NORMAL); ! 591: expand_cleanups_to (NULL_TREE); ! 592: } ! 593: } ! 594: CLEAR_BINFO_BASEINIT_MARKED (base_binfo); ! 595: ! 596: if (! TYPE_USES_VIRTUAL_BASECLASSES (t)) ! 597: { ! 598: while (! TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (base_binfo)) ! 599: && BINFO_BASETYPES (base_binfo) != NULL_TREE ! 600: && TREE_VEC_LENGTH (BINFO_BASETYPES (base_binfo)) == 1) ! 601: { ! 602: /* ?? This should be fixed in RENO by forcing ! 603: default constructors to exist. It is needed for symmetry ! 604: with code above. */ ! 605: base_binfo = BINFO_BASETYPE (base_binfo, 0); ! 606: CLEAR_BINFO_BASEINIT_MARKED (base_binfo); ! 607: } ! 608: } ! 609: } ! 610: ! 611: /* Initialize all the virtual function table fields that ! 612: do come from virtual base classes. */ ! 613: if (TYPE_USES_VIRTUAL_BASECLASSES (t)) ! 614: expand_indirect_vtbls_init (t_binfo, C_C_D, current_class_decl, 0); ! 615: for (vbases = CLASSTYPE_VBASECLASSES (t); vbases; vbases = TREE_CHAIN (vbases)) ! 616: CLEAR_BINFO_BASEINIT_MARKED (vbases); ! 617: ! 618: /* Initialize all the virtual function table fields that ! 619: do not come from virtual base classes. */ ! 620: expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_decl); ! 621: ! 622: if (current_member_init_list) ! 623: { ! 624: init_list = sort_member_init (t); ! 625: have_init_list = 1; ! 626: } ! 627: ! 628: for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) ! 629: { ! 630: tree init, name; ! 631: from_init_list = 0; ! 632: ! 633: /* See if we had a user-specified member initialization. */ ! 634: if (have_init_list) ! 635: { ! 636: if (TREE_PURPOSE (init_list)) ! 637: { ! 638: name = TREE_PURPOSE (init_list); ! 639: init = TREE_VALUE (init_list); ! 640: from_init_list = 1; ! 641: ! 642: if (TREE_STATIC (member)) ! 643: { ! 644: error_with_aggr_type (DECL_FIELD_CONTEXT (member), ! 645: "field `%s::%s' is static; only point of initialization is its declaration", ! 646: IDENTIFIER_POINTER (TREE_PURPOSE (init_list))); ! 647: continue; ! 648: } ! 649: ! 650: /* Also see if it's ever a COMPONENT_REF here. If it is, we ! 651: need to do `expand_assignment (name, init, 0, 0);' and ! 652: a continue. */ ! 653: my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349); ! 654: } ! 655: ! 656: init_list = TREE_CHAIN (init_list); ! 657: } ! 658: ! 659: if (! from_init_list) ! 660: { ! 661: /* member could be, for example, a CONST_DECL for an enumerated ! 662: tag; we don't want to try to initialize that, since it already ! 663: has a value. */ ! 664: if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member)) ! 665: continue; ! 666: ! 667: name = DECL_NAME (member); ! 668: init = DECL_INITIAL (member); ! 669: } ! 670: ! 671: perform_member_init (member, name, init, from_init_list); ! 672: } ! 673: ! 674: current_member_init_list = NULL_TREE; ! 675: ! 676: if (! immediately) ! 677: { ! 678: extern rtx base_init_insns; ! 679: ! 680: do_pending_stack_adjust (); ! 681: my_friendly_assert (base_init_insns == 0, 207); ! 682: base_init_insns = get_insns (); ! 683: end_sequence (); ! 684: } ! 685: ! 686: /* All the implicit try blocks we built up will be zapped ! 687: when we come to a real binding contour boundary. */ ! 688: } ! 689: ! 690: /* Check that all fields are properly initialized after ! 691: an assignment to `this'. */ ! 692: void ! 693: check_base_init (t) ! 694: tree t; ! 695: { ! 696: tree member; ! 697: for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) ! 698: if (DECL_NAME (member) && TREE_USED (member)) ! 699: cp_error ("field `%D' used before initialized (after assignment to `this')", ! 700: member); ! 701: } ! 702: ! 703: /* This code sets up the virtual function tables appropriate for ! 704: the pointer DECL. It is a one-ply initialization. ! 705: ! 706: BINFO is the exact type that DECL is supposed to be. In ! 707: multiple inheritance, this might mean "C's A" if C : A, B. */ ! 708: static void ! 709: expand_virtual_init (binfo, decl) ! 710: tree binfo, decl; ! 711: { ! 712: tree type = BINFO_TYPE (binfo); ! 713: tree vtbl, vtbl_ptr; ! 714: tree vtype, vtype_binfo; ! 715: ! 716: /* This code is crusty. Should be simple, like: ! 717: vtbl = BINFO_VTABLE (binfo); ! 718: */ ! 719: vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type)); ! 720: vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0); ! 721: vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo)); ! 722: if (!flag_vtable_thunks) ! 723: assemble_external (vtbl); ! 724: TREE_USED (vtbl) = 1; ! 725: vtbl = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (vtbl)), vtbl); ! 726: decl = convert_pointer_to_real (vtype_binfo, decl); ! 727: vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, NULL_PTR), vtype); ! 728: if (vtbl_ptr == error_mark_node) ! 729: return; ! 730: ! 731: /* Have to convert VTBL since array sizes may be different. */ ! 732: vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl); ! 733: expand_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl)); ! 734: } ! 735: ! 736: /* Subroutine of `expand_aggr_vbase_init'. ! 737: BINFO is the binfo of the type that is being initialized. ! 738: INIT_LIST is the list of initializers for the virtual baseclass. */ ! 739: static void ! 740: expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) ! 741: tree binfo, exp, addr, init_list; ! 742: { ! 743: tree init = value_member (BINFO_TYPE (binfo), init_list); ! 744: tree ref = build_indirect_ref (addr, NULL_PTR); ! 745: if (init) ! 746: init = TREE_PURPOSE (init); ! 747: /* Call constructors, but don't set up vtables. */ ! 748: expand_aggr_init_1 (binfo, exp, ref, init, 0, ! 749: LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY); ! 750: expand_cleanups_to (NULL_TREE); ! 751: CLEAR_BINFO_VBASE_INIT_MARKED (binfo); ! 752: } ! 753: ! 754: /* Initialize this object's virtual base class pointers. This must be ! 755: done only at the top-level of the object being constructed. ! 756: ! 757: INIT_LIST is list of initialization for constructor to perform. */ ! 758: static void ! 759: expand_aggr_vbase_init (binfo, exp, addr, init_list) ! 760: tree binfo; ! 761: tree exp; ! 762: tree addr; ! 763: tree init_list; ! 764: { ! 765: tree type = BINFO_TYPE (binfo); ! 766: ! 767: if (TYPE_USES_VIRTUAL_BASECLASSES (type)) ! 768: { ! 769: tree result = init_vbase_pointers (type, addr); ! 770: tree vbases; ! 771: ! 772: if (result) ! 773: expand_expr_stmt (build_compound_expr (result)); ! 774: ! 775: /* Mark everything as having an initializer ! 776: (either explicit or default). */ ! 777: for (vbases = CLASSTYPE_VBASECLASSES (type); ! 778: vbases; vbases = TREE_CHAIN (vbases)) ! 779: SET_BINFO_VBASE_INIT_MARKED (vbases); ! 780: ! 781: /* First, initialize baseclasses which could be baseclasses ! 782: for other virtual baseclasses. */ ! 783: for (vbases = CLASSTYPE_VBASECLASSES (type); ! 784: vbases; vbases = TREE_CHAIN (vbases)) ! 785: /* Don't initialize twice. */ ! 786: if (BINFO_VBASE_INIT_MARKED (vbases)) ! 787: { ! 788: tree tmp = result; ! 789: ! 790: while (BINFO_TYPE (vbases) != BINFO_TYPE (TREE_PURPOSE (tmp))) ! 791: tmp = TREE_CHAIN (tmp); ! 792: expand_aggr_vbase_init_1 (vbases, exp, ! 793: TREE_OPERAND (TREE_VALUE (tmp), 0), ! 794: init_list); ! 795: } ! 796: ! 797: /* Now initialize the baseclasses which don't have virtual baseclasses. */ ! 798: for (; result; result = TREE_CHAIN (result)) ! 799: /* Don't initialize twice. */ ! 800: if (BINFO_VBASE_INIT_MARKED (TREE_PURPOSE (result))) ! 801: { ! 802: my_friendly_abort (47); ! 803: expand_aggr_vbase_init_1 (TREE_PURPOSE (result), exp, ! 804: TREE_OPERAND (TREE_VALUE (result), 0), ! 805: init_list); ! 806: } ! 807: } ! 808: } ! 809: ! 810: /* Subroutine to perform parser actions for member initialization. ! 811: S_ID is the scoped identifier. ! 812: NAME is the name of the member. ! 813: INIT is the initializer, or `void_type_node' if none. */ ! 814: void ! 815: do_member_init (s_id, name, init) ! 816: tree s_id, name, init; ! 817: { ! 818: tree binfo, base; ! 819: ! 820: if (current_class_type == NULL_TREE ! 821: || ! is_aggr_typedef (s_id, 1)) ! 822: return; ! 823: binfo = get_binfo (IDENTIFIER_TYPE_VALUE (s_id), ! 824: current_class_type, 1); ! 825: if (binfo == error_mark_node) ! 826: return; ! 827: if (binfo == 0) ! 828: { ! 829: error_not_base_type (IDENTIFIER_TYPE_VALUE (s_id), current_class_type); ! 830: return; ! 831: } ! 832: ! 833: base = convert_pointer_to (binfo, current_class_decl); ! 834: expand_member_init (build_indirect_ref (base, NULL_PTR), name, init); ! 835: } ! 836: ! 837: /* Function to give error message if member initialization specification ! 838: is erroneous. FIELD is the member we decided to initialize. ! 839: TYPE is the type for which the initialization is being performed. ! 840: FIELD must be a member of TYPE, or the base type from which FIELD ! 841: comes must not need a constructor. ! 842: ! 843: MEMBER_NAME is the name of the member. */ ! 844: ! 845: static int ! 846: member_init_ok_or_else (field, type, member_name) ! 847: tree field; ! 848: tree type; ! 849: char *member_name; ! 850: { ! 851: if (field == error_mark_node) ! 852: return 0; ! 853: if (field == NULL_TREE) ! 854: { ! 855: cp_error ("class `%T' does not have any field named `%s'", type, ! 856: member_name); ! 857: return 0; ! 858: } ! 859: if (DECL_CONTEXT (field) != type ! 860: && TYPE_NEEDS_CONSTRUCTING (DECL_CONTEXT (field))) ! 861: { ! 862: cp_error ("member `%D' comes from base class needing constructor", ! 863: field); ! 864: return 0; ! 865: } ! 866: return 1; ! 867: } ! 868: ! 869: /* If NAME is a viable field name for the aggregate DECL, ! 870: and PARMS is a viable parameter list, then expand an _EXPR ! 871: which describes this initialization. ! 872: ! 873: Note that we do not need to chase through the class's base classes ! 874: to look for NAME, because if it's in that list, it will be handled ! 875: by the constructor for that base class. ! 876: ! 877: We do not yet have a fixed-point finder to instantiate types ! 878: being fed to overloaded constructors. If there is a unique ! 879: constructor, then argument types can be got from that one. ! 880: ! 881: If INIT is non-NULL, then it the initialization should ! 882: be placed in `current_base_init_list', where it will be processed ! 883: by `emit_base_init'. */ ! 884: void ! 885: expand_member_init (exp, name, init) ! 886: tree exp, name, init; ! 887: { ! 888: extern tree ptr_type_node; /* should be in tree.h */ ! 889: ! 890: tree basetype = NULL_TREE, field; ! 891: tree parm; ! 892: tree rval, type; ! 893: tree actual_name; ! 894: ! 895: if (exp == NULL_TREE) ! 896: return; /* complain about this later */ ! 897: ! 898: type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); ! 899: ! 900: if (name == NULL_TREE && IS_AGGR_TYPE (type)) ! 901: switch (CLASSTYPE_N_BASECLASSES (type)) ! 902: { ! 903: case 0: ! 904: error ("base class initializer specified, but no base class to initialize"); ! 905: return; ! 906: case 1: ! 907: basetype = TYPE_BINFO_BASETYPE (type, 0); ! 908: break; ! 909: default: ! 910: error ("initializer for unnamed base class ambiguous"); ! 911: cp_error ("(type `%T' uses multiple inheritance)", type); ! 912: return; ! 913: } ! 914: ! 915: if (init) ! 916: { ! 917: /* The grammar should not allow fields which have names ! 918: that are TYPENAMEs. Therefore, if the field has ! 919: a non-NULL TREE_TYPE, we may assume that this is an ! 920: attempt to initialize a base class member of the current ! 921: type. Otherwise, it is an attempt to initialize a ! 922: member field. */ ! 923: ! 924: if (init == void_type_node) ! 925: init = NULL_TREE; ! 926: ! 927: if (name == NULL_TREE || IDENTIFIER_HAS_TYPE_VALUE (name)) ! 928: { ! 929: tree base_init; ! 930: ! 931: if (name == NULL_TREE) ! 932: { ! 933: /* ! 934: if (basetype) ! 935: name = TYPE_IDENTIFIER (basetype); ! 936: else ! 937: { ! 938: error ("no base class to initialize"); ! 939: return; ! 940: } ! 941: */ ! 942: } ! 943: else ! 944: { ! 945: basetype = IDENTIFIER_TYPE_VALUE (name); ! 946: if (basetype != type ! 947: && ! binfo_member (basetype, TYPE_BINFO (type)) ! 948: && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type))) ! 949: { ! 950: if (IDENTIFIER_CLASS_VALUE (name)) ! 951: goto try_member; ! 952: if (TYPE_USES_VIRTUAL_BASECLASSES (type)) ! 953: error ("type `%s' is not an immediate or virtual basetype for `%s'", ! 954: IDENTIFIER_POINTER (name), ! 955: TYPE_NAME_STRING (type)); ! 956: else ! 957: error ("type `%s' is not an immediate basetype for `%s'", ! 958: IDENTIFIER_POINTER (name), ! 959: TYPE_NAME_STRING (type)); ! 960: return; ! 961: } ! 962: } ! 963: ! 964: if (purpose_member (name, current_base_init_list)) ! 965: { ! 966: error ("base class `%s' already initialized", ! 967: IDENTIFIER_POINTER (name)); ! 968: return; ! 969: } ! 970: ! 971: base_init = build_tree_list (name, init); ! 972: TREE_TYPE (base_init) = basetype; ! 973: current_base_init_list = chainon (current_base_init_list, base_init); ! 974: } ! 975: else ! 976: { ! 977: tree member_init; ! 978: ! 979: try_member: ! 980: field = lookup_field (type, name, 1, 0); ! 981: ! 982: if (! member_init_ok_or_else (field, type, IDENTIFIER_POINTER (name))) ! 983: return; ! 984: ! 985: if (purpose_member (name, current_member_init_list)) ! 986: { ! 987: error ("field `%s' already initialized", IDENTIFIER_POINTER (name)); ! 988: return; ! 989: } ! 990: ! 991: member_init = build_tree_list (name, init); ! 992: TREE_TYPE (member_init) = TREE_TYPE (field); ! 993: current_member_init_list = chainon (current_member_init_list, member_init); ! 994: } ! 995: return; ! 996: } ! 997: else if (name == NULL_TREE) ! 998: { ! 999: compiler_error ("expand_member_init: name == NULL_TREE"); ! 1000: return; ! 1001: } ! 1002: ! 1003: basetype = type; ! 1004: field = lookup_field (basetype, name, 0, 0); ! 1005: ! 1006: if (! member_init_ok_or_else (field, basetype, IDENTIFIER_POINTER (name))) ! 1007: return; ! 1008: ! 1009: /* now see if there is a constructor for this type ! 1010: which will take these args. */ ! 1011: ! 1012: if (TYPE_HAS_CONSTRUCTOR (TREE_TYPE (field))) ! 1013: { ! 1014: tree parmtypes, fndecl; ! 1015: ! 1016: if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL) ! 1017: { ! 1018: /* just know that we've seen something for this node */ ! 1019: DECL_INITIAL (exp) = error_mark_node; ! 1020: TREE_USED (exp) = 1; ! 1021: } ! 1022: type = TYPE_MAIN_VARIANT (TREE_TYPE (field)); ! 1023: actual_name = TYPE_IDENTIFIER (type); ! 1024: parm = build_component_ref (exp, name, 0, 0); ! 1025: ! 1026: /* Now get to the constructor. */ ! 1027: fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0); ! 1028: /* Get past destructor, if any. */ ! 1029: if (TYPE_HAS_DESTRUCTOR (type)) ! 1030: fndecl = DECL_CHAIN (fndecl); ! 1031: ! 1032: if (fndecl) ! 1033: my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 209); ! 1034: ! 1035: /* If the field is unique, we can use the parameter ! 1036: types to guide possible type instantiation. */ ! 1037: if (DECL_CHAIN (fndecl) == NULL_TREE) ! 1038: { ! 1039: /* There was a confusion here between ! 1040: FIELD and FNDECL. The following code ! 1041: should be correct, but abort is here ! 1042: to make sure. */ ! 1043: my_friendly_abort (48); ! 1044: parmtypes = FUNCTION_ARG_CHAIN (fndecl); ! 1045: } ! 1046: else ! 1047: { ! 1048: parmtypes = NULL_TREE; ! 1049: fndecl = NULL_TREE; ! 1050: } ! 1051: ! 1052: init = convert_arguments (parm, parmtypes, NULL_TREE, fndecl, LOOKUP_NORMAL); ! 1053: if (init == NULL_TREE || TREE_TYPE (init) != error_mark_node) ! 1054: rval = build_method_call (NULL_TREE, actual_name, init, NULL_TREE, LOOKUP_NORMAL); ! 1055: else ! 1056: return; ! 1057: ! 1058: if (rval != error_mark_node) ! 1059: { ! 1060: /* Now, fill in the first parm with our guy */ ! 1061: TREE_VALUE (TREE_OPERAND (rval, 1)) ! 1062: = build_unary_op (ADDR_EXPR, parm, 0); ! 1063: TREE_TYPE (rval) = ptr_type_node; ! 1064: TREE_SIDE_EFFECTS (rval) = 1; ! 1065: } ! 1066: } ! 1067: else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field))) ! 1068: { ! 1069: parm = build_component_ref (exp, name, 0, 0); ! 1070: expand_aggr_init (parm, NULL_TREE, 0); ! 1071: rval = error_mark_node; ! 1072: } ! 1073: ! 1074: /* Now initialize the member. It does not have to ! 1075: be of aggregate type to receive initialization. */ ! 1076: if (rval != error_mark_node) ! 1077: expand_expr_stmt (rval); ! 1078: } ! 1079: ! 1080: /* This is like `expand_member_init', only it stores one aggregate ! 1081: value into another. ! 1082: ! 1083: INIT comes in two flavors: it is either a value which ! 1084: is to be stored in EXP, or it is a parameter list ! 1085: to go to a constructor, which will operate on EXP. ! 1086: If `init' is a CONSTRUCTOR, then we emit a warning message, ! 1087: explaining that such initializations are illegal. ! 1088: ! 1089: ALIAS_THIS is nonzero iff we are initializing something which is ! 1090: essentially an alias for C_C_D. In this case, the base constructor ! 1091: may move it on us, and we must keep track of such deviations. ! 1092: ! 1093: If INIT resolves to a CALL_EXPR which happens to return ! 1094: something of the type we are looking for, then we know ! 1095: that we can safely use that call to perform the ! 1096: initialization. ! 1097: ! 1098: The virtual function table pointer cannot be set up here, because ! 1099: we do not really know its type. ! 1100: ! 1101: Virtual baseclass pointers are also set up here. ! 1102: ! 1103: This never calls operator=(). ! 1104: ! 1105: When initializing, nothing is CONST. ! 1106: ! 1107: A default copy constructor may have to be used to perform the ! 1108: initialization. ! 1109: ! 1110: A constructor or a conversion operator may have to be used to ! 1111: perform the initialization, but not both, as it would be ambiguous. ! 1112: */ ! 1113: ! 1114: void ! 1115: expand_aggr_init (exp, init, alias_this) ! 1116: tree exp, init; ! 1117: int alias_this; ! 1118: { ! 1119: tree type = TREE_TYPE (exp); ! 1120: int was_const = TREE_READONLY (exp); ! 1121: ! 1122: if (init == error_mark_node) ! 1123: return; ! 1124: ! 1125: TREE_READONLY (exp) = 0; ! 1126: ! 1127: if (TREE_CODE (type) == ARRAY_TYPE) ! 1128: { ! 1129: /* Must arrange to initialize each element of EXP ! 1130: from elements of INIT. */ ! 1131: int was_const_elts = TYPE_READONLY (TREE_TYPE (type)); ! 1132: tree itype = init ? TREE_TYPE (init) : NULL_TREE; ! 1133: if (was_const_elts) ! 1134: { ! 1135: TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); ! 1136: if (init) ! 1137: TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); ! 1138: } ! 1139: if (init && TREE_TYPE (init) == NULL_TREE) ! 1140: { ! 1141: /* Handle bad initializers like: ! 1142: class COMPLEX { ! 1143: public: ! 1144: double re, im; ! 1145: COMPLEX(double r = 0.0, double i = 0.0) {re = r; im = i;}; ! 1146: ~COMPLEX() {}; ! 1147: }; ! 1148: ! 1149: int main(int argc, char **argv) { ! 1150: COMPLEX zees(1.0, 0.0)[10]; ! 1151: } ! 1152: */ ! 1153: error ("bad array initializer"); ! 1154: return; ! 1155: } ! 1156: expand_vec_init (exp, exp, array_type_nelts (type), init, ! 1157: init && comptypes (TREE_TYPE (init), TREE_TYPE (exp), 1)); ! 1158: TREE_READONLY (exp) = was_const; ! 1159: TREE_TYPE (exp) = type; ! 1160: if (init) ! 1161: TREE_TYPE (init) = itype; ! 1162: return; ! 1163: } ! 1164: ! 1165: if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL) ! 1166: /* just know that we've seen something for this node */ ! 1167: TREE_USED (exp) = 1; ! 1168: ! 1169: #if 0 ! 1170: /* If initializing from a GNU C CONSTRUCTOR, consider the elts in the ! 1171: constructor as parameters to an implicit GNU C++ constructor. */ ! 1172: if (init && TREE_CODE (init) == CONSTRUCTOR ! 1173: && TYPE_HAS_CONSTRUCTOR (type) ! 1174: && TREE_TYPE (init) == type) ! 1175: init = CONSTRUCTOR_ELTS (init); ! 1176: #endif ! 1177: expand_aggr_init_1 (TYPE_BINFO (type), exp, exp, ! 1178: init, alias_this, LOOKUP_NORMAL); ! 1179: TREE_READONLY (exp) = was_const; ! 1180: } ! 1181: ! 1182: static void ! 1183: expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags) ! 1184: tree binfo; ! 1185: tree true_exp, exp; ! 1186: tree type; ! 1187: tree init; ! 1188: int alias_this; ! 1189: int flags; ! 1190: { ! 1191: /* It fails because there may not be a constructor which takes ! 1192: its own type as the first (or only parameter), but which does ! 1193: take other types via a conversion. So, if the thing initializing ! 1194: the expression is a unit element of type X, first try X(X&), ! 1195: followed by initialization by X. If neither of these work ! 1196: out, then look hard. */ ! 1197: tree rval; ! 1198: tree parms; ! 1199: int xxref_init_possible; ! 1200: ! 1201: if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST) ! 1202: { ! 1203: parms = init; ! 1204: if (parms) init = TREE_VALUE (parms); ! 1205: } ! 1206: else if (TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init)) ! 1207: { ! 1208: rval = convert_for_initialization (exp, type, init, 0, 0, 0, 0); ! 1209: TREE_USED (rval) = 1; ! 1210: expand_expr_stmt (rval); ! 1211: return; ! 1212: } ! 1213: else ! 1214: parms = build_tree_list (NULL_TREE, init); ! 1215: ! 1216: if (TYPE_HAS_INIT_REF (type) ! 1217: || init == NULL_TREE ! 1218: || TREE_CHAIN (parms) != NULL_TREE) ! 1219: xxref_init_possible = 0; ! 1220: else ! 1221: { ! 1222: xxref_init_possible = LOOKUP_SPECULATIVELY; ! 1223: flags &= ~LOOKUP_COMPLAIN; ! 1224: } ! 1225: ! 1226: if (TYPE_USES_VIRTUAL_BASECLASSES (type)) ! 1227: { ! 1228: if (true_exp == exp) ! 1229: parms = tree_cons (NULL_TREE, integer_one_node, parms); ! 1230: else ! 1231: parms = tree_cons (NULL_TREE, integer_zero_node, parms); ! 1232: flags |= LOOKUP_HAS_IN_CHARGE; ! 1233: } ! 1234: ! 1235: rval = build_method_call (exp, constructor_name_full (type), ! 1236: parms, binfo, flags|xxref_init_possible); ! 1237: if (rval == NULL_TREE && xxref_init_possible) ! 1238: { ! 1239: /* It is an error to implement a default copy constructor if ! 1240: (see ARM 12.8 for details) ... one case being if another ! 1241: copy constructor already exists. */ ! 1242: tree init_type = TREE_TYPE (init); ! 1243: if (TREE_CODE (init_type) == REFERENCE_TYPE) ! 1244: init_type = TREE_TYPE (init_type); ! 1245: if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type) ! 1246: || (IS_AGGR_TYPE (init_type) ! 1247: && UNIQUELY_DERIVED_FROM_P (type, init_type))) ! 1248: { ! 1249: if (type == BINFO_TYPE (binfo) ! 1250: && TYPE_USES_VIRTUAL_BASECLASSES (type)) ! 1251: { ! 1252: tree addr = build_unary_op (ADDR_EXPR, exp, 0); ! 1253: expand_aggr_vbase_init (binfo, exp, addr, NULL_TREE); ! 1254: ! 1255: expand_indirect_vtbls_init (binfo, exp, addr, 1); ! 1256: } ! 1257: expand_expr_stmt (build_modify_expr (exp, INIT_EXPR, init)); ! 1258: return; ! 1259: } ! 1260: else ! 1261: rval = build_method_call (exp, constructor_name_full (type), parms, ! 1262: binfo, flags); ! 1263: } ! 1264: ! 1265: /* Private, protected, or otherwise unavailable. */ ! 1266: if (rval == error_mark_node && (flags&LOOKUP_COMPLAIN)) ! 1267: cp_error ("in base initialization for class `%T'", binfo); ! 1268: /* A valid initialization using constructor. */ ! 1269: else if (rval != error_mark_node && rval != NULL_TREE) ! 1270: { ! 1271: /* p. 222: if the base class assigns to `this', then that ! 1272: value is used in the derived class. */ ! 1273: if ((flag_this_is_variable & 1) && alias_this) ! 1274: { ! 1275: TREE_TYPE (rval) = TREE_TYPE (current_class_decl); ! 1276: expand_assignment (current_class_decl, rval, 0, 0); ! 1277: } ! 1278: else ! 1279: expand_expr_stmt (rval); ! 1280: } ! 1281: else if (parms && TREE_CHAIN (parms) == NULL_TREE) ! 1282: { ! 1283: /* If we are initializing one aggregate value ! 1284: from another, and though there are constructors, ! 1285: and none accept the initializer, just do a bitwise ! 1286: copy. ! 1287: ! 1288: The above sounds wrong, ``If a class has any copy ! 1289: constructor defined, the default copy constructor will ! 1290: not be generated.'' 12.8 Copying Class Objects (mrs) ! 1291: ! 1292: @@ This should reject initializer which a constructor ! 1293: @@ rejected on access gounds, but there is ! 1294: @@ no way right now to recognize that case with ! 1295: @@ just `error_mark_node'. */ ! 1296: tree itype; ! 1297: init = TREE_VALUE (parms); ! 1298: itype = TREE_TYPE (init); ! 1299: if (TREE_CODE (itype) == REFERENCE_TYPE) ! 1300: { ! 1301: init = convert_from_reference (init); ! 1302: itype = TREE_TYPE (init); ! 1303: } ! 1304: itype = TYPE_MAIN_VARIANT (itype); ! 1305: ! 1306: /* This is currently how the default X(X&) constructor ! 1307: is implemented. */ ! 1308: if (comptypes (TYPE_MAIN_VARIANT (type), itype, 0)) ! 1309: { ! 1310: #if 0 ! 1311: warning ("bitwise copy in initialization of type `%s'", ! 1312: TYPE_NAME_STRING (type)); ! 1313: #endif ! 1314: rval = build (INIT_EXPR, type, exp, init); ! 1315: expand_expr_stmt (rval); ! 1316: } ! 1317: else ! 1318: { ! 1319: cp_error ("in base initialization for class `%T',", binfo); ! 1320: cp_error ("invalid initializer to constructor for type `%T'", type); ! 1321: return; ! 1322: } ! 1323: } ! 1324: else ! 1325: { ! 1326: if (init == NULL_TREE) ! 1327: my_friendly_assert (parms == NULL_TREE, 210); ! 1328: if (parms == NULL_TREE && TREE_VIA_VIRTUAL (binfo)) ! 1329: cp_error ("virtual baseclass `%T' does not have default initializer", binfo); ! 1330: else ! 1331: { ! 1332: cp_error ("in base initialization for class `%T',", binfo); ! 1333: /* This will make an error message for us. */ ! 1334: build_method_call (exp, constructor_name_full (type), parms, binfo, ! 1335: (TYPE_USES_VIRTUAL_BASECLASSES (type) ! 1336: ? LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE ! 1337: : LOOKUP_NORMAL)); ! 1338: } ! 1339: return; ! 1340: } ! 1341: /* Constructor has been called, but vtables may be for TYPE ! 1342: rather than for FOR_TYPE. */ ! 1343: } ! 1344: ! 1345: /* This function is responsible for initializing EXP with INIT ! 1346: (if any). ! 1347: ! 1348: BINFO is the binfo of the type for who we are performing the ! 1349: initialization. For example, if W is a virtual base class of A and B, ! 1350: and C : A, B. ! 1351: If we are initializing B, then W must contain B's W vtable, whereas ! 1352: were we initializing C, W must contain C's W vtable. ! 1353: ! 1354: TRUE_EXP is nonzero if it is the true expression being initialized. ! 1355: In this case, it may be EXP, or may just contain EXP. The reason we ! 1356: need this is because if EXP is a base element of TRUE_EXP, we ! 1357: don't necessarily know by looking at EXP where its virtual ! 1358: baseclass fields should really be pointing. But we do know ! 1359: from TRUE_EXP. In constructors, we don't know anything about ! 1360: the value being initialized. ! 1361: ! 1362: ALIAS_THIS serves the same purpose it serves for expand_aggr_init. ! 1363: ! 1364: FLAGS is just passes to `build_method_call'. See that function for ! 1365: its description. */ ! 1366: ! 1367: static void ! 1368: expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) ! 1369: tree binfo; ! 1370: tree true_exp, exp; ! 1371: tree init; ! 1372: int alias_this; ! 1373: int flags; ! 1374: { ! 1375: tree type = TREE_TYPE (exp); ! 1376: tree init_type = NULL_TREE; ! 1377: ! 1378: my_friendly_assert (init != error_mark_node && type != error_mark_node, 211); ! 1379: ! 1380: /* Use a function returning the desired type to initialize EXP for us. ! 1381: If the function is a constructor, and its first argument is ! 1382: NULL_TREE, know that it was meant for us--just slide exp on ! 1383: in and expand the constructor. Constructors now come ! 1384: as TARGET_EXPRs. */ ! 1385: if (init) ! 1386: { ! 1387: tree init_list = NULL_TREE; ! 1388: ! 1389: if (TREE_CODE (init) == TREE_LIST) ! 1390: { ! 1391: init_list = init; ! 1392: if (TREE_CHAIN (init) == NULL_TREE) ! 1393: init = TREE_VALUE (init); ! 1394: } ! 1395: ! 1396: init_type = TREE_TYPE (init); ! 1397: ! 1398: if (TREE_CODE (init) != TREE_LIST) ! 1399: { ! 1400: if (TREE_CODE (init_type) == ERROR_MARK) ! 1401: return; ! 1402: ! 1403: #if 0 ! 1404: /* These lines are found troublesome 5/11/89. */ ! 1405: if (TREE_CODE (init_type) == REFERENCE_TYPE) ! 1406: init_type = TREE_TYPE (init_type); ! 1407: #endif ! 1408: ! 1409: /* This happens when we use C++'s functional cast notation. ! 1410: If the types match, then just use the TARGET_EXPR ! 1411: directly. Otherwise, we need to create the initializer ! 1412: separately from the object being initialized. */ ! 1413: if (TREE_CODE (init) == TARGET_EXPR) ! 1414: { ! 1415: if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type)) ! 1416: { ! 1417: if (TREE_CODE (exp) == VAR_DECL ! 1418: || TREE_CODE (exp) == RESULT_DECL) ! 1419: /* Unify the initialization targets. */ ! 1420: DECL_RTL (TREE_OPERAND (init, 0)) = DECL_RTL (exp); ! 1421: else ! 1422: DECL_RTL (TREE_OPERAND (init, 0)) = expand_expr (exp, NULL_RTX, 0, 0); ! 1423: ! 1424: expand_expr_stmt (init); ! 1425: return; ! 1426: } ! 1427: else ! 1428: { ! 1429: init = TREE_OPERAND (init, 1); ! 1430: init = build (CALL_EXPR, init_type, ! 1431: TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), 0); ! 1432: TREE_SIDE_EFFECTS (init) = 1; ! 1433: #if 0 ! 1434: TREE_RAISES (init) = ?? ! 1435: #endif ! 1436: if (init_list) ! 1437: TREE_VALUE (init_list) = init; ! 1438: } ! 1439: } ! 1440: ! 1441: if (init_type == type && TREE_CODE (init) == CALL_EXPR ! 1442: #if 0 ! 1443: /* It is legal to directly initialize from a CALL_EXPR ! 1444: without going through X(X&), apparently. */ ! 1445: && ! TYPE_GETS_INIT_REF (type) ! 1446: #endif ! 1447: ) ! 1448: { ! 1449: /* A CALL_EXPR is a legitimate form of initialization, so ! 1450: we should not print this warning message. */ ! 1451: #if 0 ! 1452: /* Should have gone away due to 5/11/89 change. */ ! 1453: if (TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE) ! 1454: init = convert_from_reference (init); ! 1455: #endif ! 1456: expand_assignment (exp, init, 0, 0); ! 1457: if (exp == DECL_RESULT (current_function_decl)) ! 1458: { ! 1459: /* Failing this assertion means that the return value ! 1460: from receives multiple initializations. */ ! 1461: my_friendly_assert (DECL_INITIAL (exp) == NULL_TREE ! 1462: || DECL_INITIAL (exp) == error_mark_node, ! 1463: 212); ! 1464: DECL_INITIAL (exp) = init; ! 1465: } ! 1466: return; ! 1467: } ! 1468: else if (init_type == type ! 1469: && TREE_CODE (init) == COND_EXPR) ! 1470: { ! 1471: /* Push value to be initialized into the cond, where possible. ! 1472: Avoid spurious warning messages when initializing the ! 1473: result of this function. */ ! 1474: TREE_OPERAND (init, 1) ! 1475: = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 1)); ! 1476: if (exp == DECL_RESULT (current_function_decl)) ! 1477: DECL_INITIAL (exp) = NULL_TREE; ! 1478: TREE_OPERAND (init, 2) ! 1479: = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 2)); ! 1480: if (exp == DECL_RESULT (current_function_decl)) ! 1481: DECL_INITIAL (exp) = init; ! 1482: TREE_SIDE_EFFECTS (init) = 1; ! 1483: expand_expr (init, const0_rtx, VOIDmode, 0); ! 1484: free_temp_slots (); ! 1485: return; ! 1486: } ! 1487: } ! 1488: ! 1489: /* We did not know what we were initializing before. Now we do. */ ! 1490: if (TREE_CODE (init) == TARGET_EXPR) ! 1491: { ! 1492: tree tmp = TREE_OPERAND (TREE_OPERAND (init, 1), 1); ! 1493: ! 1494: if (TREE_CODE (TREE_VALUE (tmp)) == NOP_EXPR ! 1495: && TREE_OPERAND (TREE_VALUE (tmp), 0) == integer_zero_node) ! 1496: { ! 1497: /* In order for this to work for RESULT_DECLs, if their ! 1498: type has a constructor, then they must be BLKmode ! 1499: so that they will be meaningfully addressable. */ ! 1500: tree arg = build_unary_op (ADDR_EXPR, exp, 0); ! 1501: init = TREE_OPERAND (init, 1); ! 1502: init = build (CALL_EXPR, build_pointer_type (TREE_TYPE (init)), ! 1503: TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), 0); ! 1504: TREE_SIDE_EFFECTS (init) = 1; ! 1505: #if 0 ! 1506: TREE_RAISES (init) = ?? ! 1507: #endif ! 1508: TREE_VALUE (TREE_OPERAND (init, 1)) ! 1509: = convert_pointer_to (TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))), arg); ! 1510: ! 1511: if (alias_this) ! 1512: { ! 1513: expand_assignment (current_function_decl, init, 0, 0); ! 1514: return; ! 1515: } ! 1516: if (exp == DECL_RESULT (current_function_decl)) ! 1517: { ! 1518: if (DECL_INITIAL (DECL_RESULT (current_function_decl))) ! 1519: fatal ("return value from function receives multiple initializations"); ! 1520: DECL_INITIAL (exp) = init; ! 1521: } ! 1522: expand_expr_stmt (init); ! 1523: return; ! 1524: } ! 1525: } ! 1526: ! 1527: if (TREE_CODE (exp) == VAR_DECL ! 1528: && TREE_CODE (init) == CONSTRUCTOR ! 1529: && TREE_HAS_CONSTRUCTOR (init)) ! 1530: { ! 1531: tree t = store_init_value (exp, init); ! 1532: if (!t) ! 1533: { ! 1534: expand_decl_init (exp); ! 1535: return; ! 1536: } ! 1537: t = build (INIT_EXPR, type, exp, init); ! 1538: TREE_SIDE_EFFECTS (t) = 1; ! 1539: expand_expr_stmt (t); ! 1540: return; ! 1541: } ! 1542: ! 1543: /* Handle this case: when calling a constructor: xyzzy foo(bar); ! 1544: which really means: xyzzy foo = bar; Ugh! ! 1545: ! 1546: More useful for this case: xyzzy *foo = new xyzzy (bar); */ ! 1547: ! 1548: if (! TYPE_NEEDS_CONSTRUCTING (type) && ! IS_AGGR_TYPE (type)) ! 1549: { ! 1550: if (init_list && TREE_CHAIN (init_list)) ! 1551: { ! 1552: warning ("initializer list being treated as compound expression"); ! 1553: init = convert (type, build_compound_expr (init_list)); ! 1554: if (init == error_mark_node) ! 1555: return; ! 1556: } ! 1557: ! 1558: expand_assignment (exp, init, 0, 0); ! 1559: ! 1560: return; ! 1561: } ! 1562: /* See whether we can go through a type conversion operator. ! 1563: This wins over going through a non-existent constructor. If ! 1564: there is a constructor, it is ambiguous. */ ! 1565: if (TREE_CODE (init) != TREE_LIST) ! 1566: { ! 1567: tree ttype = TREE_CODE (init_type) == REFERENCE_TYPE ! 1568: ? TREE_TYPE (init_type) : init_type; ! 1569: ! 1570: if (ttype != type && IS_AGGR_TYPE (ttype)) ! 1571: { ! 1572: tree rval = build_type_conversion (CONVERT_EXPR, type, init, 0); ! 1573: ! 1574: if (rval) ! 1575: { ! 1576: /* See if there is a constructor for``type'' that takes a ! 1577: ``ttype''-typed object. */ ! 1578: tree parms = build_tree_list (NULL_TREE, init); ! 1579: tree as_cons = NULL_TREE; ! 1580: if (TYPE_HAS_CONSTRUCTOR (type)) ! 1581: as_cons = build_method_call (exp, constructor_name_full (type), ! 1582: parms, binfo, ! 1583: LOOKUP_SPECULATIVELY|LOOKUP_NO_CONVERSION); ! 1584: if (as_cons != NULL_TREE && as_cons != error_mark_node) ! 1585: /* ANSI C++ June 5 1992 WP 12.3.2.6.1 */ ! 1586: cp_error ("ambiguity between conversion to `%T' and constructor", ! 1587: type); ! 1588: else ! 1589: expand_assignment (exp, rval, 0, 0); ! 1590: return; ! 1591: } ! 1592: } ! 1593: } ! 1594: } ! 1595: ! 1596: /* Handle default copy constructors here, does not matter if there is ! 1597: a constructor or not. */ ! 1598: if (type == init_type && IS_AGGR_TYPE (type) ! 1599: && init && TREE_CODE (init) != TREE_LIST) ! 1600: expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags); ! 1601: /* Not sure why this is here... */ ! 1602: else if (TYPE_HAS_CONSTRUCTOR (type)) ! 1603: expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags); ! 1604: else if (TREE_CODE (type) == ARRAY_TYPE) ! 1605: { ! 1606: if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))) ! 1607: expand_vec_init (exp, exp, array_type_nelts (type), init, 0); ! 1608: else if (TYPE_VIRTUAL_P (TREE_TYPE (type))) ! 1609: sorry ("arrays of objects with virtual functions but no constructors"); ! 1610: } ! 1611: else ! 1612: expand_recursive_init (binfo, true_exp, exp, init, ! 1613: CLASSTYPE_BASE_INIT_LIST (type), alias_this); ! 1614: } ! 1615: ! 1616: /* A pointer which holds the initializer. First call to ! 1617: expand_aggr_init gets this value pointed to, and sets it to init_null. */ ! 1618: static tree *init_ptr, init_null; ! 1619: ! 1620: /* Subroutine of expand_recursive_init: ! 1621: ! 1622: ADDR is the address of the expression being initialized. ! 1623: INIT_LIST is the cons-list of initializations to be performed. ! 1624: ALIAS_THIS is its same, lovable self. */ ! 1625: static void ! 1626: expand_recursive_init_1 (binfo, true_exp, addr, init_list, alias_this) ! 1627: tree binfo, true_exp, addr; ! 1628: tree init_list; ! 1629: int alias_this; ! 1630: { ! 1631: while (init_list) ! 1632: { ! 1633: if (TREE_PURPOSE (init_list)) ! 1634: { ! 1635: if (TREE_CODE (TREE_PURPOSE (init_list)) == FIELD_DECL) ! 1636: { ! 1637: tree member = TREE_PURPOSE (init_list); ! 1638: tree subexp = build_indirect_ref (convert_pointer_to (TREE_VALUE (init_list), addr), NULL_PTR); ! 1639: tree member_base = build (COMPONENT_REF, TREE_TYPE (member), subexp, member); ! 1640: if (IS_AGGR_TYPE (TREE_TYPE (member))) ! 1641: expand_aggr_init (member_base, DECL_INITIAL (member), 0); ! 1642: else if (TREE_CODE (TREE_TYPE (member)) == ARRAY_TYPE ! 1643: && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (member))) ! 1644: { ! 1645: member_base = save_expr (default_conversion (member_base)); ! 1646: expand_vec_init (member, member_base, ! 1647: array_type_nelts (TREE_TYPE (member)), ! 1648: DECL_INITIAL (member), 0); ! 1649: } ! 1650: else ! 1651: expand_expr_stmt (build_modify_expr (member_base, INIT_EXPR, DECL_INITIAL (member))); ! 1652: } ! 1653: else if (TREE_CODE (TREE_PURPOSE (init_list)) == TREE_LIST) ! 1654: { ! 1655: expand_recursive_init_1 (binfo, true_exp, addr, TREE_PURPOSE (init_list), alias_this); ! 1656: expand_recursive_init_1 (binfo, true_exp, addr, TREE_VALUE (init_list), alias_this); ! 1657: } ! 1658: else if (TREE_CODE (TREE_PURPOSE (init_list)) == ERROR_MARK) ! 1659: { ! 1660: /* Only initialize the virtual function tables if we ! 1661: are initializing the ultimate users of those vtables. */ ! 1662: if (TREE_VALUE (init_list)) ! 1663: { ! 1664: /* We have to ensure that the first argment to ! 1665: expand_virtual_init is in binfo's hierarchy. */ ! 1666: /* Is it the case that this is exactly the right binfo? */ ! 1667: /* If it is ok, then fixup expand_virtual_init, to make ! 1668: it much simpler. */ ! 1669: expand_virtual_init (get_binfo (TREE_VALUE (init_list), binfo, 0), ! 1670: addr); ! 1671: if (TREE_VALUE (init_list) == binfo ! 1672: && TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))) ! 1673: expand_indirect_vtbls_init (binfo, true_exp, addr, 1); ! 1674: } ! 1675: } ! 1676: else ! 1677: my_friendly_abort (49); ! 1678: } ! 1679: else if (TREE_VALUE (init_list) ! 1680: && TREE_CODE (TREE_VALUE (init_list)) == TREE_VEC) ! 1681: { ! 1682: tree subexp = build_indirect_ref (convert_pointer_to (TREE_VALUE (init_list), addr), NULL_PTR); ! 1683: expand_aggr_init_1 (binfo, true_exp, subexp, *init_ptr, ! 1684: alias_this && BINFO_OFFSET_ZEROP (TREE_VALUE (init_list)), ! 1685: LOOKUP_COMPLAIN); ! 1686: ! 1687: /* INIT_PTR is used up. */ ! 1688: init_ptr = &init_null; ! 1689: } ! 1690: else ! 1691: my_friendly_abort (50); ! 1692: init_list = TREE_CHAIN (init_list); ! 1693: } ! 1694: } ! 1695: ! 1696: /* Initialize EXP with INIT. Type EXP does not have a constructor, ! 1697: but it has a baseclass with a constructor or a virtual function ! 1698: table which needs initializing. ! 1699: ! 1700: INIT_LIST is a cons-list describing what parts of EXP actually ! 1701: need to be initialized. INIT is given to the *unique*, first ! 1702: constructor within INIT_LIST. If there are multiple first ! 1703: constructors, such as with multiple inheritance, INIT must ! 1704: be zero or an ambiguity error is reported. ! 1705: ! 1706: ALIAS_THIS is passed from `expand_aggr_init'. See comments ! 1707: there. */ ! 1708: ! 1709: static void ! 1710: expand_recursive_init (binfo, true_exp, exp, init, init_list, alias_this) ! 1711: tree binfo, true_exp, exp, init; ! 1712: tree init_list; ! 1713: int alias_this; ! 1714: { ! 1715: tree *old_init_ptr = init_ptr; ! 1716: tree addr = build_unary_op (ADDR_EXPR, exp, 0); ! 1717: init_ptr = &init; ! 1718: ! 1719: if (true_exp == exp && TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))) ! 1720: { ! 1721: expand_aggr_vbase_init (binfo, exp, addr, init_list); ! 1722: expand_indirect_vtbls_init (binfo, true_exp, addr, 1); ! 1723: } ! 1724: expand_recursive_init_1 (binfo, true_exp, addr, init_list, alias_this); ! 1725: ! 1726: if (*init_ptr) ! 1727: { ! 1728: tree type = TREE_TYPE (exp); ! 1729: ! 1730: if (TREE_CODE (type) == REFERENCE_TYPE) ! 1731: type = TREE_TYPE (type); ! 1732: if (IS_AGGR_TYPE (type)) ! 1733: cp_error ("unexpected argument to constructor `%T'", type); ! 1734: else ! 1735: error ("unexpected argument to constructor"); ! 1736: } ! 1737: init_ptr = old_init_ptr; ! 1738: } ! 1739: ! 1740: /* Report an error if NAME is not the name of a user-defined, ! 1741: aggregate type. If OR_ELSE is nonzero, give an error message. */ ! 1742: int ! 1743: is_aggr_typedef (name, or_else) ! 1744: tree name; ! 1745: int or_else; ! 1746: { ! 1747: tree type; ! 1748: ! 1749: if (name == error_mark_node) ! 1750: return 0; ! 1751: ! 1752: if (IDENTIFIER_HAS_TYPE_VALUE (name)) ! 1753: type = IDENTIFIER_TYPE_VALUE (name); ! 1754: else ! 1755: { ! 1756: if (or_else) ! 1757: cp_error ("`%T' is not an aggregate typedef", name); ! 1758: return 0; ! 1759: } ! 1760: ! 1761: if (! IS_AGGR_TYPE (type) ! 1762: && TREE_CODE (type) != TEMPLATE_TYPE_PARM) ! 1763: { ! 1764: if (or_else) ! 1765: cp_error ("`%T' is not an aggregate type", type); ! 1766: return 0; ! 1767: } ! 1768: return 1; ! 1769: } ! 1770: ! 1771: /* Like is_aggr_typedef, but returns typedef if successful. */ ! 1772: tree ! 1773: get_aggr_from_typedef (name, or_else) ! 1774: tree name; ! 1775: int or_else; ! 1776: { ! 1777: tree type; ! 1778: ! 1779: if (name == error_mark_node) ! 1780: return NULL_TREE; ! 1781: ! 1782: if (IDENTIFIER_HAS_TYPE_VALUE (name)) ! 1783: type = IDENTIFIER_TYPE_VALUE (name); ! 1784: else ! 1785: { ! 1786: if (or_else) ! 1787: cp_error ("`%T' fails to be an aggregate typedef", name); ! 1788: return NULL_TREE; ! 1789: } ! 1790: ! 1791: if (! IS_AGGR_TYPE (type) ! 1792: && TREE_CODE (type) != TEMPLATE_TYPE_PARM) ! 1793: { ! 1794: if (or_else) ! 1795: cp_error ("type `%T' is of non-aggregate type", type); ! 1796: return NULL_TREE; ! 1797: } ! 1798: return type; ! 1799: } ! 1800: ! 1801: tree ! 1802: get_type_value (name) ! 1803: tree name; ! 1804: { ! 1805: if (name == error_mark_node) ! 1806: return NULL_TREE; ! 1807: ! 1808: if (IDENTIFIER_HAS_TYPE_VALUE (name)) ! 1809: return IDENTIFIER_TYPE_VALUE (name); ! 1810: else ! 1811: return NULL_TREE; ! 1812: } ! 1813: ! 1814: ! 1815: /* This code could just as well go in `class.c', but is placed here for ! 1816: modularity. */ ! 1817: ! 1818: /* For an expression of the form CNAME :: NAME (PARMLIST), build ! 1819: the appropriate function call. */ ! 1820: tree ! 1821: build_member_call (cname, name, parmlist) ! 1822: tree cname, name, parmlist; ! 1823: { ! 1824: tree type, t; ! 1825: tree method_name = name; ! 1826: int dtor = 0; ! 1827: int dont_use_this = 0; ! 1828: tree basetype_path, decl; ! 1829: ! 1830: if (TREE_CODE (method_name) == BIT_NOT_EXPR) ! 1831: { ! 1832: method_name = TREE_OPERAND (method_name, 0); ! 1833: dtor = 1; ! 1834: } ! 1835: ! 1836: if (TREE_CODE (cname) == SCOPE_REF) ! 1837: cname = resolve_scope_to_name (NULL_TREE, cname); ! 1838: ! 1839: if (cname == NULL_TREE || ! (type = get_aggr_from_typedef (cname, 1))) ! 1840: return error_mark_node; ! 1841: ! 1842: /* An operator we did not like. */ ! 1843: if (name == NULL_TREE) ! 1844: return error_mark_node; ! 1845: ! 1846: if (dtor) ! 1847: { ! 1848: #if 0 ! 1849: /* Everything can explicitly call a destructor; see 12.4 */ ! 1850: if (! TYPE_HAS_DESTRUCTOR (type)) ! 1851: cp_error ("type `%#T' does not have a destructor", type); ! 1852: else ! 1853: #endif ! 1854: cp_error ("cannot call destructor `%T::~%T' without object", type, ! 1855: method_name); ! 1856: return error_mark_node; ! 1857: } ! 1858: ! 1859: /* No object? Then just fake one up, and let build_method_call ! 1860: figure out what to do. */ ! 1861: if (current_class_type == 0 ! 1862: || get_base_distance (type, current_class_type, 0, &basetype_path) == -1) ! 1863: dont_use_this = 1; ! 1864: ! 1865: if (dont_use_this) ! 1866: { ! 1867: basetype_path = TYPE_BINFO (type); ! 1868: decl = build1 (NOP_EXPR, TYPE_POINTER_TO (type), error_mark_node); ! 1869: } ! 1870: else if (current_class_decl == 0) ! 1871: { ! 1872: dont_use_this = 1; ! 1873: decl = build1 (NOP_EXPR, TYPE_POINTER_TO (type), error_mark_node); ! 1874: } ! 1875: else ! 1876: { ! 1877: tree olddecl = current_class_decl; ! 1878: tree oldtype = TREE_TYPE (TREE_TYPE (olddecl)); ! 1879: if (oldtype != type) ! 1880: { ! 1881: tree newtype = build_type_variant (type, TYPE_READONLY (oldtype), ! 1882: TYPE_VOLATILE (oldtype)); ! 1883: decl = convert_force (build_pointer_type (newtype), olddecl); ! 1884: } ! 1885: else ! 1886: decl = olddecl; ! 1887: } ! 1888: ! 1889: decl = build_indirect_ref (decl, NULL_PTR); ! 1890: ! 1891: if (t = lookup_fnfields (basetype_path, method_name, 0)) ! 1892: return build_method_call (decl, method_name, parmlist, basetype_path, ! 1893: LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); ! 1894: if (TREE_CODE (name) == IDENTIFIER_NODE ! 1895: && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0)))) ! 1896: { ! 1897: if (t == error_mark_node) ! 1898: return error_mark_node; ! 1899: if (TREE_CODE (t) == FIELD_DECL) ! 1900: { ! 1901: if (dont_use_this) ! 1902: { ! 1903: cp_error ("invalid use of non-static field `%D'", t); ! 1904: return error_mark_node; ! 1905: } ! 1906: decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t); ! 1907: } ! 1908: else if (TREE_CODE (t) == VAR_DECL) ! 1909: decl = t; ! 1910: else ! 1911: { ! 1912: cp_error ("invalid use of member `%D'", t); ! 1913: return error_mark_node; ! 1914: } ! 1915: if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl)) ! 1916: && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (decl))) ! 1917: return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, parmlist, NULL_TREE); ! 1918: return build_function_call (decl, parmlist); ! 1919: } ! 1920: else ! 1921: { ! 1922: cp_error ("no method `%T::%D'", type, name); ! 1923: return error_mark_node; ! 1924: } ! 1925: } ! 1926: ! 1927: /* Build a reference to a member of an aggregate. This is not a ! 1928: C++ `&', but really something which can have its address taken, ! 1929: and then act as a pointer to member, for example CNAME :: FIELD ! 1930: can have its address taken by saying & CNAME :: FIELD. ! 1931: ! 1932: @@ Prints out lousy diagnostics for operator <typename> ! 1933: @@ fields. ! 1934: ! 1935: @@ This function should be rewritten and placed in search.c. */ ! 1936: tree ! 1937: build_offset_ref (cname, name) ! 1938: tree cname, name; ! 1939: { ! 1940: tree decl, type, fnfields, fields, t = error_mark_node; ! 1941: tree basetypes = NULL_TREE; ! 1942: int dtor = 0; ! 1943: ! 1944: if (TREE_CODE (cname) == SCOPE_REF) ! 1945: cname = resolve_scope_to_name (NULL_TREE, cname); ! 1946: ! 1947: if (cname == NULL_TREE || ! is_aggr_typedef (cname, 1)) ! 1948: return error_mark_node; ! 1949: ! 1950: type = IDENTIFIER_TYPE_VALUE (cname); ! 1951: ! 1952: if (TREE_CODE (name) == BIT_NOT_EXPR) ! 1953: { ! 1954: dtor = 1; ! 1955: name = TREE_OPERAND (name, 0); ! 1956: } ! 1957: ! 1958: if (TYPE_SIZE (type) == 0) ! 1959: { ! 1960: t = IDENTIFIER_CLASS_VALUE (name); ! 1961: if (t == 0) ! 1962: { ! 1963: cp_error ("incomplete type `%T' does not have member `%D'", type, ! 1964: name); ! 1965: return error_mark_node; ! 1966: } ! 1967: if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == VAR_DECL ! 1968: || TREE_CODE (t) == CONST_DECL) ! 1969: { ! 1970: TREE_USED (t) = 1; ! 1971: return t; ! 1972: } ! 1973: if (TREE_CODE (t) == FIELD_DECL) ! 1974: sorry ("use of member in incomplete aggregate type"); ! 1975: else if (TREE_CODE (t) == FUNCTION_DECL) ! 1976: sorry ("use of member function in incomplete aggregate type"); ! 1977: else ! 1978: my_friendly_abort (52); ! 1979: return error_mark_node; ! 1980: } ! 1981: ! 1982: #if 0 ! 1983: if (TREE_CODE (name) == TYPE_EXPR) ! 1984: /* Pass a TYPE_DECL to build_component_type_expr. */ ! 1985: return build_component_type_expr (TYPE_NAME (TREE_TYPE (cname)), ! 1986: name, NULL_TREE, 1); ! 1987: #endif ! 1988: ! 1989: if (current_class_type == 0 ! 1990: || get_base_distance (type, current_class_type, 0, &basetypes) == -1) ! 1991: { ! 1992: basetypes = TYPE_BINFO (type); ! 1993: decl = build1 (NOP_EXPR, ! 1994: IDENTIFIER_TYPE_VALUE (cname), ! 1995: error_mark_node); ! 1996: } ! 1997: else if (current_class_decl == 0) ! 1998: decl = build1 (NOP_EXPR, IDENTIFIER_TYPE_VALUE (cname), ! 1999: error_mark_node); ! 2000: else ! 2001: decl = C_C_D; ! 2002: ! 2003: fnfields = lookup_fnfields (basetypes, name, 1); ! 2004: fields = lookup_field (basetypes, name, 0, 0); ! 2005: ! 2006: if (fields == error_mark_node || fnfields == error_mark_node) ! 2007: return error_mark_node; ! 2008: ! 2009: /* A lot of this logic is now handled in lookup_field and ! 2010: lookup_fnfield. */ ! 2011: if (fnfields) ! 2012: { ! 2013: basetypes = TREE_PURPOSE (fnfields); ! 2014: ! 2015: /* Go from the TREE_BASELINK to the member function info. */ ! 2016: t = TREE_VALUE (fnfields); ! 2017: ! 2018: if (fields) ! 2019: { ! 2020: if (DECL_FIELD_CONTEXT (fields) == DECL_FIELD_CONTEXT (t)) ! 2021: { ! 2022: error ("ambiguous member reference: member `%s' defined as both field and function", ! 2023: IDENTIFIER_POINTER (name)); ! 2024: return error_mark_node; ! 2025: } ! 2026: if (UNIQUELY_DERIVED_FROM_P (DECL_FIELD_CONTEXT (fields), DECL_FIELD_CONTEXT (t))) ! 2027: ; ! 2028: else if (UNIQUELY_DERIVED_FROM_P (DECL_FIELD_CONTEXT (t), DECL_FIELD_CONTEXT (fields))) ! 2029: t = fields; ! 2030: else ! 2031: { ! 2032: error ("ambiguous member reference: member `%s' derives from distinct classes in multiple inheritance lattice"); ! 2033: return error_mark_node; ! 2034: } ! 2035: } ! 2036: ! 2037: if (t == TREE_VALUE (fnfields)) ! 2038: { ! 2039: extern int flag_save_memoized_contexts; ! 2040: ! 2041: if (DECL_CHAIN (t) == NULL_TREE || dtor) ! 2042: { ! 2043: enum access_type access; ! 2044: ! 2045: /* unique functions are handled easily. */ ! 2046: unique: ! 2047: access = compute_access (basetypes, t); ! 2048: if (access == access_protected) ! 2049: { ! 2050: cp_error_at ("member function `%#D' is protected", t); ! 2051: error ("in this context"); ! 2052: return error_mark_node; ! 2053: } ! 2054: if (access == access_private) ! 2055: { ! 2056: cp_error_at ("member function `%#D' is private", t); ! 2057: error ("in this context"); ! 2058: return error_mark_node; ! 2059: } ! 2060: assemble_external (t); ! 2061: return build (OFFSET_REF, TREE_TYPE (t), decl, t); ! 2062: } ! 2063: ! 2064: /* overloaded functions may need more work. */ ! 2065: if (cname == name) ! 2066: { ! 2067: if (TYPE_HAS_DESTRUCTOR (type) ! 2068: && DECL_CHAIN (DECL_CHAIN (t)) == NULL_TREE) ! 2069: { ! 2070: t = DECL_CHAIN (t); ! 2071: goto unique; ! 2072: } ! 2073: } ! 2074: /* FNFIELDS is most likely allocated on the search_obstack, ! 2075: which will go away after this class scope. If we need ! 2076: to save this value for later (either for memoization ! 2077: or for use as an initializer for a static variable), then ! 2078: do so here. ! 2079: ! 2080: ??? The smart thing to do for the case of saving initializers ! 2081: is to resolve them before we're done with this scope. */ ! 2082: if (!TREE_PERMANENT (fnfields) ! 2083: && ((flag_save_memoized_contexts && global_bindings_p ()) ! 2084: || ! allocation_temporary_p ())) ! 2085: fnfields = copy_list (fnfields); ! 2086: t = build_tree_list (error_mark_node, fnfields); ! 2087: TREE_TYPE (t) = build_offset_type (type, unknown_type_node); ! 2088: return t; ! 2089: } ! 2090: } ! 2091: ! 2092: /* Now that we know we are looking for a field, see if we ! 2093: have access to that field. Lookup_field will give us the ! 2094: error message. */ ! 2095: ! 2096: t = lookup_field (basetypes, name, 1, 0); ! 2097: ! 2098: if (t == error_mark_node) ! 2099: return error_mark_node; ! 2100: ! 2101: if (t == NULL_TREE) ! 2102: { ! 2103: cp_error ("`%D' is not a member of type `%T'", name, type); ! 2104: return error_mark_node; ! 2105: } ! 2106: ! 2107: if (TREE_CODE (t) == TYPE_DECL) ! 2108: { ! 2109: TREE_USED (t) = 1; ! 2110: return t; ! 2111: } ! 2112: /* static class members and class-specific enum ! 2113: values can be returned without further ado. */ ! 2114: if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL) ! 2115: { ! 2116: assemble_external (t); ! 2117: TREE_USED (t) = 1; ! 2118: return t; ! 2119: } ! 2120: ! 2121: /* static class functions too. */ ! 2122: if (TREE_CODE (t) == FUNCTION_DECL && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) ! 2123: my_friendly_abort (53); ! 2124: ! 2125: /* In member functions, the form `cname::name' is no longer ! 2126: equivalent to `this->cname::name'. */ ! 2127: return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t); ! 2128: } ! 2129: ! 2130: /* Given an object EXP and a member function reference MEMBER, ! 2131: return the address of the actual member function. */ ! 2132: tree ! 2133: get_member_function (exp_addr_ptr, exp, member) ! 2134: tree *exp_addr_ptr; ! 2135: tree exp, member; ! 2136: { ! 2137: tree ctype = TREE_TYPE (exp); ! 2138: tree function = save_expr (build_unary_op (ADDR_EXPR, member, 0)); ! 2139: ! 2140: if (TYPE_VIRTUAL_P (ctype) ! 2141: || (flag_all_virtual == 1 && TYPE_OVERLOADS_METHOD_CALL_EXPR (ctype))) ! 2142: { ! 2143: tree e0, e1, e3; ! 2144: tree exp_addr; ! 2145: ! 2146: /* Save away the unadulterated `this' pointer. */ ! 2147: exp_addr = save_expr (*exp_addr_ptr); ! 2148: ! 2149: /* Cast function to signed integer. */ ! 2150: e0 = build1 (NOP_EXPR, integer_type_node, function); ! 2151: ! 2152: /* There is a hack here that takes advantage of ! 2153: twos complement arithmetic, and the fact that ! 2154: there are more than one UNITS to the WORD. ! 2155: If the high bit is set for the `function', ! 2156: then we pretend it is a virtual function, ! 2157: and the array indexing will knock this bit ! 2158: out the top, leaving a valid index. */ ! 2159: if (UNITS_PER_WORD <= 1) ! 2160: my_friendly_abort (54); ! 2161: ! 2162: e1 = build (GT_EXPR, integer_type_node, e0, integer_zero_node); ! 2163: e1 = build_compound_expr (tree_cons (NULL_TREE, exp_addr, ! 2164: build_tree_list (NULL_TREE, e1))); ! 2165: e1 = save_expr (e1); ! 2166: ! 2167: if (TREE_SIDE_EFFECTS (*exp_addr_ptr)) ! 2168: { ! 2169: exp = build_indirect_ref (exp_addr, NULL_PTR); ! 2170: *exp_addr_ptr = exp_addr; ! 2171: } ! 2172: ! 2173: /* This is really hairy: if the function pointer is a pointer ! 2174: to a non-virtual member function, then we can't go mucking ! 2175: with the `this' pointer (any more than we already have to ! 2176: this point). If it is a pointer to a virtual member function, ! 2177: then we have to adjust the `this' pointer according to ! 2178: what the virtual function table tells us. */ ! 2179: ! 2180: e3 = build_vfn_ref (exp_addr_ptr, exp, e0); ! 2181: my_friendly_assert (e3 != error_mark_node, 213); ! 2182: ! 2183: /* Change this pointer type from `void *' to the ! 2184: type it is really supposed to be. */ ! 2185: TREE_TYPE (e3) = TREE_TYPE (function); ! 2186: ! 2187: /* If non-virtual, use what we had originally. Otherwise, ! 2188: use the value we get from the virtual function table. */ ! 2189: *exp_addr_ptr = build_conditional_expr (e1, exp_addr, *exp_addr_ptr); ! 2190: ! 2191: function = build_conditional_expr (e1, function, e3); ! 2192: } ! 2193: return build_indirect_ref (function, NULL_PTR); ! 2194: } ! 2195: ! 2196: /* If a OFFSET_REF made it through to here, then it did ! 2197: not have its address taken. */ ! 2198: ! 2199: tree ! 2200: resolve_offset_ref (exp) ! 2201: tree exp; ! 2202: { ! 2203: tree type = TREE_TYPE (exp); ! 2204: tree base = NULL_TREE; ! 2205: tree member; ! 2206: tree basetype, addr; ! 2207: ! 2208: if (TREE_CODE (exp) == TREE_LIST) ! 2209: return build_unary_op (ADDR_EXPR, exp, 0); ! 2210: ! 2211: if (TREE_CODE (exp) != OFFSET_REF) ! 2212: { ! 2213: my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214); ! 2214: if (TYPE_OFFSET_BASETYPE (type) != current_class_type) ! 2215: { ! 2216: error ("object missing in use of pointer-to-member construct"); ! 2217: return error_mark_node; ! 2218: } ! 2219: member = exp; ! 2220: type = TREE_TYPE (type); ! 2221: base = C_C_D; ! 2222: } ! 2223: else ! 2224: { ! 2225: member = TREE_OPERAND (exp, 1); ! 2226: base = TREE_OPERAND (exp, 0); ! 2227: } ! 2228: ! 2229: if ((TREE_CODE (member) == VAR_DECL ! 2230: && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member))) ! 2231: || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE) ! 2232: { ! 2233: /* These were static members. */ ! 2234: if (mark_addressable (member) == 0) ! 2235: return error_mark_node; ! 2236: return member; ! 2237: } ! 2238: ! 2239: /* Syntax error can cause a member which should ! 2240: have been seen as static to be grok'd as non-static. */ ! 2241: if (TREE_CODE (member) == FIELD_DECL && C_C_D == NULL_TREE) ! 2242: { ! 2243: if (TREE_ADDRESSABLE (member) == 0) ! 2244: { ! 2245: cp_error_at ("member `%D' is non-static in static member function context", member); ! 2246: error ("at this point in file"); ! 2247: TREE_ADDRESSABLE (member) = 1; ! 2248: } ! 2249: return error_mark_node; ! 2250: } ! 2251: ! 2252: /* The first case is really just a reference to a member of `this'. */ ! 2253: if (TREE_CODE (member) == FIELD_DECL ! 2254: && (base == C_C_D ! 2255: || (TREE_CODE (base) == NOP_EXPR ! 2256: && TREE_OPERAND (base, 0) == error_mark_node))) ! 2257: { ! 2258: tree basetype_path; ! 2259: enum access_type access; ! 2260: ! 2261: if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE) ! 2262: basetype = TYPE_OFFSET_BASETYPE (type); ! 2263: else ! 2264: basetype = DECL_CONTEXT (member); ! 2265: ! 2266: base = current_class_decl; ! 2267: ! 2268: if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0) ! 2269: { ! 2270: error_not_base_type (basetype, TREE_TYPE (TREE_TYPE (base))); ! 2271: return error_mark_node; ! 2272: } ! 2273: addr = convert_pointer_to (basetype, base); ! 2274: access = compute_access (basetype_path, member); ! 2275: if (access == access_public) ! 2276: return build (COMPONENT_REF, TREE_TYPE (member), ! 2277: build_indirect_ref (addr, NULL_PTR), member); ! 2278: if (access == access_protected) ! 2279: { ! 2280: cp_error_at ("member `%D' is protected", member); ! 2281: error ("in this context"); ! 2282: return error_mark_node; ! 2283: } ! 2284: if (access == access_private) ! 2285: { ! 2286: cp_error_at ("member `%D' is private", member); ! 2287: error ("in this context"); ! 2288: return error_mark_node; ! 2289: } ! 2290: my_friendly_abort (55); ! 2291: } ! 2292: ! 2293: /* If this is a reference to a member function, then return ! 2294: the address of the member function (which may involve going ! 2295: through the object's vtable), otherwise, return an expression ! 2296: for the dereferenced pointer-to-member construct. */ ! 2297: addr = build_unary_op (ADDR_EXPR, base, 0); ! 2298: ! 2299: if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE) ! 2300: { ! 2301: basetype = DECL_CLASS_CONTEXT (member); ! 2302: addr = convert_pointer_to (basetype, addr); ! 2303: return build_unary_op (ADDR_EXPR, get_member_function (&addr, build_indirect_ref (addr, NULL_PTR), member), 0); ! 2304: } ! 2305: else if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE) ! 2306: { ! 2307: basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member)); ! 2308: addr = convert_pointer_to (basetype, addr); ! 2309: member = convert (ptrdiff_type_node, ! 2310: build_unary_op (ADDR_EXPR, member, 0)); ! 2311: return build1 (INDIRECT_REF, type, ! 2312: build (PLUS_EXPR, build_pointer_type (type), ! 2313: addr, member)); ! 2314: } ! 2315: else if (TYPE_PTRMEMFUNC_P (TREE_TYPE (member))) ! 2316: { ! 2317: return get_member_function_from_ptrfunc (&addr, base, member); ! 2318: } ! 2319: my_friendly_abort (56); ! 2320: /* NOTREACHED */ ! 2321: return NULL_TREE; ! 2322: } ! 2323: ! 2324: /* Return either DECL or its known constant value (if it has one). */ ! 2325: ! 2326: tree ! 2327: decl_constant_value (decl) ! 2328: tree decl; ! 2329: { ! 2330: if (! TREE_THIS_VOLATILE (decl) ! 2331: #if 0 ! 2332: /* These may be necessary for C, but they break C++. */ ! 2333: ! TREE_PUBLIC (decl) ! 2334: /* Don't change a variable array bound or initial value to a constant ! 2335: in a place where a variable is invalid. */ ! 2336: && ! pedantic ! 2337: #endif /* 0 */ ! 2338: && DECL_INITIAL (decl) != 0 ! 2339: && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK ! 2340: /* This is invalid if initial value is not constant. ! 2341: If it has either a function call, a memory reference, ! 2342: or a variable, then re-evaluating it could give different results. */ ! 2343: && TREE_CONSTANT (DECL_INITIAL (decl)) ! 2344: /* Check for cases where this is sub-optimal, even though valid. */ ! 2345: && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR ! 2346: #if 0 ! 2347: /* We must allow this to work outside of functions so that ! 2348: static constants can be used for array sizes. */ ! 2349: && current_function_decl != 0 ! 2350: && DECL_MODE (decl) != BLKmode ! 2351: #endif ! 2352: ) ! 2353: return DECL_INITIAL (decl); ! 2354: return decl; ! 2355: } ! 2356: ! 2357: /* Friend handling routines. */ ! 2358: /* Friend data structures: ! 2359: ! 2360: Lists of friend functions come from TYPE_DECL nodes. Since all ! 2361: aggregate types are automatically typedef'd, these nodes are guaranteed ! 2362: to exist. ! 2363: ! 2364: The TREE_PURPOSE of a friend list is the name of the friend, ! 2365: and its TREE_VALUE is another list. ! 2366: ! 2367: For each element of that list, either the TREE_VALUE or the TREE_PURPOSE ! 2368: will be filled in, but not both. The TREE_VALUE of that list is an ! 2369: individual function which is a friend. The TREE_PURPOSE of that list ! 2370: indicates a type in which all functions by that name are friends. ! 2371: ! 2372: Lists of friend classes come from _TYPE nodes. Love that consistency ! 2373: thang. */ ! 2374: ! 2375: int ! 2376: is_friend_type (type1, type2) ! 2377: tree type1, type2; ! 2378: { ! 2379: return is_friend (type1, type2); ! 2380: } ! 2381: ! 2382: int ! 2383: is_friend (type, supplicant) ! 2384: tree type, supplicant; ! 2385: { ! 2386: int declp; ! 2387: register tree list; ! 2388: ! 2389: if (supplicant == NULL_TREE || type == NULL_TREE) ! 2390: return 0; ! 2391: ! 2392: declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd'); ! 2393: ! 2394: if (declp) ! 2395: /* It's a function decl. */ ! 2396: { ! 2397: tree list = DECL_FRIENDLIST (TYPE_NAME (type)); ! 2398: tree name = DECL_NAME (supplicant); ! 2399: tree ctype = DECL_CLASS_CONTEXT (supplicant); ! 2400: for (; list ; list = TREE_CHAIN (list)) ! 2401: { ! 2402: if (name == TREE_PURPOSE (list)) ! 2403: { ! 2404: tree friends = TREE_VALUE (list); ! 2405: name = DECL_ASSEMBLER_NAME (supplicant); ! 2406: for (; friends ; friends = TREE_CHAIN (friends)) ! 2407: { ! 2408: if (ctype == TREE_PURPOSE (friends)) ! 2409: return 1; ! 2410: if (name == DECL_ASSEMBLER_NAME (TREE_VALUE (friends))) ! 2411: return 1; ! 2412: } ! 2413: break; ! 2414: } ! 2415: } ! 2416: } ! 2417: else ! 2418: /* It's a type. */ ! 2419: { ! 2420: if (type == supplicant) ! 2421: return 1; ! 2422: ! 2423: list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_NAME (type))); ! 2424: for (; list ; list = TREE_CHAIN (list)) ! 2425: if (supplicant == TREE_VALUE (list)) ! 2426: return 1; ! 2427: } ! 2428: ! 2429: { ! 2430: tree context = declp ? DECL_CLASS_CONTEXT (supplicant) ! 2431: : DECL_CONTEXT (TYPE_NAME (supplicant)); ! 2432: ! 2433: if (context) ! 2434: return is_friend (type, context); ! 2435: } ! 2436: ! 2437: return 0; ! 2438: } ! 2439: ! 2440: /* Add a new friend to the friends of the aggregate type TYPE. ! 2441: DECL is the FUNCTION_DECL of the friend being added. */ ! 2442: static void ! 2443: add_friend (type, decl) ! 2444: tree type, decl; ! 2445: { ! 2446: tree typedecl = TYPE_NAME (type); ! 2447: tree list = DECL_FRIENDLIST (typedecl); ! 2448: tree name = DECL_NAME (decl); ! 2449: ! 2450: while (list) ! 2451: { ! 2452: if (name == TREE_PURPOSE (list)) ! 2453: { ! 2454: tree friends = TREE_VALUE (list); ! 2455: for (; friends ; friends = TREE_CHAIN (friends)) ! 2456: { ! 2457: if (decl == TREE_VALUE (friends)) ! 2458: { ! 2459: cp_pedwarn ("`%D' is already a friend of class `%T'", ! 2460: decl, type); ! 2461: cp_pedwarn_at ("previous friend declaration of `%D'", ! 2462: TREE_VALUE (friends)); ! 2463: return; ! 2464: } ! 2465: } ! 2466: TREE_VALUE (list) = tree_cons (error_mark_node, decl, ! 2467: TREE_VALUE (list)); ! 2468: return; ! 2469: } ! 2470: list = TREE_CHAIN (list); ! 2471: } ! 2472: DECL_FRIENDLIST (typedecl) ! 2473: = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), ! 2474: DECL_FRIENDLIST (typedecl)); ! 2475: if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR]) ! 2476: { ! 2477: tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); ! 2478: TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; ! 2479: if (parmtypes && TREE_CHAIN (parmtypes)) ! 2480: { ! 2481: tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes)); ! 2482: if (TREE_CODE (parmtype) == REFERENCE_TYPE ! 2483: && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl)) ! 2484: TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1; ! 2485: } ! 2486: } ! 2487: } ! 2488: ! 2489: /* Declare that every member function NAME in FRIEND_TYPE ! 2490: (which may be NULL_TREE) is a friend of type TYPE. */ ! 2491: static void ! 2492: add_friends (type, name, friend_type) ! 2493: tree type, name, friend_type; ! 2494: { ! 2495: tree typedecl = TYPE_NAME (type); ! 2496: tree list = DECL_FRIENDLIST (typedecl); ! 2497: ! 2498: while (list) ! 2499: { ! 2500: if (name == TREE_PURPOSE (list)) ! 2501: { ! 2502: tree friends = TREE_VALUE (list); ! 2503: while (friends && TREE_PURPOSE (friends) != friend_type) ! 2504: friends = TREE_CHAIN (friends); ! 2505: if (friends) ! 2506: if (friend_type) ! 2507: warning ("method `%s::%s' is already a friend of class", ! 2508: TYPE_NAME_STRING (friend_type), ! 2509: IDENTIFIER_POINTER (name)); ! 2510: else ! 2511: warning ("function `%s' is already a friend of class `%s'", ! 2512: IDENTIFIER_POINTER (name), ! 2513: IDENTIFIER_POINTER (DECL_NAME (typedecl))); ! 2514: else ! 2515: TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE, ! 2516: TREE_VALUE (list)); ! 2517: return; ! 2518: } ! 2519: list = TREE_CHAIN (list); ! 2520: } ! 2521: DECL_FRIENDLIST (typedecl) = ! 2522: tree_cons (name, ! 2523: build_tree_list (friend_type, NULL_TREE), ! 2524: DECL_FRIENDLIST (typedecl)); ! 2525: if (! strncmp (IDENTIFIER_POINTER (name), ! 2526: IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]), ! 2527: strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR])))) ! 2528: { ! 2529: TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; ! 2530: sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists"); ! 2531: } ! 2532: } ! 2533: ! 2534: /* Set up a cross reference so that type TYPE will make member function ! 2535: CTYPE::DECL a friend when CTYPE is finally defined. For more than ! 2536: one, set up a cross reference so that functions with the name DECL ! 2537: and type CTYPE know that they are friends of TYPE. */ ! 2538: static void ! 2539: xref_friend (type, decl, ctype) ! 2540: tree type, decl, ctype; ! 2541: { ! 2542: tree friend_decl = TYPE_NAME (ctype); ! 2543: #if 0 ! 2544: tree typedecl = TYPE_NAME (type); ! 2545: tree t = tree_cons (NULL_TREE, ctype, DECL_UNDEFINED_FRIENDS (typedecl)); ! 2546: ! 2547: DECL_UNDEFINED_FRIENDS (typedecl) = t; ! 2548: #else ! 2549: tree t = 0; ! 2550: #endif ! 2551: SET_DECL_WAITING_FRIENDS (friend_decl, ! 2552: tree_cons (type, t, ! 2553: DECL_WAITING_FRIENDS (friend_decl))); ! 2554: TREE_TYPE (DECL_WAITING_FRIENDS (friend_decl)) = decl; ! 2555: } ! 2556: ! 2557: /* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already ! 2558: been defined, we make all of its member functions friends of ! 2559: TYPE. If not, we make it a pending friend, which can later be added ! 2560: when its definition is seen. If a type is defined, then its TYPE_DECL's ! 2561: DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend ! 2562: classes that are not defined. If a type has not yet been defined, ! 2563: then the DECL_WAITING_FRIENDS contains a list of types ! 2564: waiting to make it their friend. Note that these two can both ! 2565: be in use at the same time! */ ! 2566: void ! 2567: make_friend_class (type, friend_type) ! 2568: tree type, friend_type; ! 2569: { ! 2570: tree classes; ! 2571: ! 2572: if (IS_SIGNATURE (type)) ! 2573: { ! 2574: error ("`friend' declaration in signature definition"); ! 2575: return; ! 2576: } ! 2577: if (IS_SIGNATURE (friend_type)) ! 2578: { ! 2579: error ("signature type `%s' declared `friend'", ! 2580: IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (friend_type)))); ! 2581: return; ! 2582: } ! 2583: if (type == friend_type) ! 2584: { ! 2585: warning ("class `%s' is implicitly friends with itself", ! 2586: TYPE_NAME_STRING (type)); ! 2587: return; ! 2588: } ! 2589: ! 2590: GNU_xref_hier (TYPE_NAME_STRING (type), ! 2591: TYPE_NAME_STRING (friend_type), 0, 0, 1); ! 2592: ! 2593: classes = CLASSTYPE_FRIEND_CLASSES (type); ! 2594: while (classes && TREE_VALUE (classes) != friend_type) ! 2595: classes = TREE_CHAIN (classes); ! 2596: if (classes) ! 2597: warning ("class `%s' is already friends with class `%s'", ! 2598: TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type)); ! 2599: else ! 2600: { ! 2601: CLASSTYPE_FRIEND_CLASSES (type) ! 2602: = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); ! 2603: } ! 2604: } ! 2605: ! 2606: /* Main friend processor. This is large, and for modularity purposes, ! 2607: has been removed from grokdeclarator. It returns `void_type_node' ! 2608: to indicate that something happened, though a FIELD_DECL is ! 2609: not returned. ! 2610: ! 2611: CTYPE is the class this friend belongs to. ! 2612: ! 2613: DECLARATOR is the name of the friend. ! 2614: ! 2615: DECL is the FUNCTION_DECL that the friend is. ! 2616: ! 2617: In case we are parsing a friend which is part of an inline ! 2618: definition, we will need to store PARM_DECL chain that comes ! 2619: with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL. ! 2620: ! 2621: FLAGS is just used for `grokclassfn'. ! 2622: ! 2623: QUALS say what special qualifies should apply to the object ! 2624: pointed to by `this'. */ ! 2625: tree ! 2626: do_friend (ctype, declarator, decl, parmdecls, flags, quals) ! 2627: tree ctype, declarator, decl, parmdecls; ! 2628: enum overload_flags flags; ! 2629: tree quals; ! 2630: { ! 2631: /* Every decl that gets here is a friend of something. */ ! 2632: DECL_FRIEND_P (decl) = 1; ! 2633: ! 2634: if (ctype) ! 2635: { ! 2636: tree cname = TYPE_NAME (ctype); ! 2637: if (TREE_CODE (cname) == TYPE_DECL) ! 2638: cname = DECL_NAME (cname); ! 2639: ! 2640: /* A method friend. */ ! 2641: if (TREE_CODE (decl) == FUNCTION_DECL) ! 2642: { ! 2643: if (flags == NO_SPECIAL && ctype && declarator == cname) ! 2644: DECL_CONSTRUCTOR_P (decl) = 1; ! 2645: ! 2646: /* This will set up DECL_ARGUMENTS for us. */ ! 2647: grokclassfn (ctype, cname, decl, flags, quals); ! 2648: if (TYPE_SIZE (ctype) != 0) ! 2649: check_classfn (ctype, cname, decl); ! 2650: ! 2651: if (TREE_TYPE (decl) != error_mark_node) ! 2652: { ! 2653: if (TYPE_SIZE (ctype)) ! 2654: { ! 2655: /* We don't call pushdecl here yet, or ever on this ! 2656: actual FUNCTION_DECL. We must preserve its TREE_CHAIN ! 2657: until the end. */ ! 2658: make_decl_rtl (decl, NULL_PTR, 1); ! 2659: add_friend (current_class_type, decl); ! 2660: } ! 2661: else ! 2662: { ! 2663: register char *classname ! 2664: = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (ctype))); ! 2665: ! 2666: error ("member declared as friend before type `%s' defined", ! 2667: classname); ! 2668: } ! 2669: } ! 2670: } ! 2671: else ! 2672: { ! 2673: /* Possibly a bunch of method friends. */ ! 2674: ! 2675: /* Get the class they belong to. */ ! 2676: tree ctype = IDENTIFIER_TYPE_VALUE (cname); ! 2677: ! 2678: /* This class is defined, use its methods now. */ ! 2679: if (TYPE_SIZE (ctype)) ! 2680: { ! 2681: tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0); ! 2682: if (fields) ! 2683: add_friends (current_class_type, declarator, ctype); ! 2684: else ! 2685: error ("method `%s' is not a member of class `%s'", ! 2686: IDENTIFIER_POINTER (declarator), ! 2687: IDENTIFIER_POINTER (cname)); ! 2688: } ! 2689: else ! 2690: /* Note: DECLARATOR actually has more than one; in this ! 2691: case, we're making sure that fns with the name DECLARATOR ! 2692: and type CTYPE know they are friends of the current ! 2693: class type. */ ! 2694: xref_friend (current_class_type, declarator, ctype); ! 2695: decl = void_type_node; ! 2696: } ! 2697: } ! 2698: else if (TREE_CODE (decl) == FUNCTION_DECL ! 2699: && ((IDENTIFIER_LENGTH (declarator) == 4 ! 2700: && IDENTIFIER_POINTER (declarator)[0] == 'm' ! 2701: && ! strcmp (IDENTIFIER_POINTER (declarator), "main")) ! 2702: || (IDENTIFIER_LENGTH (declarator) > 10 ! 2703: && IDENTIFIER_POINTER (declarator)[0] == '_' ! 2704: && IDENTIFIER_POINTER (declarator)[1] == '_' ! 2705: && strncmp (IDENTIFIER_POINTER (declarator)+2, ! 2706: "builtin_", 8) == 0))) ! 2707: { ! 2708: /* raw "main", and builtin functions never gets overloaded, ! 2709: but they can become friends. */ ! 2710: TREE_PUBLIC (decl) = 1; ! 2711: add_friend (current_class_type, decl); ! 2712: DECL_FRIEND_P (decl) = 1; ! 2713: decl = void_type_node; ! 2714: } ! 2715: /* A global friend. ! 2716: @@ or possibly a friend from a base class ?!? */ ! 2717: else if (TREE_CODE (decl) == FUNCTION_DECL) ! 2718: { ! 2719: /* Friends must all go through the overload machinery, ! 2720: even though they may not technically be overloaded. ! 2721: ! 2722: Note that because classes all wind up being top-level ! 2723: in their scope, their friend wind up in top-level scope as well. */ ! 2724: DECL_ASSEMBLER_NAME (decl) ! 2725: = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)), ! 2726: TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE); ! 2727: DECL_ARGUMENTS (decl) = parmdecls; ! 2728: DECL_CLASS_CONTEXT (decl) = current_class_type; ! 2729: ! 2730: /* We can call pushdecl here, because the TREE_CHAIN of this ! 2731: FUNCTION_DECL is not needed for other purposes. */ ! 2732: decl = pushdecl (decl); ! 2733: ! 2734: make_decl_rtl (decl, NULL_PTR, 1); ! 2735: add_friend (current_class_type, decl); ! 2736: ! 2737: DECL_FRIEND_P (decl) = 1; ! 2738: #if 0 ! 2739: TREE_OVERLOADED (declarator) = 1; ! 2740: #endif ! 2741: } ! 2742: else ! 2743: { ! 2744: /* @@ Should be able to ingest later definitions of this function ! 2745: before use. */ ! 2746: tree decl = lookup_name_nonclass (declarator); ! 2747: if (decl == NULL_TREE) ! 2748: { ! 2749: warning ("implicitly declaring `%s' as struct", ! 2750: IDENTIFIER_POINTER (declarator)); ! 2751: decl = xref_tag (record_type_node, declarator, NULL_TREE, 1); ! 2752: decl = TYPE_NAME (decl); ! 2753: } ! 2754: ! 2755: /* Allow abbreviated declarations of overloaded functions, ! 2756: but not if those functions are really class names. */ ! 2757: if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl))) ! 2758: { ! 2759: warning ("`friend %s' archaic, use `friend class %s' instead", ! 2760: IDENTIFIER_POINTER (declarator), ! 2761: IDENTIFIER_POINTER (declarator)); ! 2762: decl = TREE_TYPE (TREE_PURPOSE (decl)); ! 2763: } ! 2764: ! 2765: if (TREE_CODE (decl) == TREE_LIST) ! 2766: add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE); ! 2767: else ! 2768: make_friend_class (current_class_type, TREE_TYPE (decl)); ! 2769: decl = void_type_node; ! 2770: } ! 2771: return decl; ! 2772: } ! 2773: ! 2774: /* TYPE has now been defined. It may, however, have a number of things ! 2775: waiting make make it their friend. We resolve these references ! 2776: here. */ ! 2777: void ! 2778: embrace_waiting_friends (type) ! 2779: tree type; ! 2780: { ! 2781: tree decl = TYPE_NAME (type); ! 2782: tree waiters; ! 2783: ! 2784: if (TREE_CODE (decl) != TYPE_DECL) ! 2785: return; ! 2786: ! 2787: for (waiters = DECL_WAITING_FRIENDS (decl); waiters; ! 2788: waiters = TREE_CHAIN (waiters)) ! 2789: { ! 2790: tree waiter = TREE_PURPOSE (waiters); ! 2791: #if 0 ! 2792: tree waiter_prev = TREE_VALUE (waiters); ! 2793: #endif ! 2794: tree decl = TREE_TYPE (waiters); ! 2795: tree name = decl ? (TREE_CODE (decl) == IDENTIFIER_NODE ! 2796: ? decl : DECL_NAME (decl)) : NULL_TREE; ! 2797: if (name) ! 2798: { ! 2799: /* @@ There may be work to be done since we have not verified ! 2800: @@ consistency between original and friend declarations ! 2801: @@ of the functions waiting to become friends. */ ! 2802: tree field = lookup_fnfields (TYPE_BINFO (type), name, 0); ! 2803: if (field) ! 2804: if (decl == name) ! 2805: add_friends (waiter, name, type); ! 2806: else ! 2807: add_friend (waiter, decl); ! 2808: else ! 2809: error_with_file_and_line (DECL_SOURCE_FILE (TYPE_NAME (waiter)), ! 2810: DECL_SOURCE_LINE (TYPE_NAME (waiter)), ! 2811: "no method `%s' defined in class `%s' to be friend", ! 2812: IDENTIFIER_POINTER (DECL_NAME (TREE_TYPE (waiters))), ! 2813: TYPE_NAME_STRING (type)); ! 2814: } ! 2815: else ! 2816: make_friend_class (type, waiter); ! 2817: ! 2818: #if 0 ! 2819: if (TREE_CHAIN (waiter_prev)) ! 2820: TREE_CHAIN (waiter_prev) = TREE_CHAIN (TREE_CHAIN (waiter_prev)); ! 2821: else ! 2822: DECL_UNDEFINED_FRIENDS (TYPE_NAME (waiter)) = NULL_TREE; ! 2823: #endif ! 2824: } ! 2825: } ! 2826: ! 2827: /* Common subroutines of build_new and build_vec_delete. */ ! 2828: ! 2829: /* Common interface for calling "builtin" functions that are not ! 2830: really builtin. */ ! 2831: ! 2832: tree ! 2833: build_builtin_call (type, node, arglist) ! 2834: tree type; ! 2835: tree node; ! 2836: tree arglist; ! 2837: { ! 2838: tree rval = build (CALL_EXPR, type, node, arglist, 0); ! 2839: TREE_SIDE_EFFECTS (rval) = 1; ! 2840: assemble_external (TREE_OPERAND (node, 0)); ! 2841: TREE_USED (TREE_OPERAND (node, 0)) = 1; ! 2842: return rval; ! 2843: } ! 2844: ! 2845: /* Generate a C++ "new" expression. DECL is either a TREE_LIST ! 2846: (which needs to go through some sort of groktypename) or it ! 2847: is the name of the class we are newing. INIT is an initialization value. ! 2848: It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces. ! 2849: If INIT is void_type_node, it means do *not* call a constructor ! 2850: for this instance. ! 2851: ! 2852: For types with constructors, the data returned is initialized ! 2853: by the appropriate constructor. ! 2854: ! 2855: Whether the type has a constructor or not, if it has a pointer ! 2856: to a virtual function table, then that pointer is set up ! 2857: here. ! 2858: ! 2859: Unless I am mistaken, a call to new () will return initialized ! 2860: data regardless of whether the constructor itself is private or ! 2861: not. NOPE; new fails if the constructor is private (jcm). ! 2862: ! 2863: Note that build_new does nothing to assure that any special ! 2864: alignment requirements of the type are met. Rather, it leaves ! 2865: it up to malloc to do the right thing. Otherwise, folding to ! 2866: the right alignment cal cause problems if the user tries to later ! 2867: free the memory returned by `new'. ! 2868: ! 2869: PLACEMENT is the `placement' list for user-defined operator new (). */ ! 2870: ! 2871: tree ! 2872: build_new (placement, decl, init, use_global_new) ! 2873: tree placement; ! 2874: tree decl, init; ! 2875: int use_global_new; ! 2876: { ! 2877: tree type, true_type, size, rval; ! 2878: tree nelts; ! 2879: int has_array = 0; ! 2880: enum tree_code code = NEW_EXPR; ! 2881: ! 2882: tree pending_sizes = NULL_TREE; ! 2883: ! 2884: if (decl == error_mark_node) ! 2885: return error_mark_node; ! 2886: ! 2887: if (TREE_CODE (decl) == TREE_LIST) ! 2888: { ! 2889: tree absdcl = TREE_VALUE (decl); ! 2890: tree last_absdcl = NULL_TREE; ! 2891: int old_immediate_size_expand; ! 2892: ! 2893: if (current_function_decl ! 2894: && DECL_CONSTRUCTOR_P (current_function_decl)) ! 2895: { ! 2896: old_immediate_size_expand = immediate_size_expand; ! 2897: immediate_size_expand = 0; ! 2898: } ! 2899: ! 2900: nelts = integer_one_node; ! 2901: ! 2902: if (absdcl && TREE_CODE (absdcl) == CALL_EXPR) ! 2903: my_friendly_abort (215); ! 2904: while (absdcl && TREE_CODE (absdcl) == INDIRECT_REF) ! 2905: { ! 2906: last_absdcl = absdcl; ! 2907: absdcl = TREE_OPERAND (absdcl, 0); ! 2908: } ! 2909: ! 2910: if (absdcl && TREE_CODE (absdcl) == ARRAY_REF) ! 2911: { ! 2912: /* probably meant to be a vec new */ ! 2913: tree this_nelts; ! 2914: ! 2915: while (TREE_OPERAND (absdcl, 0) ! 2916: && TREE_CODE (TREE_OPERAND (absdcl, 0)) == ARRAY_REF) ! 2917: { ! 2918: last_absdcl = absdcl; ! 2919: absdcl = TREE_OPERAND (absdcl, 0); ! 2920: } ! 2921: ! 2922: has_array = 1; ! 2923: this_nelts = TREE_OPERAND (absdcl, 1); ! 2924: if (this_nelts != error_mark_node) ! 2925: { ! 2926: if (this_nelts == NULL_TREE) ! 2927: error ("new of array type fails to specify size"); ! 2928: else ! 2929: { ! 2930: this_nelts = save_expr (convert (sizetype, this_nelts)); ! 2931: absdcl = TREE_OPERAND (absdcl, 0); ! 2932: if (this_nelts == integer_zero_node) ! 2933: { ! 2934: warning ("zero size array reserves no space"); ! 2935: nelts = integer_zero_node; ! 2936: } ! 2937: else ! 2938: nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1); ! 2939: } ! 2940: } ! 2941: else ! 2942: nelts = integer_zero_node; ! 2943: } ! 2944: ! 2945: if (last_absdcl) ! 2946: TREE_OPERAND (last_absdcl, 0) = absdcl; ! 2947: else ! 2948: TREE_VALUE (decl) = absdcl; ! 2949: ! 2950: type = true_type = groktypename (decl); ! 2951: if (! type || type == error_mark_node) ! 2952: { ! 2953: immediate_size_expand = old_immediate_size_expand; ! 2954: return error_mark_node; ! 2955: } ! 2956: ! 2957: if (current_function_decl ! 2958: && DECL_CONSTRUCTOR_P (current_function_decl)) ! 2959: { ! 2960: pending_sizes = get_pending_sizes (); ! 2961: immediate_size_expand = old_immediate_size_expand; ! 2962: } ! 2963: } ! 2964: else if (TREE_CODE (decl) == IDENTIFIER_NODE) ! 2965: { ! 2966: if (IDENTIFIER_HAS_TYPE_VALUE (decl)) ! 2967: { ! 2968: /* An aggregate type. */ ! 2969: type = IDENTIFIER_TYPE_VALUE (decl); ! 2970: decl = TYPE_NAME (type); ! 2971: } ! 2972: else ! 2973: { ! 2974: /* A builtin type. */ ! 2975: decl = lookup_name (decl, 1); ! 2976: my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 215); ! 2977: type = TREE_TYPE (decl); ! 2978: } ! 2979: true_type = type; ! 2980: } ! 2981: else if (TREE_CODE (decl) == TYPE_DECL) ! 2982: { ! 2983: type = TREE_TYPE (decl); ! 2984: true_type = type; ! 2985: } ! 2986: else ! 2987: { ! 2988: type = decl; ! 2989: true_type = type; ! 2990: decl = TYPE_NAME (type); ! 2991: } ! 2992: ! 2993: /* ``A reference cannot be created by the new operator. A reference ! 2994: is not an object (8.2.2, 8.4.3), so a pointer to it could not be ! 2995: returned by new.'' ARM 5.3.3 */ ! 2996: if (TREE_CODE (type) == REFERENCE_TYPE) ! 2997: { ! 2998: error ("new cannot be applied to a reference type"); ! 2999: type = true_type = TREE_TYPE (type); ! 3000: } ! 3001: ! 3002: /* When the object being created is an array, the new-expression yields a ! 3003: pointer to the initial element (if any) of the array. For example, ! 3004: both new int and new int[10] return an int*. 5.3.4. */ ! 3005: if (TREE_CODE (type) == ARRAY_TYPE && has_array == 0) ! 3006: { ! 3007: nelts = array_type_nelts_top (type); ! 3008: has_array = 1; ! 3009: type = true_type = TREE_TYPE (type); ! 3010: } ! 3011: ! 3012: if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) ! 3013: { ! 3014: pedwarn ("const and volatile types cannot be created with operator new"); ! 3015: type = true_type = TYPE_MAIN_VARIANT (type); ! 3016: } ! 3017: ! 3018: /* If our base type is an array, then make sure we know how many elements ! 3019: it has. */ ! 3020: while (TREE_CODE (true_type) == ARRAY_TYPE) ! 3021: { ! 3022: tree this_nelts = array_type_nelts_top (true_type); ! 3023: nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1); ! 3024: true_type = TREE_TYPE (true_type); ! 3025: } ! 3026: if (has_array) ! 3027: size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type), ! 3028: nelts, 1)); ! 3029: else ! 3030: size = size_in_bytes (type); ! 3031: ! 3032: if (TYPE_SIZE (true_type) == 0) ! 3033: { ! 3034: if (true_type == void_type_node) ! 3035: error ("invalid type for new: `void'"); ! 3036: else ! 3037: incomplete_type_error (0, true_type); ! 3038: return error_mark_node; ! 3039: } ! 3040: ! 3041: if (TYPE_LANG_SPECIFIC (true_type) ! 3042: && CLASSTYPE_ABSTRACT_VIRTUALS (true_type)) ! 3043: { ! 3044: abstract_virtuals_error (NULL_TREE, true_type); ! 3045: return error_mark_node; ! 3046: } ! 3047: ! 3048: if (TYPE_LANG_SPECIFIC (true_type) && IS_SIGNATURE (true_type)) ! 3049: { ! 3050: signature_error (NULL_TREE, true_type); ! 3051: return error_mark_node; ! 3052: } ! 3053: ! 3054: /* Get a little extra space to store a couple of things before the new'ed ! 3055: array. */ ! 3056: if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)) ! 3057: { ! 3058: tree extra = BI_header_size; ! 3059: ! 3060: size = size_binop (PLUS_EXPR, size, extra); ! 3061: } ! 3062: ! 3063: if (has_array) ! 3064: code = VEC_NEW_EXPR; ! 3065: ! 3066: /* Allocate the object. */ ! 3067: if (! use_global_new && TYPE_LANG_SPECIFIC (true_type) ! 3068: && (TYPE_GETS_NEW (true_type) & (1 << has_array))) ! 3069: rval = build_opfncall (code, LOOKUP_NORMAL, ! 3070: TYPE_POINTER_TO (true_type), size, placement); ! 3071: else if (placement) ! 3072: { ! 3073: rval = build_opfncall (code, LOOKUP_GLOBAL|LOOKUP_COMPLAIN, ! 3074: ptr_type_node, size, placement); ! 3075: rval = convert (TYPE_POINTER_TO (true_type), rval); ! 3076: } ! 3077: else if (! has_array && flag_this_is_variable > 0 ! 3078: && TYPE_HAS_CONSTRUCTOR (true_type) && init != void_type_node) ! 3079: { ! 3080: if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST) ! 3081: rval = NULL_TREE; ! 3082: else ! 3083: { ! 3084: error ("constructors take parameter lists"); ! 3085: return error_mark_node; ! 3086: } ! 3087: } ! 3088: else ! 3089: { ! 3090: rval = build_builtin_call (build_pointer_type (true_type), ! 3091: has_array ? BIVN : BIN, ! 3092: build_tree_list (NULL_TREE, size)); ! 3093: #if 0 ! 3094: /* See comment above as to why this is disabled. */ ! 3095: if (alignment) ! 3096: { ! 3097: rval = build (PLUS_EXPR, TYPE_POINTER_TO (true_type), rval, ! 3098: alignment); ! 3099: rval = build (BIT_AND_EXPR, TYPE_POINTER_TO (true_type), ! 3100: rval, build1 (BIT_NOT_EXPR, integer_type_node, ! 3101: alignment)); ! 3102: } ! 3103: #endif ! 3104: TREE_CALLS_NEW (rval) = 1; ! 3105: } ! 3106: ! 3107: /* if rval is NULL_TREE I don't have to allocate it, but are we totally ! 3108: sure we have some extra bytes in that case for the BI_header_size ! 3109: cookies? And how does that interact with the code below? (mrs) */ ! 3110: /* Finish up some magic for new'ed arrays */ ! 3111: if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) && rval != NULL_TREE) ! 3112: { ! 3113: tree extra = BI_header_size; ! 3114: tree cookie, exp1; ! 3115: rval = convert (ptr_type_node, rval); /* convert to void * first */ ! 3116: rval = convert (string_type_node, rval); /* lets not add void* and ints */ ! 3117: rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1)); ! 3118: /* Store header info. */ ! 3119: cookie = build_indirect_ref (build (MINUS_EXPR, TYPE_POINTER_TO (BI_header_type), ! 3120: rval, extra), NULL_PTR); ! 3121: exp1 = build (MODIFY_EXPR, void_type_node, ! 3122: build_component_ref (cookie, nc_nelts_field_id, 0, 0), ! 3123: nelts); ! 3124: TREE_SIDE_EFFECTS (exp1) = 1; ! 3125: rval = convert (build_pointer_type (true_type), rval); ! 3126: TREE_CALLS_NEW (rval) = 1; ! 3127: TREE_SIDE_EFFECTS (rval) = 1; ! 3128: rval = build_compound_expr (tree_cons (NULL_TREE, exp1, ! 3129: build_tree_list (NULL_TREE, rval))); ! 3130: } ! 3131: ! 3132: /* We've figured out where the allocation is to go. ! 3133: If we're not eliding constructors, then if a constructor ! 3134: is defined, we must go through it. */ ! 3135: if (!has_array && (rval == NULL_TREE || !flag_elide_constructors) ! 3136: && TYPE_HAS_CONSTRUCTOR (true_type) && init != void_type_node) ! 3137: { ! 3138: tree newrval; ! 3139: /* Constructors are never virtual. If it has an initialization, we ! 3140: need to complain if we aren't allowed to use the ctor that took ! 3141: that argument. */ ! 3142: int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_COMPLAIN; ! 3143: ! 3144: /* If a copy constructor might work, set things up so that we can ! 3145: try that after this. We deliberately don't clear LOOKUP_COMPLAIN ! 3146: any more, since that would make it impossible to rationally use ! 3147: the access of a constructor that matches perfectly. */ ! 3148: #if 0 ! 3149: if (rval != NULL_TREE) ! 3150: flags |= LOOKUP_SPECULATIVELY; ! 3151: #endif ! 3152: ! 3153: if (rval && TYPE_USES_VIRTUAL_BASECLASSES (true_type)) ! 3154: { ! 3155: init = tree_cons (NULL_TREE, integer_one_node, init); ! 3156: flags |= LOOKUP_HAS_IN_CHARGE; ! 3157: } ! 3158: ! 3159: { ! 3160: tree tmp = rval; ! 3161: ! 3162: if (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE) ! 3163: tmp = build_indirect_ref (tmp, NULL_PTR); ! 3164: ! 3165: newrval = build_method_call (tmp, constructor_name_full (true_type), ! 3166: init, NULL_TREE, flags); ! 3167: } ! 3168: ! 3169: if (newrval) ! 3170: { ! 3171: rval = newrval; ! 3172: TREE_HAS_CONSTRUCTOR (rval) = 1; ! 3173: } ! 3174: else ! 3175: rval = error_mark_node; ! 3176: goto done; ! 3177: } ! 3178: ! 3179: if (rval == error_mark_node) ! 3180: return error_mark_node; ! 3181: rval = save_expr (rval); ! 3182: TREE_HAS_CONSTRUCTOR (rval) = 1; ! 3183: ! 3184: /* Don't call any constructors or do any initialization. */ ! 3185: if (init == void_type_node) ! 3186: goto done; ! 3187: ! 3188: if (TYPE_NEEDS_CONSTRUCTING (type) || init) ! 3189: { ! 3190: if (! TYPE_NEEDS_CONSTRUCTING (type) && ! IS_AGGR_TYPE (type)) ! 3191: { ! 3192: /* New 2.0 interpretation: `new int (10)' means ! 3193: allocate an int, and initialize it with 10. */ ! 3194: ! 3195: init = build_c_cast (type, init); ! 3196: rval = build (COMPOUND_EXPR, TREE_TYPE (rval), ! 3197: build_modify_expr (build_indirect_ref (rval, NULL_PTR), ! 3198: NOP_EXPR, init), ! 3199: rval); ! 3200: TREE_SIDE_EFFECTS (rval) = 1; ! 3201: TREE_CALLS_NEW (rval) = 1; ! 3202: } ! 3203: else if (current_function_decl == NULL_TREE) ! 3204: { ! 3205: extern tree static_aggregates; ! 3206: ! 3207: /* In case of static initialization, SAVE_EXPR is good enough. */ ! 3208: init = copy_to_permanent (init); ! 3209: rval = copy_to_permanent (rval); ! 3210: static_aggregates = perm_tree_cons (init, rval, static_aggregates); ! 3211: } ! 3212: else ! 3213: { ! 3214: /* Have to wrap this in RTL_EXPR for two cases: ! 3215: in base or member initialization and if we ! 3216: are a branch of a ?: operator. Since we ! 3217: can't easily know the latter, just do it always. */ ! 3218: tree xval = make_node (RTL_EXPR); ! 3219: ! 3220: TREE_TYPE (xval) = TREE_TYPE (rval); ! 3221: do_pending_stack_adjust (); ! 3222: start_sequence_for_rtl_expr (xval); ! 3223: ! 3224: /* As a matter of principle, `start_sequence' should do this. */ ! 3225: emit_note (0, -1); ! 3226: ! 3227: if (has_array) ! 3228: rval = expand_vec_init (decl, rval, ! 3229: build_binary_op (MINUS_EXPR, nelts, integer_one_node, 1), ! 3230: init, 0); ! 3231: else ! 3232: expand_aggr_init (build_indirect_ref (rval, NULL_PTR), init, 0); ! 3233: ! 3234: do_pending_stack_adjust (); ! 3235: ! 3236: TREE_SIDE_EFFECTS (xval) = 1; ! 3237: TREE_CALLS_NEW (xval) = 1; ! 3238: RTL_EXPR_SEQUENCE (xval) = get_insns (); ! 3239: end_sequence (); ! 3240: ! 3241: if (TREE_CODE (rval) == SAVE_EXPR) ! 3242: { ! 3243: /* Errors may cause this to not get evaluated. */ ! 3244: if (SAVE_EXPR_RTL (rval) == 0) ! 3245: SAVE_EXPR_RTL (rval) = const0_rtx; ! 3246: RTL_EXPR_RTL (xval) = SAVE_EXPR_RTL (rval); ! 3247: } ! 3248: else ! 3249: { ! 3250: my_friendly_assert (TREE_CODE (rval) == VAR_DECL, 217); ! 3251: RTL_EXPR_RTL (xval) = DECL_RTL (rval); ! 3252: } ! 3253: rval = xval; ! 3254: } ! 3255: } ! 3256: done: ! 3257: if (rval && TREE_TYPE (rval) != build_pointer_type (type)) ! 3258: { ! 3259: /* The type of new int [3][3] is not int *, but int [3] * */ ! 3260: rval = build_c_cast (build_pointer_type (type), rval); ! 3261: } ! 3262: ! 3263: if (pending_sizes) ! 3264: rval = build_compound_expr (chainon (pending_sizes, ! 3265: build_tree_list (NULL_TREE, rval))); ! 3266: ! 3267: if (flag_gc) ! 3268: { ! 3269: extern tree gc_visible; ! 3270: tree objbits; ! 3271: tree update_expr; ! 3272: ! 3273: rval = save_expr (rval); ! 3274: /* We don't need a `headof' operation to do this because ! 3275: we know where the object starts. */ ! 3276: objbits = build1 (INDIRECT_REF, unsigned_type_node, ! 3277: build (MINUS_EXPR, ptr_type_node, ! 3278: rval, c_sizeof_nowarn (unsigned_type_node))); ! 3279: update_expr = build_modify_expr (objbits, BIT_IOR_EXPR, gc_visible); ! 3280: rval = build_compound_expr (tree_cons (NULL_TREE, rval, ! 3281: tree_cons (NULL_TREE, update_expr, ! 3282: build_tree_list (NULL_TREE, rval)))); ! 3283: } ! 3284: ! 3285: return rval; ! 3286: } ! 3287: ! 3288: /* `expand_vec_init' performs initialization of a vector of aggregate ! 3289: types. ! 3290: ! 3291: DECL is passed only for error reporting, and provides line number ! 3292: and source file name information. ! 3293: BASE is the space where the vector will be. ! 3294: MAXINDEX is the maximum index of the array (one less than the ! 3295: number of elements). ! 3296: INIT is the (possibly NULL) initializer. ! 3297: ! 3298: FROM_ARRAY is 0 if we should init everything with INIT ! 3299: (i.e., every element initialized from INIT). ! 3300: FROM_ARRAY is 1 if we should index into INIT in parallel ! 3301: with initialization of DECL. ! 3302: FROM_ARRAY is 2 if we should index into INIT in parallel, ! 3303: but use assignment instead of initialization. */ ! 3304: ! 3305: tree ! 3306: expand_vec_init (decl, base, maxindex, init, from_array) ! 3307: tree decl, base, maxindex, init; ! 3308: int from_array; ! 3309: { ! 3310: tree rval; ! 3311: tree iterator, base2 = NULL_TREE; ! 3312: tree type = TREE_TYPE (TREE_TYPE (base)); ! 3313: tree size; ! 3314: ! 3315: maxindex = convert (integer_type_node, maxindex); ! 3316: if (maxindex == error_mark_node) ! 3317: return error_mark_node; ! 3318: ! 3319: if (current_function_decl == NULL_TREE) ! 3320: { ! 3321: rval = make_tree_vec (3); ! 3322: TREE_VEC_ELT (rval, 0) = base; ! 3323: TREE_VEC_ELT (rval, 1) = maxindex; ! 3324: TREE_VEC_ELT (rval, 2) = init; ! 3325: return rval; ! 3326: } ! 3327: ! 3328: size = size_in_bytes (type); ! 3329: ! 3330: /* Set to zero in case size is <= 0. Optimizer will delete this if ! 3331: it is not needed. */ ! 3332: rval = get_temp_regvar (TYPE_POINTER_TO (type), ! 3333: convert (TYPE_POINTER_TO (type), null_pointer_node)); ! 3334: base = default_conversion (base); ! 3335: base = convert (TYPE_POINTER_TO (type), base); ! 3336: expand_assignment (rval, base, 0, 0); ! 3337: base = get_temp_regvar (TYPE_POINTER_TO (type), base); ! 3338: ! 3339: if (init != NULL_TREE ! 3340: && TREE_CODE (init) == CONSTRUCTOR ! 3341: && TREE_TYPE (init) == TREE_TYPE (decl)) ! 3342: { ! 3343: /* Initialization of array from {...}. */ ! 3344: tree elts = CONSTRUCTOR_ELTS (init); ! 3345: tree baseref = build1 (INDIRECT_REF, type, base); ! 3346: tree baseinc = build (PLUS_EXPR, TYPE_POINTER_TO (type), base, size); ! 3347: int host_i = TREE_INT_CST_LOW (maxindex); ! 3348: ! 3349: if (IS_AGGR_TYPE (type)) ! 3350: { ! 3351: while (elts) ! 3352: { ! 3353: host_i -= 1; ! 3354: expand_aggr_init (baseref, TREE_VALUE (elts), 0); ! 3355: ! 3356: expand_assignment (base, baseinc, 0, 0); ! 3357: elts = TREE_CHAIN (elts); ! 3358: } ! 3359: /* Initialize any elements by default if possible. */ ! 3360: if (host_i >= 0) ! 3361: { ! 3362: if (TYPE_NEEDS_CONSTRUCTING (type) == 0) ! 3363: { ! 3364: if (obey_regdecls) ! 3365: use_variable (DECL_RTL (base)); ! 3366: goto done_init; ! 3367: } ! 3368: ! 3369: iterator = get_temp_regvar (integer_type_node, ! 3370: build_int_2 (host_i, 0)); ! 3371: init = NULL_TREE; ! 3372: goto init_by_default; ! 3373: } ! 3374: } ! 3375: else ! 3376: while (elts) ! 3377: { ! 3378: expand_assignment (baseref, TREE_VALUE (elts), 0, 0); ! 3379: ! 3380: expand_assignment (base, baseinc, 0, 0); ! 3381: elts = TREE_CHAIN (elts); ! 3382: } ! 3383: ! 3384: if (obey_regdecls) ! 3385: use_variable (DECL_RTL (base)); ! 3386: } ! 3387: else ! 3388: { ! 3389: tree itype; ! 3390: ! 3391: iterator = get_temp_regvar (integer_type_node, maxindex); ! 3392: ! 3393: init_by_default: ! 3394: ! 3395: /* If initializing one array from another, ! 3396: initialize element by element. */ ! 3397: if (from_array) ! 3398: { ! 3399: /* We rely upon the below calls the do argument checking */ ! 3400: if (decl == NULL_TREE) ! 3401: { ! 3402: sorry ("initialization of array from dissimilar array type"); ! 3403: return error_mark_node; ! 3404: } ! 3405: if (init) ! 3406: { ! 3407: base2 = default_conversion (init); ! 3408: itype = TREE_TYPE (base2); ! 3409: base2 = get_temp_regvar (itype, base2); ! 3410: itype = TREE_TYPE (itype); ! 3411: } ! 3412: else if (TYPE_LANG_SPECIFIC (type) ! 3413: && TYPE_NEEDS_CONSTRUCTING (type) ! 3414: && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) ! 3415: { ! 3416: error ("initializer ends prematurely"); ! 3417: return error_mark_node; ! 3418: } ! 3419: } ! 3420: ! 3421: expand_start_cond (build (GE_EXPR, integer_type_node, ! 3422: iterator, integer_zero_node), 0); ! 3423: expand_start_loop_continue_elsewhere (1); ! 3424: ! 3425: if (from_array) ! 3426: { ! 3427: tree to = build1 (INDIRECT_REF, type, base); ! 3428: tree from; ! 3429: ! 3430: if (base2) ! 3431: from = build1 (INDIRECT_REF, itype, base2); ! 3432: else ! 3433: from = NULL_TREE; ! 3434: ! 3435: if (from_array == 2) ! 3436: expand_expr_stmt (build_modify_expr (to, NOP_EXPR, from)); ! 3437: else if (TYPE_NEEDS_CONSTRUCTING (type)) ! 3438: expand_aggr_init (to, from, 0); ! 3439: else if (from) ! 3440: expand_assignment (to, from, 0, 0); ! 3441: else ! 3442: my_friendly_abort (57); ! 3443: } ! 3444: else if (TREE_CODE (type) == ARRAY_TYPE) ! 3445: { ! 3446: if (init != 0) ! 3447: sorry ("cannot initialize multi-dimensional array with initializer"); ! 3448: expand_vec_init (decl, build1 (NOP_EXPR, TYPE_POINTER_TO (TREE_TYPE (type)), base), ! 3449: array_type_nelts (type), 0, 0); ! 3450: } ! 3451: else ! 3452: expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0); ! 3453: ! 3454: expand_assignment (base, ! 3455: build (PLUS_EXPR, TYPE_POINTER_TO (type), base, size), ! 3456: 0, 0); ! 3457: if (base2) ! 3458: expand_assignment (base2, ! 3459: build (PLUS_EXPR, TYPE_POINTER_TO (type), base2, size), 0, 0); ! 3460: expand_loop_continue_here (); ! 3461: expand_exit_loop_if_false (0, build (NE_EXPR, integer_type_node, ! 3462: build (PREDECREMENT_EXPR, integer_type_node, iterator, integer_one_node), minus_one)); ! 3463: ! 3464: if (obey_regdecls) ! 3465: { ! 3466: use_variable (DECL_RTL (base)); ! 3467: if (base2) ! 3468: use_variable (DECL_RTL (base2)); ! 3469: } ! 3470: expand_end_loop (); ! 3471: expand_end_cond (); ! 3472: if (obey_regdecls) ! 3473: use_variable (DECL_RTL (iterator)); ! 3474: } ! 3475: done_init: ! 3476: ! 3477: if (obey_regdecls) ! 3478: use_variable (DECL_RTL (rval)); ! 3479: return rval; ! 3480: } ! 3481: ! 3482: /* Free up storage of type TYPE, at address ADDR. ! 3483: ! 3484: TYPE is a POINTER_TYPE and can be ptr_type_node for no special type ! 3485: of pointer. ! 3486: ! 3487: VIRTUAL_SIZE is the amount of storage that was allocated, and is ! 3488: used as the second argument to operator delete. It can include ! 3489: things like padding and magic size cookies. It has virtual in it, ! 3490: because if you have a base pointer and you delete through a virtual ! 3491: destructor, it should be the size of the dynamic object, not the ! 3492: static object, see Free Store 12.5 ANSI C++ WP. ! 3493: ! 3494: This does not call any destructors. */ ! 3495: tree ! 3496: build_x_delete (type, addr, which_delete, virtual_size) ! 3497: tree type, addr; ! 3498: int which_delete; ! 3499: tree virtual_size; ! 3500: { ! 3501: int use_global_delete = which_delete & 1; ! 3502: int use_vec_delete = !!(which_delete & 2); ! 3503: tree rval; ! 3504: enum tree_code code = use_vec_delete ? VEC_DELETE_EXPR : DELETE_EXPR; ! 3505: ! 3506: if (! use_global_delete && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) ! 3507: && (TYPE_GETS_DELETE (TREE_TYPE (type)) & (1 << use_vec_delete))) ! 3508: rval = build_opfncall (code, LOOKUP_NORMAL, addr, virtual_size, NULL_TREE); ! 3509: else ! 3510: rval = build_builtin_call (void_type_node, use_vec_delete ? BIVD : BID, ! 3511: build_tree_list (NULL_TREE, addr)); ! 3512: return rval; ! 3513: } ! 3514: ! 3515: /* Generate a call to a destructor. TYPE is the type to cast ADDR to. ! 3516: ADDR is an expression which yields the store to be destroyed. ! 3517: AUTO_DELETE is nonzero if a call to DELETE should be made or not. ! 3518: If in the program, (AUTO_DELETE & 2) is non-zero, we tear down the ! 3519: virtual baseclasses. ! 3520: If in the program, (AUTO_DELETE & 1) is non-zero, then we deallocate. ! 3521: ! 3522: FLAGS is the logical disjunction of zero or more LOOKUP_ ! 3523: flags. See cp-tree.h for more info. ! 3524: ! 3525: This function does not delete an object's virtual base classes. */ ! 3526: tree ! 3527: build_delete (type, addr, auto_delete, flags, use_global_delete) ! 3528: tree type, addr; ! 3529: tree auto_delete; ! 3530: int flags; ! 3531: int use_global_delete; ! 3532: { ! 3533: tree function, parms; ! 3534: tree member; ! 3535: tree expr; ! 3536: tree ref; ! 3537: int ptr; ! 3538: ! 3539: if (addr == error_mark_node) ! 3540: return error_mark_node; ! 3541: ! 3542: /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type ! 3543: set to `error_mark_node' before it gets properly cleaned up. */ ! 3544: if (type == error_mark_node) ! 3545: return error_mark_node; ! 3546: ! 3547: type = TYPE_MAIN_VARIANT (type); ! 3548: ! 3549: if (TREE_CODE (type) == POINTER_TYPE) ! 3550: { ! 3551: type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); ! 3552: if (TYPE_SIZE (type) == 0) ! 3553: { ! 3554: incomplete_type_error (0, type); ! 3555: return error_mark_node; ! 3556: } ! 3557: if (TREE_CODE (type) == ARRAY_TYPE) ! 3558: goto handle_array; ! 3559: if (! IS_AGGR_TYPE (type)) ! 3560: { ! 3561: /* Call the builtin operator delete. */ ! 3562: return build_builtin_call (void_type_node, BID, ! 3563: build_tree_list (NULL_TREE, addr)); ! 3564: } ! 3565: if (TREE_SIDE_EFFECTS (addr)) ! 3566: addr = save_expr (addr); ! 3567: ! 3568: /* throw away const and volatile on target type of addr */ ! 3569: addr = convert_force (build_pointer_type (type), addr); ! 3570: ref = build_indirect_ref (addr, NULL_PTR); ! 3571: ptr = 1; ! 3572: } ! 3573: else if (TREE_CODE (type) == ARRAY_TYPE) ! 3574: { ! 3575: handle_array: ! 3576: if (TREE_SIDE_EFFECTS (addr)) ! 3577: addr = save_expr (addr); ! 3578: return build_vec_delete (addr, array_type_nelts (type), ! 3579: c_sizeof_nowarn (TREE_TYPE (type)), ! 3580: auto_delete, integer_two_node, ! 3581: use_global_delete); ! 3582: } ! 3583: else ! 3584: { ! 3585: /* Don't check PROTECT here; leave that decision to the ! 3586: destructor. If the destructor is accessible, call it, ! 3587: else report error. */ ! 3588: addr = build_unary_op (ADDR_EXPR, addr, 0); ! 3589: if (TREE_SIDE_EFFECTS (addr)) ! 3590: addr = save_expr (addr); ! 3591: ! 3592: if (TREE_CONSTANT (addr)) ! 3593: addr = convert_pointer_to (type, addr); ! 3594: else ! 3595: addr = convert_force (build_pointer_type (type), addr); ! 3596: ! 3597: if (TREE_CODE (addr) == NOP_EXPR ! 3598: && TREE_OPERAND (addr, 0) == current_class_decl) ! 3599: ref = C_C_D; ! 3600: else ! 3601: ref = build_indirect_ref (addr, NULL_PTR); ! 3602: ptr = 0; ! 3603: } ! 3604: ! 3605: my_friendly_assert (IS_AGGR_TYPE (type), 220); ! 3606: ! 3607: if (! TYPE_NEEDS_DESTRUCTOR (type)) ! 3608: { ! 3609: if (auto_delete == integer_zero_node) ! 3610: return void_zero_node; ! 3611: ! 3612: /* Pass the size of the object down to the operator delete() in ! 3613: addition to the ADDR. */ ! 3614: if (TYPE_GETS_REG_DELETE (type) && !use_global_delete) ! 3615: { ! 3616: tree virtual_size = c_sizeof_nowarn (type); ! 3617: return build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr, ! 3618: virtual_size, NULL_TREE); ! 3619: } ! 3620: ! 3621: /* Call the builtin operator delete. */ ! 3622: return build_builtin_call (void_type_node, BID, ! 3623: build_tree_list (NULL_TREE, addr)); ! 3624: } ! 3625: parms = build_tree_list (NULL_TREE, addr); ! 3626: ! 3627: /* Below, we will reverse the order in which these calls are made. ! 3628: If we have a destructor, then that destructor will take care ! 3629: of the base classes; otherwise, we must do that here. */ ! 3630: if (TYPE_HAS_DESTRUCTOR (type)) ! 3631: { ! 3632: tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0)); ! 3633: tree basetypes = TYPE_BINFO (type); ! 3634: tree passed_auto_delete; ! 3635: tree do_delete = NULL_TREE; ! 3636: ! 3637: if (use_global_delete) ! 3638: { ! 3639: tree cond = fold (build (BIT_AND_EXPR, integer_type_node, ! 3640: auto_delete, integer_one_node)); ! 3641: tree call = build_builtin_call ! 3642: (void_type_node, BID, build_tree_list (NULL_TREE, addr)); ! 3643: ! 3644: cond = fold (build (COND_EXPR, void_type_node, cond, ! 3645: call, void_zero_node)); ! 3646: if (cond != void_zero_node) ! 3647: do_delete = cond; ! 3648: ! 3649: passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node, ! 3650: auto_delete, integer_two_node)); ! 3651: } ! 3652: else ! 3653: passed_auto_delete = auto_delete; ! 3654: ! 3655: if (flags & LOOKUP_PROTECT) ! 3656: { ! 3657: enum access_type access = compute_access (basetypes, dtor); ! 3658: ! 3659: if (access == access_private) ! 3660: { ! 3661: if (flags & LOOKUP_COMPLAIN) ! 3662: cp_error ("destructor for type `%T' is private in this scope", type); ! 3663: return error_mark_node; ! 3664: } ! 3665: else if (access == access_protected) ! 3666: { ! 3667: if (flags & LOOKUP_COMPLAIN) ! 3668: cp_error ("destructor for type `%T' is protected in this scope", type); ! 3669: return error_mark_node; ! 3670: } ! 3671: } ! 3672: ! 3673: /* Once we are in a destructor, try not going through ! 3674: the virtual function table to find the next destructor. */ ! 3675: if (DECL_VINDEX (dtor) ! 3676: && ! (flags & LOOKUP_NONVIRTUAL) ! 3677: && TREE_CODE (auto_delete) != PARM_DECL ! 3678: && (ptr == 1 || ! resolves_to_fixed_type_p (ref, 0))) ! 3679: { ! 3680: tree binfo, basetype; ! 3681: /* The code below is probably all broken. See call.c for the ! 3682: complete right way to do this. this offsets may not be right ! 3683: in the below. (mrs) */ ! 3684: /* This destructor must be called via virtual function table. */ ! 3685: dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (DECL_CONTEXT (dtor)), 0); ! 3686: basetype = DECL_CLASS_CONTEXT (dtor); ! 3687: binfo = get_binfo (basetype, ! 3688: TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))), ! 3689: 0); ! 3690: expr = convert_pointer_to_real (binfo, TREE_VALUE (parms)); ! 3691: if (expr != TREE_VALUE (parms)) ! 3692: { ! 3693: expr = fold (expr); ! 3694: ref = build_indirect_ref (expr, NULL_PTR); ! 3695: TREE_VALUE (parms) = expr; ! 3696: } ! 3697: function = build_vfn_ref (&TREE_VALUE (parms), ref, DECL_VINDEX (dtor)); ! 3698: if (function == error_mark_node) ! 3699: return error_mark_node; ! 3700: TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor)); ! 3701: TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete); ! 3702: expr = build_function_call (function, parms); ! 3703: if (do_delete) ! 3704: expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete); ! 3705: if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0) ! 3706: { ! 3707: /* Handle the case where a virtual destructor is ! 3708: being called on an item that is 0. ! 3709: ! 3710: @@ Does this really need to be done? */ ! 3711: tree ifexp = build_binary_op(NE_EXPR, addr, integer_zero_node,1); ! 3712: #if 0 ! 3713: if (TREE_CODE (ref) == VAR_DECL ! 3714: || TREE_CODE (ref) == COMPONENT_REF) ! 3715: warning ("losing in build_delete"); ! 3716: #endif ! 3717: expr = build (COND_EXPR, void_type_node, ! 3718: ifexp, expr, void_zero_node); ! 3719: } ! 3720: } ! 3721: else ! 3722: { ! 3723: tree ifexp; ! 3724: ! 3725: if ((flags & LOOKUP_DESTRUCTOR) ! 3726: || TREE_CODE (ref) == VAR_DECL ! 3727: || TREE_CODE (ref) == PARM_DECL ! 3728: || TREE_CODE (ref) == COMPONENT_REF ! 3729: || TREE_CODE (ref) == ARRAY_REF) ! 3730: /* These can't be 0. */ ! 3731: ifexp = integer_one_node; ! 3732: else ! 3733: /* Handle the case where a non-virtual destructor is ! 3734: being called on an item that is 0. */ ! 3735: ifexp = build_binary_op (NE_EXPR, addr, integer_zero_node, 1); ! 3736: ! 3737: /* Used to mean that this destructor was known to be empty, ! 3738: but that's now obsolete. */ ! 3739: my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221); ! 3740: ! 3741: TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete); ! 3742: expr = build_function_call (dtor, parms); ! 3743: if (do_delete) ! 3744: expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete); ! 3745: ! 3746: if (ifexp != integer_one_node) ! 3747: expr = build (COND_EXPR, void_type_node, ! 3748: ifexp, expr, void_zero_node); ! 3749: } ! 3750: return expr; ! 3751: } ! 3752: else ! 3753: { ! 3754: /* This can get visibilities wrong. */ ! 3755: tree binfos = BINFO_BASETYPES (TYPE_BINFO (type)); ! 3756: int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; ! 3757: tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE; ! 3758: tree exprstmt = NULL_TREE; ! 3759: tree parent_auto_delete = auto_delete; ! 3760: tree cond; ! 3761: ! 3762: /* If this type does not have a destructor, but does have ! 3763: operator delete, call the parent parent destructor (if any), ! 3764: but let this node do the deleting. Otherwise, it is ok ! 3765: to let the parent destructor do the deleting. */ ! 3766: if (TYPE_GETS_REG_DELETE (type) && !use_global_delete) ! 3767: { ! 3768: parent_auto_delete = integer_zero_node; ! 3769: if (auto_delete == integer_zero_node) ! 3770: cond = NULL_TREE; ! 3771: else ! 3772: { ! 3773: tree virtual_size; ! 3774: ! 3775: /* This is probably wrong. It should be the size of the ! 3776: virtual object being deleted. */ ! 3777: virtual_size = c_sizeof_nowarn (type); ! 3778: ! 3779: expr = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr, ! 3780: virtual_size, NULL_TREE); ! 3781: if (expr == error_mark_node) ! 3782: return error_mark_node; ! 3783: if (auto_delete != integer_one_node) ! 3784: cond = build (COND_EXPR, void_type_node, ! 3785: build (BIT_AND_EXPR, integer_type_node, ! 3786: auto_delete, integer_one_node), ! 3787: expr, void_zero_node); ! 3788: else ! 3789: cond = expr; ! 3790: } ! 3791: } ! 3792: else if (base_binfo == NULL_TREE ! 3793: || (TREE_VIA_VIRTUAL (base_binfo) == 0 ! 3794: && ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))) ! 3795: { ! 3796: tree virtual_size; ! 3797: ! 3798: /* This is probably wrong. It should be the size of the virtual ! 3799: object being deleted. */ ! 3800: virtual_size = c_sizeof_nowarn (type); ! 3801: ! 3802: cond = build (COND_EXPR, void_type_node, ! 3803: build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node), ! 3804: build_builtin_call (void_type_node, BID, ! 3805: build_tree_list (NULL_TREE, addr)), ! 3806: void_zero_node); ! 3807: } ! 3808: else ! 3809: cond = NULL_TREE; ! 3810: ! 3811: if (cond) ! 3812: exprstmt = build_tree_list (NULL_TREE, cond); ! 3813: ! 3814: if (base_binfo ! 3815: && ! TREE_VIA_VIRTUAL (base_binfo) ! 3816: && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) ! 3817: { ! 3818: tree this_auto_delete; ! 3819: ! 3820: if (BINFO_OFFSET_ZEROP (base_binfo)) ! 3821: this_auto_delete = parent_auto_delete; ! 3822: else ! 3823: this_auto_delete = integer_zero_node; ! 3824: ! 3825: expr = build_delete (TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), addr, ! 3826: this_auto_delete, flags, 0); ! 3827: exprstmt = tree_cons (NULL_TREE, expr, exprstmt); ! 3828: } ! 3829: ! 3830: /* Take care of the remaining baseclasses. */ ! 3831: for (i = 1; i < n_baseclasses; i++) ! 3832: { ! 3833: base_binfo = TREE_VEC_ELT (binfos, i); ! 3834: if (! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)) ! 3835: || TREE_VIA_VIRTUAL (base_binfo)) ! 3836: continue; ! 3837: ! 3838: /* May be zero offset if other baseclasses are virtual. */ ! 3839: expr = fold (build (PLUS_EXPR, TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), ! 3840: addr, BINFO_OFFSET (base_binfo))); ! 3841: ! 3842: expr = build_delete (TYPE_POINTER_TO (BINFO_TYPE (base_binfo)), expr, ! 3843: integer_zero_node, ! 3844: flags, 0); ! 3845: ! 3846: exprstmt = tree_cons (NULL_TREE, expr, exprstmt); ! 3847: } ! 3848: ! 3849: for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member)) ! 3850: { ! 3851: if (TREE_CODE (member) != FIELD_DECL) ! 3852: continue; ! 3853: if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (member))) ! 3854: { ! 3855: tree this_member = build_component_ref (ref, DECL_NAME (member), 0, 0); ! 3856: tree this_type = TREE_TYPE (member); ! 3857: expr = build_delete (this_type, this_member, integer_two_node, flags, 0); ! 3858: exprstmt = tree_cons (NULL_TREE, expr, exprstmt); ! 3859: } ! 3860: } ! 3861: ! 3862: if (exprstmt) ! 3863: return build_compound_expr (exprstmt); ! 3864: /* Virtual base classes make this function do nothing. */ ! 3865: return void_zero_node; ! 3866: } ! 3867: } ! 3868: ! 3869: /* For type TYPE, delete the virtual baseclass objects of DECL. */ ! 3870: ! 3871: tree ! 3872: build_vbase_delete (type, decl) ! 3873: tree type, decl; ! 3874: { ! 3875: tree vbases = CLASSTYPE_VBASECLASSES (type); ! 3876: tree result = NULL_TREE; ! 3877: tree addr = build_unary_op (ADDR_EXPR, decl, 0); ! 3878: ! 3879: my_friendly_assert (addr != error_mark_node, 222); ! 3880: ! 3881: while (vbases) ! 3882: { ! 3883: tree this_addr = convert_force (TYPE_POINTER_TO (BINFO_TYPE (vbases)), ! 3884: addr); ! 3885: result = tree_cons (NULL_TREE, ! 3886: build_delete (TREE_TYPE (this_addr), this_addr, ! 3887: integer_zero_node, ! 3888: LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0), ! 3889: result); ! 3890: vbases = TREE_CHAIN (vbases); ! 3891: } ! 3892: return build_compound_expr (nreverse (result)); ! 3893: } ! 3894: ! 3895: /* Build a C++ vector delete expression. ! 3896: MAXINDEX is the number of elements to be deleted. ! 3897: ELT_SIZE is the nominal size of each element in the vector. ! 3898: BASE is the expression that should yield the store to be deleted. ! 3899: This function expands (or synthesizes) these calls itself. ! 3900: AUTO_DELETE_VEC says whether the container (vector) should be deallocated. ! 3901: AUTO_DELETE say whether each item in the container should be deallocated. ! 3902: ! 3903: This also calls delete for virtual baseclasses of elements of the vector. ! 3904: ! 3905: Update: MAXINDEX is no longer needed. The size can be extracted from the ! 3906: start of the vector for pointers, and from the type for arrays. We still ! 3907: use MAXINDEX for arrays because it happens to already have one of the ! 3908: values we'd have to extract. (We could use MAXINDEX with pointers to ! 3909: confirm the size, and trap if the numbers differ; not clear that it'd ! 3910: be worth bothering.) */ ! 3911: tree ! 3912: build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete, ! 3913: use_global_delete) ! 3914: tree base, maxindex, elt_size; ! 3915: tree auto_delete_vec, auto_delete; ! 3916: int use_global_delete; ! 3917: { ! 3918: tree ptype = TREE_TYPE (base); ! 3919: tree type; ! 3920: tree virtual_size; ! 3921: /* Temporary variables used by the loop. */ ! 3922: tree tbase, size_exp, tbase_init; ! 3923: ! 3924: /* This is the body of the loop that implements the deletion of a ! 3925: single element, and moves temp variables to next elements. */ ! 3926: tree body; ! 3927: ! 3928: /* This is the LOOP_EXPR that governs the deletion of the elements. */ ! 3929: tree loop; ! 3930: ! 3931: /* This is the thing that governs what to do after the loop has run. */ ! 3932: tree deallocate_expr = 0; ! 3933: ! 3934: /* This is the BIND_EXPR which holds the outermost iterator of the ! 3935: loop. It is convenient to set this variable up and test it before ! 3936: executing any other code in the loop. ! 3937: This is also the containing expression returned by this function. */ ! 3938: tree controller = NULL_TREE; ! 3939: ! 3940: /* This is the BLOCK to record the symbol binding for debugging. */ ! 3941: tree block; ! 3942: ! 3943: base = stabilize_reference (base); ! 3944: ! 3945: /* Since we can use base many times, save_expr it. */ ! 3946: if (TREE_SIDE_EFFECTS (base)) ! 3947: base = save_expr (base); ! 3948: ! 3949: if (TREE_CODE (ptype) == POINTER_TYPE) ! 3950: { ! 3951: /* Step back one from start of vector, and read dimension. */ ! 3952: tree cookie_addr = build (MINUS_EXPR, TYPE_POINTER_TO (BI_header_type), ! 3953: base, BI_header_size); ! 3954: tree cookie = build_indirect_ref (cookie_addr, NULL_PTR); ! 3955: maxindex = build_component_ref (cookie, nc_nelts_field_id, 0, 0); ! 3956: do ! 3957: ptype = TREE_TYPE (ptype); ! 3958: while (TREE_CODE (ptype) == ARRAY_TYPE); ! 3959: } ! 3960: else if (TREE_CODE (ptype) == ARRAY_TYPE) ! 3961: { ! 3962: /* get the total number of things in the array, maxindex is a bad name */ ! 3963: maxindex = array_type_nelts_total (ptype); ! 3964: while (TREE_CODE (ptype) == ARRAY_TYPE) ! 3965: ptype = TREE_TYPE (ptype); ! 3966: base = build_unary_op (ADDR_EXPR, base, 1); ! 3967: } ! 3968: else ! 3969: { ! 3970: error ("type to vector delete is neither pointer or array type"); ! 3971: return error_mark_node; ! 3972: } ! 3973: type = ptype; ! 3974: ptype = TYPE_POINTER_TO (type); ! 3975: ! 3976: size_exp = size_in_bytes (type); ! 3977: ! 3978: if (! IS_AGGR_TYPE (type) || ! TYPE_NEEDS_DESTRUCTOR (type)) ! 3979: { ! 3980: loop = integer_zero_node; ! 3981: goto no_destructor; ! 3982: } ! 3983: ! 3984: /* The below is short by BI_header_size */ ! 3985: virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); ! 3986: ! 3987: tbase = build_decl (VAR_DECL, NULL_TREE, ptype); ! 3988: tbase_init = build_modify_expr (tbase, NOP_EXPR, ! 3989: fold (build (PLUS_EXPR, ptype, ! 3990: base, ! 3991: virtual_size))); ! 3992: DECL_REGISTER (tbase) = 1; ! 3993: controller = build (BIND_EXPR, void_type_node, tbase, 0, 0); ! 3994: TREE_SIDE_EFFECTS (controller) = 1; ! 3995: block = build_block (tbase, 0, 0, 0, 0); ! 3996: add_block_current_level (block); ! 3997: ! 3998: if (auto_delete != integer_zero_node ! 3999: && auto_delete != integer_two_node) ! 4000: { ! 4001: tree base_tbd = convert (ptype, ! 4002: build_binary_op (MINUS_EXPR, ! 4003: convert (ptr_type_node, base), ! 4004: BI_header_size, ! 4005: 1)); ! 4006: /* This is the real size */ ! 4007: virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); ! 4008: body = build_tree_list (NULL_TREE, ! 4009: build_x_delete (ptype, base_tbd, ! 4010: 2 | use_global_delete, ! 4011: virtual_size)); ! 4012: body = build (COND_EXPR, void_type_node, ! 4013: build (BIT_AND_EXPR, integer_type_node, ! 4014: auto_delete, integer_one_node), ! 4015: body, integer_zero_node); ! 4016: } ! 4017: else ! 4018: body = NULL_TREE; ! 4019: ! 4020: body = tree_cons (NULL_TREE, ! 4021: build_delete (ptype, tbase, auto_delete, ! 4022: LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1), ! 4023: body); ! 4024: ! 4025: body = tree_cons (NULL_TREE, ! 4026: build_modify_expr (tbase, NOP_EXPR, build (MINUS_EXPR, ptype, tbase, size_exp)), ! 4027: body); ! 4028: ! 4029: body = tree_cons (NULL_TREE, ! 4030: build (EXIT_EXPR, void_type_node, ! 4031: build (EQ_EXPR, integer_type_node, base, tbase)), ! 4032: body); ! 4033: ! 4034: loop = build (LOOP_EXPR, void_type_node, build_compound_expr (body)); ! 4035: ! 4036: loop = tree_cons (NULL_TREE, tbase_init, ! 4037: tree_cons (NULL_TREE, loop, NULL_TREE)); ! 4038: loop = build_compound_expr (loop); ! 4039: ! 4040: no_destructor: ! 4041: /* If the delete flag is one, or anything else with the low bit set, ! 4042: delete the storage. */ ! 4043: if (auto_delete_vec == integer_zero_node ! 4044: || auto_delete_vec == integer_two_node) ! 4045: deallocate_expr = integer_zero_node; ! 4046: else ! 4047: { ! 4048: tree base_tbd; ! 4049: ! 4050: /* The below is short by BI_header_size */ ! 4051: virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); ! 4052: ! 4053: if (! TYPE_VEC_NEW_USES_COOKIE (type)) ! 4054: /* no header */ ! 4055: base_tbd = base; ! 4056: else ! 4057: { ! 4058: base_tbd = convert (ptype, ! 4059: build_binary_op (MINUS_EXPR, ! 4060: convert (string_type_node, base), ! 4061: BI_header_size, ! 4062: 1)); ! 4063: /* True size with header. */ ! 4064: virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); ! 4065: } ! 4066: deallocate_expr = build_x_delete (ptype, base_tbd, ! 4067: 2 | use_global_delete, ! 4068: virtual_size); ! 4069: if (auto_delete_vec != integer_one_node) ! 4070: deallocate_expr = build (COND_EXPR, void_type_node, ! 4071: build (BIT_AND_EXPR, integer_type_node, ! 4072: auto_delete_vec, integer_one_node), ! 4073: deallocate_expr, integer_zero_node); ! 4074: } ! 4075: ! 4076: if (loop && deallocate_expr != integer_zero_node) ! 4077: { ! 4078: body = tree_cons (NULL_TREE, loop, ! 4079: tree_cons (NULL_TREE, deallocate_expr, NULL_TREE)); ! 4080: body = build_compound_expr (body); ! 4081: } ! 4082: else ! 4083: body = loop; ! 4084: ! 4085: /* Outermost wrapper: If pointer is null, punt. */ ! 4086: body = build (COND_EXPR, void_type_node, ! 4087: build (NE_EXPR, integer_type_node, base, integer_zero_node), ! 4088: body, integer_zero_node); ! 4089: body = build1 (NOP_EXPR, void_type_node, body); ! 4090: ! 4091: if (controller) ! 4092: { ! 4093: TREE_OPERAND (controller, 1) = body; ! 4094: return controller; ! 4095: } ! 4096: else ! 4097: return convert (void_type_node, body); ! 4098: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.