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