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