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