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