00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "system.h"
00030 #include "coretypes.h"
00031 #include "tm.h"
00032 #include "tree.h"
00033 #include "rtl.h"
00034 #include "expr.h"
00035 #include "cp-tree.h"
00036 #include "flags.h"
00037 #include "output.h"
00038 #include "except.h"
00039 #include "toplev.h"
00040 #include "target.h"
00041
00042 static bool begin_init_stmts (tree *, tree *);
00043 static tree finish_init_stmts (bool, tree, tree);
00044 static void construct_virtual_base (tree, tree);
00045 static void expand_aggr_init_1 (tree, tree, tree, tree, int);
00046 static void expand_default_init (tree, tree, tree, tree, int);
00047 static tree build_vec_delete_1 (tree, tree, tree, special_function_kind, int);
00048 static void perform_member_init (tree, tree);
00049 static tree build_builtin_delete_call (tree);
00050 static int member_init_ok_or_else (tree, tree, tree);
00051 static void expand_virtual_init (tree, tree);
00052 static tree sort_mem_initializers (tree, tree);
00053 static tree initializing_context (tree);
00054 static void expand_cleanup_for_base (tree, tree);
00055 static tree get_temp_regvar (tree, tree);
00056 static tree dfs_initialize_vtbl_ptrs (tree, void *);
00057 static tree build_default_init (tree, tree);
00058 static tree build_new_1 (tree);
00059 static tree build_dtor_call (tree, special_function_kind, int);
00060 static tree build_field_list (tree, tree, int *);
00061 static tree build_vtbl_address (tree);
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 static bool
00073 begin_init_stmts (tree *stmt_expr_p, tree *compound_stmt_p)
00074 {
00075 bool is_global = !building_stmt_tree ();
00076
00077 *stmt_expr_p = begin_stmt_expr ();
00078 *compound_stmt_p = begin_compound_stmt (BCS_NO_SCOPE);
00079
00080 return is_global;
00081 }
00082
00083
00084
00085
00086 static tree
00087 finish_init_stmts (bool is_global, tree stmt_expr, tree compound_stmt)
00088 {
00089 finish_compound_stmt (compound_stmt);
00090
00091 stmt_expr = finish_stmt_expr (stmt_expr, true);
00092
00093 gcc_assert (!building_stmt_tree () == is_global);
00094
00095 return stmt_expr;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104 static tree
00105 dfs_initialize_vtbl_ptrs (tree binfo, void *data)
00106 {
00107 if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
00108 return dfs_skip_bases;
00109
00110 if (!BINFO_PRIMARY_P (binfo) || BINFO_VIRTUAL_P (binfo))
00111 {
00112 tree base_ptr = TREE_VALUE ((tree) data);
00113
00114 base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, 1);
00115
00116 expand_virtual_init (binfo, base_ptr);
00117 }
00118
00119 return NULL_TREE;
00120 }
00121
00122
00123
00124
00125 void
00126 initialize_vtbl_ptrs (tree addr)
00127 {
00128 tree list;
00129 tree type;
00130
00131 type = TREE_TYPE (TREE_TYPE (addr));
00132 list = build_tree_list (type, addr);
00133
00134
00135
00136
00137
00138 dfs_walk_once (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, NULL, list);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 tree
00153 build_zero_init (tree type, tree nelts, bool static_storage_p)
00154 {
00155 tree init = NULL_TREE;
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 gcc_assert (nelts == NULL_TREE || TREE_CODE (nelts) == INTEGER_CST);
00176
00177 if (type == error_mark_node)
00178 ;
00179 else if (static_storage_p && zero_init_p (type))
00180
00181
00182
00183
00184 ;
00185 else if (SCALAR_TYPE_P (type))
00186 init = convert (type, integer_zero_node);
00187 else if (CLASS_TYPE_P (type))
00188 {
00189 tree field;
00190 tree inits;
00191
00192
00193 init = build_constructor (type, NULL_TREE);
00194
00195 inits = NULL_TREE;
00196 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
00197 {
00198 if (TREE_CODE (field) != FIELD_DECL)
00199 continue;
00200
00201
00202
00203
00204
00205 if (static_storage_p && !zero_init_p (TREE_TYPE (field)))
00206 inits = tree_cons (field,
00207 build_zero_init (TREE_TYPE (field),
00208 NULL_TREE,
00209 static_storage_p),
00210 inits);
00211
00212
00213 if (TREE_CODE (type) == UNION_TYPE)
00214 break;
00215 }
00216 CONSTRUCTOR_ELTS (init) = nreverse (inits);
00217 }
00218 else if (TREE_CODE (type) == ARRAY_TYPE)
00219 {
00220 tree max_index;
00221 tree inits;
00222
00223
00224 init = build_constructor (type, NULL_TREE);
00225
00226 inits = NULL_TREE;
00227 if (nelts)
00228 max_index = fold (build2 (MINUS_EXPR, TREE_TYPE (nelts),
00229 nelts, integer_one_node));
00230 else
00231 max_index = array_type_nelts (type);
00232 gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
00233
00234
00235
00236 if (!tree_int_cst_equal (max_index, integer_minus_one_node))
00237 {
00238 tree elt_init = build_zero_init (TREE_TYPE (type),
00239 NULL_TREE,
00240 static_storage_p);
00241 tree range;
00242
00243
00244 if (tree_int_cst_equal (size_zero_node, max_index))
00245 range = size_zero_node;
00246 else
00247 range = build2 (RANGE_EXPR, sizetype, size_zero_node, max_index);
00248
00249 inits = tree_cons (range, elt_init, inits);
00250 }
00251
00252 CONSTRUCTOR_ELTS (init) = nreverse (inits);
00253 }
00254 else
00255 gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
00256
00257
00258 if (init)
00259 {
00260 TREE_CONSTANT (init) = 1;
00261 TREE_INVARIANT (init) = 1;
00262 }
00263
00264 return init;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274 static tree
00275 build_default_init (tree type, tree nelts)
00276 {
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 if (TYPE_NEEDS_CONSTRUCTING (type)
00305 || (nelts && TREE_CODE (nelts) != INTEGER_CST))
00306 return NULL_TREE;
00307
00308
00309
00310 return build_zero_init (type, nelts, false);
00311 }
00312
00313
00314
00315
00316
00317 static void
00318 perform_member_init (tree member, tree init)
00319 {
00320 tree decl;
00321 tree type = TREE_TYPE (member);
00322 bool explicit;
00323
00324 explicit = (init != NULL_TREE);
00325
00326
00327
00328 if (warn_ecpp && !explicit && TREE_CODE (type) != ARRAY_TYPE)
00329 warning ("%J%qD should be initialized in the member initialization "
00330 "list", current_function_decl, member);
00331
00332 if (init == void_type_node)
00333 init = NULL_TREE;
00334
00335
00336 decl = build_class_member_access_expr (current_class_ref, member,
00337 NULL_TREE,
00338 true);
00339 if (decl == error_mark_node)
00340 return;
00341
00342
00343
00344
00345 if (ANON_AGGR_TYPE_P (type))
00346 {
00347 if (init)
00348 {
00349 init = build2 (INIT_EXPR, type, decl, TREE_VALUE (init));
00350 finish_expr_stmt (init);
00351 }
00352 }
00353 else if (TYPE_NEEDS_CONSTRUCTING (type))
00354 {
00355 if (explicit
00356 && TREE_CODE (type) == ARRAY_TYPE
00357 && init != NULL_TREE
00358 && TREE_CHAIN (init) == NULL_TREE
00359 && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE)
00360 {
00361
00362 finish_expr_stmt (build_vec_init (decl, NULL_TREE, TREE_VALUE (init),
00363 false,
00364 1));
00365 }
00366 else
00367 finish_expr_stmt (build_aggr_init (decl, init, 0));
00368 }
00369 else
00370 {
00371 if (init == NULL_TREE)
00372 {
00373 if (explicit)
00374 {
00375 init = build_default_init (type, NULL_TREE);
00376 if (TREE_CODE (type) == REFERENCE_TYPE)
00377 warning ("%Jdefault-initialization of %q#D, "
00378 "which has reference type",
00379 current_function_decl, member);
00380 }
00381
00382 else if (TREE_CODE (type) == REFERENCE_TYPE)
00383 pedwarn ("%Juninitialized reference member %qD",
00384 current_function_decl, member);
00385 else if (CP_TYPE_CONST_P (type))
00386 pedwarn ("%Juninitialized member %qD with %<const%> type %qT",
00387 current_function_decl, member, type);
00388 }
00389 else if (TREE_CODE (init) == TREE_LIST)
00390
00391
00392 init = build_x_compound_expr_from_list (init, "member initializer");
00393
00394 if (init)
00395 finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
00396 }
00397
00398 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
00399 {
00400 tree expr;
00401
00402 expr = build_class_member_access_expr (current_class_ref, member,
00403 NULL_TREE,
00404 false);
00405 expr = build_delete (type, expr, sfk_complete_destructor,
00406 LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
00407
00408 if (expr != error_mark_node)
00409 finish_eh_cleanup (expr);
00410 }
00411 }
00412
00413
00414
00415
00416 static tree
00417 build_field_list (tree t, tree list, int *uses_unions_p)
00418 {
00419 tree fields;
00420
00421 *uses_unions_p = 0;
00422
00423
00424 if (TREE_CODE (t) == UNION_TYPE)
00425 *uses_unions_p = 1;
00426
00427 for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields))
00428 {
00429
00430 if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
00431 continue;
00432
00433
00434 if (TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
00435 *uses_unions_p = 1;
00436
00437
00438
00439
00440 if (ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
00441 {
00442
00443
00444 list = tree_cons (fields, NULL_TREE, list);
00445
00446 list = build_field_list (TREE_TYPE (fields), list,
00447 uses_unions_p);
00448 }
00449
00450 else if (DECL_NAME (fields))
00451 list = tree_cons (fields, NULL_TREE, list);
00452 }
00453
00454 return list;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 static tree
00466 sort_mem_initializers (tree t, tree mem_inits)
00467 {
00468 tree init;
00469 tree base, binfo, base_binfo;
00470 tree sorted_inits;
00471 tree next_subobject;
00472 VEC (tree) *vbases;
00473 int i;
00474 int uses_unions_p;
00475
00476
00477
00478
00479
00480 sorted_inits = NULL_TREE;
00481
00482
00483 for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
00484 VEC_iterate (tree, vbases, i, base); i++)
00485 sorted_inits = tree_cons (base, NULL_TREE, sorted_inits);
00486
00487
00488 for (binfo = TYPE_BINFO (t), i = 0;
00489 BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
00490 if (!BINFO_VIRTUAL_P (base_binfo))
00491 sorted_inits = tree_cons (base_binfo, NULL_TREE, sorted_inits);
00492
00493
00494 sorted_inits = build_field_list (t, sorted_inits, &uses_unions_p);
00495
00496
00497 sorted_inits = nreverse (sorted_inits);
00498
00499
00500
00501
00502
00503 next_subobject = sorted_inits;
00504
00505
00506
00507 for (init = mem_inits; init; init = TREE_CHAIN (init))
00508 {
00509 tree subobject;
00510 tree subobject_init;
00511
00512 subobject = TREE_PURPOSE (init);
00513
00514
00515
00516
00517 for (subobject_init = next_subobject;
00518 subobject_init;
00519 subobject_init = TREE_CHAIN (subobject_init))
00520 if (TREE_PURPOSE (subobject_init) == subobject)
00521 break;
00522
00523
00524
00525
00526 if (warn_reorder && !subobject_init)
00527 {
00528 if (TREE_CODE (TREE_PURPOSE (next_subobject)) == FIELD_DECL)
00529 cp_warning_at ("%qD will be initialized after",
00530 TREE_PURPOSE (next_subobject));
00531 else
00532 warning ("base %qT will be initialized after",
00533 TREE_PURPOSE (next_subobject));
00534 if (TREE_CODE (subobject) == FIELD_DECL)
00535 cp_warning_at (" %q#D", subobject);
00536 else
00537 warning (" base %qT", subobject);
00538 warning ("%J when initialized here", current_function_decl);
00539 }
00540
00541
00542 if (!subobject_init)
00543 {
00544 subobject_init = sorted_inits;
00545 while (TREE_PURPOSE (subobject_init) != subobject)
00546 subobject_init = TREE_CHAIN (subobject_init);
00547 }
00548
00549
00550
00551 if (TREE_VALUE (subobject_init))
00552 {
00553 if (TREE_CODE (subobject) == FIELD_DECL)
00554 error ("%Jmultiple initializations given for %qD",
00555 current_function_decl, subobject);
00556 else
00557 error ("%Jmultiple initializations given for base %qT",
00558 current_function_decl, subobject);
00559 }
00560
00561
00562 TREE_VALUE (subobject_init) = TREE_VALUE (init);
00563 next_subobject = subobject_init;
00564 }
00565
00566
00567
00568
00569
00570
00571 if (uses_unions_p)
00572 {
00573 tree last_field = NULL_TREE;
00574 for (init = sorted_inits; init; init = TREE_CHAIN (init))
00575 {
00576 tree field;
00577 tree field_type;
00578 int done;
00579
00580
00581 if (!TREE_VALUE (init)
00582 || TREE_CODE (TREE_PURPOSE (init)) != FIELD_DECL)
00583 continue;
00584
00585
00586 field = TREE_PURPOSE (init);
00587 for (field_type = DECL_CONTEXT (field);
00588 !same_type_p (field_type, t);
00589 field_type = TYPE_CONTEXT (field_type))
00590 if (TREE_CODE (field_type) == UNION_TYPE)
00591 break;
00592
00593 if (TREE_CODE (field_type) != UNION_TYPE)
00594 continue;
00595
00596
00597
00598 if (!last_field)
00599 {
00600 last_field = field;
00601 continue;
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 field_type = DECL_CONTEXT (field);
00613 done = 0;
00614 do
00615 {
00616 tree last_field_type;
00617
00618 last_field_type = DECL_CONTEXT (last_field);
00619 while (1)
00620 {
00621 if (same_type_p (last_field_type, field_type))
00622 {
00623 if (TREE_CODE (field_type) == UNION_TYPE)
00624 error ("%Jinitializations for multiple members of %qT",
00625 current_function_decl, last_field_type);
00626 done = 1;
00627 break;
00628 }
00629
00630 if (same_type_p (last_field_type, t))
00631 break;
00632
00633 last_field_type = TYPE_CONTEXT (last_field_type);
00634 }
00635
00636
00637
00638 if (same_type_p (field_type, t))
00639 break;
00640
00641 field_type = TYPE_CONTEXT (field_type);
00642 }
00643 while (!done);
00644
00645 last_field = field;
00646 }
00647 }
00648
00649 return sorted_inits;
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659 void
00660 emit_mem_initializers (tree mem_inits)
00661 {
00662
00663
00664 if (!COMPLETE_TYPE_P (current_class_type))
00665 return;
00666
00667
00668
00669 mem_inits = sort_mem_initializers (current_class_type, mem_inits);
00670
00671 in_base_initializer = 1;
00672
00673
00674 while (mem_inits
00675 && TREE_CODE (TREE_PURPOSE (mem_inits)) != FIELD_DECL)
00676 {
00677 tree subobject = TREE_PURPOSE (mem_inits);
00678 tree arguments = TREE_VALUE (mem_inits);
00679
00680
00681
00682
00683 if (extra_warnings && !arguments
00684 && DECL_COPY_CONSTRUCTOR_P (current_function_decl)
00685 && TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (subobject)))
00686 warning ("%Jbase class %q#T should be explicitly initialized in the "
00687 "copy constructor",
00688 current_function_decl, BINFO_TYPE (subobject));
00689
00690
00691
00692 if (arguments == void_type_node)
00693 arguments = NULL_TREE;
00694
00695
00696 if (BINFO_VIRTUAL_P (subobject))
00697 construct_virtual_base (subobject, arguments);
00698 else
00699 {
00700 tree base_addr;
00701
00702 base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
00703 subobject, 1);
00704 expand_aggr_init_1 (subobject, NULL_TREE,
00705 build_indirect_ref (base_addr, NULL),
00706 arguments,
00707 LOOKUP_NORMAL);
00708 expand_cleanup_for_base (subobject, NULL_TREE);
00709 }
00710
00711 mem_inits = TREE_CHAIN (mem_inits);
00712 }
00713 in_base_initializer = 0;
00714
00715
00716 initialize_vtbl_ptrs (current_class_ptr);
00717
00718
00719 while (mem_inits)
00720 {
00721 perform_member_init (TREE_PURPOSE (mem_inits),
00722 TREE_VALUE (mem_inits));
00723 mem_inits = TREE_CHAIN (mem_inits);
00724 }
00725 }
00726
00727
00728
00729
00730 static tree
00731 build_vtbl_address (tree binfo)
00732 {
00733 tree binfo_for = binfo;
00734 tree vtbl;
00735
00736 if (BINFO_VPTR_INDEX (binfo) && BINFO_VIRTUAL_P (binfo))
00737
00738
00739
00740
00741
00742 while (BINFO_PRIMARY_P (binfo_for))
00743 binfo_for = BINFO_INHERITANCE_CHAIN (binfo_for);
00744
00745
00746
00747 vtbl = get_vtbl_decl_for_binfo (binfo_for);
00748 assemble_external (vtbl);
00749 TREE_USED (vtbl) = 1;
00750
00751
00752 vtbl = unshare_expr (BINFO_VTABLE (binfo_for));
00753 if (TREE_CODE (vtbl) == VAR_DECL)
00754 vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
00755
00756 return vtbl;
00757 }
00758
00759
00760
00761
00762
00763
00764
00765 static void
00766 expand_virtual_init (tree binfo, tree decl)
00767 {
00768 tree vtbl, vtbl_ptr;
00769 tree vtt_index;
00770
00771
00772 vtbl = build_vtbl_address (binfo);
00773
00774
00775
00776 vtt_index = BINFO_VPTR_INDEX (binfo);
00777 if (vtt_index)
00778 {
00779 tree vtbl2;
00780 tree vtt_parm;
00781
00782
00783 vtt_parm = current_vtt_parm;
00784 vtbl2 = build2 (PLUS_EXPR,
00785 TREE_TYPE (vtt_parm),
00786 vtt_parm,
00787 vtt_index);
00788 vtbl2 = build_indirect_ref (vtbl2, NULL);
00789 vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
00790
00791
00792
00793
00794 vtbl = build3 (COND_EXPR,
00795 TREE_TYPE (vtbl),
00796 build2 (EQ_EXPR, boolean_type_node,
00797 current_in_charge_parm, integer_zero_node),
00798 vtbl2,
00799 vtbl);
00800 }
00801
00802
00803 vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, NULL),
00804 TREE_TYPE (binfo));
00805 gcc_assert (vtbl_ptr != error_mark_node);
00806
00807
00808 vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0);
00809 finish_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl));
00810 }
00811
00812
00813
00814
00815
00816
00817
00818 static void
00819 expand_cleanup_for_base (tree binfo, tree flag)
00820 {
00821 tree expr;
00822
00823 if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (binfo)))
00824 return;
00825
00826
00827 expr = build_special_member_call (current_class_ref,
00828 base_dtor_identifier,
00829 NULL_TREE,
00830 binfo,
00831 LOOKUP_NORMAL | LOOKUP_NONVIRTUAL);
00832 if (flag)
00833 expr = fold (build3 (COND_EXPR, void_type_node,
00834 c_common_truthvalue_conversion (flag),
00835 expr, integer_zero_node));
00836
00837 finish_eh_cleanup (expr);
00838 }
00839
00840
00841
00842
00843 static void
00844 construct_virtual_base (tree vbase, tree arguments)
00845 {
00846 tree inner_if_stmt;
00847 tree exp;
00848 tree flag;
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864 flag = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
00865 inner_if_stmt = begin_if_stmt ();
00866 finish_if_stmt_cond (flag, inner_if_stmt);
00867
00868
00869
00870
00871
00872 exp = convert_to_base_statically (current_class_ref, vbase);
00873
00874 expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
00875 LOOKUP_COMPLAIN);
00876 finish_then_clause (inner_if_stmt);
00877 finish_if_stmt (inner_if_stmt);
00878
00879 expand_cleanup_for_base (vbase, flag);
00880 }
00881
00882
00883
00884 static tree
00885 initializing_context (tree field)
00886 {
00887 tree t = DECL_CONTEXT (field);
00888
00889
00890
00891 while (t && ANON_AGGR_TYPE_P (t))
00892 t = TYPE_CONTEXT (t);
00893 return t;
00894 }
00895
00896
00897
00898
00899
00900
00901
00902
00903 static int
00904 member_init_ok_or_else (tree field, tree type, tree member_name)
00905 {
00906 if (field == error_mark_node)
00907 return 0;
00908 if (!field)
00909 {
00910 error ("class %qT does not have any field named %qD", type,
00911 member_name);
00912 return 0;
00913 }
00914 if (TREE_CODE (field) == VAR_DECL)
00915 {
00916 error ("%q#D is a static data member; it can only be "
00917 "initialized at its definition",
00918 field);
00919 return 0;
00920 }
00921 if (TREE_CODE (field) != FIELD_DECL)
00922 {
00923 error ("%q#D is not a non-static data member of %qT",
00924 field, type);
00925 return 0;
00926 }
00927 if (initializing_context (field) != type)
00928 {
00929 error ("class %qT does not have any field named %qD", type,
00930 member_name);
00931 return 0;
00932 }
00933
00934 return 1;
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 tree
00947 expand_member_init (tree name)
00948 {
00949 tree basetype;
00950 tree field;
00951
00952 if (!current_class_ref)
00953 return NULL_TREE;
00954
00955 if (!name)
00956 {
00957
00958
00959 switch (BINFO_N_BASE_BINFOS (TYPE_BINFO (current_class_type)))
00960 {
00961 case 0:
00962 error ("unnamed initializer for %qT, which has no base classes",
00963 current_class_type);
00964 return NULL_TREE;
00965 case 1:
00966 basetype = BINFO_TYPE
00967 (BINFO_BASE_BINFO (TYPE_BINFO (current_class_type), 0));
00968 break;
00969 default:
00970 error ("unnamed initializer for %qT, which uses multiple inheritance",
00971 current_class_type);
00972 return NULL_TREE;
00973 }
00974 }
00975 else if (TYPE_P (name))
00976 {
00977 basetype = TYPE_MAIN_VARIANT (name);
00978 name = TYPE_NAME (name);
00979 }
00980 else if (TREE_CODE (name) == TYPE_DECL)
00981 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
00982 else
00983 basetype = NULL_TREE;
00984
00985 if (basetype)
00986 {
00987 tree class_binfo;
00988 tree direct_binfo;
00989 tree virtual_binfo;
00990 int i;
00991
00992 if (current_template_parms)
00993 return basetype;
00994
00995 class_binfo = TYPE_BINFO (current_class_type);
00996 direct_binfo = NULL_TREE;
00997 virtual_binfo = NULL_TREE;
00998
00999
01000 for (i = 0; BINFO_BASE_ITERATE (class_binfo, i, direct_binfo); ++i)
01001 if (SAME_BINFO_TYPE_P (BINFO_TYPE (direct_binfo), basetype))
01002 break;
01003
01004
01005
01006 if (!direct_binfo || !BINFO_VIRTUAL_P (direct_binfo))
01007 virtual_binfo = binfo_for_vbase (basetype, current_class_type);
01008
01009
01010
01011
01012
01013
01014 if (direct_binfo && virtual_binfo)
01015 {
01016 error ("%qD is both a direct base and an indirect virtual base",
01017 basetype);
01018 return NULL_TREE;
01019 }
01020
01021 if (!direct_binfo && !virtual_binfo)
01022 {
01023 if (CLASSTYPE_VBASECLASSES (current_class_type))
01024 error ("type %qD is not a direct or virtual base of %qT",
01025 name, current_class_type);
01026 else
01027 error ("type %qD is not a direct base of %qT",
01028 name, current_class_type);
01029 return NULL_TREE;
01030 }
01031
01032 return direct_binfo ? direct_binfo : virtual_binfo;
01033 }
01034 else
01035 {
01036 if (TREE_CODE (name) == IDENTIFIER_NODE)
01037 field = lookup_field (current_class_type, name, 1, false);
01038 else
01039 field = name;
01040
01041 if (member_init_ok_or_else (field, current_class_type, name))
01042 return field;
01043 }
01044
01045 return NULL_TREE;
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 tree
01080 build_aggr_init (tree exp, tree init, int flags)
01081 {
01082 tree stmt_expr;
01083 tree compound_stmt;
01084 int destroy_temps;
01085 tree type = TREE_TYPE (exp);
01086 int was_const = TREE_READONLY (exp);
01087 int was_volatile = TREE_THIS_VOLATILE (exp);
01088 int is_global;
01089
01090 if (init == error_mark_node)
01091 return error_mark_node;
01092
01093 TREE_READONLY (exp) = 0;
01094 TREE_THIS_VOLATILE (exp) = 0;
01095
01096 if (init && TREE_CODE (init) != TREE_LIST)
01097 flags |= LOOKUP_ONLYCONVERTING;
01098
01099 if (TREE_CODE (type) == ARRAY_TYPE)
01100 {
01101 tree itype;
01102
01103
01104
01105 if (init && TREE_CODE (init) == TREE_LIST)
01106 {
01107 error ("bad array initializer");
01108 return error_mark_node;
01109 }
01110
01111
01112 itype = init ? TREE_TYPE (init) : NULL_TREE;
01113 if (cp_type_quals (type) != TYPE_UNQUALIFIED)
01114 TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
01115 if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
01116 itype = TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
01117 stmt_expr = build_vec_init (exp, NULL_TREE, init,
01118 false,
01119 itype && same_type_p (itype,
01120 TREE_TYPE (exp)));
01121 TREE_READONLY (exp) = was_const;
01122 TREE_THIS_VOLATILE (exp) = was_volatile;
01123 TREE_TYPE (exp) = type;
01124 if (init)
01125 TREE_TYPE (init) = itype;
01126 return stmt_expr;
01127 }
01128
01129 if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
01130
01131 TREE_USED (exp) = 1;
01132
01133 TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
01134 is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
01135 destroy_temps = stmts_are_full_exprs_p ();
01136 current_stmt_tree ()->stmts_are_full_exprs_p = 0;
01137 expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
01138 init, LOOKUP_NORMAL|flags);
01139 stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
01140 current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
01141 TREE_TYPE (exp) = type;
01142 TREE_READONLY (exp) = was_const;
01143 TREE_THIS_VOLATILE (exp) = was_volatile;
01144
01145 return stmt_expr;
01146 }
01147
01148
01149
01150 tree
01151 build_init (tree decl, tree init, int flags)
01152 {
01153 tree expr;
01154
01155 if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
01156 expr = build_aggr_init (decl, init, flags);
01157 else if (CLASS_TYPE_P (TREE_TYPE (decl)))
01158 expr = build_special_member_call (decl, complete_ctor_identifier,
01159 build_tree_list (NULL_TREE, init),
01160 TREE_TYPE (decl),
01161 LOOKUP_NORMAL|flags);
01162 else
01163 expr = build2 (INIT_EXPR, TREE_TYPE (decl), decl, init);
01164
01165 return expr;
01166 }
01167
01168 static void
01169 expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
01170 {
01171 tree type = TREE_TYPE (exp);
01172 tree ctor_name;
01173
01174
01175
01176
01177
01178
01179
01180 tree rval;
01181 tree parms;
01182
01183 if (init && TREE_CODE (init) != TREE_LIST
01184 && (flags & LOOKUP_ONLYCONVERTING))
01185 {
01186
01187 gcc_assert (true_exp == exp);
01188
01189 if (flags & DIRECT_BIND)
01190
01191
01192
01193
01194 ;
01195 else if (BRACE_ENCLOSED_INITIALIZER_P (init))
01196 {
01197
01198 gcc_assert (CP_AGGREGATE_TYPE_P (type));
01199 init = digest_init (type, init, (tree *)NULL);
01200 }
01201 else
01202 init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
01203
01204 if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
01205
01206
01207
01208
01209 {
01210 TREE_OPERAND (init, 0) = build2 (INIT_EXPR, TREE_TYPE (exp), exp,
01211 TREE_OPERAND (init, 0));
01212 TREE_TYPE (init) = void_type_node;
01213 }
01214 else
01215 init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
01216 TREE_SIDE_EFFECTS (init) = 1;
01217 finish_expr_stmt (init);
01218 return;
01219 }
01220
01221 if (init == NULL_TREE
01222 || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))
01223 {
01224 parms = init;
01225 if (parms)
01226 init = TREE_VALUE (parms);
01227 }
01228 else
01229 parms = build_tree_list (NULL_TREE, init);
01230
01231 if (true_exp == exp)
01232 ctor_name = complete_ctor_identifier;
01233 else
01234 ctor_name = base_ctor_identifier;
01235
01236 rval = build_special_member_call (exp, ctor_name, parms, binfo, flags);
01237 if (TREE_SIDE_EFFECTS (rval))
01238 finish_expr_stmt (convert_to_void (rval, NULL));
01239 }
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 static void
01262 expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags)
01263 {
01264 tree type = TREE_TYPE (exp);
01265
01266 gcc_assert (init != error_mark_node && type != error_mark_node);
01267 gcc_assert (building_stmt_tree ());
01268
01269
01270
01271
01272
01273
01274
01275 if (init && TREE_CODE (exp) == VAR_DECL
01276 && TREE_CODE (init) == CONSTRUCTOR
01277 && TREE_HAS_CONSTRUCTOR (init))
01278 {
01279
01280
01281
01282 init = store_init_value (exp, init);
01283 if (init)
01284 finish_expr_stmt (init);
01285 return;
01286 }
01287
01288
01289
01290 expand_default_init (binfo, true_exp, exp, init, flags);
01291 }
01292
01293
01294
01295
01296 int
01297 is_aggr_type (tree type, int or_else)
01298 {
01299 if (type == error_mark_node)
01300 return 0;
01301
01302 if (! IS_AGGR_TYPE (type)
01303 && TREE_CODE (type) != TEMPLATE_TYPE_PARM
01304 && TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM)
01305 {
01306 if (or_else)
01307 error ("%qT is not an aggregate type", type);
01308 return 0;
01309 }
01310 return 1;
01311 }
01312
01313 tree
01314 get_type_value (tree name)
01315 {
01316 if (name == error_mark_node)
01317 return NULL_TREE;
01318
01319 if (IDENTIFIER_HAS_TYPE_VALUE (name))
01320 return IDENTIFIER_TYPE_VALUE (name);
01321 else
01322 return NULL_TREE;
01323 }
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336 tree
01337 build_offset_ref (tree type, tree name, bool address_p)
01338 {
01339 tree decl;
01340 tree member;
01341 tree basebinfo = NULL_TREE;
01342 tree orig_name = name;
01343
01344
01345 if (TREE_CODE (name) == TEMPLATE_DECL)
01346 return name;
01347
01348 if (dependent_type_p (type) || type_dependent_expression_p (name))
01349 return build_min_nt (SCOPE_REF, type, name);
01350
01351 if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
01352 {
01353
01354
01355
01356
01357 name = TREE_OPERAND (orig_name, 0);
01358
01359 if (DECL_P (name))
01360 name = DECL_NAME (name);
01361 else
01362 {
01363 if (TREE_CODE (name) == COMPONENT_REF)
01364 name = TREE_OPERAND (name, 1);
01365 if (TREE_CODE (name) == OVERLOAD)
01366 name = DECL_NAME (OVL_CURRENT (name));
01367 }
01368
01369 gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
01370 }
01371
01372 if (type == NULL_TREE)
01373 return error_mark_node;
01374
01375
01376 if (TREE_CODE (type) == NAMESPACE_DECL)
01377 {
01378 tree t = lookup_namespace_name (type, name);
01379 if (t == error_mark_node)
01380 return t;
01381 if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
01382
01383 t = build2 (TEMPLATE_ID_EXPR, TREE_TYPE (t),
01384 t, TREE_OPERAND (orig_name, 1));
01385 if (! type_unknown_p (t))
01386 {
01387 mark_used (t);
01388 t = convert_from_reference (t);
01389 }
01390 return t;
01391 }
01392
01393 if (! is_aggr_type (type, 1))
01394 return error_mark_node;
01395
01396 if (TREE_CODE (name) == BIT_NOT_EXPR)
01397 {
01398 if (! check_dtor_name (type, name))
01399 error ("qualified type %qT does not match destructor name %<~%T%>",
01400 type, TREE_OPERAND (name, 0));
01401 name = dtor_identifier;
01402 }
01403
01404 if (!COMPLETE_TYPE_P (complete_type (type))
01405 && !TYPE_BEING_DEFINED (type))
01406 {
01407 error ("incomplete type %qT does not have member %qD", type, name);
01408 return error_mark_node;
01409 }
01410
01411
01412 decl = maybe_dummy_object (type, &basebinfo);
01413
01414 if (BASELINK_P (name) || DECL_P (name))
01415 member = name;
01416 else
01417 {
01418 member = lookup_member (basebinfo, name, 1, 0);
01419
01420 if (member == error_mark_node)
01421 return error_mark_node;
01422 }
01423
01424 if (!member)
01425 {
01426 error ("%qD is not a member of type %qT", name, type);
01427 return error_mark_node;
01428 }
01429
01430 if (TREE_CODE (member) == TYPE_DECL)
01431 {
01432 TREE_USED (member) = 1;
01433 return member;
01434 }
01435
01436
01437 if (TREE_CODE (member) == VAR_DECL || TREE_CODE (member) == CONST_DECL)
01438 {
01439 mark_used (member);
01440 return convert_from_reference (member);
01441 }
01442
01443 if (TREE_CODE (member) == FIELD_DECL && DECL_C_BIT_FIELD (member))
01444 {
01445 error ("invalid pointer to bit-field %qD", member);
01446 return error_mark_node;
01447 }
01448
01449
01450 if (BASELINK_P (member))
01451 {
01452
01453 tree fnfields = member;
01454 tree t = BASELINK_FUNCTIONS (fnfields);
01455
01456 if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
01457 {
01458
01459
01460
01461
01462
01463
01464
01465 if (TREE_CODE (t) != OVERLOAD)
01466
01467
01468 t = ovl_cons (t, NULL_TREE);
01469
01470 t = build2 (TEMPLATE_ID_EXPR, TREE_TYPE (t), t,
01471 TREE_OPERAND (orig_name, 1));
01472 t = build2 (OFFSET_REF, unknown_type_node, decl, t);
01473
01474 PTRMEM_OK_P (t) = 1;
01475
01476 return t;
01477 }
01478
01479 if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t))
01480 {
01481
01482 t = OVL_CURRENT (t);
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492 if (address_p && DECL_P (t)
01493 && DECL_NONSTATIC_MEMBER_P (t))
01494 perform_or_defer_access_check (TYPE_BINFO (type), t);
01495 else
01496 perform_or_defer_access_check (basebinfo, t);
01497
01498 mark_used (t);
01499 if (DECL_STATIC_FUNCTION_P (t))
01500 return t;
01501 member = t;
01502 }
01503 else
01504 {
01505 TREE_TYPE (fnfields) = unknown_type_node;
01506 member = fnfields;
01507 }
01508 }
01509 else if (address_p && TREE_CODE (member) == FIELD_DECL)
01510
01511
01512
01513 perform_or_defer_access_check (TYPE_BINFO (type), member);
01514
01515 if (!address_p)
01516 {
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
01535 {
01536
01537
01538
01539 member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
01540
01541
01542 if (flag_ms_extensions)
01543 {
01544 PTRMEM_OK_P (member) = 1;
01545 return build_unary_op (ADDR_EXPR, member, 0);
01546 }
01547 error ("invalid use of non-static member function %qD",
01548 TREE_OPERAND (member, 1));
01549 return member;
01550 }
01551 else if (TREE_CODE (member) == FIELD_DECL)
01552 {
01553 error ("invalid use of non-static data member %qD", member);
01554 return error_mark_node;
01555 }
01556 return member;
01557 }
01558
01559 member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
01560 PTRMEM_OK_P (member) = 1;
01561 return member;
01562 }
01563
01564
01565
01566
01567
01568
01569 tree
01570 integral_constant_value (tree decl)
01571 {
01572 #ifdef KEY
01573
01574
01575
01576 while (TREE_CODE (decl) == CONST_DECL
01577 || DECL_INTEGRAL_CONSTANT_VAR_P (decl))
01578 #else
01579 while ((TREE_CODE (decl) == CONST_DECL
01580 || (TREE_CODE (decl) == VAR_DECL
01581
01582
01583 && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))
01584 && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))))
01585 #endif
01586 {
01587 tree init;
01588
01589
01590
01591 mark_used (decl);
01592 init = DECL_INITIAL (decl);
01593
01594
01595
01596 if (init)
01597 init = fold_non_dependent_expr (init);
01598 if (!(init || init == error_mark_node)
01599 || !TREE_TYPE (init)
01600 || !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (init)))
01601 break;
01602 decl = init;
01603 }
01604 return decl;
01605 }
01606
01607
01608
01609
01610
01611 tree
01612 decl_constant_value (tree decl)
01613 {
01614 if ((TREE_CODE (decl) == CONST_DECL
01615 || (TREE_CODE (decl) == VAR_DECL
01616
01617
01618 && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))))
01619 && DECL_INITIAL (decl)
01620 && DECL_INITIAL (decl) != error_mark_node
01621
01622
01623
01624 && TREE_CONSTANT (DECL_INITIAL (decl)))
01625 return DECL_INITIAL (decl);
01626
01627 return decl;
01628 }
01629
01630
01631
01632
01633
01634 static tree
01635 build_builtin_delete_call (tree addr)
01636 {
01637 mark_used (global_delete_fndecl);
01638 return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
01639 }
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 tree
01651 build_new (tree placement, tree type, tree nelts, tree init,
01652 int use_global_new)
01653 {
01654 tree rval;
01655
01656 if (type == error_mark_node)
01657 return error_mark_node;
01658
01659 if (processing_template_decl)
01660 {
01661 rval = build_min (NEW_EXPR, build_pointer_type (type),
01662 placement, type, nelts, init);
01663 NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
01664 TREE_SIDE_EFFECTS (rval) = 1;
01665 return rval;
01666 }
01667
01668 if (nelts)
01669 {
01670 if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
01671 pedwarn ("size in array new must have integral type");
01672 nelts = save_expr (cp_convert (sizetype, nelts));
01673 if (nelts == integer_zero_node)
01674 warning ("zero size array reserves no space");
01675 }
01676
01677
01678
01679
01680 if (TREE_CODE (type) == REFERENCE_TYPE)
01681 {
01682 error ("new cannot be applied to a reference type");
01683 type = TREE_TYPE (type);
01684 }
01685
01686 if (TREE_CODE (type) == FUNCTION_TYPE)
01687 {
01688 error ("new cannot be applied to a function type");
01689 return error_mark_node;
01690 }
01691
01692 rval = build4 (NEW_EXPR, build_pointer_type (type), placement, type,
01693 nelts, init);
01694 NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
01695 TREE_SIDE_EFFECTS (rval) = 1;
01696 rval = build_new_1 (rval);
01697 if (rval == error_mark_node)
01698 return error_mark_node;
01699
01700
01701 rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
01702 TREE_NO_WARNING (rval) = 1;
01703
01704 return rval;
01705 }
01706
01707
01708
01709 tree
01710 build_java_class_ref (tree type)
01711 {
01712 tree name = NULL_TREE, class_decl;
01713 static tree CL_suffix = NULL_TREE;
01714 if (CL_suffix == NULL_TREE)
01715 CL_suffix = get_identifier("class$");
01716 if (jclass_node == NULL_TREE)
01717 {
01718 jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass"));
01719 if (jclass_node == NULL_TREE)
01720 fatal_error ("call to Java constructor, while %<jclass%> undefined");
01721
01722 jclass_node = TREE_TYPE (jclass_node);
01723 }
01724
01725
01726 {
01727 tree field;
01728 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
01729 if (DECL_NAME (field) == CL_suffix)
01730 {
01731 mangle_decl (field);
01732 name = DECL_ASSEMBLER_NAME (field);
01733 break;
01734 }
01735 if (!field)
01736 internal_error ("can't find class$");
01737 }
01738
01739 class_decl = IDENTIFIER_GLOBAL_VALUE (name);
01740 if (class_decl == NULL_TREE)
01741 {
01742 class_decl = build_decl (VAR_DECL, name, TREE_TYPE (jclass_node));
01743 TREE_STATIC (class_decl) = 1;
01744 DECL_EXTERNAL (class_decl) = 1;
01745 TREE_PUBLIC (class_decl) = 1;
01746 DECL_ARTIFICIAL (class_decl) = 1;
01747 DECL_IGNORED_P (class_decl) = 1;
01748 pushdecl_top_level (class_decl);
01749 make_decl_rtl (class_decl);
01750 }
01751 return class_decl;
01752 }
01753
01754
01755
01756
01757
01758 static tree
01759 build_new_1 (tree exp)
01760 {
01761 tree placement, init;
01762 tree size, rval;
01763
01764
01765 bool array_p = false;
01766
01767
01768
01769 bool vla_p = false;
01770
01771
01772 tree full_type;
01773
01774
01775
01776
01777 tree elt_type;
01778
01779
01780 tree pointer_type;
01781
01782
01783
01784 tree type;
01785
01786 tree full_pointer_type;
01787 tree outer_nelts = NULL_TREE;
01788 tree nelts = NULL_TREE;
01789 tree alloc_call, alloc_expr;
01790
01791
01792 tree alloc_node;
01793 tree alloc_fn;
01794 tree cookie_expr, init_expr;
01795 int nothrow, check_new;
01796
01797 int globally_qualified_p;
01798 int use_java_new = 0;
01799
01800
01801
01802 tree cookie_size = NULL_TREE;
01803
01804
01805 bool placement_allocation_fn_p;
01806 tree args = NULL_TREE;
01807
01808
01809 bool is_initialized;
01810
01811
01812
01813
01814 tree data_addr;
01815 tree init_preeval_expr = NULL_TREE;
01816
01817 placement = TREE_OPERAND (exp, 0);
01818 type = TREE_OPERAND (exp, 1);
01819 nelts = TREE_OPERAND (exp, 2);
01820 init = TREE_OPERAND (exp, 3);
01821 globally_qualified_p = NEW_EXPR_USE_GLOBAL (exp);
01822
01823 if (nelts)
01824 {
01825 tree index;
01826
01827 outer_nelts = nelts;
01828 array_p = true;
01829
01830
01831
01832
01833 vla_p = true;
01834 full_type = build_cplus_array_type (type, NULL_TREE);
01835 index = convert (sizetype, nelts);
01836 index = size_binop (MINUS_EXPR, index, size_one_node);
01837 TYPE_DOMAIN (full_type) = build_index_type (index);
01838 }
01839 else
01840 {
01841 full_type = type;
01842 if (TREE_CODE (type) == ARRAY_TYPE)
01843 {
01844 array_p = true;
01845 nelts = array_type_nelts_top (type);
01846 outer_nelts = nelts;
01847 type = TREE_TYPE (type);
01848 }
01849 }
01850
01851 if (!complete_type_or_else (type, exp))
01852 return error_mark_node;
01853
01854
01855
01856 for (elt_type = type;
01857 TREE_CODE (elt_type) == ARRAY_TYPE;
01858 elt_type = TREE_TYPE (elt_type))
01859 nelts = cp_build_binary_op (MULT_EXPR, nelts,
01860 array_type_nelts_top (elt_type));
01861
01862 if (TREE_CODE (elt_type) == VOID_TYPE)
01863 {
01864 error ("invalid type %<void%> for new");
01865 return error_mark_node;
01866 }
01867
01868 if (abstract_virtuals_error (NULL_TREE, elt_type))
01869 return error_mark_node;
01870
01871 is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || init);
01872 if (CP_TYPE_CONST_P (elt_type) && !is_initialized)
01873 {
01874 error ("uninitialized const in %<new%> of %q#T", elt_type);
01875 return error_mark_node;
01876 }
01877
01878 size = size_in_bytes (elt_type);
01879 if (array_p)
01880 {
01881 size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
01882 if (vla_p)
01883 {
01884 tree n, bitsize;
01885
01886
01887
01888
01889 TYPE_SIZE_UNIT (full_type) = size;
01890 n = convert (bitsizetype, nelts);
01891 bitsize = size_binop (MULT_EXPR, TYPE_SIZE (elt_type), n);
01892 TYPE_SIZE (full_type) = bitsize;
01893 }
01894 }
01895
01896
01897 if (! placement && TYPE_FOR_JAVA (elt_type))
01898 {
01899 tree class_addr, alloc_decl;
01900 tree class_decl = build_java_class_ref (elt_type);
01901 static const char alloc_name[] = "_Jv_AllocObject";
01902
01903 use_java_new = 1;
01904 alloc_decl = NULL;
01905 if (!get_global_value_if_present (get_identifier (alloc_name),
01906 &alloc_decl))
01907 {
01908 error ("call to Java constructor with %qs undefined", alloc_name);
01909 return error_mark_node;
01910 }
01911 else if (really_overloaded_fn (alloc_decl))
01912 {
01913 error ("%qD should never be overloaded", alloc_decl);
01914 return error_mark_node;
01915 }
01916 alloc_decl = OVL_CURRENT (alloc_decl);
01917 class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
01918 alloc_call = (build_function_call
01919 (alloc_decl,
01920 build_tree_list (NULL_TREE, class_addr)));
01921 }
01922 else
01923 {
01924 tree fnname;
01925 tree fns;
01926
01927 fnname = ansi_opname (array_p ? VEC_NEW_EXPR : NEW_EXPR);
01928
01929 if (!globally_qualified_p
01930 && CLASS_TYPE_P (elt_type)
01931 && (array_p
01932 ? TYPE_HAS_ARRAY_NEW_OPERATOR (elt_type)
01933 : TYPE_HAS_NEW_OPERATOR (elt_type)))
01934 {
01935
01936
01937 if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
01938 {
01939 cookie_size = targetm.cxx.get_cookie_size (elt_type);
01940 size = size_binop (PLUS_EXPR, size, cookie_size);
01941 }
01942
01943 args = tree_cons (NULL_TREE, size, placement);
01944
01945 fns = lookup_fnfields (elt_type, fnname, 2);
01946 if (fns == NULL_TREE)
01947 {
01948 error ("no suitable %qD found in class %qT", fnname, elt_type);
01949 return error_mark_node;
01950 }
01951 if (TREE_CODE (fns) == TREE_LIST)
01952 {
01953 error ("request for member %qD is ambiguous", fnname);
01954 print_candidates (fns);
01955 return error_mark_node;
01956 }
01957 alloc_call = build_new_method_call (build_dummy_object (elt_type),
01958 fns, args,
01959 NULL_TREE,
01960 LOOKUP_NORMAL);
01961 }
01962 else
01963 {
01964
01965
01966 if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
01967 cookie_size = targetm.cxx.get_cookie_size (elt_type);
01968 else
01969 cookie_size = NULL_TREE;
01970
01971 alloc_call = build_operator_new_call (fnname, placement,
01972 &size, &cookie_size);
01973 }
01974 }
01975
01976 if (alloc_call == error_mark_node)
01977 return error_mark_node;
01978
01979
01980 pointer_type = build_pointer_type (type);
01981 if (!cookie_size && !is_initialized)
01982 return build_nop (pointer_type, alloc_call);
01983
01984
01985
01986
01987 full_pointer_type = build_pointer_type (full_type);
01988 alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
01989 alloc_node = TARGET_EXPR_SLOT (alloc_expr);
01990
01991
01992 while (TREE_CODE (alloc_call) == COMPOUND_EXPR)
01993 alloc_call = TREE_OPERAND (alloc_call, 1);
01994 alloc_fn = get_callee_fndecl (alloc_call);
01995 gcc_assert (alloc_fn != NULL_TREE);
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007 placement_allocation_fn_p
02008 = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
02009 || varargs_function_p (alloc_fn));
02010
02011
02012
02013 if (placement_allocation_fn_p)
02014 {
02015 tree inits;
02016 stabilize_call (alloc_call, &inits);
02017 if (inits)
02018 alloc_expr = build2 (COMPOUND_EXPR, TREE_TYPE (alloc_expr), inits,
02019 alloc_expr);
02020 }
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032 nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn));
02033 check_new = (flag_check_new || nothrow) && ! use_java_new;
02034
02035 if (cookie_size)
02036 {
02037 tree cookie;
02038 tree cookie_ptr;
02039
02040
02041 data_addr = get_target_expr (build2 (PLUS_EXPR, full_pointer_type,
02042 alloc_node, cookie_size));
02043
02044
02045
02046
02047 cookie_ptr = build2 (MINUS_EXPR, build_pointer_type (sizetype),
02048 data_addr, size_in_bytes (sizetype));
02049 cookie = build_indirect_ref (cookie_ptr, NULL);
02050
02051 cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
02052
02053 if (targetm.cxx.cookie_has_size ())
02054 {
02055
02056 cookie_ptr = build2 (MINUS_EXPR, build_pointer_type (sizetype),
02057 cookie_ptr, size_in_bytes (sizetype));
02058 cookie = build_indirect_ref (cookie_ptr, NULL);
02059 cookie = build2 (MODIFY_EXPR, sizetype, cookie,
02060 size_in_bytes(elt_type));
02061 cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
02062 cookie, cookie_expr);
02063 }
02064 data_addr = TARGET_EXPR_SLOT (data_addr);
02065 }
02066 else
02067 {
02068 cookie_expr = NULL_TREE;
02069 data_addr = alloc_node;
02070 }
02071
02072
02073
02074
02075
02076
02077 if (is_initialized)
02078 {
02079 bool stable;
02080
02081 init_expr = build_indirect_ref (data_addr, NULL);
02082
02083 if (array_p)
02084 {
02085 bool explicit_default_init_p = false;
02086
02087 if (init == void_zero_node)
02088 {
02089 init = NULL_TREE;
02090 explicit_default_init_p = true;
02091 }
02092 else if (init)
02093 pedwarn ("ISO C++ forbids initialization in array new");
02094
02095 init_expr
02096 = build_vec_init (init_expr,
02097 cp_build_binary_op (MINUS_EXPR, outer_nelts,
02098 integer_one_node),
02099 init,
02100 explicit_default_init_p,
02101 0);
02102
02103
02104
02105
02106 stable = true;
02107 }
02108 else
02109 {
02110 if (init == void_zero_node)
02111 init = build_default_init (full_type, nelts);
02112
02113 if (TYPE_NEEDS_CONSTRUCTING (type))
02114 {
02115 init_expr = build_special_member_call (init_expr,
02116 complete_ctor_identifier,
02117 init, elt_type,
02118 LOOKUP_NORMAL);
02119 stable = stabilize_init (init_expr, &init_preeval_expr);
02120 }
02121 else
02122 {
02123
02124
02125
02126 if (TREE_CODE (init) == TREE_LIST)
02127 init = build_x_compound_expr_from_list (init,
02128 "new initializer");
02129
02130 else
02131 gcc_assert (TREE_CODE (init) != CONSTRUCTOR
02132 || TREE_TYPE (init) != NULL_TREE);
02133
02134 init_expr = build_modify_expr (init_expr, INIT_EXPR, init);
02135 stable = stabilize_init (init_expr, &init_preeval_expr);
02136 }
02137 }
02138
02139 if (init_expr == error_mark_node)
02140 return error_mark_node;
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 if (flag_exceptions && ! use_java_new)
02151 {
02152 enum tree_code dcode = array_p ? VEC_DELETE_EXPR : DELETE_EXPR;
02153 tree cleanup;
02154
02155
02156
02157
02158 cleanup = build_op_delete_call (dcode, alloc_node, size,
02159 globally_qualified_p,
02160 (placement_allocation_fn_p
02161 ? alloc_call : NULL_TREE));
02162
02163 if (!cleanup)
02164 ;
02165 else if (stable)
02166
02167
02168 init_expr = build2 (TRY_CATCH_EXPR, void_type_node,
02169 init_expr, cleanup);
02170 else
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181 {
02182 tree end, sentry, begin;
02183
02184 begin = get_target_expr (boolean_true_node);
02185 CLEANUP_EH_ONLY (begin) = 1;
02186
02187 sentry = TARGET_EXPR_SLOT (begin);
02188
02189 TARGET_EXPR_CLEANUP (begin)
02190 = build3 (COND_EXPR, void_type_node, sentry,
02191 cleanup, void_zero_node);
02192
02193 end = build2 (MODIFY_EXPR, TREE_TYPE (sentry),
02194 sentry, boolean_false_node);
02195
02196 init_expr
02197 = build2 (COMPOUND_EXPR, void_type_node, begin,
02198 build2 (COMPOUND_EXPR, void_type_node, init_expr,
02199 end));
02200 }
02201
02202 }
02203 }
02204 else
02205 init_expr = NULL_TREE;
02206
02207
02208
02209 rval = data_addr;
02210
02211 if (init_expr)
02212 rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_expr, rval);
02213 if (cookie_expr)
02214 rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
02215
02216 if (rval == alloc_node)
02217
02218
02219 rval = TARGET_EXPR_INITIAL (alloc_expr);
02220 else
02221 {
02222 if (check_new)
02223 {
02224 tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node,
02225 integer_zero_node);
02226 rval = build_conditional_expr (ifexp, rval, alloc_node);
02227 }
02228
02229
02230
02231 rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
02232 }
02233
02234 if (init_preeval_expr)
02235 rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval);
02236
02237
02238 rval = build_nop (pointer_type, rval);
02239
02240
02241 rval = rvalue (rval);
02242
02243 return rval;
02244 }
02245
02246 static tree
02247 build_vec_delete_1 (tree base, tree maxindex, tree type,
02248 special_function_kind auto_delete_vec, int use_global_delete)
02249 {
02250 tree virtual_size;
02251 tree ptype = build_pointer_type (type = complete_type (type));
02252 tree size_exp = size_in_bytes (type);
02253
02254
02255 tree tbase, tbase_init;
02256
02257
02258
02259 tree body;
02260
02261
02262 tree loop = 0;
02263
02264
02265 tree deallocate_expr = 0;
02266
02267
02268
02269
02270
02271 tree controller = NULL_TREE;
02272
02273
02274 gcc_assert (TREE_CODE (type) != ARRAY_TYPE);
02275
02276 if (! IS_AGGR_TYPE (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
02277 goto no_destructor;
02278
02279
02280 virtual_size = size_binop (MULT_EXPR, size_exp,
02281 convert (sizetype, maxindex));
02282
02283 tbase = create_temporary_var (ptype);
02284 tbase_init = build_modify_expr (tbase, NOP_EXPR,
02285 fold (build2 (PLUS_EXPR, ptype,
02286 base,
02287 virtual_size)));
02288 DECL_REGISTER (tbase) = 1;
02289 controller = build3 (BIND_EXPR, void_type_node, tbase,
02290 NULL_TREE, NULL_TREE);
02291 TREE_SIDE_EFFECTS (controller) = 1;
02292
02293 body = build1 (EXIT_EXPR, void_type_node,
02294 build2 (EQ_EXPR, boolean_type_node, base, tbase));
02295 body = build_compound_expr
02296 (body, build_modify_expr (tbase, NOP_EXPR,
02297 build2 (MINUS_EXPR, ptype, tbase, size_exp)));
02298 body = build_compound_expr
02299 (body, build_delete (ptype, tbase, sfk_complete_destructor,
02300 LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1));
02301
02302 loop = build1 (LOOP_EXPR, void_type_node, body);
02303 loop = build_compound_expr (tbase_init, loop);
02304
02305 no_destructor:
02306
02307
02308 if (auto_delete_vec != sfk_base_destructor)
02309 {
02310 tree base_tbd;
02311
02312
02313 virtual_size = size_binop (MULT_EXPR, size_exp,
02314 convert (sizetype, maxindex));
02315
02316 if (! TYPE_VEC_NEW_USES_COOKIE (type))
02317
02318 base_tbd = base;
02319 else
02320 {
02321 tree cookie_size;
02322
02323 cookie_size = targetm.cxx.get_cookie_size (type);
02324 base_tbd
02325 = cp_convert (ptype,
02326 cp_build_binary_op (MINUS_EXPR,
02327 cp_convert (string_type_node,
02328 base),
02329 cookie_size));
02330
02331 virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size);
02332 }
02333
02334 if (auto_delete_vec == sfk_deleting_destructor)
02335 deallocate_expr = build_x_delete (base_tbd,
02336 2 | use_global_delete,
02337 virtual_size);
02338 }
02339
02340 body = loop;
02341 if (!deallocate_expr)
02342 ;
02343 else if (!body)
02344 body = deallocate_expr;
02345 else
02346 body = build_compound_expr (body, deallocate_expr);
02347
02348 if (!body)
02349 body = integer_zero_node;
02350
02351
02352 body = fold (build3 (COND_EXPR, void_type_node,
02353 fold (build2 (NE_EXPR, boolean_type_node, base,
02354 convert (TREE_TYPE (base),
02355 integer_zero_node))),
02356 body, integer_zero_node));
02357 body = build1 (NOP_EXPR, void_type_node, body);
02358
02359 if (controller)
02360 {
02361 TREE_OPERAND (controller, 1) = body;
02362 body = controller;
02363 }
02364
02365 if (TREE_CODE (base) == SAVE_EXPR)
02366
02367 body = build2 (COMPOUND_EXPR, void_type_node, base, body);
02368
02369 return convert_to_void (body, NULL);
02370 }
02371
02372
02373
02374 tree
02375 create_temporary_var (tree type)
02376 {
02377 tree decl;
02378
02379 decl = build_decl (VAR_DECL, NULL_TREE, type);
02380 TREE_USED (decl) = 1;
02381 DECL_ARTIFICIAL (decl) = 1;
02382 DECL_IGNORED_P (decl) = 1;
02383 DECL_SOURCE_LOCATION (decl) = input_location;
02384 DECL_CONTEXT (decl) = current_function_decl;
02385
02386 return decl;
02387 }
02388
02389
02390
02391
02392
02393
02394
02395
02396 static tree
02397 get_temp_regvar (tree type, tree init)
02398 {
02399 tree decl;
02400
02401 decl = create_temporary_var (type);
02402 add_decl_expr (decl);
02403
02404 finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
02405
02406 return decl;
02407 }
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429 tree
02430 build_vec_init (tree base, tree maxindex, tree init,
02431 bool explicit_default_init_p,
02432 int from_array)
02433 {
02434 tree rval;
02435 tree base2 = NULL_TREE;
02436 tree size;
02437 tree itype = NULL_TREE;
02438 tree iterator;
02439
02440 tree atype = TREE_TYPE (base);
02441
02442 tree type = TREE_TYPE (atype);
02443
02444
02445 tree inner_elt_type;
02446
02447 tree ptype;
02448 tree stmt_expr;
02449 tree compound_stmt;
02450 int destroy_temps;
02451 tree try_block = NULL_TREE;
02452 int num_initialized_elts = 0;
02453 bool is_global;
02454
02455 if (TYPE_DOMAIN (atype))
02456 maxindex = array_type_nelts (atype);
02457
02458 if (maxindex == NULL_TREE || maxindex == error_mark_node)
02459 return error_mark_node;
02460
02461 if (explicit_default_init_p)
02462 gcc_assert (!init);
02463
02464 inner_elt_type = strip_array_types (atype);
02465 if (init
02466 && (from_array == 2
02467 ? (!CLASS_TYPE_P (inner_elt_type)
02468 || !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type))
02469 : !TYPE_NEEDS_CONSTRUCTING (type))
02470 && ((TREE_CODE (init) == CONSTRUCTOR
02471
02472
02473 && (CONSTRUCTOR_ELTS (init) == NULL_TREE
02474 || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
02475 || from_array))
02476 {
02477
02478
02479
02480
02481 stmt_expr = build2 (INIT_EXPR, atype, base, init);
02482 return stmt_expr;
02483 }
02484
02485 maxindex = cp_convert (ptrdiff_type_node, maxindex);
02486 ptype = build_pointer_type (type);
02487 size = size_in_bytes (type);
02488 if (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
02489 base = cp_convert (ptype, decay_conversion (base));
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521 is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
02522 destroy_temps = stmts_are_full_exprs_p ();
02523 current_stmt_tree ()->stmts_are_full_exprs_p = 0;
02524 rval = get_temp_regvar (ptype, base);
02525 base = get_temp_regvar (ptype, rval);
02526 iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
02527
02528
02529
02530
02531 if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
02532 && from_array != 2)
02533 {
02534 try_block = begin_try_block ();
02535 }
02536
02537 if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
02538 {
02539
02540
02541
02542 tree elts;
02543 from_array = 0;
02544
02545 for (elts = CONSTRUCTOR_ELTS (init); elts; elts = TREE_CHAIN (elts))
02546 {
02547 tree elt = TREE_VALUE (elts);
02548 tree baseref = build1 (INDIRECT_REF, type, base);
02549
02550 num_initialized_elts++;
02551
02552 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
02553 if (IS_AGGR_TYPE (type) || TREE_CODE (type) == ARRAY_TYPE)
02554 finish_expr_stmt (build_aggr_init (baseref, elt, 0));
02555 else
02556 finish_expr_stmt (build_modify_expr (baseref, NOP_EXPR,
02557 elt));
02558 current_stmt_tree ()->stmts_are_full_exprs_p = 0;
02559
02560 finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base, 0));
02561 finish_expr_stmt (build_unary_op (PREDECREMENT_EXPR, iterator, 0));
02562 }
02563
02564
02565 init = NULL_TREE;
02566 }
02567 else if (from_array)
02568 {
02569
02570
02571
02572 if (init)
02573 {
02574 base2 = decay_conversion (init);
02575 itype = TREE_TYPE (base2);
02576 base2 = get_temp_regvar (itype, base2);
02577 itype = TREE_TYPE (itype);
02578 }
02579 else if (TYPE_LANG_SPECIFIC (type)
02580 && TYPE_NEEDS_CONSTRUCTING (type)
02581 && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
02582 {
02583 error ("initializer ends prematurely");
02584 return error_mark_node;
02585 }
02586 }
02587
02588
02589
02590
02591
02592
02593
02594 if (from_array
02595 || ((TYPE_NEEDS_CONSTRUCTING (type) || explicit_default_init_p)
02596 && ! (host_integerp (maxindex, 0)
02597 && (num_initialized_elts
02598 == tree_low_cst (maxindex, 0) + 1))))
02599 {
02600
02601
02602 tree for_stmt;
02603 tree elt_init;
02604 tree to;
02605
02606 for_stmt = begin_for_stmt ();
02607 finish_for_init_stmt (for_stmt);
02608 finish_for_cond (build2 (NE_EXPR, boolean_type_node,
02609 iterator, integer_minus_one_node),
02610 for_stmt);
02611 finish_for_expr (build_unary_op (PREDECREMENT_EXPR, iterator, 0),
02612 for_stmt);
02613
02614 to = build1 (INDIRECT_REF, type, base);
02615
02616 if (from_array)
02617 {
02618 tree from;
02619
02620 if (base2)
02621 from = build1 (INDIRECT_REF, itype, base2);
02622 else
02623 from = NULL_TREE;
02624
02625 if (from_array == 2)
02626 elt_init = build_modify_expr (to, NOP_EXPR, from);
02627 else if (TYPE_NEEDS_CONSTRUCTING (type))
02628 elt_init = build_aggr_init (to, from, 0);
02629 else if (from)
02630 elt_init = build_modify_expr (to, NOP_EXPR, from);
02631 else
02632 gcc_unreachable ();
02633 }
02634 else if (TREE_CODE (type) == ARRAY_TYPE)
02635 {
02636 if (init != 0)
02637 sorry
02638 ("cannot initialize multi-dimensional array with initializer");
02639 elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
02640 0, 0,
02641 false,
02642 0);
02643 }
02644 else if (!TYPE_NEEDS_CONSTRUCTING (type))
02645 elt_init = (build_modify_expr
02646 (to, INIT_EXPR,
02647 build_zero_init (type, size_one_node,
02648 false)));
02649 else
02650 elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base),
02651 init, 0);
02652
02653 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
02654 finish_expr_stmt (elt_init);
02655 current_stmt_tree ()->stmts_are_full_exprs_p = 0;
02656
02657 finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base, 0));
02658 if (base2)
02659 finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base2, 0));
02660
02661 finish_for_stmt (for_stmt);
02662 }
02663
02664
02665 if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
02666 && from_array != 2)
02667 {
02668 tree e;
02669 tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator);
02670
02671
02672
02673 if (TREE_CODE (type) == ARRAY_TYPE)
02674 m = cp_build_binary_op (MULT_EXPR, m,
02675 array_type_nelts_total (type));
02676
02677 finish_cleanup_try_block (try_block);
02678 e = build_vec_delete_1 (rval, m,
02679 inner_elt_type, sfk_base_destructor,
02680 0);
02681 finish_cleanup (e, try_block);
02682 }
02683
02684
02685
02686 finish_stmt_expr_expr (rval, stmt_expr);
02687
02688 stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
02689
02690
02691 atype = build_pointer_type (atype);
02692 stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
02693 stmt_expr = build_indirect_ref (stmt_expr, NULL);
02694
02695 current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
02696 return stmt_expr;
02697 }
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713 tree
02714 build_x_delete (tree addr, int which_delete, tree virtual_size)
02715 {
02716 int use_global_delete = which_delete & 1;
02717 int use_vec_delete = !!(which_delete & 2);
02718 enum tree_code code = use_vec_delete ? VEC_DELETE_EXPR : DELETE_EXPR;
02719
02720 return build_op_delete_call (code, addr, virtual_size, use_global_delete,
02721 NULL_TREE);
02722 }
02723
02724
02725
02726
02727 static tree
02728 build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
02729 {
02730 tree name;
02731 tree fn;
02732 switch (dtor_kind)
02733 {
02734 case sfk_complete_destructor:
02735 name = complete_dtor_identifier;
02736 break;
02737
02738 case sfk_base_destructor:
02739 name = base_dtor_identifier;
02740 break;
02741
02742 case sfk_deleting_destructor:
02743 name = deleting_dtor_identifier;
02744 break;
02745
02746 default:
02747 gcc_unreachable ();
02748 }
02749 fn = lookup_fnfields (TREE_TYPE (exp), name, 2);
02750 return build_new_method_call (exp, fn,
02751 NULL_TREE,
02752 NULL_TREE,
02753 flags);
02754 }
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765 tree
02766 build_delete (tree type, tree addr, special_function_kind auto_delete,
02767 int flags, int use_global_delete)
02768 {
02769 tree expr;
02770
02771 if (addr == error_mark_node)
02772 return error_mark_node;
02773
02774
02775
02776 if (type == error_mark_node)
02777 return error_mark_node;
02778
02779 type = TYPE_MAIN_VARIANT (type);
02780
02781 if (TREE_CODE (type) == POINTER_TYPE)
02782 {
02783 bool complete_p = true;
02784
02785 type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
02786 if (TREE_CODE (type) == ARRAY_TYPE)
02787 goto handle_array;
02788
02789
02790
02791
02792
02793
02794
02795 if (!VOID_TYPE_P (type))
02796 {
02797 complete_type (type);
02798 if (!COMPLETE_TYPE_P (type))
02799 {
02800 warning ("possible problem detected in invocation of "
02801 "delete operator:");
02802 cxx_incomplete_type_diagnostic (addr, type, 1);
02803 inform ("neither the destructor nor the class-specific "
02804 "operator delete will be called, even if they are "
02805 "declared when the class is defined.");
02806 complete_p = false;
02807 }
02808 }
02809 if (VOID_TYPE_P (type) || !complete_p || !IS_AGGR_TYPE (type))
02810
02811 return build_builtin_delete_call (addr);
02812 if (TREE_SIDE_EFFECTS (addr))
02813 addr = save_expr (addr);
02814
02815
02816 addr = convert_force (build_pointer_type (type), addr, 0);
02817 }
02818 else if (TREE_CODE (type) == ARRAY_TYPE)
02819 {
02820 handle_array:
02821
02822 if (TYPE_DOMAIN (type) == NULL_TREE)
02823 {
02824 error ("unknown array size in delete");
02825 return error_mark_node;
02826 }
02827 return build_vec_delete (addr, array_type_nelts (type),
02828 auto_delete, use_global_delete);
02829 }
02830 else
02831 {
02832
02833
02834
02835 addr = build_unary_op (ADDR_EXPR, addr, 0);
02836 if (TREE_SIDE_EFFECTS (addr))
02837 addr = save_expr (addr);
02838
02839 addr = convert_force (build_pointer_type (type), addr, 0);
02840 }
02841
02842 gcc_assert (IS_AGGR_TYPE (type));
02843
02844 if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
02845 {
02846 if (auto_delete != sfk_deleting_destructor)
02847 return void_zero_node;
02848
02849 return build_op_delete_call
02850 (DELETE_EXPR, addr, cxx_sizeof_nowarn (type), use_global_delete,
02851 NULL_TREE);
02852 }
02853 else
02854 {
02855 tree do_delete = NULL_TREE;
02856 tree ifexp;
02857
02858 if (CLASSTYPE_LAZY_DESTRUCTOR (type))
02859 lazily_declare_fn (sfk_destructor, type);
02860
02861
02862
02863
02864 if (use_global_delete && auto_delete == sfk_deleting_destructor)
02865 {
02866
02867 addr = save_expr (addr);
02868
02869 do_delete = build_builtin_delete_call (addr);
02870
02871
02872 auto_delete = sfk_complete_destructor;
02873 }
02874
02875
02876
02877 else if (!DECL_VIRTUAL_P (CLASSTYPE_DESTRUCTORS (type))
02878 && auto_delete == sfk_deleting_destructor)
02879 {
02880
02881 addr = save_expr (addr);
02882
02883 do_delete = build_op_delete_call (DELETE_EXPR,
02884 addr,
02885 cxx_sizeof_nowarn (type),
02886 false,
02887 NULL_TREE);
02888
02889 auto_delete = sfk_complete_destructor;
02890 }
02891 else if (auto_delete == sfk_deleting_destructor
02892 && TYPE_GETS_REG_DELETE (type))
02893 {
02894
02895
02896 build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
02897 false, NULL_TREE);
02898 }
02899
02900 expr = build_dtor_call (build_indirect_ref (addr, NULL),
02901 auto_delete, flags);
02902 if (do_delete)
02903 expr = build2 (COMPOUND_EXPR, void_type_node, expr, do_delete);
02904
02905 if (flags & LOOKUP_DESTRUCTOR)
02906
02907 ifexp = integer_one_node;
02908 else
02909
02910 ifexp = fold (cp_build_binary_op (NE_EXPR, addr, integer_zero_node));
02911
02912 if (ifexp != integer_one_node)
02913 expr = build3 (COND_EXPR, void_type_node,
02914 ifexp, expr, void_zero_node);
02915
02916 return expr;
02917 }
02918 }
02919
02920
02921
02922
02923
02924
02925 void
02926 push_base_cleanups (void)
02927 {
02928 tree binfo, base_binfo;
02929 int i;
02930 tree member;
02931 tree expr;
02932 VEC (tree) *vbases;
02933
02934
02935 if (CLASSTYPE_VBASECLASSES (current_class_type))
02936 {
02937 tree cond = (condition_conversion
02938 (build2 (BIT_AND_EXPR, integer_type_node,
02939 current_in_charge_parm,
02940 integer_two_node)));
02941
02942
02943
02944 for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
02945 VEC_iterate (tree, vbases, i, base_binfo); i++)
02946 {
02947 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
02948 {
02949 expr = build_special_member_call (current_class_ref,
02950 base_dtor_identifier,
02951 NULL_TREE,
02952 base_binfo,
02953 (LOOKUP_NORMAL
02954 | LOOKUP_NONVIRTUAL));
02955 expr = build3 (COND_EXPR, void_type_node, cond,
02956 expr, void_zero_node);
02957 finish_decl_cleanup (NULL_TREE, expr);
02958 }
02959 }
02960 }
02961
02962
02963 for (binfo = TYPE_BINFO (current_class_type), i = 0;
02964 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
02965 {
02966 if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))
02967 || BINFO_VIRTUAL_P (base_binfo))
02968 continue;
02969
02970 expr = build_special_member_call (current_class_ref,
02971 base_dtor_identifier,
02972 NULL_TREE, base_binfo,
02973 LOOKUP_NORMAL | LOOKUP_NONVIRTUAL);
02974 finish_decl_cleanup (NULL_TREE, expr);
02975 }
02976
02977 for (member = TYPE_FIELDS (current_class_type); member;
02978 member = TREE_CHAIN (member))
02979 {
02980 if (TREE_CODE (member) != FIELD_DECL || DECL_ARTIFICIAL (member))
02981 continue;
02982 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (member)))
02983 {
02984 tree this_member = (build_class_member_access_expr
02985 (current_class_ref, member,
02986 NULL_TREE,
02987 false));
02988 tree this_type = TREE_TYPE (member);
02989 expr = build_delete (this_type, this_member,
02990 sfk_complete_destructor,
02991 LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
02992 0);
02993 finish_decl_cleanup (NULL_TREE, expr);
02994 }
02995 }
02996 }
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014 tree
03015 build_vec_delete (tree base, tree maxindex,
03016 special_function_kind auto_delete_vec, int use_global_delete)
03017 {
03018 tree type;
03019 tree rval;
03020 tree base_init = NULL_TREE;
03021
03022 type = TREE_TYPE (base);
03023
03024 if (TREE_CODE (type) == POINTER_TYPE)
03025 {
03026
03027 tree cookie_addr;
03028
03029 if (TREE_SIDE_EFFECTS (base))
03030 {
03031 base_init = get_target_expr (base);
03032 base = TARGET_EXPR_SLOT (base_init);
03033 }
03034 type = strip_array_types (TREE_TYPE (type));
03035 cookie_addr = build2 (MINUS_EXPR,
03036 build_pointer_type (sizetype),
03037 base,
03038 TYPE_SIZE_UNIT (sizetype));
03039 maxindex = build_indirect_ref (cookie_addr, NULL);
03040 }
03041 else if (TREE_CODE (type) == ARRAY_TYPE)
03042 {
03043
03044
03045 maxindex = array_type_nelts_total (type);
03046 type = strip_array_types (type);
03047 base = build_unary_op (ADDR_EXPR, base, 1);
03048 if (TREE_SIDE_EFFECTS (base))
03049 {
03050 base_init = get_target_expr (base);
03051 base = TARGET_EXPR_SLOT (base_init);
03052 }
03053 }
03054 else
03055 {
03056 if (base != error_mark_node)
03057 error ("type to vector delete is neither pointer or array type");
03058 return error_mark_node;
03059 }
03060
03061 rval = build_vec_delete_1 (base, maxindex, type, auto_delete_vec,
03062 use_global_delete);
03063 if (base_init)
03064 rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), base_init, rval);
03065
03066 return rval;
03067 }