00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "config.h"
00031 #include "system.h"
00032 #include "coretypes.h"
00033 #include "tm.h"
00034 #include "tree.h"
00035 #include "cp-tree.h"
00036 #include "flags.h"
00037 #include "rtl.h"
00038 #include "output.h"
00039 #include "toplev.h"
00040 #include "target.h"
00041 #include "convert.h"
00042 #include "cgraph.h"
00043 #include "tree-dump.h"
00044
00045
00046
00047
00048 int current_class_depth;
00049
00050
00051
00052
00053
00054 typedef struct class_stack_node {
00055
00056 tree name;
00057
00058
00059 tree type;
00060
00061
00062
00063 tree access;
00064
00065
00066 splay_tree names_used;
00067
00068
00069
00070 size_t hidden;
00071 }* class_stack_node_t;
00072
00073 typedef struct vtbl_init_data_s
00074 {
00075
00076 tree binfo;
00077
00078 tree derived;
00079
00080
00081 tree rtti_binfo;
00082
00083
00084 tree inits;
00085
00086 tree* last_init;
00087
00088
00089 tree vbase;
00090
00091
00092 VEC(tree,gc) *fns;
00093
00094 tree index;
00095
00096
00097 int primary_vtbl_p;
00098
00099
00100 int ctor_vtbl_p;
00101
00102
00103 bool generate_vcall_entries;
00104 } vtbl_init_data;
00105
00106
00107 typedef int (*subobject_offset_fn) (tree, tree, splay_tree);
00108
00109
00110
00111 static int current_class_stack_size;
00112 static class_stack_node_t current_class_stack;
00113
00114
00115 static GTY (()) tree sizeof_biggest_empty_class;
00116
00117
00118
00119 VEC(tree,gc) *local_classes;
00120
00121 static tree get_vfield_name (tree);
00122 static void finish_struct_anon (tree);
00123 static tree get_vtable_name (tree);
00124 static tree get_basefndecls (tree, tree);
00125 static int build_primary_vtable (tree, tree);
00126 static int build_secondary_vtable (tree);
00127 static void finish_vtbls (tree);
00128 static void modify_vtable_entry (tree, tree, tree, tree, tree *);
00129 static void finish_struct_bits (tree);
00130 static int alter_access (tree, tree, tree);
00131 static void handle_using_decl (tree, tree);
00132 static tree dfs_modify_vtables (tree, void *);
00133 static tree modify_all_vtables (tree, tree);
00134 static void determine_primary_bases (tree);
00135 static void finish_struct_methods (tree);
00136 static void maybe_warn_about_overly_private_class (tree);
00137 static int method_name_cmp (const void *, const void *);
00138 static int resort_method_name_cmp (const void *, const void *);
00139 static void add_implicitly_declared_members (tree, int, int);
00140 static tree fixed_type_or_null (tree, int *, int *);
00141 static tree build_simple_base_path (tree expr, tree binfo);
00142 static tree build_vtbl_ref_1 (tree, tree);
00143 static tree build_vtbl_initializer (tree, tree, tree, tree, int *);
00144 static int count_fields (tree);
00145 static int add_fields_to_record_type (tree, struct sorted_fields_type*, int);
00146 static void check_bitfield_decl (tree);
00147 static void check_field_decl (tree, tree, int *, int *, int *);
00148 static void check_field_decls (tree, tree *, int *, int *);
00149 static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
00150 static void build_base_fields (record_layout_info, splay_tree, tree *);
00151 static void check_methods (tree);
00152 static void remove_zero_width_bit_fields (tree);
00153 static void check_bases (tree, int *, int *);
00154 static void check_bases_and_members (tree);
00155 static tree create_vtable_ptr (tree, tree *);
00156 static void include_empty_classes (record_layout_info);
00157 static void layout_class_type (tree, tree *);
00158 static void fixup_pending_inline (tree);
00159 static void fixup_inline_methods (tree);
00160 static void propagate_binfo_offsets (tree, tree);
00161 static void layout_virtual_bases (record_layout_info, splay_tree);
00162 static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
00163 static void add_vcall_offset_vtbl_entries_r (tree, vtbl_init_data *);
00164 static void add_vcall_offset_vtbl_entries_1 (tree, vtbl_init_data *);
00165 static void build_vcall_offset_vtbl_entries (tree, vtbl_init_data *);
00166 static void add_vcall_offset (tree, tree, vtbl_init_data *);
00167 static void layout_vtable_decl (tree, int);
00168 static tree dfs_find_final_overrider_pre (tree, void *);
00169 static tree dfs_find_final_overrider_post (tree, void *);
00170 static tree find_final_overrider (tree, tree, tree);
00171 static int make_new_vtable (tree, tree);
00172 static tree get_primary_binfo (tree);
00173 static int maybe_indent_hierarchy (FILE *, int, int);
00174 static tree dump_class_hierarchy_r (FILE *, int, tree, tree, int);
00175 static void dump_class_hierarchy (tree);
00176 static void dump_class_hierarchy_1 (FILE *, int, tree);
00177 static void dump_array (FILE *, tree);
00178 static void dump_vtable (tree, tree, tree);
00179 static void dump_vtt (tree, tree);
00180 static void dump_thunk (FILE *, int, tree);
00181 static tree build_vtable (tree, tree, tree);
00182 static void initialize_vtable (tree, tree);
00183 static void layout_nonempty_base_or_field (record_layout_info,
00184 tree, tree, splay_tree);
00185 static tree end_of_class (tree, int);
00186 static bool layout_empty_base (tree, tree, splay_tree);
00187 static void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
00188 static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree,
00189 tree);
00190 static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
00191 static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *);
00192 static void clone_constructors_and_destructors (tree);
00193 static tree build_clone (tree, tree);
00194 static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
00195 static void build_ctor_vtbl_group (tree, tree);
00196 static void build_vtt (tree);
00197 static tree binfo_ctor_vtable (tree);
00198 static tree *build_vtt_inits (tree, tree, tree *, tree *);
00199 static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
00200 static tree dfs_fixup_binfo_vtbls (tree, void *);
00201 static int record_subobject_offset (tree, tree, splay_tree);
00202 static int check_subobject_offset (tree, tree, splay_tree);
00203 static int walk_subobject_offsets (tree, subobject_offset_fn,
00204 tree, splay_tree, tree, int);
00205 static void record_subobject_offsets (tree, tree, splay_tree, bool);
00206 static int layout_conflict_p (tree, tree, splay_tree, int);
00207 static int splay_tree_compare_integer_csts (splay_tree_key k1,
00208 splay_tree_key k2);
00209 static void warn_about_ambiguous_bases (tree);
00210 static bool type_requires_array_cookie (tree);
00211 static bool contains_empty_class_p (tree);
00212 static bool base_derived_from (tree, tree);
00213 static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
00214 static tree end_of_base (tree);
00215 static tree get_vcall_index (tree, tree);
00216
00217
00218
00219 #ifdef GATHER_STATISTICS
00220 int n_vtables = 0;
00221 int n_vtable_entries = 0;
00222 int n_vtable_searches = 0;
00223 int n_vtable_elems = 0;
00224 int n_convert_harshness = 0;
00225 int n_compute_conversion_costs = 0;
00226 int n_inner_fields_searched = 0;
00227 #endif
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 tree
00240 build_base_path (enum tree_code code,
00241 tree expr,
00242 tree binfo,
00243 int nonnull)
00244 {
00245 tree v_binfo = NULL_TREE;
00246 tree d_binfo = NULL_TREE;
00247 tree probe;
00248 tree offset;
00249 tree target_type;
00250 tree null_test = NULL;
00251 tree ptr_target_type;
00252 int fixed_type_p;
00253 int want_pointer = TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE;
00254 bool has_empty = false;
00255 bool virtual_access;
00256
00257 if (expr == error_mark_node || binfo == error_mark_node || !binfo)
00258 return error_mark_node;
00259
00260 for (probe = binfo; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
00261 {
00262 d_binfo = probe;
00263 if (is_empty_class (BINFO_TYPE (probe)))
00264 has_empty = true;
00265 if (!v_binfo && BINFO_VIRTUAL_P (probe))
00266 v_binfo = probe;
00267 }
00268
00269 probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
00270 if (want_pointer)
00271 probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
00272
00273 gcc_assert ((code == MINUS_EXPR
00274 && SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), probe))
00275 || (code == PLUS_EXPR
00276 && SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe)));
00277
00278 if (binfo == d_binfo)
00279
00280 return expr;
00281
00282 if (code == MINUS_EXPR && v_binfo)
00283 {
00284 error ("cannot convert from base %qT to derived type %qT via virtual base %qT",
00285 BINFO_TYPE (binfo), BINFO_TYPE (d_binfo), BINFO_TYPE (v_binfo));
00286 return error_mark_node;
00287 }
00288
00289 if (!want_pointer)
00290
00291 expr = build_unary_op (ADDR_EXPR, expr, 0);
00292
00293 offset = BINFO_OFFSET (binfo);
00294 fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
00295 target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
00296
00297
00298 virtual_access = (v_binfo && fixed_type_p <= 0);
00299
00300
00301 if (want_pointer && !nonnull)
00302 {
00303
00304
00305
00306
00307
00308 if (!virtual_access && integer_zerop (offset))
00309 {
00310 tree class_type;
00311
00312
00313
00314
00315 class_type = TREE_TYPE (TREE_TYPE (expr));
00316 target_type
00317 = cp_build_qualified_type (target_type,
00318 cp_type_quals (class_type));
00319 return build_nop (build_pointer_type (target_type), expr);
00320 }
00321 null_test = error_mark_node;
00322 }
00323
00324
00325 if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access))
00326 expr = save_expr (expr);
00327
00328
00329 if (null_test)
00330 {
00331 tree zero = cp_convert (TREE_TYPE (expr), integer_zero_node);
00332 null_test = fold_build2 (NE_EXPR, boolean_type_node,
00333 expr, zero);
00334 }
00335
00336
00337 if (code == PLUS_EXPR && !virtual_access
00338
00339
00340 && !has_empty)
00341 {
00342 expr = build_indirect_ref (expr, NULL);
00343 expr = build_simple_base_path (expr, binfo);
00344 if (want_pointer)
00345 expr = build_address (expr);
00346 target_type = TREE_TYPE (expr);
00347 goto out;
00348 }
00349
00350 if (virtual_access)
00351 {
00352
00353
00354
00355 tree v_offset;
00356
00357 if (fixed_type_p < 0 && in_base_initializer)
00358 {
00359
00360
00361
00362 tree t;
00363
00364 t = TREE_TYPE (TYPE_VFIELD (current_class_type));
00365 t = build_pointer_type (t);
00366 v_offset = convert (t, current_vtt_parm);
00367 v_offset = build_indirect_ref (v_offset, NULL);
00368 }
00369 else
00370 v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
00371 TREE_TYPE (TREE_TYPE (expr)));
00372
00373 v_offset = build2 (PLUS_EXPR, TREE_TYPE (v_offset),
00374 v_offset, BINFO_VPTR_FIELD (v_binfo));
00375 v_offset = build1 (NOP_EXPR,
00376 build_pointer_type (ptrdiff_type_node),
00377 v_offset);
00378 v_offset = build_indirect_ref (v_offset, NULL);
00379 TREE_CONSTANT (v_offset) = 1;
00380 TREE_INVARIANT (v_offset) = 1;
00381
00382 offset = convert_to_integer (ptrdiff_type_node,
00383 size_diffop (offset,
00384 BINFO_OFFSET (v_binfo)));
00385
00386 if (!integer_zerop (offset))
00387 v_offset = build2 (code, ptrdiff_type_node, v_offset, offset);
00388
00389 if (fixed_type_p < 0)
00390
00391
00392
00393 offset = build3 (COND_EXPR, ptrdiff_type_node,
00394 build2 (EQ_EXPR, boolean_type_node,
00395 current_in_charge_parm, integer_zero_node),
00396 v_offset,
00397 convert_to_integer (ptrdiff_type_node,
00398 BINFO_OFFSET (binfo)));
00399 else
00400 offset = v_offset;
00401 }
00402
00403 target_type = cp_build_qualified_type
00404 (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
00405 ptr_target_type = build_pointer_type (target_type);
00406 if (want_pointer)
00407 target_type = ptr_target_type;
00408
00409 expr = build1 (NOP_EXPR, ptr_target_type, expr);
00410
00411 if (!integer_zerop (offset))
00412 expr = build2 (code, ptr_target_type, expr, offset);
00413 else
00414 null_test = NULL;
00415
00416 if (!want_pointer)
00417 expr = build_indirect_ref (expr, NULL);
00418
00419 out:
00420 if (null_test)
00421 expr = fold_build3 (COND_EXPR, target_type, null_test, expr,
00422 fold_build1 (NOP_EXPR, target_type,
00423 integer_zero_node));
00424
00425 return expr;
00426 }
00427
00428
00429
00430
00431
00432 static tree
00433 build_simple_base_path (tree expr, tree binfo)
00434 {
00435 tree type = BINFO_TYPE (binfo);
00436 tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
00437 tree field;
00438
00439 if (d_binfo == NULL_TREE)
00440 {
00441 tree temp;
00442
00443 gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type);
00444
00445
00446
00447
00448
00449 temp = unary_complex_lvalue (ADDR_EXPR, expr);
00450 if (temp)
00451 expr = build_indirect_ref (temp, NULL);
00452
00453 return expr;
00454 }
00455
00456
00457 expr = build_simple_base_path (expr, d_binfo);
00458
00459 for (field = TYPE_FIELDS (BINFO_TYPE (d_binfo));
00460 field; field = TREE_CHAIN (field))
00461
00462 if (TREE_CODE (field) == FIELD_DECL
00463 && DECL_FIELD_IS_BASE (field)
00464 && TREE_TYPE (field) == type)
00465 {
00466
00467
00468
00469 int type_quals = cp_type_quals (TREE_TYPE (expr));
00470
00471 expr = build3 (COMPONENT_REF,
00472 cp_build_qualified_type (type, type_quals),
00473 expr, field, NULL_TREE);
00474 expr = fold_if_not_in_template (expr);
00475
00476
00477
00478
00479 if (type_quals & TYPE_QUAL_CONST)
00480 TREE_READONLY (expr) = 1;
00481 if (type_quals & TYPE_QUAL_VOLATILE)
00482 TREE_THIS_VOLATILE (expr) = 1;
00483
00484 return expr;
00485 }
00486
00487
00488 gcc_unreachable ();
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498 tree
00499 convert_to_base (tree object, tree type, bool check_access, bool nonnull)
00500 {
00501 tree binfo;
00502 tree object_type;
00503
00504 if (TYPE_PTR_P (TREE_TYPE (object)))
00505 {
00506 object_type = TREE_TYPE (TREE_TYPE (object));
00507 type = TREE_TYPE (type);
00508 }
00509 else
00510 object_type = TREE_TYPE (object);
00511
00512 binfo = lookup_base (object_type, type,
00513 check_access ? ba_check : ba_unique,
00514 NULL);
00515 if (!binfo || binfo == error_mark_node)
00516 return error_mark_node;
00517
00518 return build_base_path (PLUS_EXPR, object, binfo, nonnull);
00519 }
00520
00521
00522
00523
00524
00525
00526 tree
00527 convert_to_base_statically (tree expr, tree base)
00528 {
00529 tree expr_type;
00530
00531 expr_type = TREE_TYPE (expr);
00532 if (!SAME_BINFO_TYPE_P (BINFO_TYPE (base), expr_type))
00533 {
00534 tree pointer_type;
00535
00536 pointer_type = build_pointer_type (expr_type);
00537 expr = build_unary_op (ADDR_EXPR, expr, 1);
00538 if (!integer_zerop (BINFO_OFFSET (base)))
00539 expr = build2 (PLUS_EXPR, pointer_type, expr,
00540 build_nop (pointer_type, BINFO_OFFSET (base)));
00541 expr = build_nop (build_pointer_type (BINFO_TYPE (base)), expr);
00542 expr = build1 (INDIRECT_REF, BINFO_TYPE (base), expr);
00543 }
00544
00545 return expr;
00546 }
00547
00548
00549 tree
00550 build_vfield_ref (tree datum, tree type)
00551 {
00552 tree vfield, vcontext;
00553
00554 if (datum == error_mark_node)
00555 return error_mark_node;
00556
00557
00558 if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
00559 datum = convert_to_base (datum, type, false,
00560 true);
00561
00562
00563
00564
00565
00566
00567
00568 vfield = TYPE_VFIELD (type);
00569 vcontext = DECL_CONTEXT (vfield);
00570 while (!same_type_ignoring_top_level_qualifiers_p (vcontext, type))
00571 {
00572 datum = build_simple_base_path (datum, CLASSTYPE_PRIMARY_BINFO (type));
00573 type = TREE_TYPE (datum);
00574 }
00575
00576 return build3 (COMPONENT_REF, TREE_TYPE (vfield), datum, vfield, NULL_TREE);
00577 }
00578
00579
00580
00581
00582
00583
00584 static tree
00585 build_vtbl_ref_1 (tree instance, tree idx)
00586 {
00587 tree aref;
00588 tree vtbl = NULL_TREE;
00589
00590
00591
00592
00593 int cdtorp = 0;
00594 tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
00595
00596 tree basetype = non_reference (TREE_TYPE (instance));
00597
00598 if (fixed_type && !cdtorp)
00599 {
00600 tree binfo = lookup_base (fixed_type, basetype,
00601 ba_unique | ba_quiet, NULL);
00602 if (binfo)
00603 vtbl = unshare_expr (BINFO_VTABLE (binfo));
00604 }
00605
00606 if (!vtbl)
00607 vtbl = build_vfield_ref (instance, basetype);
00608
00609 assemble_external (vtbl);
00610
00611 aref = build_array_ref (vtbl, idx);
00612 TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
00613 TREE_INVARIANT (aref) = TREE_CONSTANT (aref);
00614
00615 return aref;
00616 }
00617
00618 tree
00619 build_vtbl_ref (tree instance, tree idx)
00620 {
00621 tree aref = build_vtbl_ref_1 (instance, idx);
00622
00623 return aref;
00624 }
00625
00626
00627
00628
00629 tree
00630 build_vfn_ref (tree instance_ptr, tree idx)
00631 {
00632 tree aref;
00633
00634 aref = build_vtbl_ref_1 (build_indirect_ref (instance_ptr, 0), idx);
00635
00636
00637
00638 if (TARGET_VTABLE_USES_DESCRIPTORS)
00639 aref = build1 (NOP_EXPR, TREE_TYPE (aref),
00640 build_unary_op (ADDR_EXPR, aref, 1));
00641
00642
00643 aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);
00644
00645 return aref;
00646 }
00647
00648
00649
00650
00651 static tree
00652 get_vtable_name (tree type)
00653 {
00654 return mangle_vtbl_for_type (type);
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 void
00666 set_linkage_according_to_type (tree type, tree decl)
00667 {
00668
00669
00670
00671
00672
00673
00674 if (no_linkage_check (type, true))
00675 {
00676 TREE_PUBLIC (decl) = 0;
00677 DECL_INTERFACE_KNOWN (decl) = 1;
00678 }
00679 else
00680 TREE_PUBLIC (decl) = 1;
00681 }
00682
00683
00684
00685
00686
00687 static tree
00688 build_vtable (tree class_type, tree name, tree vtable_type)
00689 {
00690 tree decl;
00691
00692 decl = build_lang_decl (VAR_DECL, name, vtable_type);
00693
00694
00695 SET_DECL_ASSEMBLER_NAME (decl, name);
00696 DECL_CONTEXT (decl) = class_type;
00697 DECL_ARTIFICIAL (decl) = 1;
00698 TREE_STATIC (decl) = 1;
00699 TREE_READONLY (decl) = 1;
00700 DECL_VIRTUAL_P (decl) = 1;
00701 DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
00702 DECL_VTABLE_OR_VTT_P (decl) = 1;
00703
00704
00705 DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
00706 DECL_ALIGN (decl));
00707 set_linkage_according_to_type (class_type, decl);
00708
00709 DECL_EXTERNAL (decl) = 1;
00710 DECL_NOT_REALLY_EXTERN (decl) = 1;
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 DECL_IGNORED_P (decl) = 1;
00733
00734 return decl;
00735 }
00736
00737
00738
00739
00740
00741
00742
00743 tree
00744 get_vtable_decl (tree type, int complete)
00745 {
00746 tree decl;
00747
00748 if (CLASSTYPE_VTABLES (type))
00749 return CLASSTYPE_VTABLES (type);
00750
00751 decl = build_vtable (type, get_vtable_name (type), vtbl_type_node);
00752 CLASSTYPE_VTABLES (type) = decl;
00753
00754 if (complete)
00755 {
00756 DECL_EXTERNAL (decl) = 1;
00757 finish_decl (decl, NULL_TREE, NULL_TREE);
00758 }
00759
00760 return decl;
00761 }
00762
00763
00764
00765
00766
00767
00768
00769 static int
00770 build_primary_vtable (tree binfo, tree type)
00771 {
00772 tree decl;
00773 tree virtuals;
00774
00775 decl = get_vtable_decl (type, 0);
00776
00777 if (binfo)
00778 {
00779 if (BINFO_NEW_VTABLE_MARKED (binfo))
00780
00781
00782 return 0;
00783
00784 virtuals = copy_list (BINFO_VIRTUALS (binfo));
00785 TREE_TYPE (decl) = TREE_TYPE (get_vtbl_decl_for_binfo (binfo));
00786 DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl));
00787 DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
00788 }
00789 else
00790 {
00791 gcc_assert (TREE_TYPE (decl) == vtbl_type_node);
00792 virtuals = NULL_TREE;
00793 }
00794
00795 #ifdef GATHER_STATISTICS
00796 n_vtables += 1;
00797 n_vtable_elems += list_length (virtuals);
00798 #endif
00799
00800
00801
00802 BINFO_VTABLE (TYPE_BINFO (type)) = decl;
00803 BINFO_VIRTUALS (TYPE_BINFO (type)) = virtuals;
00804 SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type));
00805 return 1;
00806 }
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 static int
00823 build_secondary_vtable (tree binfo)
00824 {
00825 if (BINFO_NEW_VTABLE_MARKED (binfo))
00826
00827
00828 return 0;
00829
00830
00831
00832 SET_BINFO_NEW_VTABLE_MARKED (binfo);
00833
00834
00835 BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
00836
00837
00838
00839 BINFO_VTABLE (binfo) = NULL_TREE;
00840 return 1;
00841 }
00842
00843
00844
00845
00846 static int
00847 make_new_vtable (tree t, tree binfo)
00848 {
00849 if (binfo == TYPE_BINFO (t))
00850
00851
00852
00853 return build_primary_vtable (binfo, t);
00854 else
00855
00856
00857
00858
00859 return build_secondary_vtable (binfo);
00860 }
00861
00862
00863
00864
00865
00866
00867
00868 static void
00869 modify_vtable_entry (tree t,
00870 tree binfo,
00871 tree fndecl,
00872 tree delta,
00873 tree *virtuals)
00874 {
00875 tree v;
00876
00877 v = *virtuals;
00878
00879 if (fndecl != BV_FN (v)
00880 || !tree_int_cst_equal (delta, BV_DELTA (v)))
00881 {
00882
00883 if (make_new_vtable (t, binfo))
00884 {
00885
00886
00887
00888 *virtuals = BINFO_VIRTUALS (binfo);
00889 while (BV_FN (*virtuals) != BV_FN (v))
00890 *virtuals = TREE_CHAIN (*virtuals);
00891 v = *virtuals;
00892 }
00893
00894 BV_DELTA (v) = delta;
00895 BV_VCALL_INDEX (v) = NULL_TREE;
00896 BV_FN (v) = fndecl;
00897 }
00898 }
00899
00900
00901
00902
00903
00904
00905 bool
00906 add_method (tree type, tree method, tree using_decl)
00907 {
00908 unsigned slot;
00909 tree overload;
00910 bool template_conv_p = false;
00911 bool conv_p;
00912 VEC(tree,gc) *method_vec;
00913 bool complete_p;
00914 bool insert_p = false;
00915 tree current_fns;
00916
00917 if (method == error_mark_node)
00918 return false;
00919
00920 complete_p = COMPLETE_TYPE_P (type);
00921 conv_p = DECL_CONV_FN_P (method);
00922 if (conv_p)
00923 template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
00924 && DECL_TEMPLATE_CONV_FN_P (method));
00925
00926 method_vec = CLASSTYPE_METHOD_VEC (type);
00927 if (!method_vec)
00928 {
00929
00930
00931
00932
00933 method_vec = VEC_alloc (tree, gc, 8);
00934
00935 VEC_quick_push (tree, method_vec, NULL_TREE);
00936 VEC_quick_push (tree, method_vec, NULL_TREE);
00937 CLASSTYPE_METHOD_VEC (type) = method_vec;
00938 }
00939
00940
00941 grok_special_member_properties (method);
00942
00943
00944 if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
00945 slot = CLASSTYPE_CONSTRUCTOR_SLOT;
00946 else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
00947 {
00948 slot = CLASSTYPE_DESTRUCTOR_SLOT;
00949
00950 if (TYPE_FOR_JAVA (type))
00951 {
00952 if (!DECL_ARTIFICIAL (method))
00953 error ("Java class %qT cannot have a destructor", type);
00954 else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
00955 error ("Java class %qT cannot have an implicit non-trivial "
00956 "destructor",
00957 type);
00958 }
00959 }
00960 else
00961 {
00962 tree m;
00963
00964 insert_p = true;
00965
00966 for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
00967 VEC_iterate (tree, method_vec, slot, m);
00968 ++slot)
00969 {
00970 m = OVL_CURRENT (m);
00971 if (template_conv_p)
00972 {
00973 if (TREE_CODE (m) == TEMPLATE_DECL
00974 && DECL_TEMPLATE_CONV_FN_P (m))
00975 insert_p = false;
00976 break;
00977 }
00978 if (conv_p && !DECL_CONV_FN_P (m))
00979 break;
00980 if (DECL_NAME (m) == DECL_NAME (method))
00981 {
00982 insert_p = false;
00983 break;
00984 }
00985 if (complete_p
00986 && !DECL_CONV_FN_P (m)
00987 && DECL_NAME (m) > DECL_NAME (method))
00988 break;
00989 }
00990 }
00991 current_fns = insert_p ? NULL_TREE : VEC_index (tree, method_vec, slot);
00992
00993 if (processing_template_decl)
00994
00995
00996 ;
00997 else
00998 {
00999 tree fns;
01000
01001
01002 for (fns = current_fns; fns; fns = OVL_NEXT (fns))
01003 {
01004 tree fn = OVL_CURRENT (fns);
01005 tree fn_type;
01006 tree method_type;
01007 tree parms1;
01008 tree parms2;
01009
01010 if (TREE_CODE (fn) != TREE_CODE (method))
01011 continue;
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 fn_type = TREE_TYPE (fn);
01024 method_type = TREE_TYPE (method);
01025 parms1 = TYPE_ARG_TYPES (fn_type);
01026 parms2 = TYPE_ARG_TYPES (method_type);
01027
01028
01029
01030
01031 if (! DECL_STATIC_FUNCTION_P (fn)
01032 && ! DECL_STATIC_FUNCTION_P (method)
01033 && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
01034 != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
01035 continue;
01036
01037
01038
01039 if (TREE_CODE (fn) == TEMPLATE_DECL
01040 && (!same_type_p (TREE_TYPE (fn_type),
01041 TREE_TYPE (method_type))
01042 || !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
01043 DECL_TEMPLATE_PARMS (method))))
01044 continue;
01045
01046 if (! DECL_STATIC_FUNCTION_P (fn))
01047 parms1 = TREE_CHAIN (parms1);
01048 if (! DECL_STATIC_FUNCTION_P (method))
01049 parms2 = TREE_CHAIN (parms2);
01050
01051 if (compparms (parms1, parms2)
01052 && (!DECL_CONV_FN_P (fn)
01053 || same_type_p (TREE_TYPE (fn_type),
01054 TREE_TYPE (method_type))))
01055 {
01056 if (using_decl)
01057 {
01058 if (DECL_CONTEXT (fn) == type)
01059
01060 return false;
01061 if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
01062 error ("repeated using declaration %q+D", using_decl);
01063 else
01064 error ("using declaration %q+D conflicts with a previous using declaration",
01065 using_decl);
01066 }
01067 else
01068 {
01069 error ("%q+#D cannot be overloaded", method);
01070 error ("with %q+#D", fn);
01071 }
01072
01073
01074
01075
01076
01077 return false;
01078 }
01079 }
01080 }
01081
01082
01083 if (current_fns && DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
01084 return false;
01085
01086
01087 overload = build_overload (method, current_fns);
01088
01089 if (conv_p)
01090 TYPE_HAS_CONVERSION (type) = 1;
01091 else if (slot >= CLASSTYPE_FIRST_CONVERSION_SLOT && !complete_p)
01092 push_class_level_binding (DECL_NAME (method), overload);
01093
01094 if (insert_p)
01095 {
01096 bool reallocated;
01097
01098
01099
01100 if (complete_p)
01101 reallocated = VEC_reserve_exact (tree, gc, method_vec, 1);
01102 else
01103 reallocated = VEC_reserve (tree, gc, method_vec, 1);
01104 if (reallocated)
01105 CLASSTYPE_METHOD_VEC (type) = method_vec;
01106 if (slot == VEC_length (tree, method_vec))
01107 VEC_quick_push (tree, method_vec, overload);
01108 else
01109 VEC_quick_insert (tree, method_vec, slot, overload);
01110 }
01111 else
01112
01113 VEC_replace (tree, method_vec, slot, overload);
01114 return true;
01115 }
01116
01117
01118
01119
01120
01121
01122 static int
01123 alter_access (tree t, tree fdecl, tree access)
01124 {
01125 tree elem;
01126
01127 if (!DECL_LANG_SPECIFIC (fdecl))
01128 retrofit_lang_decl (fdecl);
01129
01130 gcc_assert (!DECL_DISCRIMINATOR_P (fdecl));
01131
01132 elem = purpose_member (t, DECL_ACCESS (fdecl));
01133 if (elem)
01134 {
01135 if (TREE_VALUE (elem) != access)
01136 {
01137 if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
01138 error ("conflicting access specifications for method"
01139 " %q+D, ignored", TREE_TYPE (fdecl));
01140 else
01141 error ("conflicting access specifications for field %qE, ignored",
01142 DECL_NAME (fdecl));
01143 }
01144 else
01145 {
01146
01147
01148 ;
01149 }
01150 }
01151 else
01152 {
01153 perform_or_defer_access_check (TYPE_BINFO (t), fdecl, fdecl);
01154 DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
01155 return 1;
01156 }
01157 return 0;
01158 }
01159
01160
01161
01162 static void
01163 handle_using_decl (tree using_decl, tree t)
01164 {
01165 tree decl = USING_DECL_DECLS (using_decl);
01166 tree name = DECL_NAME (using_decl);
01167 tree access
01168 = TREE_PRIVATE (using_decl) ? access_private_node
01169 : TREE_PROTECTED (using_decl) ? access_protected_node
01170 : access_public_node;
01171 tree flist = NULL_TREE;
01172 tree old_value;
01173
01174 gcc_assert (!processing_template_decl && decl);
01175
01176 old_value = lookup_member (t, name, 0, false);
01177 if (old_value)
01178 {
01179 if (is_overloaded_fn (old_value))
01180 old_value = OVL_CURRENT (old_value);
01181
01182 if (DECL_P (old_value) && DECL_CONTEXT (old_value) == t)
01183 ;
01184 else
01185 old_value = NULL_TREE;
01186 }
01187
01188 cp_emit_debug_info_for_using (decl, USING_DECL_SCOPE (using_decl));
01189
01190 if (is_overloaded_fn (decl))
01191 flist = decl;
01192
01193 if (! old_value)
01194 ;
01195 else if (is_overloaded_fn (old_value))
01196 {
01197 if (flist)
01198
01199 ;
01200 else
01201 {
01202 error ("%q+D invalid in %q#T", using_decl, t);
01203 error (" because of local method %q+#D with same name",
01204 OVL_CURRENT (old_value));
01205 return;
01206 }
01207 }
01208 else if (!DECL_ARTIFICIAL (old_value))
01209 {
01210 error ("%q+D invalid in %q#T", using_decl, t);
01211 error (" because of local member %q+#D with same name", old_value);
01212 return;
01213 }
01214
01215
01216 if (flist)
01217 for (; flist; flist = OVL_NEXT (flist))
01218 {
01219 add_method (t, OVL_CURRENT (flist), using_decl);
01220 alter_access (t, OVL_CURRENT (flist), access);
01221 }
01222 else
01223 alter_access (t, decl, access);
01224 }
01225
01226
01227
01228
01229
01230 static void
01231 check_bases (tree t,
01232 int* cant_have_const_ctor_p,
01233 int* no_const_asn_ref_p)
01234 {
01235 int i;
01236 int seen_non_virtual_nearly_empty_base_p;
01237 tree base_binfo;
01238 tree binfo;
01239
01240 seen_non_virtual_nearly_empty_base_p = 0;
01241
01242 for (binfo = TYPE_BINFO (t), i = 0;
01243 BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
01244 {
01245 tree basetype = TREE_TYPE (base_binfo);
01246
01247 gcc_assert (COMPLETE_TYPE_P (basetype));
01248
01249
01250
01251
01252 if (!TYPE_POLYMORPHIC_P (basetype))
01253 warning (OPT_Weffc__,
01254 "base class %q#T has a non-virtual destructor", basetype);
01255
01256
01257
01258
01259
01260 if (! TYPE_HAS_CONST_INIT_REF (basetype))
01261 *cant_have_const_ctor_p = 1;
01262 if (TYPE_HAS_ASSIGN_REF (basetype)
01263 && !TYPE_HAS_CONST_ASSIGN_REF (basetype))
01264 *no_const_asn_ref_p = 1;
01265
01266 if (BINFO_VIRTUAL_P (base_binfo))
01267
01268 ;
01269 else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
01270 {
01271 if (seen_non_virtual_nearly_empty_base_p)
01272
01273
01274 CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
01275 else
01276
01277 seen_non_virtual_nearly_empty_base_p = 1;
01278 }
01279 else if (!is_empty_class (basetype))
01280
01281
01282 CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
01283
01284
01285
01286 TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
01287 TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
01288 |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype);
01289 TYPE_HAS_COMPLEX_ASSIGN_REF (t)
01290 |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
01291 TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
01292 TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
01293 CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
01294 |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
01295 }
01296 }
01297
01298
01299
01300
01301
01302
01303
01304 static void
01305 determine_primary_bases (tree t)
01306 {
01307 unsigned i;
01308 tree primary = NULL_TREE;
01309 tree type_binfo = TYPE_BINFO (t);
01310 tree base_binfo;
01311
01312
01313 for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
01314 base_binfo = TREE_CHAIN (base_binfo))
01315 {
01316 tree primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (base_binfo));
01317
01318
01319
01320 if (!BINFO_VIRTUAL_P (base_binfo))
01321 {
01322 tree parent = BINFO_INHERITANCE_CHAIN (base_binfo);
01323 tree parent_primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (parent));
01324
01325 if (parent_primary
01326 && SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
01327 BINFO_TYPE (parent_primary)))
01328
01329 BINFO_PRIMARY_P (base_binfo) = 1;
01330 }
01331
01332
01333 if (primary && BINFO_VIRTUAL_P (primary))
01334 {
01335 tree this_primary = copied_binfo (primary, base_binfo);
01336
01337 if (BINFO_PRIMARY_P (this_primary))
01338
01339 BINFO_LOST_PRIMARY_P (base_binfo) = 1;
01340 else
01341 {
01342 tree delta;
01343
01344 BINFO_PRIMARY_P (this_primary) = 1;
01345 BINFO_INHERITANCE_CHAIN (this_primary) = base_binfo;
01346
01347
01348
01349
01350 delta = size_diffop (convert (ssizetype,
01351 BINFO_OFFSET (base_binfo)),
01352 convert (ssizetype,
01353 BINFO_OFFSET (this_primary)));
01354
01355 propagate_binfo_offsets (this_primary, delta);
01356 }
01357 }
01358 }
01359
01360
01361 for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, base_binfo); i++)
01362 {
01363 tree basetype = BINFO_TYPE (base_binfo);
01364
01365 if (TYPE_CONTAINS_VPTR_P (basetype) && !BINFO_VIRTUAL_P (base_binfo))
01366 {
01367 primary = base_binfo;
01368 goto found;
01369 }
01370 }
01371
01372
01373
01374
01375
01376
01377
01378 for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
01379 base_binfo = TREE_CHAIN (base_binfo))
01380 if (BINFO_VIRTUAL_P (base_binfo)
01381 && CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (base_binfo)))
01382 {
01383 if (!BINFO_PRIMARY_P (base_binfo))
01384 {
01385
01386 primary = base_binfo;
01387 goto found;
01388 }
01389 else if (!primary)
01390
01391 primary = base_binfo;
01392 }
01393
01394 found:
01395
01396 if (primary)
01397 {
01398 tree basetype = BINFO_TYPE (primary);
01399
01400 CLASSTYPE_PRIMARY_BINFO (t) = primary;
01401 if (BINFO_PRIMARY_P (primary))
01402
01403 BINFO_LOST_PRIMARY_P (BINFO_INHERITANCE_CHAIN (primary)) = 1;
01404 BINFO_PRIMARY_P (primary) = 1;
01405 if (BINFO_VIRTUAL_P (primary))
01406 {
01407 tree delta;
01408
01409 BINFO_INHERITANCE_CHAIN (primary) = type_binfo;
01410
01411
01412
01413 delta = size_diffop (ssize_int (0),
01414 convert (ssizetype, BINFO_OFFSET (primary)));
01415
01416 propagate_binfo_offsets (primary, delta);
01417 }
01418
01419 primary = TYPE_BINFO (basetype);
01420
01421 TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
01422 BINFO_VTABLE (type_binfo) = BINFO_VTABLE (primary);
01423 BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary);
01424 }
01425 }
01426
01427
01428
01429
01430 static void
01431 finish_struct_bits (tree t)
01432 {
01433 tree variants;
01434
01435
01436 for (variants = TYPE_NEXT_VARIANT (t);
01437 variants;
01438 variants = TYPE_NEXT_VARIANT (variants))
01439 {
01440
01441
01442 TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t);
01443 TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t);
01444 TYPE_HAS_NONTRIVIAL_DESTRUCTOR (variants)
01445 = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
01446
01447 TYPE_POLYMORPHIC_P (variants) = TYPE_POLYMORPHIC_P (t);
01448
01449 TYPE_BINFO (variants) = TYPE_BINFO (t);
01450
01451
01452 TYPE_VFIELD (variants) = TYPE_VFIELD (t);
01453 TYPE_METHODS (variants) = TYPE_METHODS (t);
01454 TYPE_FIELDS (variants) = TYPE_FIELDS (t);
01455 }
01456
01457 if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
01458
01459
01460
01461
01462
01463
01464
01465
01466 get_pure_virtuals (t);
01467
01468
01469
01470
01471
01472 if (! TYPE_HAS_TRIVIAL_INIT_REF (t) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
01473 {
01474 tree variants;
01475 DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
01476 for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
01477 {
01478 TYPE_MODE (variants) = BLKmode;
01479 TREE_ADDRESSABLE (variants) = 1;
01480 }
01481 }
01482 }
01483
01484
01485
01486
01487
01488
01489
01490
01491 static void
01492 maybe_warn_about_overly_private_class (tree t)
01493 {
01494 int has_member_fn = 0;
01495 int has_nonprivate_method = 0;
01496 tree fn;
01497
01498 if (!warn_ctor_dtor_privacy
01499
01500
01501 || (CLASSTYPE_FRIEND_CLASSES (t)
01502 || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
01503
01504
01505 || CLASSTYPE_TEMPLATE_INSTANTIATION (t))
01506
01507
01508 return;
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
01527
01528
01529 if (!DECL_ARTIFICIAL (fn))
01530 {
01531 if (!TREE_PRIVATE (fn))
01532 {
01533 if (DECL_STATIC_FUNCTION_P (fn))
01534
01535
01536
01537
01538 return;
01539
01540 has_nonprivate_method = 1;
01541
01542 }
01543 else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
01544 has_member_fn = 1;
01545 }
01546
01547 if (!has_nonprivate_method && has_member_fn)
01548 {
01549
01550
01551
01552
01553
01554
01555 unsigned i;
01556 tree binfo = TYPE_BINFO (t);
01557
01558 for (i = 0; i != BINFO_N_BASE_BINFOS (binfo); i++)
01559 if (BINFO_BASE_ACCESS (binfo, i) != access_private_node)
01560 {
01561 has_nonprivate_method = 1;
01562 break;
01563 }
01564 if (!has_nonprivate_method)
01565 {
01566 warning (OPT_Wctor_dtor_privacy,
01567 "all member functions in class %qT are private", t);
01568 return;
01569 }
01570 }
01571
01572
01573
01574
01575 fn = CLASSTYPE_DESTRUCTORS (t);
01576 if (fn && TREE_PRIVATE (fn))
01577 {
01578 warning (OPT_Wctor_dtor_privacy,
01579 "%q#T only defines a private destructor and has no friends",
01580 t);
01581 return;
01582 }
01583
01584 if (TYPE_HAS_CONSTRUCTOR (t)
01585
01586 && (!CLASSTYPE_LAZY_DEFAULT_CTOR (t)
01587 || !CLASSTYPE_LAZY_COPY_CTOR (t)))
01588 {
01589 int nonprivate_ctor = 0;
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601 if (!TYPE_HAS_INIT_REF (t))
01602 nonprivate_ctor = 1;
01603 else
01604 for (fn = CLASSTYPE_CONSTRUCTORS (t); fn; fn = OVL_NEXT (fn))
01605 {
01606 tree ctor = OVL_CURRENT (fn);
01607
01608
01609
01610
01611
01612
01613 if (! TREE_PRIVATE (ctor))
01614 {
01615 nonprivate_ctor = 1;
01616 break;
01617 }
01618 }
01619
01620 if (nonprivate_ctor == 0)
01621 {
01622 warning (OPT_Wctor_dtor_privacy,
01623 "%q#T only defines private constructors and has no friends",
01624 t);
01625 return;
01626 }
01627 }
01628 }
01629
01630 static struct {
01631 gt_pointer_operator new_value;
01632 void *cookie;
01633 } resort_data;
01634
01635
01636
01637 static int
01638 method_name_cmp (const void* m1_p, const void* m2_p)
01639 {
01640 const tree *const m1 = (const tree *) m1_p;
01641 const tree *const m2 = (const tree *) m2_p;
01642
01643 if (*m1 == NULL_TREE && *m2 == NULL_TREE)
01644 return 0;
01645 if (*m1 == NULL_TREE)
01646 return -1;
01647 if (*m2 == NULL_TREE)
01648 return 1;
01649 if (DECL_NAME (OVL_CURRENT (*m1)) < DECL_NAME (OVL_CURRENT (*m2)))
01650 return -1;
01651 return 1;
01652 }
01653
01654
01655
01656
01657 static int
01658 resort_method_name_cmp (const void* m1_p, const void* m2_p)
01659 {
01660 const tree *const m1 = (const tree *) m1_p;
01661 const tree *const m2 = (const tree *) m2_p;
01662 if (*m1 == NULL_TREE && *m2 == NULL_TREE)
01663 return 0;
01664 if (*m1 == NULL_TREE)
01665 return -1;
01666 if (*m2 == NULL_TREE)
01667 return 1;
01668 {
01669 tree d1 = DECL_NAME (OVL_CURRENT (*m1));
01670 tree d2 = DECL_NAME (OVL_CURRENT (*m2));
01671 resort_data.new_value (&d1, resort_data.cookie);
01672 resort_data.new_value (&d2, resort_data.cookie);
01673 if (d1 < d2)
01674 return -1;
01675 }
01676 return 1;
01677 }
01678
01679
01680
01681 void
01682 resort_type_method_vec (void* obj,
01683 void* orig_obj ATTRIBUTE_UNUSED ,
01684 gt_pointer_operator new_value,
01685 void* cookie)
01686 {
01687 VEC(tree,gc) *method_vec = (VEC(tree,gc) *) obj;
01688 int len = VEC_length (tree, method_vec);
01689 size_t slot;
01690 tree fn;
01691
01692
01693
01694 for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
01695 VEC_iterate (tree, method_vec, slot, fn);
01696 ++slot)
01697 if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
01698 break;
01699
01700 if (len - slot > 1)
01701 {
01702 resort_data.new_value = new_value;
01703 resort_data.cookie = cookie;
01704 qsort (VEC_address (tree, method_vec) + slot, len - slot, sizeof (tree),
01705 resort_method_name_cmp);
01706 }
01707 }
01708
01709
01710
01711
01712
01713
01714
01715 static void
01716 finish_struct_methods (tree t)
01717 {
01718 tree fn_fields;
01719 VEC(tree,gc) *method_vec;
01720 int slot, len;
01721
01722 method_vec = CLASSTYPE_METHOD_VEC (t);
01723 if (!method_vec)
01724 return;
01725
01726 len = VEC_length (tree, method_vec);
01727
01728
01729 for (fn_fields = TYPE_METHODS (t); fn_fields;
01730 fn_fields = TREE_CHAIN (fn_fields))
01731 DECL_IN_AGGR_P (fn_fields) = 0;
01732
01733
01734
01735 maybe_warn_about_overly_private_class (t);
01736
01737
01738
01739 for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
01740 VEC_iterate (tree, method_vec, slot, fn_fields);
01741 ++slot)
01742 if (!DECL_CONV_FN_P (OVL_CURRENT (fn_fields)))
01743 break;
01744 if (len - slot > 1)
01745 qsort (VEC_address (tree, method_vec) + slot,
01746 len-slot, sizeof (tree), method_name_cmp);
01747 }
01748
01749
01750
01751
01752
01753 static void
01754 layout_vtable_decl (tree binfo, int n)
01755 {
01756 tree atype;
01757 tree vtable;
01758
01759 atype = build_cplus_array_type (vtable_entry_type,
01760 build_index_type (size_int (n - 1)));
01761 layout_type (atype);
01762
01763
01764 vtable = get_vtbl_decl_for_binfo (binfo);
01765 if (!same_type_p (TREE_TYPE (vtable), atype))
01766 {
01767 TREE_TYPE (vtable) = atype;
01768 DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = NULL_TREE;
01769 layout_decl (vtable, 0);
01770 }
01771 }
01772
01773
01774
01775
01776 int
01777 same_signature_p (tree fndecl, tree base_fndecl)
01778 {
01779
01780
01781 if (DECL_DESTRUCTOR_P (base_fndecl) && DECL_DESTRUCTOR_P (fndecl)
01782 && special_function_p (base_fndecl) == special_function_p (fndecl))
01783 return 1;
01784
01785
01786
01787
01788 if (DECL_DESTRUCTOR_P (base_fndecl) || DECL_DESTRUCTOR_P (fndecl))
01789 return 0;
01790
01791 if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl)
01792 || (DECL_CONV_FN_P (fndecl)
01793 && DECL_CONV_FN_P (base_fndecl)
01794 && same_type_p (DECL_CONV_FN_TYPE (fndecl),
01795 DECL_CONV_FN_TYPE (base_fndecl))))
01796 {
01797 tree types, base_types;
01798 types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
01799 base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
01800 if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types)))
01801 == TYPE_QUALS (TREE_TYPE (TREE_VALUE (types))))
01802 && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types)))
01803 return 1;
01804 }
01805 return 0;
01806 }
01807
01808
01809
01810
01811 static bool
01812 base_derived_from (tree derived, tree base)
01813 {
01814 tree probe;
01815
01816 for (probe = base; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
01817 {
01818 if (probe == derived)
01819 return true;
01820 else if (BINFO_VIRTUAL_P (probe))
01821
01822
01823
01824 return (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (derived))
01825 != NULL_TREE);
01826 }
01827 return false;
01828 }
01829
01830 typedef struct find_final_overrider_data_s {
01831
01832 tree fn;
01833
01834 tree declaring_base;
01835
01836 tree candidates;
01837
01838 VEC(tree,heap) *path;
01839 } find_final_overrider_data;
01840
01841
01842
01843
01844 static bool
01845 dfs_find_final_overrider_1 (tree binfo,
01846 find_final_overrider_data *ffod,
01847 unsigned depth)
01848 {
01849 tree method;
01850
01851
01852
01853 if (depth)
01854 {
01855 depth--;
01856 if (dfs_find_final_overrider_1
01857 (VEC_index (tree, ffod->path, depth), ffod, depth))
01858 return true;
01859 }
01860
01861 method = look_for_overrides_here (BINFO_TYPE (binfo), ffod->fn);
01862 if (method)
01863 {
01864 tree *candidate = &ffod->candidates;
01865
01866
01867 while (*candidate)
01868 {
01869
01870
01871 if (base_derived_from (TREE_VALUE (*candidate), binfo))
01872 return true;
01873
01874 if (base_derived_from (binfo, TREE_VALUE (*candidate)))
01875 *candidate = TREE_CHAIN (*candidate);
01876 else
01877 candidate = &TREE_CHAIN (*candidate);
01878 }
01879
01880
01881 ffod->candidates = tree_cons (method, binfo, ffod->candidates);
01882 return true;
01883 }
01884
01885 return false;
01886 }
01887
01888
01889
01890 static tree
01891 dfs_find_final_overrider_pre (tree binfo, void *data)
01892 {
01893 find_final_overrider_data *ffod = (find_final_overrider_data *) data;
01894
01895 if (binfo == ffod->declaring_base)
01896 dfs_find_final_overrider_1 (binfo, ffod, VEC_length (tree, ffod->path));
01897 VEC_safe_push (tree, heap, ffod->path, binfo);
01898
01899 return NULL_TREE;
01900 }
01901
01902 static tree
01903 dfs_find_final_overrider_post (tree binfo ATTRIBUTE_UNUSED, void *data)
01904 {
01905 find_final_overrider_data *ffod = (find_final_overrider_data *) data;
01906 VEC_pop (tree, ffod->path);
01907
01908 return NULL_TREE;
01909 }
01910
01911
01912
01913
01914
01915
01916 static tree
01917 find_final_overrider (tree derived, tree binfo, tree fn)
01918 {
01919 find_final_overrider_data ffod;
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939 if (DECL_THUNK_P (fn))
01940 fn = THUNK_TARGET (fn);
01941
01942
01943 ffod.fn = fn;
01944 ffod.declaring_base = binfo;
01945 ffod.candidates = NULL_TREE;
01946 ffod.path = VEC_alloc (tree, heap, 30);
01947
01948 dfs_walk_all (derived, dfs_find_final_overrider_pre,
01949 dfs_find_final_overrider_post, &ffod);
01950
01951 VEC_free (tree, heap, ffod.path);
01952
01953
01954 if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
01955 return error_mark_node;
01956
01957 return ffod.candidates;
01958 }
01959
01960
01961
01962
01963 static tree
01964 get_vcall_index (tree fn, tree type)
01965 {
01966 VEC(tree_pair_s,gc) *indices = CLASSTYPE_VCALL_INDICES (type);
01967 tree_pair_p p;
01968 unsigned ix;
01969
01970 for (ix = 0; VEC_iterate (tree_pair_s, indices, ix, p); ix++)
01971 if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (p->purpose))
01972 || same_signature_p (fn, p->purpose))
01973 return p->value;
01974
01975
01976 gcc_unreachable ();
01977 }
01978
01979
01980
01981
01982
01983 static void
01984 update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
01985 unsigned ix)
01986 {
01987 tree b;
01988 tree overrider;
01989 tree delta;
01990 tree virtual_base;
01991 tree first_defn;
01992 tree overrider_fn, overrider_target;
01993 tree target_fn = DECL_THUNK_P (fn) ? THUNK_TARGET (fn) : fn;
01994 tree over_return, base_return;
01995 bool lost = false;
01996
01997
01998
01999
02000 for (b = binfo; ; b = get_primary_binfo (b))
02001 {
02002 gcc_assert (b);
02003 if (look_for_overrides_here (BINFO_TYPE (b), target_fn))
02004 break;
02005
02006
02007 if (BINFO_LOST_PRIMARY_P (b))
02008 lost = true;
02009 }
02010 first_defn = b;
02011
02012
02013 overrider = find_final_overrider (TYPE_BINFO (t), b, target_fn);
02014 if (overrider == error_mark_node)
02015 {
02016 error ("no unique final overrider for %qD in %qT", target_fn, t);
02017 return;
02018 }
02019 overrider_target = overrider_fn = TREE_PURPOSE (overrider);
02020
02021
02022 over_return = TREE_TYPE (TREE_TYPE (overrider_target));
02023 base_return = TREE_TYPE (TREE_TYPE (target_fn));
02024
02025 if (POINTER_TYPE_P (over_return)
02026 && TREE_CODE (over_return) == TREE_CODE (base_return)
02027 && CLASS_TYPE_P (TREE_TYPE (over_return))
02028 && CLASS_TYPE_P (TREE_TYPE (base_return))
02029
02030 && !DECL_INVALID_OVERRIDER_P (overrider_target))
02031 {
02032
02033
02034
02035
02036 tree fixed_offset, virtual_offset;
02037
02038 over_return = TREE_TYPE (over_return);
02039 base_return = TREE_TYPE (base_return);
02040
02041 if (DECL_THUNK_P (fn))
02042 {
02043 gcc_assert (DECL_RESULT_THUNK_P (fn));
02044 fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn));
02045 virtual_offset = THUNK_VIRTUAL_OFFSET (fn);
02046 }
02047 else
02048 fixed_offset = virtual_offset = NULL_TREE;
02049
02050 if (virtual_offset)
02051
02052
02053
02054 virtual_offset = binfo_for_vbase (BINFO_TYPE (virtual_offset),
02055 over_return);
02056 else if (!same_type_ignoring_top_level_qualifiers_p
02057 (over_return, base_return))
02058 {
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070 tree thunk_binfo, base_binfo;
02071
02072
02073
02074
02075
02076 for (base_binfo = TYPE_BINFO (base_return),
02077 thunk_binfo = TYPE_BINFO (over_return);
02078 thunk_binfo;
02079 thunk_binfo = TREE_CHAIN (thunk_binfo))
02080 if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo),
02081 BINFO_TYPE (base_binfo)))
02082 break;
02083
02084
02085 for (virtual_offset = thunk_binfo;
02086 virtual_offset;
02087 virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
02088 if (BINFO_VIRTUAL_P (virtual_offset))
02089 break;
02090
02091 if (virtual_offset
02092 || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
02093 {
02094 tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
02095
02096 if (virtual_offset)
02097 {
02098
02099
02100 offset = size_diffop
02101 (offset, convert
02102 (ssizetype, BINFO_OFFSET (virtual_offset)));
02103 }
02104 if (fixed_offset)
02105
02106
02107
02108 fixed_offset = size_binop (PLUS_EXPR, fixed_offset, offset);
02109 else
02110 fixed_offset = offset;
02111 }
02112 }
02113
02114 if (fixed_offset || virtual_offset)
02115
02116
02117
02118 overrider_fn = make_thunk (overrider_target, 0,
02119 fixed_offset, virtual_offset);
02120 }
02121 else
02122 gcc_assert (!DECL_THUNK_P (fn));
02123
02124
02125
02126 virtual_base = NULL_TREE;
02127
02128
02129
02130 for (; b; b = BINFO_INHERITANCE_CHAIN (b))
02131 {
02132
02133
02134 if (SAME_BINFO_TYPE_P (BINFO_TYPE (b),
02135 BINFO_TYPE (TREE_VALUE (overrider))))
02136 break;
02137
02138
02139
02140
02141 if (BINFO_VIRTUAL_P (b))
02142 {
02143 virtual_base = b;
02144 break;
02145 }
02146 }
02147
02148 if (overrider_fn != overrider_target && !virtual_base)
02149 {
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164 tree probe = first_defn;
02165
02166 while ((probe = get_primary_binfo (probe))
02167 && (unsigned) list_length (BINFO_VIRTUALS (probe)) > ix)
02168 if (BINFO_VIRTUAL_P (probe))
02169 virtual_base = probe;
02170
02171 if (virtual_base)
02172
02173
02174
02175 goto virtual_covariant;
02176 }
02177
02178
02179
02180
02181 if (virtual_base)
02182
02183
02184 delta = size_diffop (convert (ssizetype, BINFO_OFFSET (virtual_base)),
02185 convert (ssizetype, BINFO_OFFSET (first_defn)));
02186 else if (lost)
02187
02188
02189
02190
02191 delta = size_zero_node;
02192 else
02193
02194
02195
02196 virtual_covariant:
02197 delta = size_diffop (convert (ssizetype,
02198 BINFO_OFFSET (TREE_VALUE (overrider))),
02199 convert (ssizetype, BINFO_OFFSET (binfo)));
02200
02201 modify_vtable_entry (t, binfo, overrider_fn, delta, virtuals);
02202
02203 if (virtual_base)
02204 BV_VCALL_INDEX (*virtuals)
02205 = get_vcall_index (overrider_target, BINFO_TYPE (virtual_base));
02206 else
02207 BV_VCALL_INDEX (*virtuals) = NULL_TREE;
02208 }
02209
02210
02211
02212 static tree
02213 dfs_modify_vtables (tree binfo, void* data)
02214 {
02215 tree t = (tree) data;
02216 tree virtuals;
02217 tree old_virtuals;
02218 unsigned ix;
02219
02220 if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
02221
02222
02223 return dfs_skip_bases;
02224
02225 if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t)
02226 && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
02227
02228 return NULL_TREE;
02229
02230 if (BINFO_PRIMARY_P (binfo) && !BINFO_VIRTUAL_P (binfo))
02231
02232
02233
02234
02235 return NULL_TREE;
02236
02237 make_new_vtable (t, binfo);
02238
02239
02240
02241
02242 for (ix = 0, virtuals = BINFO_VIRTUALS (binfo),
02243 old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
02244 virtuals;
02245 ix++, virtuals = TREE_CHAIN (virtuals),
02246 old_virtuals = TREE_CHAIN (old_virtuals))
02247 update_vtable_entry_for_fn (t,
02248 binfo,
02249 BV_FN (old_virtuals),
02250 &virtuals, ix);
02251
02252 return NULL_TREE;
02253 }
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264 static tree
02265 modify_all_vtables (tree t, tree virtuals)
02266 {
02267 tree binfo = TYPE_BINFO (t);
02268 tree *fnsp;
02269
02270
02271 dfs_walk_once (binfo, dfs_modify_vtables, NULL, t);
02272
02273
02274
02275
02276
02277 for (fnsp = &virtuals; *fnsp; )
02278 {
02279 tree fn = TREE_VALUE (*fnsp);
02280
02281 if (!value_member (fn, BINFO_VIRTUALS (binfo))
02282 || DECL_VINDEX (fn) == error_mark_node)
02283 {
02284
02285
02286 BV_DELTA (*fnsp) = integer_zero_node;
02287 BV_VCALL_INDEX (*fnsp) = NULL_TREE;
02288
02289
02290 fnsp = &TREE_CHAIN (*fnsp);
02291 }
02292 else
02293
02294 *fnsp = TREE_CHAIN (*fnsp);
02295 }
02296
02297 return virtuals;
02298 }
02299
02300
02301
02302
02303 static tree
02304 get_basefndecls (tree name, tree t)
02305 {
02306 tree methods;
02307 tree base_fndecls = NULL_TREE;
02308 int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
02309 int i;
02310
02311
02312 i = lookup_fnfields_1 (t, name);
02313 if (i != -1)
02314 for (methods = VEC_index (tree, CLASSTYPE_METHOD_VEC (t), i);
02315 methods;
02316 methods = OVL_NEXT (methods))
02317 {
02318 tree method = OVL_CURRENT (methods);
02319
02320 if (TREE_CODE (method) == FUNCTION_DECL
02321 && DECL_VINDEX (method))
02322 base_fndecls = tree_cons (NULL_TREE, method, base_fndecls);
02323 }
02324
02325 if (base_fndecls)
02326 return base_fndecls;
02327
02328 for (i = 0; i < n_baseclasses; i++)
02329 {
02330 tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), i));
02331 base_fndecls = chainon (get_basefndecls (name, basetype),
02332 base_fndecls);
02333 }
02334
02335 return base_fndecls;
02336 }
02337
02338
02339
02340
02341
02342 void
02343 check_for_override (tree decl, tree ctype)
02344 {
02345 if (TREE_CODE (decl) == TEMPLATE_DECL)
02346
02347
02348
02349
02350 return;
02351 if ((DECL_DESTRUCTOR_P (decl)
02352 || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
02353 || DECL_CONV_FN_P (decl))
02354 && look_for_overrides (ctype, decl)
02355 && !DECL_STATIC_FUNCTION_P (decl))
02356
02357
02358
02359 DECL_VINDEX (decl) = decl;
02360
02361 if (DECL_VIRTUAL_P (decl))
02362 {
02363 if (!DECL_VINDEX (decl))
02364 DECL_VINDEX (decl) = error_mark_node;
02365 IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
02366 if (DECL_DLLIMPORT_P (decl))
02367 {
02368
02369
02370
02371
02372 DECL_DLLIMPORT_P (decl) = 0;
02373 DECL_ATTRIBUTES (decl)
02374 = remove_attribute ("dllimport", DECL_ATTRIBUTES (decl));
02375 }
02376 }
02377 }
02378
02379
02380
02381
02382 static void
02383 warn_hidden (tree t)
02384 {
02385 VEC(tree,gc) *method_vec = CLASSTYPE_METHOD_VEC (t);
02386 tree fns;
02387 size_t i;
02388
02389
02390 for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
02391 VEC_iterate (tree, method_vec, i, fns);
02392 ++i)
02393 {
02394 tree fn;
02395 tree name;
02396 tree fndecl;
02397 tree base_fndecls;
02398 tree base_binfo;
02399 tree binfo;
02400 int j;
02401
02402
02403
02404 name = DECL_NAME (OVL_CURRENT (fns));
02405
02406 base_fndecls = NULL_TREE;
02407
02408
02409 for (binfo = TYPE_BINFO (t), j = 0;
02410 BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
02411 {
02412 tree basetype = BINFO_TYPE (base_binfo);
02413 base_fndecls = chainon (get_basefndecls (name, basetype),
02414 base_fndecls);
02415 }
02416
02417
02418 if (!base_fndecls)
02419 continue;
02420
02421
02422 for (fn = fns; fn; fn = OVL_NEXT (fn))
02423 {
02424 fndecl = OVL_CURRENT (fn);
02425 if (DECL_VINDEX (fndecl))
02426 {
02427 tree *prev = &base_fndecls;
02428
02429 while (*prev)
02430
02431
02432
02433 if (same_signature_p (fndecl, TREE_VALUE (*prev)))
02434 *prev = TREE_CHAIN (*prev);
02435 else
02436 prev = &TREE_CHAIN (*prev);
02437 }
02438 }
02439
02440
02441
02442 while (base_fndecls)
02443 {
02444
02445 warning (0, "%q+D was hidden", TREE_VALUE (base_fndecls));
02446 warning (0, " by %q+D", fns);
02447 base_fndecls = TREE_CHAIN (base_fndecls);
02448 }
02449 }
02450 }
02451
02452
02453
02454
02455 static void
02456 finish_struct_anon (tree t)
02457 {
02458 tree field;
02459
02460 for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
02461 {
02462 if (TREE_STATIC (field))
02463 continue;
02464 if (TREE_CODE (field) != FIELD_DECL)
02465 continue;
02466
02467 if (DECL_NAME (field) == NULL_TREE
02468 && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
02469 {
02470 tree elt = TYPE_FIELDS (TREE_TYPE (field));
02471 for (; elt; elt = TREE_CHAIN (elt))
02472 {
02473
02474
02475
02476
02477
02478
02479
02480 if (DECL_ARTIFICIAL (elt)
02481 && (!DECL_IMPLICIT_TYPEDEF_P (elt)
02482 || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
02483 continue;
02484
02485 if (TREE_CODE (elt) != FIELD_DECL)
02486 {
02487 pedwarn ("%q+#D invalid; an anonymous union can "
02488 "only have non-static data members", elt);
02489 continue;
02490 }
02491
02492 if (TREE_PRIVATE (elt))
02493 pedwarn ("private member %q+#D in anonymous union", elt);
02494 else if (TREE_PROTECTED (elt))
02495 pedwarn ("protected member %q+#D in anonymous union", elt);
02496
02497 TREE_PRIVATE (elt) = TREE_PRIVATE (field);
02498 TREE_PROTECTED (elt) = TREE_PROTECTED (field);
02499 }
02500 }
02501 }
02502 }
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514 void
02515 maybe_add_class_template_decl_list (tree type, tree t, int friend_p)
02516 {
02517
02518 if (CLASSTYPE_TEMPLATE_INFO (type))
02519 CLASSTYPE_DECL_LIST (type)
02520 = tree_cons (friend_p ? NULL_TREE : type,
02521 t, CLASSTYPE_DECL_LIST (type));
02522 }
02523
02524
02525
02526
02527
02528
02529
02530
02531 static void
02532 add_implicitly_declared_members (tree t,
02533 int cant_have_const_cctor,
02534 int cant_have_const_assignment)
02535 {
02536
02537 if (!CLASSTYPE_DESTRUCTORS (t))
02538 {
02539
02540 CLASSTYPE_LAZY_DESTRUCTOR (t) = 1;
02541
02542
02543 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
02544 {
02545 bool lazy_p = true;
02546
02547 if (TYPE_FOR_JAVA (t))
02548
02549
02550
02551 lazy_p = false;
02552 else
02553 {
02554 tree binfo;
02555 tree base_binfo;
02556 int ix;
02557
02558
02559
02560
02561 binfo = TYPE_BINFO (t);
02562 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
02563 {
02564 tree base_type;
02565 tree dtor;
02566
02567 base_type = BINFO_TYPE (base_binfo);
02568 dtor = CLASSTYPE_DESTRUCTORS (base_type);
02569 if (dtor && DECL_VIRTUAL_P (dtor))
02570 {
02571 lazy_p = false;
02572 break;
02573 }
02574 }
02575 }
02576
02577
02578
02579 if (!lazy_p)
02580 lazily_declare_fn (sfk_destructor, t);
02581 }
02582 }
02583
02584
02585 if (! TYPE_HAS_CONSTRUCTOR (t))
02586 {
02587 TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
02588 CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
02589 }
02590
02591
02592 if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t))
02593 {
02594 TYPE_HAS_INIT_REF (t) = 1;
02595 TYPE_HAS_CONST_INIT_REF (t) = !cant_have_const_cctor;
02596 CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
02597 TYPE_HAS_CONSTRUCTOR (t) = 1;
02598 #ifdef KEY
02599 if (flag_spin_file)
02600 TYPE_HAS_IMPLICIT_COPY_CONSTRUCTOR(t) = 1;
02601 #endif
02602 }
02603
02604
02605
02606
02607
02608 if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t))
02609 {
02610 TYPE_HAS_ASSIGN_REF (t) = 1;
02611 TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment;
02612 CLASSTYPE_LAZY_ASSIGNMENT_OP (t) = 1;
02613 }
02614 }
02615
02616
02617
02618
02619 static int
02620 count_fields (tree fields)
02621 {
02622 tree x;
02623 int n_fields = 0;
02624 for (x = fields; x; x = TREE_CHAIN (x))
02625 {
02626 if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
02627 n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
02628 else
02629 n_fields += 1;
02630 }
02631 return n_fields;
02632 }
02633
02634
02635
02636
02637 static int
02638 add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx)
02639 {
02640 tree x;
02641 for (x = fields; x; x = TREE_CHAIN (x))
02642 {
02643 if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
02644 idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
02645 else
02646 field_vec->elts[idx++] = x;
02647 }
02648 return idx;
02649 }
02650
02651
02652
02653
02654
02655 static void
02656 check_bitfield_decl (tree field)
02657 {
02658 tree type = TREE_TYPE (field);
02659 tree w;
02660
02661
02662
02663 w = DECL_INITIAL (field);
02664 gcc_assert (w != NULL_TREE);
02665
02666
02667 DECL_INITIAL (field) = NULL_TREE;
02668
02669
02670 if (!INTEGRAL_TYPE_P (type))
02671 {
02672 error ("bit-field %q+#D with non-integral type", field);
02673 TREE_TYPE (field) = error_mark_node;
02674 w = error_mark_node;
02675 }
02676 else
02677 {
02678
02679 STRIP_NOPS (w);
02680
02681
02682 w = integral_constant_value (w);
02683
02684 if (TREE_CODE (w) != INTEGER_CST)
02685 {
02686 error ("bit-field %q+D width not an integer constant", field);
02687 w = error_mark_node;
02688 }
02689 else if (tree_int_cst_sgn (w) < 0)
02690 {
02691 error ("negative width in bit-field %q+D", field);
02692 w = error_mark_node;
02693 }
02694 else if (integer_zerop (w) && DECL_NAME (field) != 0)
02695 {
02696 error ("zero width for bit-field %q+D", field);
02697 w = error_mark_node;
02698 }
02699 else if (compare_tree_int (w, TYPE_PRECISION (type)) > 0
02700 && TREE_CODE (type) != ENUMERAL_TYPE
02701 && TREE_CODE (type) != BOOLEAN_TYPE)
02702 warning (0, "width of %q+D exceeds its type", field);
02703 else if (TREE_CODE (type) == ENUMERAL_TYPE
02704 && (0 > compare_tree_int (w,
02705 min_precision (TYPE_MIN_VALUE (type),
02706 TYPE_UNSIGNED (type)))
02707 || 0 > compare_tree_int (w,
02708 min_precision
02709 (TYPE_MAX_VALUE (type),
02710 TYPE_UNSIGNED (type)))))
02711 warning (0, "%q+D is too small to hold all values of %q#T", field, type);
02712 }
02713
02714 if (w != error_mark_node)
02715 {
02716 DECL_SIZE (field) = convert (bitsizetype, w);
02717 DECL_BIT_FIELD (field) = 1;
02718 }
02719 else
02720 {
02721
02722 DECL_BIT_FIELD (field) = 0;
02723 CLEAR_DECL_C_BIT_FIELD (field);
02724 }
02725 }
02726
02727
02728
02729
02730
02731 static void
02732 check_field_decl (tree field,
02733 tree t,
02734 int* cant_have_const_ctor,
02735 int* no_const_asn_ref,
02736 int* any_default_members)
02737 {
02738 tree type = strip_array_types (TREE_TYPE (field));
02739
02740
02741
02742 if (ANON_UNION_TYPE_P (type))
02743 ;
02744
02745
02746 else if (ANON_AGGR_TYPE_P (type))
02747 {
02748 tree fields;
02749
02750 for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
02751 if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
02752 check_field_decl (fields, t, cant_have_const_ctor,
02753 no_const_asn_ref, any_default_members);
02754 }
02755
02756
02757 else if (CLASS_TYPE_P (type))
02758 {
02759
02760
02761 abstract_virtuals_error (field, type);
02762
02763 if (TREE_CODE (t) == UNION_TYPE)
02764 {
02765 if (TYPE_NEEDS_CONSTRUCTING (type))
02766 error ("member %q+#D with constructor not allowed in union",
02767 field);
02768 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
02769 error ("member %q+#D with destructor not allowed in union", field);
02770 if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))
02771 error ("member %q+#D with copy assignment operator not allowed in union",
02772 field);
02773 }
02774 else
02775 {
02776 TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);
02777 TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
02778 |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type);
02779 TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type);
02780 TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type);
02781 }
02782
02783 if (!TYPE_HAS_CONST_INIT_REF (type))
02784 *cant_have_const_ctor = 1;
02785
02786 if (!TYPE_HAS_CONST_ASSIGN_REF (type))
02787 *no_const_asn_ref = 1;
02788 }
02789 if (DECL_INITIAL (field) != NULL_TREE)
02790 {
02791
02792
02793 if (TREE_CODE (t) == UNION_TYPE && any_default_members != 0)
02794 error ("multiple fields in union %qT initialized", t);
02795 *any_default_members = 1;
02796 }
02797 }
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824 static void
02825 check_field_decls (tree t, tree *access_decls,
02826 int *cant_have_const_ctor_p,
02827 int *no_const_asn_ref_p)
02828 {
02829 tree *field;
02830 tree *next;
02831 bool has_pointers;
02832 int any_default_members;
02833 int cant_pack = 0;
02834
02835
02836 *access_decls = NULL_TREE;
02837
02838 has_pointers = false;
02839
02840
02841 any_default_members = 0;
02842
02843 for (field = &TYPE_FIELDS (t); *field; field = next)
02844 {
02845 tree x = *field;
02846 tree type = TREE_TYPE (x);
02847
02848 next = &TREE_CHAIN (x);
02849
02850 if (TREE_CODE (x) == USING_DECL)
02851 {
02852
02853 *field = TREE_CHAIN (x);
02854
02855
02856 *access_decls = tree_cons (NULL_TREE, x, *access_decls);
02857
02858
02859
02860 next = field;
02861 continue;
02862 }
02863
02864 if (TREE_CODE (x) == TYPE_DECL
02865 || TREE_CODE (x) == TEMPLATE_DECL)
02866 continue;
02867
02868
02869
02870 DECL_CONTEXT (x) = t;
02871
02872
02873 DECL_NONLOCAL (x) = 1;
02874
02875 if (TREE_CODE (t) == UNION_TYPE)
02876 {
02877
02878
02879
02880
02881 if (TREE_CODE (x) == VAR_DECL)
02882 {
02883 error ("%q+D may not be static because it is a member of a union", x);
02884 continue;
02885 }
02886 if (TREE_CODE (type) == REFERENCE_TYPE)
02887 {
02888 error ("%q+D may not have reference type %qT because"
02889 " it is a member of a union",
02890 x, type);
02891 continue;
02892 }
02893 }
02894
02895
02896
02897 if (TREE_CODE (type) == FUNCTION_TYPE)
02898 {
02899 error ("field %q+D invalidly declared function type", x);
02900 type = build_pointer_type (type);
02901 TREE_TYPE (x) = type;
02902 }
02903 else if (TREE_CODE (type) == METHOD_TYPE)
02904 {
02905 error ("field %q+D invalidly declared method type", x);
02906 type = build_pointer_type (type);
02907 TREE_TYPE (x) = type;
02908 }
02909
02910 if (type == error_mark_node)
02911 continue;
02912
02913 if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
02914 continue;
02915
02916
02917
02918 if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
02919 CLASSTYPE_NON_AGGREGATE (t) = 1;
02920
02921
02922
02923 if (TREE_CODE (type) == REFERENCE_TYPE)
02924 {
02925 CLASSTYPE_NON_POD_P (t) = 1;
02926 if (DECL_INITIAL (x) == NULL_TREE)
02927 SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
02928
02929
02930
02931
02932
02933 TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
02934
02935 if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
02936 && extra_warnings)
02937 warning (OPT_Wextra, "non-static reference %q+#D in class without a constructor", x);
02938 }
02939
02940 type = strip_array_types (type);
02941
02942 if (TYPE_PACKED (t))
02943 {
02944 if (!pod_type_p (type) && !TYPE_PACKED (type))
02945 {
02946 warning
02947 (0,
02948 "ignoring packed attribute because of unpacked non-POD field %q+#D",
02949 x);
02950 cant_pack = 1;
02951 }
02952 else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
02953 DECL_PACKED (x) = 1;
02954 }
02955
02956 if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
02957
02958
02959 ;
02960 else
02961 {
02962
02963 CLASSTYPE_EMPTY_P (t) = 0;
02964
02965 CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
02966
02967
02968 if (CLASS_TYPE_P (type)
02969 && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
02970 CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
02971 }
02972
02973
02974
02975
02976 if (TYPE_PTR_P (type)
02977 && !TYPE_PTRFN_P (type)
02978 && !TYPE_PTR_TO_MEMBER_P (type))
02979 has_pointers = true;
02980
02981 if (CLASS_TYPE_P (type))
02982 {
02983 if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
02984 SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
02985 if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
02986 SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
02987 }
02988
02989 if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
02990 CLASSTYPE_HAS_MUTABLE (t) = 1;
02991
02992 if (! pod_type_p (type))
02993
02994
02995 CLASSTYPE_NON_POD_P (t) = 1;
02996
02997 if (! zero_init_p (type))
02998 CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
02999
03000
03001 if (CP_TYPE_CONST_P (type))
03002 {
03003 C_TYPE_FIELDS_READONLY (t) = 1;
03004 if (DECL_INITIAL (x) == NULL_TREE)
03005 SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
03006
03007
03008
03009
03010
03011 TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
03012
03013 if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)
03014 && extra_warnings)
03015 warning (OPT_Wextra, "non-static const member %q+#D in class without a constructor", x);
03016 }
03017
03018 else if (CLASS_TYPE_P (type))
03019 {
03020 C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type);
03021 SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t,
03022 CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
03023 | CLASSTYPE_READONLY_FIELDS_NEED_INIT (type));
03024 }
03025
03026
03027
03028
03029 if (constructor_name_p (DECL_NAME (x), t) && TYPE_HAS_CONSTRUCTOR (t))
03030 pedwarn ("field %q+#D with same name as class", x);
03031
03032
03033
03034 if (DECL_C_BIT_FIELD (x))
03035 check_bitfield_decl (x);
03036 else
03037 check_field_decl (x, t,
03038 cant_have_const_ctor_p,
03039 no_const_asn_ref_p,
03040 &any_default_members);
03041 }
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057 if (warn_ecpp
03058 && has_pointers
03059 && TYPE_HAS_CONSTRUCTOR (t)
03060 && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
03061 && !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
03062 {
03063 warning (OPT_Weffc__, "%q#T has pointer data members", t);
03064
03065 if (! TYPE_HAS_INIT_REF (t))
03066 {
03067 warning (OPT_Weffc__,
03068 " but does not override %<%T(const %T&)%>", t, t);
03069 if (!TYPE_HAS_ASSIGN_REF (t))
03070 warning (OPT_Weffc__, " or %<operator=(const %T&)%>", t);
03071 }
03072 else if (! TYPE_HAS_ASSIGN_REF (t))
03073 warning (OPT_Weffc__,
03074 " but does not override %<operator=(const %T&)%>", t);
03075 }
03076
03077
03078 if (cant_pack)
03079 TYPE_PACKED (t) = 0;
03080
03081
03082 finish_struct_anon (t);
03083
03084
03085
03086 *access_decls = nreverse (*access_decls);
03087 }
03088
03089
03090
03091
03092 static int
03093 record_subobject_offset (tree type, tree offset, splay_tree offsets)
03094 {
03095 splay_tree_node n;
03096
03097 if (!is_empty_class (type))
03098 return 0;
03099
03100
03101 n = splay_tree_lookup (offsets, (splay_tree_key) offset);
03102 if (!n)
03103 n = splay_tree_insert (offsets,
03104 (splay_tree_key) offset,
03105 (splay_tree_value) NULL_TREE);
03106 n->value = ((splay_tree_value)
03107 tree_cons (NULL_TREE,
03108 type,
03109 (tree) n->value));
03110
03111 return 0;
03112 }
03113
03114
03115
03116
03117 static int
03118 check_subobject_offset (tree type, tree offset, splay_tree offsets)
03119 {
03120 splay_tree_node n;
03121 tree t;
03122
03123 if (!is_empty_class (type))
03124 return 0;
03125
03126
03127 n = splay_tree_lookup (offsets, (splay_tree_key) offset);
03128 if (!n)
03129 return 0;
03130
03131 for (t = (tree) n->value; t; t = TREE_CHAIN (t))
03132 if (same_type_p (TREE_VALUE (t), type))
03133 return 1;
03134
03135 return 0;
03136 }
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149 static int
03150 walk_subobject_offsets (tree type,
03151 subobject_offset_fn f,
03152 tree offset,
03153 splay_tree offsets,
03154 tree max_offset,
03155 int vbases_p)
03156 {
03157 int r = 0;
03158 tree type_binfo = NULL_TREE;
03159
03160
03161
03162 if (max_offset && INT_CST_LT (max_offset, offset))
03163 return 0;
03164
03165 if (type == error_mark_node)
03166 return 0;
03167
03168 if (!TYPE_P (type))
03169 {
03170 if (abi_version_at_least (2))
03171 type_binfo = type;
03172 type = BINFO_TYPE (type);
03173 }
03174
03175 if (CLASS_TYPE_P (type))
03176 {
03177 tree field;
03178 tree binfo;
03179 int i;
03180
03181
03182 if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
03183 return 0;
03184
03185
03186 r = (*f) (type, offset, offsets);
03187 if (r)
03188 return r;
03189
03190
03191 if (!type_binfo)
03192 type_binfo = TYPE_BINFO (type);
03193 for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, binfo); i++)
03194 {
03195 tree binfo_offset;
03196
03197 if (abi_version_at_least (2)
03198 && BINFO_VIRTUAL_P (binfo))
03199 continue;
03200
03201 if (!vbases_p
03202 && BINFO_VIRTUAL_P (binfo)
03203 && !BINFO_PRIMARY_P (binfo))
03204 continue;
03205
03206 if (!abi_version_at_least (2))
03207 binfo_offset = size_binop (PLUS_EXPR,
03208 offset,
03209 BINFO_OFFSET (binfo));
03210 else
03211 {
03212 tree orig_binfo;
03213
03214
03215
03216 orig_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
03217 binfo_offset = size_binop (PLUS_EXPR,
03218 offset,
03219 BINFO_OFFSET (orig_binfo));
03220 }
03221
03222 r = walk_subobject_offsets (binfo,
03223 f,
03224 binfo_offset,
03225 offsets,
03226 max_offset,
03227 (abi_version_at_least (2)
03228 ? 0 : vbases_p));
03229 if (r)
03230 return r;
03231 }
03232
03233 if (abi_version_at_least (2) && CLASSTYPE_VBASECLASSES (type))
03234 {
03235 unsigned ix;
03236 VEC(tree,gc) *vbases;
03237
03238
03239
03240
03241
03242
03243 if (vbases_p)
03244 for (vbases = CLASSTYPE_VBASECLASSES (type), ix = 0;
03245 VEC_iterate (tree, vbases, ix, binfo); ix++)
03246 {
03247 r = walk_subobject_offsets (binfo,
03248 f,
03249 size_binop (PLUS_EXPR,
03250 offset,
03251 BINFO_OFFSET (binfo)),
03252 offsets,
03253 max_offset,
03254 0);
03255 if (r)
03256 return r;
03257 }
03258 else
03259 {
03260
03261
03262
03263 tree vbase = get_primary_binfo (type_binfo);
03264
03265 if (vbase && BINFO_VIRTUAL_P (vbase)
03266 && BINFO_PRIMARY_P (vbase)
03267 && BINFO_INHERITANCE_CHAIN (vbase) == type_binfo)
03268 {
03269 r = (walk_subobject_offsets
03270 (vbase, f, offset,
03271 offsets, max_offset, 0));
03272 if (r)
03273 return r;
03274 }
03275 }
03276 }
03277
03278
03279 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
03280 if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field))
03281 {
03282 tree field_offset;
03283
03284 if (abi_version_at_least (2))
03285 field_offset = byte_position (field);
03286 else
03287
03288 field_offset = DECL_FIELD_OFFSET (field);
03289
03290 r = walk_subobject_offsets (TREE_TYPE (field),
03291 f,
03292 size_binop (PLUS_EXPR,
03293 offset,
03294 field_offset),
03295 offsets,
03296 max_offset,
03297 1);
03298 if (r)
03299 return r;
03300 }
03301 }
03302 else if (TREE_CODE (type) == ARRAY_TYPE)
03303 {
03304 tree element_type = strip_array_types (type);
03305 tree domain = TYPE_DOMAIN (type);
03306 tree index;
03307
03308
03309 if (!CLASS_TYPE_P (element_type)
03310 || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
03311 return 0;
03312
03313
03314 for (index = size_zero_node;
03315
03316 (abi_version_at_least (2)
03317 ? !INT_CST_LT (TYPE_MAX_VALUE (domain), index)
03318 : INT_CST_LT (index, TYPE_MAX_VALUE (domain)));
03319 index = size_binop (PLUS_EXPR, index, size_one_node))
03320 {
03321 r = walk_subobject_offsets (TREE_TYPE (type),
03322 f,
03323 offset,
03324 offsets,
03325 max_offset,
03326 1);
03327 if (r)
03328 return r;
03329 offset = size_binop (PLUS_EXPR, offset,
03330 TYPE_SIZE_UNIT (TREE_TYPE (type)));
03331
03332
03333
03334 if (max_offset && INT_CST_LT (max_offset, offset))
03335 break;
03336 }
03337 }
03338
03339 return 0;
03340 }
03341
03342
03343
03344
03345
03346
03347 static void
03348 record_subobject_offsets (tree type,
03349 tree offset,
03350 splay_tree offsets,
03351 bool is_data_member)
03352 {
03353 tree max_offset;
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367 if (is_data_member
03368 || !is_empty_class (BINFO_TYPE (type)))
03369 max_offset = sizeof_biggest_empty_class;
03370 else
03371 max_offset = NULL_TREE;
03372 walk_subobject_offsets (type, record_subobject_offset, offset,
03373 offsets, max_offset, is_data_member);
03374 }
03375
03376
03377
03378
03379
03380 static int
03381 layout_conflict_p (tree type,
03382 tree offset,
03383 splay_tree offsets,
03384 int vbases_p)
03385 {
03386 splay_tree_node max_node;
03387
03388
03389
03390 max_node = splay_tree_max (offsets);
03391
03392
03393 if (!max_node)
03394 return 0;
03395
03396 return walk_subobject_offsets (type, check_subobject_offset, offset,
03397 offsets, (tree) (max_node->key),
03398 vbases_p);
03399 }
03400
03401
03402
03403
03404
03405
03406
03407 static void
03408 layout_nonempty_base_or_field (record_layout_info rli,
03409 tree decl,
03410 tree binfo,
03411 splay_tree offsets)
03412 {
03413 tree offset = NULL_TREE;
03414 bool field_p;
03415 tree type;
03416
03417 if (binfo)
03418 {
03419
03420
03421
03422
03423 type = TREE_TYPE (binfo);
03424 field_p = false;
03425 }
03426 else
03427 {
03428 type = TREE_TYPE (decl);
03429 field_p = true;
03430 }
03431
03432
03433
03434
03435 while (1)
03436 {
03437 struct record_layout_info_s old_rli = *rli;
03438
03439
03440 place_field (rli, decl);
03441 offset = byte_position (decl);
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460 if (TREE_CODE (rli->t) == UNION_TYPE)
03461 break;
03462
03463
03464 if (!abi_version_at_least (2) && binfo && BINFO_VIRTUAL_P (binfo))
03465 break;
03466 if (layout_conflict_p (field_p ? type : binfo, offset,
03467 offsets, field_p))
03468 {
03469
03470
03471
03472 *rli = old_rli;
03473
03474
03475 rli->bitpos
03476 = size_binop (PLUS_EXPR, rli->bitpos,
03477 bitsize_int (binfo
03478 ? CLASSTYPE_ALIGN (type)
03479 : TYPE_ALIGN (type)));
03480 normalize_rli (rli);
03481 }
03482 else
03483
03484 break;
03485 }
03486
03487
03488
03489 if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
03490
03491
03492
03493
03494 propagate_binfo_offsets (binfo,
03495 size_diffop (convert (ssizetype, offset),
03496 convert (ssizetype,
03497 BINFO_OFFSET (binfo))));
03498 }
03499
03500
03501
03502 static int
03503 empty_base_at_nonzero_offset_p (tree type,
03504 tree offset,
03505 splay_tree offsets ATTRIBUTE_UNUSED)
03506 {
03507 return is_empty_class (type) && !integer_zerop (offset);
03508 }
03509
03510
03511
03512
03513
03514
03515
03516 static bool
03517 layout_empty_base (tree binfo, tree eoc, splay_tree offsets)
03518 {
03519 tree alignment;
03520 tree basetype = BINFO_TYPE (binfo);
03521 bool atend = false;
03522
03523
03524 gcc_assert (is_empty_class (basetype));
03525 alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype));
03526
03527 if (!integer_zerop (BINFO_OFFSET (binfo)))
03528 {
03529 if (abi_version_at_least (2))
03530 propagate_binfo_offsets
03531 (binfo, size_diffop (size_zero_node, BINFO_OFFSET (binfo)));
03532 else
03533 warning (OPT_Wabi,
03534 "offset of empty base %qT may not be ABI-compliant and may"
03535 "change in a future version of GCC",
03536 BINFO_TYPE (binfo));
03537 }
03538
03539
03540
03541 if (layout_conflict_p (binfo,
03542 BINFO_OFFSET (binfo),
03543 offsets,
03544 0))
03545 {
03546
03547
03548 atend = true;
03549 propagate_binfo_offsets (binfo, convert (ssizetype, eoc));
03550 while (1)
03551 {
03552 if (!layout_conflict_p (binfo,
03553 BINFO_OFFSET (binfo),
03554 offsets,
03555 0))
03556
03557 break;
03558
03559
03560 propagate_binfo_offsets (binfo, alignment);
03561 }
03562 }
03563 return atend;
03564 }
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575 static tree *
03576 build_base_field (record_layout_info rli, tree binfo,
03577 splay_tree offsets, tree *next_field)
03578 {
03579 tree t = rli->t;
03580 tree basetype = BINFO_TYPE (binfo);
03581
03582 if (!COMPLETE_TYPE_P (basetype))
03583
03584
03585 return next_field;
03586
03587
03588 if (!is_empty_class (basetype))
03589 {
03590 tree decl;
03591
03592
03593
03594 CLASSTYPE_EMPTY_P (t) = 0;
03595
03596
03597 decl = build_decl (FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
03598 DECL_ARTIFICIAL (decl) = 1;
03599 DECL_IGNORED_P (decl) = 1;
03600 DECL_FIELD_CONTEXT (decl) = t;
03601 DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
03602 DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
03603 DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
03604 DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
03605 DECL_MODE (decl) = TYPE_MODE (basetype);
03606 DECL_FIELD_IS_BASE (decl) = 1;
03607
03608
03609
03610
03611 layout_nonempty_base_or_field (rli, decl, binfo, offsets);
03612
03613 TREE_CHAIN (decl) = *next_field;
03614 *next_field = decl;
03615 next_field = &TREE_CHAIN (decl);
03616 }
03617 else
03618 {
03619 tree eoc;
03620 bool atend;
03621
03622
03623
03624 eoc = round_up (rli_size_unit_so_far (rli),
03625 CLASSTYPE_ALIGN_UNIT (basetype));
03626 atend = layout_empty_base (binfo, eoc, offsets);
03627
03628
03629 if (!BINFO_VIRTUAL_P (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
03630 {
03631 if (atend)
03632 CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
03633
03634
03635
03636 else if (walk_subobject_offsets (basetype,
03637 empty_base_at_nonzero_offset_p,
03638 size_zero_node,
03639 NULL,
03640 NULL_TREE,
03641 true))
03642 {
03643 if (abi_version_at_least (2))
03644 CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
03645 else
03646 warning (OPT_Wabi,
03647 "class %qT will be considered nearly empty in a "
03648 "future version of GCC", t);
03649 }
03650 }
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662 }
03663
03664
03665 record_subobject_offsets (binfo,
03666 BINFO_OFFSET (binfo),
03667 offsets,
03668 false);
03669
03670 return next_field;
03671 }
03672
03673
03674
03675
03676
03677
03678
03679 static void
03680 build_base_fields (record_layout_info rli,
03681 splay_tree offsets, tree *next_field)
03682 {
03683
03684
03685 tree t = rli->t;
03686 int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
03687 int i;
03688
03689
03690 if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
03691 next_field = build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (t),
03692 offsets, next_field);
03693
03694
03695 for (i = 0; i < n_baseclasses; ++i)
03696 {
03697 tree base_binfo;
03698
03699 base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (t), i);
03700
03701
03702
03703 if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))
03704 continue;
03705
03706
03707
03708 if (BINFO_VIRTUAL_P (base_binfo))
03709 continue;
03710
03711 next_field = build_base_field (rli, base_binfo,
03712 offsets, next_field);
03713 }
03714 }
03715
03716
03717
03718
03719
03720 static void
03721 check_methods (tree t)
03722 {
03723 tree x;
03724
03725 for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
03726 {
03727 check_for_override (x, t);
03728 if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
03729 error ("initializer specified for non-virtual method %q+D", x);
03730
03731
03732 if (DECL_VINDEX (x))
03733 {
03734 TYPE_POLYMORPHIC_P (t) = 1;
03735 if (DECL_PURE_VIRTUAL_P (x))
03736 VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
03737 }
03738
03739 if (DECL_DESTRUCTOR_P (x))
03740 TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
03741 }
03742 }
03743
03744
03745
03746
03747
03748 static tree
03749 build_clone (tree fn, tree name)
03750 {
03751 tree parms;
03752 tree clone;
03753
03754
03755 clone = copy_decl (fn);
03756
03757 DECL_CLONED_FUNCTION (clone) = fn;
03758 DECL_ABSTRACT_ORIGIN (clone) = fn;
03759
03760 DECL_NAME (clone) = name;
03761 SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
03762
03763 DECL_PENDING_INLINE_INFO (clone) = NULL;
03764 DECL_PENDING_INLINE_P (clone) = 0;
03765
03766 DECL_DEFERRED_FN (clone) = 0;
03767
03768
03769 if (name == base_dtor_identifier)
03770 {
03771 DECL_VIRTUAL_P (clone) = 0;
03772 if (TREE_CODE (clone) != TEMPLATE_DECL)
03773 DECL_VINDEX (clone) = NULL_TREE;
03774 }
03775
03776
03777
03778 if (DECL_HAS_IN_CHARGE_PARM_P (clone))
03779 {
03780 tree basetype;
03781 tree parmtypes;
03782 tree exceptions;
03783
03784 exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
03785 basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
03786 parmtypes = TYPE_ARG_TYPES (TREE_TYPE (clone));
03787
03788 parmtypes = TREE_CHAIN (parmtypes);
03789
03790 parmtypes = TREE_CHAIN (parmtypes);
03791
03792 if (DECL_HAS_VTT_PARM_P (fn)
03793 && ! DECL_NEEDS_VTT_PARM_P (clone))
03794 parmtypes = TREE_CHAIN (parmtypes);
03795
03796
03797 TREE_TYPE (clone)
03798 = build_method_type_directly (basetype,
03799 TREE_TYPE (TREE_TYPE (clone)),
03800 parmtypes);
03801 if (exceptions)
03802 TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
03803 exceptions);
03804 TREE_TYPE (clone)
03805 = cp_build_type_attribute_variant (TREE_TYPE (clone),
03806 TYPE_ATTRIBUTES (TREE_TYPE (fn)));
03807 }
03808
03809
03810
03811 if (TREE_CODE (clone) != TEMPLATE_DECL)
03812 {
03813 DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
03814
03815 if (DECL_HAS_IN_CHARGE_PARM_P (clone))
03816 {
03817 TREE_CHAIN (DECL_ARGUMENTS (clone))
03818 = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
03819 DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
03820 }
03821
03822 if (DECL_HAS_VTT_PARM_P (fn))
03823 {
03824 if (DECL_NEEDS_VTT_PARM_P (clone))
03825 DECL_HAS_VTT_PARM_P (clone) = 1;
03826 else
03827 {
03828 TREE_CHAIN (DECL_ARGUMENTS (clone))
03829 = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
03830 DECL_HAS_VTT_PARM_P (clone) = 0;
03831 }
03832 }
03833
03834 for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
03835 {
03836 DECL_CONTEXT (parms) = clone;
03837 cxx_dup_lang_specific_decl (parms);
03838 }
03839 }
03840
03841
03842 SET_DECL_RTL (clone, NULL_RTX);
03843 rest_of_decl_compilation (clone, 1, at_eof);
03844
03845
03846 TREE_CHAIN (clone) = TREE_CHAIN (fn);
03847 TREE_CHAIN (fn) = clone;
03848
03849
03850 if (TREE_CODE (clone) == TEMPLATE_DECL)
03851 {
03852 tree result;
03853
03854 DECL_TEMPLATE_RESULT (clone)
03855 = build_clone (DECL_TEMPLATE_RESULT (clone), name);
03856 result = DECL_TEMPLATE_RESULT (clone);
03857 DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
03858 DECL_TI_TEMPLATE (result) = clone;
03859 }
03860 else if (pch_file)
03861 note_decl_for_pch (clone);
03862
03863 return clone;
03864 }
03865
03866
03867
03868
03869
03870 void
03871 clone_function_decl (tree fn, int update_method_vec_p)
03872 {
03873 tree clone;
03874
03875
03876 if (TREE_CHAIN (fn)
03877 && DECL_CLONED_FUNCTION (TREE_CHAIN (fn)))
03878 return;
03879
03880 if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
03881 {
03882
03883
03884 clone = build_clone (fn, complete_ctor_identifier);
03885 if (update_method_vec_p)
03886 add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
03887 #ifdef KEY
03888
03889
03890 if (flag_spin_file)
03891 {
03892 tree type = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
03893 if (!TYPE_HAS_IMPLICIT_COPY_CONSTRUCTOR (type) &&
03894 DECL_COPY_CONSTRUCTOR_P (clone)) {
03895 if (!DECL_COMPLETE_CONSTRUCTOR_P (clone))
03896 abort ();
03897 CLASSTYPE_COPY_CONSTRUCTOR (type) = clone;
03898 }
03899 }
03900 #endif
03901 clone = build_clone (fn, base_ctor_identifier);
03902 if (update_method_vec_p)
03903 add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
03904 }
03905 else
03906 {
03907 gcc_assert (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918 if (DECL_VIRTUAL_P (fn))
03919 {
03920 clone = build_clone (fn, deleting_dtor_identifier);
03921 if (update_method_vec_p)
03922 add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
03923 }
03924 clone = build_clone (fn, complete_dtor_identifier);
03925 if (update_method_vec_p)
03926 add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
03927 clone = build_clone (fn, base_dtor_identifier);
03928 if (update_method_vec_p)
03929 add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
03930 }
03931
03932
03933 DECL_ABSTRACT (fn) = 1;
03934 }
03935
03936
03937
03938
03939
03940
03941
03942
03943 void
03944 adjust_clone_args (tree decl)
03945 {
03946 tree clone;
03947
03948 for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION (clone);
03949 clone = TREE_CHAIN (clone))
03950 {
03951 tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
03952 tree orig_decl_parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
03953 tree decl_parms, clone_parms;
03954
03955 clone_parms = orig_clone_parms;
03956
03957
03958 orig_clone_parms = TREE_CHAIN (orig_clone_parms);
03959 orig_decl_parms = TREE_CHAIN (orig_decl_parms);
03960
03961 if (DECL_HAS_IN_CHARGE_PARM_P (decl))
03962 orig_decl_parms = TREE_CHAIN (orig_decl_parms);
03963 if (DECL_HAS_VTT_PARM_P (decl))
03964 orig_decl_parms = TREE_CHAIN (orig_decl_parms);
03965
03966 clone_parms = orig_clone_parms;
03967 if (DECL_HAS_VTT_PARM_P (clone))
03968 clone_parms = TREE_CHAIN (clone_parms);
03969
03970 for (decl_parms = orig_decl_parms; decl_parms;
03971 decl_parms = TREE_CHAIN (decl_parms),
03972 clone_parms = TREE_CHAIN (clone_parms))
03973 {
03974 gcc_assert (same_type_p (TREE_TYPE (decl_parms),
03975 TREE_TYPE (clone_parms)));
03976
03977 if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms))
03978 {
03979
03980
03981 tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
03982 tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
03983 tree type;
03984
03985 clone_parms = orig_decl_parms;
03986
03987 if (DECL_HAS_VTT_PARM_P (clone))
03988 {
03989 clone_parms = tree_cons (TREE_PURPOSE (orig_clone_parms),
03990 TREE_VALUE (orig_clone_parms),
03991 clone_parms);
03992 TREE_TYPE (clone_parms) = TREE_TYPE (orig_clone_parms);
03993 }
03994 type = build_method_type_directly (basetype,
03995 TREE_TYPE (TREE_TYPE (clone)),
03996 clone_parms);
03997 if (exceptions)
03998 type = build_exception_variant (type, exceptions);
03999 TREE_TYPE (clone) = type;
04000
04001 clone_parms = NULL_TREE;
04002 break;
04003 }
04004 }
04005 gcc_assert (!clone_parms);
04006 }
04007 }
04008
04009
04010
04011
04012 static void
04013 clone_constructors_and_destructors (tree t)
04014 {
04015 tree fns;
04016
04017
04018
04019 if (!CLASSTYPE_METHOD_VEC (t))
04020 return;
04021
04022 for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
04023 clone_function_decl (OVL_CURRENT (fns), 1);
04024 for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
04025 clone_function_decl (OVL_CURRENT (fns), 1);
04026 }
04027
04028
04029
04030 static void
04031 remove_zero_width_bit_fields (tree t)
04032 {
04033 tree *fieldsp;
04034
04035 fieldsp = &TYPE_FIELDS (t);
04036 while (*fieldsp)
04037 {
04038 if (TREE_CODE (*fieldsp) == FIELD_DECL
04039 && DECL_C_BIT_FIELD (*fieldsp)
04040 && DECL_INITIAL (*fieldsp))
04041 *fieldsp = TREE_CHAIN (*fieldsp);
04042 else
04043 fieldsp = &TREE_CHAIN (*fieldsp);
04044 }
04045 }
04046
04047
04048
04049
04050 static bool
04051 type_requires_array_cookie (tree type)
04052 {
04053 tree fns;
04054 bool has_two_argument_delete_p = false;
04055
04056 gcc_assert (CLASS_TYPE_P (type));
04057
04058
04059
04060
04061 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
04062 return true;
04063
04064
04065
04066
04067
04068 fns = lookup_fnfields (TYPE_BINFO (type),
04069 ansi_opname (VEC_DELETE_EXPR),
04070 0);
04071
04072
04073 if (!fns || fns == error_mark_node)
04074 return false;
04075
04076 for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
04077 {
04078 tree fn;
04079 tree second_parm;
04080
04081
04082 fn = OVL_CURRENT (fns);
04083
04084
04085 second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
04086 if (second_parm == void_list_node)
04087 return false;
04088
04089
04090
04091 if (TREE_CHAIN (second_parm) == void_list_node
04092 && same_type_p (TREE_VALUE (second_parm), sizetype))
04093 has_two_argument_delete_p = true;
04094 }
04095
04096 return has_two_argument_delete_p;
04097 }
04098
04099
04100
04101
04102
04103
04104
04105 static void
04106 check_bases_and_members (tree t)
04107 {
04108
04109
04110 int cant_have_const_ctor;
04111
04112
04113 int no_const_asn_ref;
04114 tree access_decls;
04115
04116
04117
04118 cant_have_const_ctor = 0;
04119 no_const_asn_ref = 0;
04120
04121
04122 check_bases (t, &cant_have_const_ctor,
04123 &no_const_asn_ref);
04124
04125
04126 check_methods (t);
04127
04128
04129
04130
04131
04132 check_field_decls (t, &access_decls,
04133 &cant_have_const_ctor,
04134 &no_const_asn_ref);
04135
04136
04137
04138 if (!TYPE_CONTAINS_VPTR_P (t))
04139 CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
04140
04141
04142
04143 TYPE_HAS_COMPLEX_INIT_REF (t)
04144 |= (TYPE_HAS_INIT_REF (t) || TYPE_CONTAINS_VPTR_P (t));
04145 TYPE_NEEDS_CONSTRUCTING (t)
04146 |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
04147 CLASSTYPE_NON_AGGREGATE (t)
04148 |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_POLYMORPHIC_P (t));
04149 CLASSTYPE_NON_POD_P (t)
04150 |= (CLASSTYPE_NON_AGGREGATE (t)
04151 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
04152 || TYPE_HAS_ASSIGN_REF (t));
04153 TYPE_HAS_COMPLEX_ASSIGN_REF (t)
04154 |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
04155
04156
04157 add_implicitly_declared_members (t,
04158 cant_have_const_ctor,
04159 no_const_asn_ref);
04160
04161
04162
04163 clone_constructors_and_destructors (t);
04164
04165
04166 for (; access_decls; access_decls = TREE_CHAIN (access_decls))
04167 handle_using_decl (TREE_VALUE (access_decls), t);
04168
04169
04170 finish_struct_methods (t);
04171
04172
04173
04174 TYPE_LANG_SPECIFIC (t)->u.c.vec_new_uses_cookie
04175 = type_requires_array_cookie (t);
04176 }
04177
04178
04179
04180
04181
04182
04183
04184
04185 static tree
04186 create_vtable_ptr (tree t, tree* virtuals_p)
04187 {
04188 tree fn;
04189
04190
04191 for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
04192 if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
04193 && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
04194 {
04195 tree new_virtual = make_node (TREE_LIST);
04196
04197 BV_FN (new_virtual) = fn;
04198 BV_DELTA (new_virtual) = integer_zero_node;
04199 BV_VCALL_INDEX (new_virtual) = NULL_TREE;
04200
04201 TREE_CHAIN (new_virtual) = *virtuals_p;
04202 *virtuals_p = new_virtual;
04203 }
04204
04205
04206
04207
04208
04209 if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))
04210 {
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230 tree field;
04231
04232 field = build_decl (FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
04233 DECL_VIRTUAL_P (field) = 1;
04234 DECL_ARTIFICIAL (field) = 1;
04235 DECL_FIELD_CONTEXT (field) = t;
04236 DECL_FCONTEXT (field) = t;
04237
04238 TYPE_VFIELD (t) = field;
04239
04240
04241 CLASSTYPE_EMPTY_P (t) = 0;
04242
04243 return field;
04244 }
04245
04246 return NULL_TREE;
04247 }
04248
04249
04250
04251
04252 static void
04253 fixup_pending_inline (tree fn)
04254 {
04255 if (DECL_PENDING_INLINE_INFO (fn))
04256 {
04257 tree args = DECL_ARGUMENTS (fn);
04258 while (args)
04259 {
04260 DECL_CONTEXT (args) = fn;
04261 args = TREE_CHAIN (args);
04262 }
04263 }
04264 }
04265
04266
04267
04268
04269 static void
04270 fixup_inline_methods (tree type)
04271 {
04272 tree method = TYPE_METHODS (type);
04273 VEC(tree,gc) *friends;
04274 unsigned ix;
04275
04276 if (method && TREE_CODE (method) == TREE_VEC)
04277 {
04278 if (TREE_VEC_ELT (method, 1))
04279 method = TREE_VEC_ELT (method, 1);
04280 else if (TREE_VEC_ELT (method, 0))
04281 method = TREE_VEC_ELT (method, 0);
04282 else
04283 method = TREE_VEC_ELT (method, 2);
04284 }
04285
04286
04287 for (; method; method = TREE_CHAIN (method))
04288 fixup_pending_inline (method);
04289
04290
04291 for (friends = CLASSTYPE_INLINE_FRIENDS (type), ix = 0;
04292 VEC_iterate (tree, friends, ix, method); ix++)
04293 fixup_pending_inline (method);
04294 CLASSTYPE_INLINE_FRIENDS (type) = NULL;
04295 }
04296
04297
04298
04299
04300
04301
04302 static void
04303 propagate_binfo_offsets (tree binfo, tree offset)
04304 {
04305 int i;
04306 tree primary_binfo;
04307 tree base_binfo;
04308
04309
04310 BINFO_OFFSET (binfo)
04311 = convert (sizetype,
04312 size_binop (PLUS_EXPR,
04313 convert (ssizetype, BINFO_OFFSET (binfo)),
04314 offset));
04315
04316
04317 primary_binfo = get_primary_binfo (binfo);
04318
04319 if (primary_binfo && BINFO_INHERITANCE_CHAIN (primary_binfo) == binfo)
04320 propagate_binfo_offsets (primary_binfo, offset);
04321
04322
04323
04324 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
04325 {
04326
04327 if (base_binfo == primary_binfo)
04328 continue;
04329
04330 if (BINFO_VIRTUAL_P (base_binfo))
04331 continue;
04332
04333 propagate_binfo_offsets (base_binfo, offset);
04334 }
04335 }
04336
04337
04338
04339
04340
04341 static void
04342 layout_virtual_bases (record_layout_info rli, splay_tree offsets)
04343 {
04344 tree vbase;
04345 tree t = rli->t;
04346 bool first_vbase = true;
04347 tree *next_field;
04348
04349 if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) == 0)
04350 return;
04351
04352 if (!abi_version_at_least(2))
04353 {
04354
04355
04356 finish_record_layout (rli, false);
04357 #ifdef STRUCTURE_SIZE_BOUNDARY
04358
04359 if (! TYPE_PACKED (t))
04360 TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), (unsigned) STRUCTURE_SIZE_BOUNDARY);
04361 #endif
04362 rli->offset = TYPE_SIZE_UNIT (t);
04363 rli->bitpos = bitsize_zero_node;
04364 rli->record_align = TYPE_ALIGN (t);
04365 }
04366
04367
04368
04369 next_field = &TYPE_FIELDS (t);
04370 while (*next_field)
04371 next_field = &TREE_CHAIN (*next_field);
04372
04373
04374
04375
04376 for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
04377 {
04378 if (!BINFO_VIRTUAL_P (vbase))
04379 continue;
04380
04381 if (!BINFO_PRIMARY_P (vbase))
04382 {
04383 tree basetype = TREE_TYPE (vbase);
04384
04385
04386
04387 next_field = build_base_field (rli, vbase,
04388 offsets, next_field);
04389
04390
04391
04392
04393
04394
04395
04396
04397 if (warn_abi
04398 && first_vbase
04399 && (tree_int_cst_lt
04400 (size_binop (CEIL_DIV_EXPR,
04401 round_up (CLASSTYPE_SIZE (t),
04402 CLASSTYPE_ALIGN (basetype)),
04403 bitsize_unit_node),
04404 BINFO_OFFSET (vbase))))
04405 warning (OPT_Wabi,
04406 "offset of virtual base %qT is not ABI-compliant and "
04407 "may change in a future version of GCC",
04408 basetype);
04409
04410 first_vbase = false;
04411 }
04412 }
04413 }
04414
04415
04416
04417
04418 static tree
04419 end_of_base (tree binfo)
04420 {
04421 tree size;
04422
04423 if (is_empty_class (BINFO_TYPE (binfo)))
04424
04425
04426
04427 size = TYPE_SIZE_UNIT (BINFO_TYPE (binfo));
04428 else
04429 size = CLASSTYPE_SIZE_UNIT (BINFO_TYPE (binfo));
04430
04431 return size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), size);
04432 }
04433
04434
04435
04436
04437
04438 static tree
04439 end_of_class (tree t, int include_virtuals_p)
04440 {
04441 tree result = size_zero_node;
04442 VEC(tree,gc) *vbases;
04443 tree binfo;
04444 tree base_binfo;
04445 tree offset;
04446 int i;
04447
04448 for (binfo = TYPE_BINFO (t), i = 0;
04449 BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
04450 {
04451 if (!include_virtuals_p
04452 && BINFO_VIRTUAL_P (base_binfo)
04453 && (!BINFO_PRIMARY_P (base_binfo)
04454 || BINFO_INHERITANCE_CHAIN (base_binfo) != TYPE_BINFO (t)))
04455 continue;
04456
04457 offset = end_of_base (base_binfo);
04458 if (INT_CST_LT_UNSIGNED (result, offset))
04459 result = offset;
04460 }
04461
04462
04463 if (abi_version_at_least (2) && include_virtuals_p)
04464 for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
04465 VEC_iterate (tree, vbases, i, base_binfo); i++)
04466 {
04467 offset = end_of_base (base_binfo);
04468 if (INT_CST_LT_UNSIGNED (result, offset))
04469 result = offset;
04470 }
04471
04472 return result;
04473 }
04474
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484
04485 static void
04486 warn_about_ambiguous_bases (tree t)
04487 {
04488 int i;
04489 VEC(tree,gc) *vbases;
04490 tree basetype;
04491 tree binfo;
04492 tree base_binfo;
04493
04494
04495 if (!CLASSTYPE_REPEATED_BASE_P (t))
04496 return;
04497
04498
04499 for (binfo = TYPE_BINFO (t), i = 0;
04500 BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
04501 {
04502 basetype = BINFO_TYPE (base_binfo);
04503
04504 if (!lookup_base (t, basetype, ba_unique | ba_quiet, NULL))
04505 warning (0, "direct base %qT inaccessible in %qT due to ambiguity",
04506 basetype, t);
04507 }
04508
04509
04510 if (extra_warnings)
04511 for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
04512 VEC_iterate (tree, vbases, i, binfo); i++)
04513 {
04514 basetype = BINFO_TYPE (binfo);
04515
04516 if (!lookup_base (t, basetype, ba_unique | ba_quiet, NULL))
04517 warning (OPT_Wextra, "virtual base %qT inaccessible in %qT due to ambiguity",
04518 basetype, t);
04519 }
04520 }
04521
04522
04523
04524 static int
04525 splay_tree_compare_integer_csts (splay_tree_key k1, splay_tree_key k2)
04526 {
04527 return tree_int_cst_compare ((tree) k1, (tree) k2);
04528 }
04529
04530
04531
04532
04533 static void
04534 include_empty_classes (record_layout_info rli)
04535 {
04536 tree eoc;
04537 tree rli_size;
04538
04539
04540
04541
04542
04543
04544 eoc = end_of_class (rli->t,
04545 CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
04546 rli_size = rli_size_unit_so_far (rli);
04547 if (TREE_CODE (rli_size) == INTEGER_CST
04548 && INT_CST_LT_UNSIGNED (rli_size, eoc))
04549 {
04550 if (!abi_version_at_least (2))
04551
04552
04553
04554
04555
04556 rli->bitpos = round_down (rli->bitpos, BITS_PER_UNIT);
04557 else
04558
04559 gcc_assert (tree_int_cst_equal
04560 (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT)));
04561 rli->bitpos
04562 = size_binop (PLUS_EXPR,
04563 rli->bitpos,
04564 size_binop (MULT_EXPR,
04565 convert (bitsizetype,
04566 size_binop (MINUS_EXPR,
04567 eoc, rli_size)),
04568 bitsize_int (BITS_PER_UNIT)));
04569 normalize_rli (rli);
04570 }
04571 }
04572
04573
04574
04575
04576
04577 static void
04578 layout_class_type (tree t, tree *virtuals_p)
04579 {
04580 tree non_static_data_members;
04581 tree field;
04582 tree vptr;
04583 record_layout_info rli;
04584
04585
04586 splay_tree empty_base_offsets;
04587
04588 bool last_field_was_bitfield = false;
04589
04590 tree *next_field;
04591
04592 tree base_t;
04593
04594
04595 non_static_data_members = TYPE_FIELDS (t);
04596
04597
04598 rli = start_record_layout (t);
04599
04600
04601 determine_primary_bases (t);
04602
04603
04604 vptr = create_vtable_ptr (t, virtuals_p);
04605
04606
04607 if (vptr)
04608 {
04609 TREE_CHAIN (vptr) = TYPE_FIELDS (t);
04610 TYPE_FIELDS (t) = vptr;
04611 next_field = &TREE_CHAIN (vptr);
04612 place_field (rli, vptr);
04613 }
04614 else
04615 next_field = &TYPE_FIELDS (t);
04616
04617
04618 empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts,
04619 NULL, NULL);
04620 build_base_fields (rli, empty_base_offsets, next_field);
04621
04622
04623 for (field = non_static_data_members; field; field = TREE_CHAIN (field))
04624 {
04625 tree type;
04626 tree padding;
04627
04628
04629
04630 if (TREE_CODE (field) != FIELD_DECL)
04631 {
04632 place_field (rli, field);
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643 if (TREE_CODE (field) == VAR_DECL)
04644 {
04645 maybe_register_incomplete_var (field);
04646
04647
04648
04649 determine_visibility (field);
04650 }
04651 continue;
04652 }
04653
04654 type = TREE_TYPE (field);
04655 if (type == error_mark_node)
04656 continue;
04657
04658 padding = NULL_TREE;
04659
04660
04661
04662
04663 if (DECL_C_BIT_FIELD (field)
04664 && INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
04665 {
04666 integer_type_kind itk;
04667 tree integer_type;
04668 bool was_unnamed_p = false;
04669
04670
04671
04672
04673 for (itk = itk_char; itk != itk_none; ++itk)
04674 if (INT_CST_LT (DECL_SIZE (field),
04675 TYPE_SIZE (integer_types[itk])))
04676 break;
04677
04678
04679
04680
04681 integer_type = integer_types[itk - 1];
04682
04683
04684
04685
04686 if (!abi_version_at_least (2)
04687 || INT_CST_LT (TYPE_SIZE (integer_type), DECL_SIZE (field)))
04688 {
04689 if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
04690
04691
04692 padding = DECL_SIZE (field);
04693 else
04694 {
04695 if (TREE_CODE (t) == UNION_TYPE)
04696 warning (OPT_Wabi, "size assigned to %qT may not be "
04697 "ABI-compliant and may change in a future "
04698 "version of GCC",
04699 t);
04700 padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
04701 TYPE_SIZE (integer_type));
04702 }
04703 }
04704 #ifdef PCC_BITFIELD_TYPE_MATTERS
04705
04706
04707
04708
04709
04710
04711 if (PCC_BITFIELD_TYPE_MATTERS && !DECL_NAME (field))
04712 {
04713 was_unnamed_p = true;
04714 DECL_NAME (field) = make_anon_name ();
04715 }
04716 #endif
04717 DECL_SIZE (field) = TYPE_SIZE (integer_type);
04718 DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
04719 DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
04720 layout_nonempty_base_or_field (rli, field, NULL_TREE,
04721 empty_base_offsets);
04722 if (was_unnamed_p)
04723 DECL_NAME (field) = NULL_TREE;
04724
04725
04726
04727 DECL_SIZE (field) = TYPE_SIZE (type);
04728
04729 if (abi_version_at_least (2))
04730 DECL_MODE (field) = TYPE_MODE (type);
04731 else if (warn_abi
04732 && DECL_MODE (field) != TYPE_MODE (type))
04733
04734
04735 warning (OPT_Wabi,
04736 "the offset of %qD may not be ABI-compliant and may "
04737 "change in a future version of GCC", field);
04738 }
04739 else
04740 layout_nonempty_base_or_field (rli, field, NULL_TREE,
04741 empty_base_offsets);
04742
04743
04744 if (abi_version_at_least (2))
04745 record_subobject_offsets (TREE_TYPE (field),
04746 byte_position(field),
04747 empty_base_offsets,
04748 true);
04749
04750
04751
04752
04753 if (warn_abi
04754 && DECL_C_BIT_FIELD (field)
04755
04756
04757
04758
04759 && !TREE_NO_WARNING (field)
04760 && !last_field_was_bitfield
04761 && !integer_zerop (size_binop (TRUNC_MOD_EXPR,
04762 DECL_FIELD_BIT_OFFSET (field),
04763 bitsize_unit_node)))
04764 warning (OPT_Wabi, "offset of %q+D is not ABI-compliant and may "
04765 "change in a future version of GCC", field);
04766
04767
04768
04769 if (warn_abi
04770 && !tree_int_cst_equal (DECL_FIELD_OFFSET (field),
04771 byte_position (field))
04772 && contains_empty_class_p (TREE_TYPE (field)))
04773 warning (OPT_Wabi, "%q+D contains empty classes which may cause base "
04774 "classes to be placed at different locations in a "
04775 "future version of GCC", field);
04776
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788 if (DECL_C_BIT_FIELD (field))
04789 {
04790 tree ftype;
04791 unsigned HOST_WIDE_INT width;
04792 ftype = TREE_TYPE (field);
04793 width = tree_low_cst (DECL_SIZE (field), 1);
04794 if (width != TYPE_PRECISION (ftype))
04795 TREE_TYPE (field)
04796 = c_build_bitfield_integer_type (width,
04797 TYPE_UNSIGNED (ftype));
04798 }
04799
04800
04801
04802 if (padding)
04803 {
04804 tree padding_field;
04805
04806 padding_field = build_decl (FIELD_DECL,
04807 NULL_TREE,
04808 char_type_node);
04809 DECL_BIT_FIELD (padding_field) = 1;
04810 DECL_SIZE (padding_field) = padding;
04811 DECL_CONTEXT (padding_field) = t;
04812 DECL_ARTIFICIAL (padding_field) = 1;
04813 DECL_IGNORED_P (padding_field) = 1;
04814 layout_nonempty_base_or_field (rli, padding_field,
04815 NULL_TREE,
04816 empty_base_offsets);
04817 }
04818
04819 last_field_was_bitfield = DECL_C_BIT_FIELD (field);
04820 }
04821
04822 if (abi_version_at_least (2) && !integer_zerop (rli->bitpos))
04823 {
04824
04825
04826
04827 rli->bitpos = round_up (rli->bitpos, BITS_PER_UNIT);
04828 normalize_rli (rli);
04829 }
04830
04831
04832
04833 if (!abi_version_at_least (2))
04834 include_empty_classes(rli);
04835
04836
04837
04838 remove_zero_width_bit_fields (t);
04839
04840
04841
04842
04843 if (CLASSTYPE_NON_POD_P (t) || CLASSTYPE_EMPTY_P (t))
04844 {
04845 base_t = make_node (TREE_CODE (t));
04846
04847
04848
04849
04850 if (!abi_version_at_least (2) && CLASSTYPE_EMPTY_P (t))
04851 {
04852 TYPE_SIZE (base_t) = bitsize_zero_node;
04853 TYPE_SIZE_UNIT (base_t) = size_zero_node;
04854 if (warn_abi && !integer_zerop (rli_size_unit_so_far (rli)))
04855 warning (OPT_Wabi,
04856 "layout of classes derived from empty class %qT "
04857 "may change in a future version of GCC",
04858 t);
04859 }
04860 else
04861 {
04862 tree eoc;
04863
04864
04865
04866
04867
04868
04869
04870
04871 eoc = end_of_class (t, 0);
04872 TYPE_SIZE_UNIT (base_t)
04873 = size_binop (MAX_EXPR,
04874 convert (sizetype,
04875 size_binop (CEIL_DIV_EXPR,
04876 rli_size_so_far (rli),
04877 bitsize_int (BITS_PER_UNIT))),
04878 eoc);
04879 TYPE_SIZE (base_t)
04880 = size_binop (MAX_EXPR,
04881 rli_size_so_far (rli),
04882 size_binop (MULT_EXPR,
04883 convert (bitsizetype, eoc),
04884 bitsize_int (BITS_PER_UNIT)));
04885 }
04886 TYPE_ALIGN (base_t) = rli->record_align;
04887 TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t);
04888
04889
04890 next_field = &TYPE_FIELDS (base_t);
04891 for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
04892 if (TREE_CODE (field) == FIELD_DECL)
04893 {
04894 *next_field = build_decl (FIELD_DECL,
04895 DECL_NAME (field),
04896 TREE_TYPE (field));
04897 DECL_CONTEXT (*next_field) = base_t;
04898 DECL_FIELD_OFFSET (*next_field) = DECL_FIELD_OFFSET (field);
04899 DECL_FIELD_BIT_OFFSET (*next_field)
04900 = DECL_FIELD_BIT_OFFSET (field);
04901 DECL_SIZE (*next_field) = DECL_SIZE (field);
04902 DECL_MODE (*next_field) = DECL_MODE (field);
04903 next_field = &TREE_CHAIN (*next_field);
04904 }
04905
04906
04907 CLASSTYPE_AS_BASE (t) = base_t;
04908 TYPE_CONTEXT (base_t) = t;
04909 }
04910 else
04911 CLASSTYPE_AS_BASE (t) = t;
04912
04913
04914 if (CLASSTYPE_EMPTY_P (t))
04915 CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
04916
04917
04918
04919
04920 layout_decl (TYPE_MAIN_DECL (t), 0);
04921
04922
04923
04924
04925
04926 layout_virtual_bases (rli, empty_base_offsets);
04927
04928
04929
04930 include_empty_classes(rli);
04931
04932
04933 if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
04934 place_field (rli,
04935 build_decl (FIELD_DECL, NULL_TREE, char_type_node));
04936
04937
04938 finish_record_layout (rli, true);
04939
04940
04941 warn_about_ambiguous_bases (t);
04942
04943
04944 for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
04945 if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field)))
04946 TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field));
04947
04948
04949 splay_tree_delete (empty_base_offsets);
04950
04951 if (CLASSTYPE_EMPTY_P (t)
04952 && tree_int_cst_lt (sizeof_biggest_empty_class,
04953 TYPE_SIZE_UNIT (t)))
04954 sizeof_biggest_empty_class = TYPE_SIZE_UNIT (t);
04955 }
04956
04957
04958
04959
04960 void
04961 determine_key_method (tree type)
04962 {
04963 tree method;
04964
04965 if (TYPE_FOR_JAVA (type)
04966 || processing_template_decl
04967 || CLASSTYPE_TEMPLATE_INSTANTIATION (type)
04968 || CLASSTYPE_INTERFACE_KNOWN (type))
04969 return;
04970
04971
04972
04973
04974
04975 for (method = TYPE_METHODS (type); method != NULL_TREE;
04976 method = TREE_CHAIN (method))
04977 if (DECL_VINDEX (method) != NULL_TREE
04978 && ! DECL_DECLARED_INLINE_P (method)
04979 && ! DECL_PURE_VIRTUAL_P (method))
04980 {
04981 CLASSTYPE_KEY_METHOD (type) = method;
04982 break;
04983 }
04984
04985 return;
04986 }
04987
04988
04989
04990
04991 void
04992 finish_struct_1 (tree t)
04993 {
04994 tree x;
04995
04996 tree virtuals = NULL_TREE;
04997 int n_fields = 0;
04998
04999 if (COMPLETE_TYPE_P (t))
05000 {
05001 gcc_assert (IS_AGGR_TYPE (t));
05002 error ("redefinition of %q#T", t);
05003 popclass ();
05004 return;
05005 }
05006
05007
05008
05009 TYPE_SIZE (t) = NULL_TREE;
05010 CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
05011
05012 fixup_inline_methods (t);
05013
05014
05015
05016 CLASSTYPE_EMPTY_P (t) = 1;
05017 CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
05018 CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
05019
05020
05021
05022 check_bases_and_members (t);
05023
05024
05025 if (TYPE_CONTAINS_VPTR_P (t))
05026 {
05027
05028
05029
05030
05031
05032
05033
05034
05035 if (targetm.cxx.key_method_may_be_inline ())
05036 determine_key_method (t);
05037
05038
05039
05040 if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE)
05041 keyed_classes = tree_cons (NULL_TREE, t, keyed_classes);
05042 }
05043
05044
05045 layout_class_type (t, &virtuals);
05046 if (CLASSTYPE_AS_BASE (t) != t)
05047
05048
05049 compute_record_mode (CLASSTYPE_AS_BASE (t));
05050
05051 virtuals = modify_all_vtables (t, nreverse (virtuals));
05052
05053
05054 if (virtuals || TYPE_CONTAINS_VPTR_P (t))
05055 {
05056
05057 if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
05058 build_primary_vtable (NULL_TREE, t);
05059 else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
05060
05061
05062 build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
05063 }
05064
05065 if (TYPE_CONTAINS_VPTR_P (t))
05066 {
05067 int vindex;
05068 tree fn;
05069
05070 if (BINFO_VTABLE (TYPE_BINFO (t)))
05071 gcc_assert (DECL_VIRTUAL_P (BINFO_VTABLE (TYPE_BINFO (t))));
05072 if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
05073 gcc_assert (BINFO_VIRTUALS (TYPE_BINFO (t)) == NULL_TREE);
05074
05075
05076 BINFO_VIRTUALS (TYPE_BINFO (t))
05077 = chainon (BINFO_VIRTUALS (TYPE_BINFO (t)), virtuals);
05078
05079
05080 for (vindex = 0, fn = BINFO_VIRTUALS (TYPE_BINFO (t));
05081 fn;
05082 fn = TREE_CHAIN (fn),
05083 vindex += (TARGET_VTABLE_USES_DESCRIPTORS
05084 ? TARGET_VTABLE_USES_DESCRIPTORS : 1))
05085 {
05086 tree fndecl = BV_FN (fn);
05087
05088 if (DECL_THUNK_P (fndecl))
05089
05090
05091
05092 DECL_VINDEX (fndecl) = NULL_TREE;
05093 else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
05094 DECL_VINDEX (fndecl) = build_int_cst (NULL_TREE, vindex);
05095 }
05096 }
05097
05098 finish_struct_bits (t);
05099
05100
05101
05102 for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x))
05103 if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x)
05104 && TREE_TYPE (x) != error_mark_node
05105 && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
05106 DECL_MODE (x) = TYPE_MODE (t);
05107
05108
05109
05110
05111
05112
05113
05114
05115 n_fields = count_fields (TYPE_FIELDS (t));
05116 if (n_fields > 7)
05117 {
05118 struct sorted_fields_type *field_vec = GGC_NEWVAR
05119 (struct sorted_fields_type,
05120 sizeof (struct sorted_fields_type) + n_fields * sizeof (tree));
05121 field_vec->len = n_fields;
05122 add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
05123 qsort (field_vec->elts, n_fields, sizeof (tree),
05124 field_decl_cmp);
05125 if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t)))
05126 retrofit_lang_decl (TYPE_MAIN_DECL (t));
05127 DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
05128 }
05129
05130
05131 constrain_class_visibility (t);
05132
05133
05134
05135 finish_vtbls (t);
05136
05137
05138 build_vtt (t);
05139
05140
05141
05142 if (!TYPE_FOR_JAVA (t) && warn_nonvdtor && TYPE_POLYMORPHIC_P (t))
05143 {
05144 tree dtor;
05145
05146 dtor = CLASSTYPE_DESTRUCTORS (t);
05147
05148
05149 if (
05150
05151 !dtor
05152 || (!DECL_VINDEX (dtor)
05153 && (!TREE_PRIVATE (dtor)
05154 || CLASSTYPE_FRIEND_CLASSES (t)
05155 || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))))
05156 warning (0, "%q#T has virtual functions but non-virtual destructor",
05157 t);
05158 }
05159
05160 complete_vars (t);
05161
05162 if (warn_overloaded_virtual)
05163 warn_hidden (t);
05164
05165
05166
05167
05168 targetm.cxx.adjust_class_at_definition (t);
05169
05170 maybe_suppress_debug_info (t);
05171
05172 dump_class_hierarchy (t);
05173
05174
05175 rest_of_type_compilation (t, ! LOCAL_CLASS_P (t));
05176 }
05177
05178
05179
05180
05181 void
05182 unreverse_member_declarations (tree t)
05183 {
05184 tree next;
05185 tree prev;
05186 tree x;
05187
05188
05189
05190 TYPE_METHODS (t) = nreverse (TYPE_METHODS (t));
05191 CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));
05192
05193
05194
05195 prev = NULL_TREE;
05196 for (x = TYPE_FIELDS (t);
05197 x && TREE_CODE (x) != TYPE_DECL;
05198 x = next)
05199 {
05200 next = TREE_CHAIN (x);
05201 TREE_CHAIN (x) = prev;
05202 prev = x;
05203 }
05204 if (prev)
05205 {
05206 TREE_CHAIN (TYPE_FIELDS (t)) = x;
05207 if (prev)
05208 TYPE_FIELDS (t) = prev;
05209 }
05210 }
05211
05212 tree
05213 finish_struct (tree t, tree attributes)
05214 {
05215 location_t saved_loc = input_location;
05216
05217
05218
05219 unreverse_member_declarations (t);
05220
05221 cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
05222
05223
05224
05225 input_location = DECL_SOURCE_LOCATION (TYPE_NAME (t));
05226
05227 if (processing_template_decl)
05228 {
05229 tree x;
05230
05231 finish_struct_methods (t);
05232 TYPE_SIZE (t) = bitsize_zero_node;
05233 TYPE_SIZE_UNIT (t) = size_zero_node;
05234
05235
05236
05237
05238
05239
05240
05241
05242 CLASSTYPE_PURE_VIRTUALS (t) = NULL;
05243 for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
05244 if (DECL_PURE_VIRTUAL_P (x))
05245 VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
05246 complete_vars (t);
05247 }
05248 else
05249 finish_struct_1 (t);
05250
05251 input_location = saved_loc;
05252
05253 TYPE_BEING_DEFINED (t) = 0;
05254
05255 if (current_class_type)
05256 popclass ();
05257 else
05258 error ("trying to finish struct, but kicked out due to previous parse errors");
05259
05260 if (processing_template_decl && at_function_scope_p ())
05261 add_stmt (build_min (TAG_DEFN, t));
05262
05263 return t;
05264 }
05265
05266
05267
05268
05269
05270
05271
05272
05273
05274 static tree
05275 fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
05276 {
05277 switch (TREE_CODE (instance))
05278 {
05279 case INDIRECT_REF:
05280 if (POINTER_TYPE_P (TREE_TYPE (instance)))
05281 return NULL_TREE;
05282 else
05283 return fixed_type_or_null (TREE_OPERAND (instance, 0),
05284 nonnull, cdtorp);
05285
05286 case CALL_EXPR:
05287
05288 if (TREE_HAS_CONSTRUCTOR (instance))
05289 {
05290 if (nonnull)
05291 *nonnull = 1;
05292 return TREE_TYPE (instance);
05293 }
05294 return NULL_TREE;
05295
05296 case SAVE_EXPR:
05297
05298 if (TREE_HAS_CONSTRUCTOR (instance))
05299 {
05300 if (nonnull)
05301 *nonnull = 1;
05302 return TREE_TYPE (instance);
05303 }
05304 return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
05305
05306 case PLUS_EXPR:
05307 case MINUS_EXPR:
05308 if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
05309 return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
05310 if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
05311
05312 return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
05313 return NULL_TREE;
05314
05315 case NOP_EXPR:
05316 case CONVERT_EXPR:
05317 return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
05318
05319 case ADDR_EXPR:
05320 instance = TREE_OPERAND (instance, 0);
05321 if (nonnull)
05322 {
05323
05324
05325 tree t = get_base_address (instance);
05326
05327 if (t && DECL_P (t))
05328 *nonnull = 1;
05329 }
05330 return fixed_type_or_null (instance, nonnull, cdtorp);
05331
05332 case COMPONENT_REF:
05333
05334
05335 if (DECL_FIELD_IS_BASE (TREE_OPERAND (instance, 1)))
05336 return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
05337 return fixed_type_or_null (TREE_OPERAND (instance, 1), nonnull, cdtorp);
05338
05339 case VAR_DECL:
05340 case FIELD_DECL:
05341 if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
05342 && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance))))
05343 {
05344 if (nonnull)
05345 *nonnull = 1;
05346 return TREE_TYPE (TREE_TYPE (instance));
05347 }
05348
05349 case TARGET_EXPR:
05350 case PARM_DECL:
05351 case RESULT_DECL:
05352 if (IS_AGGR_TYPE (TREE_TYPE (instance)))
05353 {
05354 if (nonnull)
05355 *nonnull = 1;
05356 return TREE_TYPE (instance);
05357 }
05358 else if (instance == current_class_ptr)
05359 {
05360 if (nonnull)
05361 *nonnull = 1;
05362
05363
05364 if (DECL_LANG_SPECIFIC (current_function_decl)
05365 && (DECL_CONSTRUCTOR_P (current_function_decl)
05366 || DECL_DESTRUCTOR_P (current_function_decl)))
05367 {
05368 if (cdtorp)
05369 *cdtorp = 1;
05370 return TREE_TYPE (TREE_TYPE (instance));
05371 }
05372 }
05373 else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
05374 {
05375
05376 if (nonnull)
05377 *nonnull = 1;
05378
05379
05380
05381
05382 if (TREE_CODE (instance) == VAR_DECL
05383 && DECL_INITIAL (instance)
05384 && !DECL_VAR_MARKED_P (instance))
05385 {
05386 tree type;
05387 DECL_VAR_MARKED_P (instance) = 1;
05388 type = fixed_type_or_null (DECL_INITIAL (instance),
05389 nonnull, cdtorp);
05390 DECL_VAR_MARKED_P (instance) = 0;
05391 return type;
05392 }
05393 }
05394 return NULL_TREE;
05395
05396 default:
05397 return NULL_TREE;
05398 }
05399 }
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409
05410
05411
05412
05413
05414
05415 int
05416 resolves_to_fixed_type_p (tree instance, int* nonnull)
05417 {
05418 tree t = TREE_TYPE (instance);
05419 int cdtorp = 0;
05420
05421 tree fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
05422 if (fixed == NULL_TREE)
05423 return 0;
05424 if (POINTER_TYPE_P (t))
05425 t = TREE_TYPE (t);
05426 if (!same_type_ignoring_top_level_qualifiers_p (t, fixed))
05427 return 0;
05428 return cdtorp ? -1 : 1;
05429 }
05430
05431
05432 void
05433 init_class_processing (void)
05434 {
05435 current_class_depth = 0;
05436 current_class_stack_size = 10;
05437 current_class_stack
05438 = XNEWVEC (struct class_stack_node, current_class_stack_size);
05439 local_classes = VEC_alloc (tree, gc, 8);
05440 sizeof_biggest_empty_class = size_zero_node;
05441
05442 ridpointers[(int) RID_PUBLIC] = access_public_node;
05443 ridpointers[(int) RID_PRIVATE] = access_private_node;
05444 ridpointers[(int) RID_PROTECTED] = access_protected_node;
05445 }
05446
05447
05448
05449 static void
05450 restore_class_cache (void)
05451 {
05452 tree type;
05453
05454
05455
05456
05457
05458 push_binding_level (previous_class_level);
05459 class_binding_level = previous_class_level;
05460
05461 for (type = class_binding_level->type_shadowed;
05462 type;
05463 type = TREE_CHAIN (type))
05464 SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (type), TREE_TYPE (type));
05465 }
05466
05467
05468
05469
05470
05471
05472
05473
05474
05475
05476 void
05477 pushclass (tree type)
05478 {
05479 class_stack_node_t csn;
05480
05481 type = TYPE_MAIN_VARIANT (type);
05482
05483
05484 if (current_class_depth + 1 >= current_class_stack_size)
05485 {
05486 current_class_stack_size *= 2;
05487 current_class_stack
05488 = XRESIZEVEC (struct class_stack_node, current_class_stack,
05489 current_class_stack_size);
05490 }
05491
05492
05493 csn = current_class_stack + current_class_depth;
05494 csn->name = current_class_name;
05495 csn->type = current_class_type;
05496 csn->access = current_access_specifier;
05497 csn->names_used = 0;
05498 csn->hidden = 0;
05499 current_class_depth++;
05500
05501
05502 current_class_name = TYPE_NAME (type);
05503 if (TREE_CODE (current_class_name) == TYPE_DECL)
05504 current_class_name = DECL_NAME (current_class_name);
05505 current_class_type = type;
05506
05507
05508
05509 current_access_specifier = (CLASSTYPE_DECLARED_CLASS (type)
05510 ? access_private_node
05511 : access_public_node);
05512
05513 if (previous_class_level
05514 && type != previous_class_level->this_entity
05515 && current_class_depth == 1)
05516 {
05517
05518 invalidate_class_lookup_cache ();
05519 }
05520
05521 if (!previous_class_level
05522 || type != previous_class_level->this_entity
05523 || current_class_depth > 1)
05524 pushlevel_class ();
05525 else
05526 restore_class_cache ();
05527 }
05528
05529
05530
05531
05532
05533 void
05534 invalidate_class_lookup_cache (void)
05535 {
05536 previous_class_level = NULL;
05537 }
05538
05539
05540
05541
05542 void
05543 popclass (void)
05544 {
05545 poplevel_class ();
05546
05547 current_class_depth--;
05548 current_class_name = current_class_stack[current_class_depth].name;
05549 current_class_type = current_class_stack[current_class_depth].type;
05550 current_access_specifier = current_class_stack[current_class_depth].access;
05551 if (current_class_stack[current_class_depth].names_used)
05552 splay_tree_delete (current_class_stack[current_class_depth].names_used);
05553 }
05554
05555
05556
05557 void
05558 push_class_stack (void)
05559 {
05560 if (current_class_depth)
05561 ++current_class_stack[current_class_depth - 1].hidden;
05562 }
05563
05564
05565
05566 void
05567 pop_class_stack (void)
05568 {
05569 if (current_class_depth)
05570 --current_class_stack[current_class_depth - 1].hidden;
05571 }
05572
05573
05574
05575
05576 bool
05577 currently_open_class (tree t)
05578 {
05579 int i;
05580
05581
05582
05583 for (i = current_class_depth; i > 0; --i)
05584 {
05585 tree c;
05586 if (i == current_class_depth)
05587 c = current_class_type;
05588 else
05589 {
05590 if (current_class_stack[i].hidden)
05591 break;
05592 c = current_class_stack[i].type;
05593 }
05594 if (!c)
05595 continue;
05596 if (same_type_p (c, t))
05597 return true;
05598 }
05599 return false;
05600 }
05601
05602
05603
05604
05605
05606 tree
05607 currently_open_derived_class (tree t)
05608 {
05609 int i;
05610
05611
05612 if (dependent_type_p (t))
05613 return NULL_TREE;
05614
05615 if (!current_class_type)
05616 return NULL_TREE;
05617
05618 if (DERIVED_FROM_P (t, current_class_type))
05619 return current_class_type;
05620
05621 for (i = current_class_depth - 1; i > 0; --i)
05622 {
05623 if (current_class_stack[i].hidden)
05624 break;
05625 if (DERIVED_FROM_P (t, current_class_stack[i].type))
05626 return current_class_stack[i].type;
05627 }
05628
05629 return NULL_TREE;
05630 }
05631
05632
05633
05634
05635
05636
05637
05638 void
05639 push_nested_class (tree type)
05640 {
05641 tree context;
05642
05643
05644 if (type == NULL_TREE
05645 || type == error_mark_node
05646 || TREE_CODE (type) == NAMESPACE_DECL
05647 || ! IS_AGGR_TYPE (type)
05648 || TREE_CODE (type) == TEMPLATE_TYPE_PARM
05649 || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
05650 return;
05651
05652 context = DECL_CONTEXT (TYPE_MAIN_DECL (type));
05653
05654 if (context && CLASS_TYPE_P (context))
05655 push_nested_class (context);
05656 pushclass (type);
05657 }
05658
05659
05660
05661 void
05662 pop_nested_class (void)
05663 {
05664 tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
05665
05666 popclass ();
05667 if (context && CLASS_TYPE_P (context))
05668 pop_nested_class ();
05669 }
05670
05671
05672
05673 int
05674 current_lang_depth (void)
05675 {
05676 return VEC_length (tree, current_lang_base);
05677 }
05678
05679
05680
05681
05682 void
05683 push_lang_context (tree name)
05684 {
05685 VEC_safe_push (tree, gc, current_lang_base, current_lang_name);
05686
05687 if (name == lang_name_cplusplus)
05688 {
05689 current_lang_name = name;
05690 }
05691 else if (name == lang_name_java)
05692 {
05693 current_lang_name = name;
05694
05695
05696
05697
05698 DECL_IGNORED_P (TYPE_NAME (java_byte_type_node)) = 0;
05699 DECL_IGNORED_P (TYPE_NAME (java_short_type_node)) = 0;
05700 DECL_IGNORED_P (TYPE_NAME (java_int_type_node)) = 0;
05701 DECL_IGNORED_P (TYPE_NAME (java_long_type_node)) = 0;
05702 DECL_IGNORED_P (TYPE_NAME (java_float_type_node)) = 0;
05703 DECL_IGNORED_P (TYPE_NAME (java_double_type_node)) = 0;
05704 DECL_IGNORED_P (TYPE_NAME (java_char_type_node)) = 0;
05705 DECL_IGNORED_P (TYPE_NAME (java_boolean_type_node)) = 0;
05706 }
05707 else if (name == lang_name_c)
05708 {
05709 current_lang_name = name;
05710 }
05711 else
05712 error ("language string %<\"%E\"%> not recognized", name);
05713 }
05714
05715
05716
05717 void
05718 pop_lang_context (void)
05719 {
05720 current_lang_name = VEC_pop (tree, current_lang_base);
05721 }
05722
05723
05724
05725
05726
05727
05728
05729
05730
05731
05732
05733
05734
05735 static tree
05736 resolve_address_of_overloaded_function (tree target_type,
05737 tree overload,
05738 tsubst_flags_t flags,
05739 bool template_only,
05740 tree explicit_targs,
05741 tree access_path)
05742 {
05743
05744
05745
05746
05747
05748
05749
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769 int is_ptrmem = 0;
05770 int is_reference = 0;
05771
05772
05773
05774 tree matches = NULL_TREE;
05775 tree fn;
05776
05777
05778
05779
05780 gcc_assert (TREE_CODE (target_type) != POINTER_TYPE
05781 || TREE_CODE (TREE_TYPE (target_type)) != METHOD_TYPE);
05782
05783 gcc_assert (is_overloaded_fn (overload));
05784
05785
05786 if (TYPE_PTRFN_P (target_type))
05787 ;
05788 else if (TYPE_PTRMEMFUNC_P (target_type))
05789
05790 is_ptrmem = 1;
05791 else if (TREE_CODE (target_type) == FUNCTION_TYPE)
05792 {
05793
05794
05795 target_type = build_reference_type (target_type);
05796 is_reference = 1;
05797 }
05798 else
05799 {
05800 if (flags & tf_error)
05801 error ("cannot resolve overloaded function %qD based on"
05802 " conversion to type %qT",
05803 DECL_NAME (OVL_FUNCTION (overload)), target_type);
05804 return error_mark_node;
05805 }
05806
05807
05808
05809
05810
05811 if (!template_only)
05812 {
05813 tree fns;
05814
05815 for (fns = overload; fns; fns = OVL_NEXT (fns))
05816 {
05817 tree fn = OVL_CURRENT (fns);
05818 tree fntype;
05819
05820 if (TREE_CODE (fn) == TEMPLATE_DECL)
05821
05822 continue;
05823
05824 if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
05825 != is_ptrmem)
05826
05827
05828 continue;
05829
05830
05831
05832 if (DECL_ANTICIPATED (fn))
05833 continue;
05834
05835
05836 fntype = TREE_TYPE (fn);
05837 if (is_ptrmem)
05838 fntype = build_ptrmemfunc_type (build_pointer_type (fntype));
05839 else if (!is_reference)
05840 fntype = build_pointer_type (fntype);
05841
05842 if (can_convert_arg (target_type, fntype, fn, LOOKUP_NORMAL))
05843 matches = tree_cons (fn, NULL_TREE, matches);
05844 }
05845 }
05846
05847
05848
05849
05850 if (!matches)
05851 {
05852 tree target_fn_type;
05853 tree target_arg_types;
05854 tree target_ret_type;
05855 tree fns;
05856
05857 if (is_ptrmem)
05858 target_fn_type
05859 = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type));
05860 else
05861 target_fn_type = TREE_TYPE (target_type);
05862 target_arg_types = TYPE_ARG_TYPES (target_fn_type);
05863 target_ret_type = TREE_TYPE (target_fn_type);
05864
05865
05866 if (TREE_CODE (target_fn_type) == METHOD_TYPE)
05867 target_arg_types = TREE_CHAIN (target_arg_types);
05868
05869 for (fns = overload; fns; fns = OVL_NEXT (fns))
05870 {
05871 tree fn = OVL_CURRENT (fns);
05872 tree instantiation;
05873 tree instantiation_type;
05874 tree targs;
05875
05876 if (TREE_CODE (fn) != TEMPLATE_DECL)
05877
05878 continue;
05879
05880 if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
05881 != is_ptrmem)
05882
05883
05884 continue;
05885
05886
05887 targs = make_tree_vec (DECL_NTPARMS (fn));
05888 if (fn_type_unification (fn, explicit_targs, targs,
05889 target_arg_types, target_ret_type,
05890 DEDUCE_EXACT, LOOKUP_NORMAL))
05891
05892 continue;
05893
05894
05895 instantiation = instantiate_template (fn, targs, flags);
05896 if (instantiation == error_mark_node)
05897
05898 continue;
05899
05900
05901 instantiation_type = TREE_TYPE (instantiation);
05902 if (is_ptrmem)
05903 instantiation_type =
05904 build_ptrmemfunc_type (build_pointer_type (instantiation_type));
05905 else if (!is_reference)
05906 instantiation_type = build_pointer_type (instantiation_type);
05907 if (can_convert_arg (target_type, instantiation_type, instantiation,
05908 LOOKUP_NORMAL))
05909 matches = tree_cons (instantiation, fn, matches);
05910 }
05911
05912
05913 if (matches)
05914 {
05915 tree match = most_specialized_instantiation (matches);
05916
05917 if (match != error_mark_node)
05918 matches = tree_cons (TREE_PURPOSE (match),
05919 NULL_TREE,
05920 NULL_TREE);
05921 }
05922 }
05923
05924
05925 if (matches == NULL_TREE)
05926 {
05927
05928 if (flags & tf_error)
05929 {
05930 error ("no matches converting function %qD to type %q#T",
05931 DECL_NAME (OVL_FUNCTION (overload)),
05932 target_type);
05933
05934
05935
05936
05937 for (; overload; overload = OVL_NEXT (overload))
05938 matches = tree_cons (NULL_TREE, OVL_CURRENT (overload),
05939 matches);
05940
05941 print_candidates (matches);
05942 }
05943 return error_mark_node;
05944 }
05945 else if (TREE_CHAIN (matches))
05946 {
05947
05948
05949 if (flags & tf_error)
05950 {
05951 tree match;
05952
05953 error ("converting overloaded function %qD to type %q#T is ambiguous",
05954 DECL_NAME (OVL_FUNCTION (overload)),
05955 target_type);
05956
05957
05958
05959 for (match = matches; match; match = TREE_CHAIN (match))
05960 TREE_VALUE (match) = TREE_PURPOSE (match);
05961
05962 print_candidates (matches);
05963 }
05964
05965 return error_mark_node;
05966 }
05967
05968
05969 fn = TREE_PURPOSE (matches);
05970
05971 if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
05972 && !(flags & tf_ptrmem_ok) && !flag_ms_extensions)
05973 {
05974 static int explained;
05975
05976 if (!(flags & tf_error))
05977 return error_mark_node;
05978
05979 pedwarn ("assuming pointer to member %qD", fn);
05980 if (!explained)
05981 {
05982 pedwarn ("(a pointer to member can only be formed with %<&%E%>)", fn);
05983 explained = 1;
05984 }
05985 }
05986
05987
05988
05989
05990
05991 if (!(flags & tf_conv))
05992 {
05993 mark_used (fn);
05994
05995
05996
05997 if (DECL_FUNCTION_MEMBER_P (fn))
05998 {
05999 gcc_assert (access_path);
06000 perform_or_defer_access_check (access_path, fn, fn);
06001 }
06002 }
06003
06004 if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
06005 return build_unary_op (ADDR_EXPR, fn, 0);
06006 else
06007 {
06008
06009
06010
06011 cxx_mark_addressable (fn);
06012
06013 return fn;
06014 }
06015 }
06016
06017
06018
06019
06020
06021
06022
06023
06024
06025
06026
06027 tree
06028 instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
06029 {
06030 tsubst_flags_t flags_in = flags;
06031 tree access_path = NULL_TREE;
06032
06033 flags &= ~tf_ptrmem_ok;
06034
06035 if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
06036 {
06037 if (flags & tf_error)
06038 error ("not enough type information");
06039 return error_mark_node;
06040 }
06041
06042 if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
06043 {
06044 if (same_type_p (lhstype, TREE_TYPE (rhs)))
06045 return rhs;
06046 if (flag_ms_extensions
06047 && TYPE_PTRMEMFUNC_P (lhstype)
06048 && !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
06049
06050
06051 ;
06052 else
06053 {
06054 if (flags & tf_error)
06055 error ("argument of type %qT does not match %qT",
06056 TREE_TYPE (rhs), lhstype);
06057 return error_mark_node;
06058 }
06059 }
06060
06061 if (TREE_CODE (rhs) == BASELINK)
06062 {
06063 access_path = BASELINK_ACCESS_BINFO (rhs);
06064 rhs = BASELINK_FUNCTIONS (rhs);
06065 }
06066
06067
06068
06069 if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
06070 {
06071 if (flags & tf_error)
06072 error ("not enough type information");
06073 return error_mark_node;
06074 }
06075
06076
06077
06078 gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
06079 || TREE_CODE (rhs) == COMPONENT_REF
06080 || TREE_CODE (rhs) == COMPOUND_EXPR
06081 || really_overloaded_fn (rhs));
06082
06083
06084
06085 if (TREE_CODE (rhs) != OVERLOAD)
06086 rhs = copy_node (rhs);
06087
06088
06089
06090
06091
06092
06093 switch (TREE_CODE (rhs))
06094 {
06095 case COMPONENT_REF:
06096 {
06097 tree member = TREE_OPERAND (rhs, 1);
06098
06099 member = instantiate_type (lhstype, member, flags);
06100 if (member != error_mark_node
06101 && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
06102
06103 return build2 (COMPOUND_EXPR, TREE_TYPE (member),
06104 TREE_OPERAND (rhs, 0), member);
06105 return member;
06106 }
06107
06108 case OFFSET_REF:
06109 rhs = TREE_OPERAND (rhs, 1);
06110 if (BASELINK_P (rhs))
06111 return instantiate_type (lhstype, rhs, flags_in);
06112
06113
06114
06115 gcc_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR);
06116
06117
06118
06119 case TEMPLATE_ID_EXPR:
06120 {
06121 tree fns = TREE_OPERAND (rhs, 0);
06122 tree args = TREE_OPERAND (rhs, 1);
06123
06124 return
06125 resolve_address_of_overloaded_function (lhstype, fns, flags_in,
06126 true,
06127 args, access_path);
06128 }
06129
06130 case OVERLOAD:
06131 case FUNCTION_DECL:
06132 return
06133 resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
06134 false,
06135 NULL_TREE,
06136 access_path);
06137
06138 case COMPOUND_EXPR:
06139 TREE_OPERAND (rhs, 0)
06140 = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
06141 if (TREE_OPERAND (rhs, 0) == error_mark_node)
06142 return error_mark_node;
06143 TREE_OPERAND (rhs, 1)
06144 = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
06145 if (TREE_OPERAND (rhs, 1) == error_mark_node)
06146 return error_mark_node;
06147
06148 TREE_TYPE (rhs) = lhstype;
06149 return rhs;
06150
06151 case ADDR_EXPR:
06152 {
06153 if (PTRMEM_OK_P (rhs))
06154 flags |= tf_ptrmem_ok;
06155
06156 return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
06157 }
06158
06159 case ERROR_MARK:
06160 return error_mark_node;
06161
06162 default:
06163 gcc_unreachable ();
06164 }
06165 return error_mark_node;
06166 }
06167
06168
06169
06170
06171
06172
06173
06174 static tree
06175 get_vfield_name (tree type)
06176 {
06177 tree binfo, base_binfo;
06178 char *buf;
06179
06180 for (binfo = TYPE_BINFO (type);
06181 BINFO_N_BASE_BINFOS (binfo);
06182 binfo = base_binfo)
06183 {
06184 base_binfo = BINFO_BASE_BINFO (binfo, 0);
06185
06186 if (BINFO_VIRTUAL_P (base_binfo)
06187 || !TYPE_CONTAINS_VPTR_P (BINFO_TYPE (base_binfo)))
06188 break;
06189 }
06190
06191 type = BINFO_TYPE (binfo);
06192 buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
06193 + TYPE_NAME_LENGTH (type) + 2);
06194 sprintf (buf, VFIELD_NAME_FORMAT,
06195 IDENTIFIER_POINTER (constructor_name (type)));
06196 return get_identifier (buf);
06197 }
06198
06199 void
06200 print_class_statistics (void)
06201 {
06202 #ifdef GATHER_STATISTICS
06203 fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness);
06204 fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs);
06205 if (n_vtables)
06206 {
06207 fprintf (stderr, "vtables = %d; vtable searches = %d\n",
06208 n_vtables, n_vtable_searches);
06209 fprintf (stderr, "vtable entries = %d; vtable elems = %d\n",
06210 n_vtable_entries, n_vtable_elems);
06211 }
06212 #endif
06213 }
06214
06215
06216
06217
06218
06219
06220
06221 void
06222 build_self_reference (void)
06223 {
06224 tree name = constructor_name (current_class_type);
06225 tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
06226 tree saved_cas;
06227
06228 DECL_NONLOCAL (value) = 1;
06229 DECL_CONTEXT (value) = current_class_type;
06230 DECL_ARTIFICIAL (value) = 1;
06231 SET_DECL_SELF_REFERENCE_P (value);
06232
06233 if (processing_template_decl)
06234 value = push_template_decl (value);
06235
06236 saved_cas = current_access_specifier;
06237 current_access_specifier = access_public_node;
06238 finish_member_declaration (value);
06239 current_access_specifier = saved_cas;
06240 }
06241
06242 #ifdef KEY
06243
06244 int (*p_is_empty_class) (tree) = is_empty_class;
06245 #endif
06246
06247
06248
06249 int
06250 is_empty_class (tree type)
06251 {
06252 if (type == error_mark_node)
06253 return 0;
06254
06255 if (! IS_AGGR_TYPE (type))
06256 return 0;
06257
06258
06259
06260 if (abi_version_at_least (2))
06261 return CLASSTYPE_EMPTY_P (type);
06262 else
06263 return integer_zerop (CLASSTYPE_SIZE (type));
06264 }
06265
06266
06267
06268 static bool
06269 contains_empty_class_p (tree type)
06270 {
06271 if (is_empty_class (type))
06272 return true;
06273 if (CLASS_TYPE_P (type))
06274 {
06275 tree field;
06276 tree binfo;
06277 tree base_binfo;
06278 int i;
06279
06280 for (binfo = TYPE_BINFO (type), i = 0;
06281 BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
06282 if (contains_empty_class_p (BINFO_TYPE (base_binfo)))
06283 return true;
06284 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
06285 if (TREE_CODE (field) == FIELD_DECL
06286 && !DECL_ARTIFICIAL (field)
06287 && is_empty_class (TREE_TYPE (field)))
06288 return true;
06289 }
06290 else if (TREE_CODE (type) == ARRAY_TYPE)
06291 return contains_empty_class_p (TREE_TYPE (type));
06292 return false;
06293 }
06294
06295
06296
06297
06298 void
06299 maybe_note_name_used_in_class (tree name, tree decl)
06300 {
06301 splay_tree names_used;
06302
06303
06304 if (!(innermost_scope_kind() == sk_class
06305 && TYPE_BEING_DEFINED (current_class_type)))
06306 return;
06307
06308
06309
06310 if (lookup_member (current_class_type, name,
06311 0, false))
06312 return;
06313
06314 if (!current_class_stack[current_class_depth - 1].names_used)
06315 current_class_stack[current_class_depth - 1].names_used
06316 = splay_tree_new (splay_tree_compare_pointers, 0, 0);
06317 names_used = current_class_stack[current_class_depth - 1].names_used;
06318
06319 splay_tree_insert (names_used,
06320 (splay_tree_key) name,
06321 (splay_tree_value) decl);
06322 }
06323
06324
06325
06326
06327 void
06328 note_name_declared_in_class (tree name, tree decl)
06329 {
06330 splay_tree names_used;
06331 splay_tree_node n;
06332
06333
06334 names_used
06335 = current_class_stack[current_class_depth - 1].names_used;
06336 if (!names_used)
06337 return;
06338
06339 n = splay_tree_lookup (names_used, (splay_tree_key) name);
06340 if (n)
06341 {
06342
06343
06344
06345
06346
06347 error ("declaration of %q#D", decl);
06348 error ("changes meaning of %qD from %q+#D",
06349 DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
06350 }
06351 }
06352
06353
06354
06355
06356
06357 tree
06358 get_vtbl_decl_for_binfo (tree binfo)
06359 {
06360 tree decl;
06361
06362 decl = BINFO_VTABLE (binfo);
06363 if (decl && TREE_CODE (decl) == PLUS_EXPR)
06364 {
06365 gcc_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR);
06366 decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
06367 }
06368 if (decl)
06369 gcc_assert (TREE_CODE (decl) == VAR_DECL);
06370 return decl;
06371 }
06372
06373
06374
06375
06376
06377
06378
06379
06380 static tree
06381 get_primary_binfo (tree binfo)
06382 {
06383 tree primary_base;
06384
06385 primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
06386 if (!primary_base)
06387 return NULL_TREE;
06388
06389 return copied_binfo (primary_base, binfo);
06390 }
06391
06392
06393
06394 static int
06395 maybe_indent_hierarchy (FILE * stream, int indent, int indented_p)
06396 {
06397 if (!indented_p)
06398 fprintf (stream, "%*s", indent, "");
06399 return 1;
06400 }
06401
06402
06403
06404
06405
06406
06407 static tree
06408 dump_class_hierarchy_r (FILE *stream,
06409 int flags,
06410 tree binfo,
06411 tree igo,
06412 int indent)
06413 {
06414 int indented = 0;
06415 tree base_binfo;
06416 int i;
06417
06418 indented = maybe_indent_hierarchy (stream, indent, 0);
06419 fprintf (stream, "%s (0x%lx) ",
06420 type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER),
06421 (unsigned long) binfo);
06422 if (binfo != igo)
06423 {
06424 fprintf (stream, "alternative-path\n");
06425 return igo;
06426 }
06427 igo = TREE_CHAIN (binfo);
06428
06429 fprintf (stream, HOST_WIDE_INT_PRINT_DEC,
06430 tree_low_cst (BINFO_OFFSET (binfo), 0));
06431 if (is_empty_class (BINFO_TYPE (binfo)))
06432 fprintf (stream, " empty");
06433 else if (CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (binfo)))
06434 fprintf (stream, " nearly-empty");
06435 if (BINFO_VIRTUAL_P (binfo))
06436 fprintf (stream, " virtual");
06437 fprintf (stream, "\n");
06438
06439 indented = 0;
06440 if (BINFO_PRIMARY_P (binfo))
06441 {
06442 indented = maybe_indent_hierarchy (stream, indent + 3, indented);
06443 fprintf (stream, " primary-for %s (0x%lx)",
06444 type_as_string (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
06445 TFF_PLAIN_IDENTIFIER),
06446 (unsigned long)BINFO_INHERITANCE_CHAIN (binfo));
06447 }
06448 if (BINFO_LOST_PRIMARY_P (binfo))
06449 {
06450 indented = maybe_indent_hierarchy (stream, indent + 3, indented);
06451 fprintf (stream, " lost-primary");
06452 }
06453 if (indented)
06454 fprintf (stream, "\n");
06455
06456 if (!(flags & TDF_SLIM))
06457 {
06458 int indented = 0;
06459
06460 if (BINFO_SUBVTT_INDEX (binfo))
06461 {
06462 indented = maybe_indent_hierarchy (stream, indent + 3, indented);
06463 fprintf (stream, " subvttidx=%s",
06464 expr_as_string (BINFO_SUBVTT_INDEX (binfo),
06465 TFF_PLAIN_IDENTIFIER));
06466 }
06467 if (BINFO_VPTR_INDEX (binfo))
06468 {
06469 indented = maybe_indent_hierarchy (stream, indent + 3, indented);
06470 fprintf (stream, " vptridx=%s",
06471 expr_as_string (BINFO_VPTR_INDEX (binfo),
06472 TFF_PLAIN_IDENTIFIER));
06473 }
06474 if (BINFO_VPTR_FIELD (binfo))
06475 {
06476 indented = maybe_indent_hierarchy (stream, indent + 3, indented);
06477 fprintf (stream, " vbaseoffset=%s",
06478 expr_as_string (BINFO_VPTR_FIELD (binfo),
06479 TFF_PLAIN_IDENTIFIER));
06480 }
06481 if (BINFO_VTABLE (binfo))
06482 {
06483 indented = maybe_indent_hierarchy (stream, indent + 3, indented);
06484 fprintf (stream, " vptr=%s",
06485 expr_as_string (BINFO_VTABLE (binfo),
06486 TFF_PLAIN_IDENTIFIER));
06487 }
06488
06489 if (indented)
06490 fprintf (stream, "\n");
06491 }
06492
06493 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
06494 igo = dump_class_hierarchy_r (stream, flags, base_binfo, igo, indent + 2);
06495
06496 return igo;
06497 }
06498
06499
06500
06501 static void
06502 dump_class_hierarchy_1 (FILE *stream, int flags, tree t)
06503 {
06504 fprintf (stream, "Class %s\n", type_as_string (t, TFF_PLAIN_IDENTIFIER));
06505 fprintf (stream, " size=%lu align=%lu\n",
06506 (unsigned long)(tree_low_cst (TYPE_SIZE (t), 0) / BITS_PER_UNIT),
06507 (unsigned long)(TYPE_ALIGN (t) / BITS_PER_UNIT));
06508 fprintf (stream, " base size=%lu base align=%lu\n",
06509 (unsigned long)(tree_low_cst (TYPE_SIZE (CLASSTYPE_AS_BASE (t)), 0)
06510 / BITS_PER_UNIT),
06511 (unsigned long)(TYPE_ALIGN (CLASSTYPE_AS_BASE (t))
06512 / BITS_PER_UNIT));
06513 dump_class_hierarchy_r (stream, flags, TYPE_BINFO (t), TYPE_BINFO (t), 0);
06514 fprintf (stream, "\n");
06515 }
06516
06517
06518
06519 void
06520 debug_class (tree t)
06521 {
06522 dump_class_hierarchy_1 (stderr, TDF_SLIM, t);
06523 }
06524
06525 static void
06526 dump_class_hierarchy (tree t)
06527 {
06528 int flags;
06529 FILE *stream = dump_begin (TDI_class, &flags);
06530
06531 if (stream)
06532 {
06533 dump_class_hierarchy_1 (stream, flags, t);
06534 dump_end (TDI_class, stream);
06535 }
06536 }
06537
06538 static void
06539 dump_array (FILE * stream, tree decl)
06540 {
06541 tree value;
06542 unsigned HOST_WIDE_INT ix;
06543 HOST_WIDE_INT elt;
06544 tree size = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (decl)));
06545
06546 elt = (tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))), 0)
06547 / BITS_PER_UNIT);
06548 fprintf (stream, "%s:", decl_as_string (decl, TFF_PLAIN_IDENTIFIER));
06549 fprintf (stream, " %s entries",
06550 expr_as_string (size_binop (PLUS_EXPR, size, size_one_node),
06551 TFF_PLAIN_IDENTIFIER));
06552 fprintf (stream, "\n");
06553
06554 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)),
06555 ix, value)
06556 fprintf (stream, "%-4ld %s\n", (long)(ix * elt),
06557 expr_as_string (value, TFF_PLAIN_IDENTIFIER));
06558 }
06559
06560 static void
06561 dump_vtable (tree t, tree binfo, tree vtable)
06562 {
06563 int flags;
06564 FILE *stream = dump_begin (TDI_class, &flags);
06565
06566 if (!stream)
06567 return;
06568
06569 if (!(flags & TDF_SLIM))
06570 {
06571 int ctor_vtbl_p = TYPE_BINFO (t) != binfo;
06572
06573 fprintf (stream, "%s for %s",
06574 ctor_vtbl_p ? "Construction vtable" : "Vtable",
06575 type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER));
06576 if (ctor_vtbl_p)
06577 {
06578 if (!BINFO_VIRTUAL_P (binfo))
06579 fprintf (stream, " (0x%lx instance)", (unsigned long)binfo);
06580 fprintf (stream, " in %s", type_as_string (t, TFF_PLAIN_IDENTIFIER));
06581 }
06582 fprintf (stream, "\n");
06583 dump_array (stream, vtable);
06584 fprintf (stream, "\n");
06585 }
06586
06587 dump_end (TDI_class, stream);
06588 }
06589
06590 static void
06591 dump_vtt (tree t, tree vtt)
06592 {
06593 int flags;
06594 FILE *stream = dump_begin (TDI_class, &flags);
06595
06596 if (!stream)
06597 return;
06598
06599 if (!(flags & TDF_SLIM))
06600 {
06601 fprintf (stream, "VTT for %s\n",
06602 type_as_string (t, TFF_PLAIN_IDENTIFIER));
06603 dump_array (stream, vtt);
06604 fprintf (stream, "\n");
06605 }
06606
06607 dump_end (TDI_class, stream);
06608 }
06609
06610
06611
06612 static void
06613 dump_thunk (FILE *stream, int indent, tree thunk)
06614 {
06615 static const char spaces[] = " ";
06616 tree name = DECL_NAME (thunk);
06617 tree thunks;
06618
06619 fprintf (stream, "%.*s%p %s %s", indent, spaces,
06620 (void *)thunk,
06621 !DECL_THUNK_P (thunk) ? "function"
06622 : DECL_THIS_THUNK_P (thunk) ? "this-thunk" : "covariant-thunk",
06623 name ? IDENTIFIER_POINTER (name) : "<unset>");
06624 if (DECL_THUNK_P (thunk))
06625 {
06626 HOST_WIDE_INT fixed_adjust = THUNK_FIXED_OFFSET (thunk);
06627 tree virtual_adjust = THUNK_VIRTUAL_OFFSET (thunk);
06628
06629 fprintf (stream, " fixed=" HOST_WIDE_INT_PRINT_DEC, fixed_adjust);
06630 if (!virtual_adjust)
06631 ;
06632 else if (DECL_THIS_THUNK_P (thunk))
06633 fprintf (stream, " vcall=" HOST_WIDE_INT_PRINT_DEC,
06634 tree_low_cst (virtual_adjust, 0));
06635 else
06636 fprintf (stream, " vbase=" HOST_WIDE_INT_PRINT_DEC "(%s)",
06637 tree_low_cst (BINFO_VPTR_FIELD (virtual_adjust), 0),
06638 type_as_string (BINFO_TYPE (virtual_adjust), TFF_SCOPE));
06639 if (THUNK_ALIAS (thunk))
06640 fprintf (stream, " alias to %p", (void *)THUNK_ALIAS (thunk));
06641 }
06642 fprintf (stream, "\n");
06643 for (thunks = DECL_THUNKS (thunk); thunks; thunks = TREE_CHAIN (thunks))
06644 dump_thunk (stream, indent + 2, thunks);
06645 }
06646
06647
06648
06649 void
06650 debug_thunks (tree fn)
06651 {
06652 dump_thunk (stderr, 0, fn);
06653 }
06654
06655
06656
06657
06658
06659 static void
06660 finish_vtbls (tree t)
06661 {
06662 tree list;
06663 tree vbase;
06664
06665
06666
06667
06668 list = build_tree_list (BINFO_VTABLE (TYPE_BINFO (t)), NULL_TREE);
06669 accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t),
06670 TYPE_BINFO (t), t, list);
06671
06672
06673 for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
06674 {
06675 if (!BINFO_VIRTUAL_P (vbase))
06676 continue;
06677 accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), t, list);
06678 }
06679
06680 if (BINFO_VTABLE (TYPE_BINFO (t)))
06681 initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
06682 }
06683
06684
06685
06686 static void
06687 initialize_vtable (tree binfo, tree inits)
06688 {
06689 tree decl;
06690
06691 layout_vtable_decl (binfo, list_length (inits));
06692 decl = get_vtbl_decl_for_binfo (binfo);
06693 initialize_artificial_var (decl, inits);
06694 dump_vtable (BINFO_TYPE (binfo), binfo, decl);
06695 }
06696
06697
06698
06699
06700
06701
06702
06703
06704
06705
06706
06707
06708
06709
06710 static void
06711 build_vtt (tree t)
06712 {
06713 tree inits;
06714 tree type;
06715 tree vtt;
06716 tree index;
06717
06718
06719 inits = NULL_TREE;
06720 index = size_zero_node;
06721 build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);
06722
06723
06724 if (!inits)
06725 return;
06726
06727
06728 type = build_index_type (size_int (list_length (inits) - 1));
06729 type = build_cplus_array_type (const_ptr_type_node, type);
06730
06731
06732 vtt = build_vtable (t, mangle_vtt_for_type (t), type);
06733 initialize_artificial_var (vtt, inits);
06734
06735 TREE_CHAIN (vtt) = TREE_CHAIN (CLASSTYPE_VTABLES (t));
06736 TREE_CHAIN (CLASSTYPE_VTABLES (t)) = vtt;
06737
06738 dump_vtt (t, vtt);
06739 }
06740
06741
06742
06743
06744
06745
06746 static tree
06747 binfo_ctor_vtable (tree binfo)
06748 {
06749 tree vt;
06750
06751 while (1)
06752 {
06753 vt = BINFO_VTABLE (binfo);
06754 if (TREE_CODE (vt) == TREE_LIST)
06755 vt = TREE_VALUE (vt);
06756 if (TREE_CODE (vt) == TREE_BINFO)
06757 binfo = vt;
06758 else
06759 break;
06760 }
06761
06762 return vt;
06763 }
06764
06765
06766 typedef struct secondary_vptr_vtt_init_data_s
06767 {
06768
06769 bool top_level_p;
06770
06771
06772 tree index;
06773
06774
06775 tree inits;
06776
06777
06778 tree type_being_constructed;
06779 } secondary_vptr_vtt_init_data;
06780
06781
06782
06783
06784
06785
06786
06787
06788
06789 static tree *
06790 build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
06791 {
06792 int i;
06793 tree b;
06794 tree init;
06795 tree secondary_vptrs;
06796 secondary_vptr_vtt_init_data data;
06797 int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
06798
06799
06800 if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
06801 return inits;
06802
06803
06804
06805 if (!top_level_p)
06806 {
06807 build_ctor_vtbl_group (binfo, t);
06808
06809
06810 BINFO_SUBVTT_INDEX (binfo) = *index;
06811 }
06812
06813
06814 init = binfo_ctor_vtable (binfo);
06815 *inits = build_tree_list (NULL_TREE, init);
06816 inits = &TREE_CHAIN (*inits);
06817 if (top_level_p)
06818 {
06819 gcc_assert (!BINFO_VPTR_INDEX (binfo));
06820 BINFO_VPTR_INDEX (binfo) = *index;
06821 }
06822 *index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));
06823
06824
06825 for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
06826 if (!BINFO_VIRTUAL_P (b))
06827 inits = build_vtt_inits (b, t, inits, index);
06828
06829
06830
06831
06832 data.top_level_p = top_level_p;
06833 data.index = *index;
06834 data.inits = NULL;
06835 data.type_being_constructed = BINFO_TYPE (binfo);
06836
06837 dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data);
06838
06839 *index = data.index;
06840
06841
06842
06843
06844 secondary_vptrs = data.inits;
06845 if (secondary_vptrs)
06846 {
06847 *inits = nreverse (secondary_vptrs);
06848 inits = &TREE_CHAIN (secondary_vptrs);
06849 gcc_assert (*inits == NULL_TREE);
06850 }
06851
06852 if (top_level_p)
06853
06854
06855 for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
06856 {
06857 if (!BINFO_VIRTUAL_P (b))
06858 continue;
06859
06860 inits = build_vtt_inits (b, t, inits, index);
06861 }
06862 else
06863
06864 dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo);
06865
06866 return inits;
06867 }
06868
06869
06870
06871
06872 static tree
06873 dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_)
06874 {
06875 secondary_vptr_vtt_init_data *data = (secondary_vptr_vtt_init_data *)data_;
06876
06877
06878 if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
06879 return dfs_skip_bases;
06880
06881
06882
06883 if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->type_being_constructed))
06884 return NULL_TREE;
06885
06886
06887
06888 if (!(CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
06889 || binfo_via_virtual (binfo, data->type_being_constructed)))
06890 return dfs_skip_bases;
06891
06892
06893 if (!BINFO_VIRTUAL_P (binfo) && BINFO_PRIMARY_P (binfo))
06894 return NULL_TREE;
06895
06896
06897 if (data->top_level_p)
06898 {
06899 gcc_assert (!BINFO_VPTR_INDEX (binfo));
06900 BINFO_VPTR_INDEX (binfo) = data->index;
06901
06902 if (BINFO_VIRTUAL_P (binfo))
06903 {
06904
06905
06906
06907
06908 while (BINFO_PRIMARY_P (binfo))
06909 binfo = BINFO_INHERITANCE_CHAIN (binfo);
06910 }
06911 }
06912
06913
06914 data->inits = tree_cons (NULL_TREE, binfo_ctor_vtable (binfo), data->inits);
06915
06916
06917 data->index = size_binop (PLUS_EXPR, data->index,
06918 TYPE_SIZE_UNIT (ptr_type_node));
06919
06920 return NULL_TREE;
06921 }
06922
06923
06924
06925
06926
06927
06928 static tree
06929 dfs_fixup_binfo_vtbls (tree binfo, void* data)
06930 {
06931 tree vtable = BINFO_VTABLE (binfo);
06932
06933 if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
06934
06935 return dfs_skip_bases;
06936
06937 if (!vtable)
06938
06939
06940 return NULL_TREE;
06941
06942
06943
06944 if (TREE_CODE (vtable) == TREE_LIST
06945 && (TREE_PURPOSE (vtable) == (tree) data))
06946 BINFO_VTABLE (binfo) = TREE_CHAIN (vtable);
06947
06948 return NULL_TREE;
06949 }
06950
06951
06952
06953
06954 static void
06955 build_ctor_vtbl_group (tree binfo, tree t)
06956 {
06957 tree list;
06958 tree type;
06959 tree vtbl;
06960 tree inits;
06961 tree id;
06962 tree vbase;
06963
06964
06965 id = mangle_ctor_vtbl_for_type (t, binfo);
06966 if (IDENTIFIER_GLOBAL_VALUE (id))
06967 return;
06968
06969 gcc_assert (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t));
06970
06971
06972
06973 vtbl = build_vtable (t, id, ptr_type_node);
06974 DECL_CONSTRUCTION_VTABLE_P (vtbl) = 1;
06975 list = build_tree_list (vtbl, NULL_TREE);
06976 accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
06977 binfo, t, list);
06978
06979
06980
06981 for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
06982 vbase;
06983 vbase = TREE_CHAIN (vbase))
06984 {
06985 tree b;
06986
06987 if (!BINFO_VIRTUAL_P (vbase))
06988 continue;
06989 b = copied_binfo (vbase, binfo);
06990
06991 accumulate_vtbl_inits (b, vbase, binfo, t, list);
06992 }
06993 inits = TREE_VALUE (list);
06994
06995
06996 type = build_index_type (size_int (list_length (inits) - 1));
06997 type = build_cplus_array_type (vtable_entry_type, type);
06998 TREE_TYPE (vtbl) = type;
06999
07000
07001 CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
07002 initialize_artificial_var (vtbl, inits);
07003 dump_vtable (t, binfo, vtbl);
07004 }
07005
07006
07007
07008
07009
07010
07011
07012
07013
07014
07015
07016 static void
07017 accumulate_vtbl_inits (tree binfo,
07018 tree orig_binfo,
07019 tree rtti_binfo,
07020 tree t,
07021 tree inits)
07022 {
07023 int i;
07024 tree base_binfo;
07025 int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
07026
07027 gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (orig_binfo)));
07028
07029
07030 if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
07031 return;
07032
07033
07034
07035 if (ctor_vtbl_p
07036 && !CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
07037 && !binfo_via_virtual (orig_binfo, BINFO_TYPE (rtti_binfo)))
07038 return;
07039
07040
07041 TREE_VALUE (inits)
07042 = chainon (TREE_VALUE (inits),
07043 dfs_accumulate_vtbl_inits (binfo, orig_binfo,
07044 rtti_binfo, t, inits));
07045
07046
07047
07048
07049
07050
07051 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
07052 {
07053
07054 if (BINFO_VIRTUAL_P (base_binfo))
07055 continue;
07056 accumulate_vtbl_inits (base_binfo,
07057 BINFO_BASE_BINFO (orig_binfo, i),
07058 rtti_binfo, t,
07059 inits);
07060 }
07061 }
07062
07063
07064
07065
07066 static tree
07067 dfs_accumulate_vtbl_inits (tree binfo,
07068 tree orig_binfo,
07069 tree rtti_binfo,
07070 tree t,
07071 tree l)
07072 {
07073 tree inits = NULL_TREE;
07074 tree vtbl = NULL_TREE;
07075 int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
07076
07077 if (ctor_vtbl_p
07078 && BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo))
07079 {
07080
07081
07082
07083
07084
07085
07086
07087
07088
07089
07090
07091
07092
07093
07094
07095 tree b;
07096 tree last = NULL_TREE;
07097
07098
07099
07100 b = binfo;
07101 while (BINFO_PRIMARY_P (b))
07102 {
07103 b = BINFO_INHERITANCE_CHAIN (b);
07104 last = b;
07105 if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
07106 goto found;
07107 }
07108
07109
07110 for (b = last; b; b = BINFO_INHERITANCE_CHAIN (b))
07111 if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
07112 break;
07113 found:
07114
07115
07116
07117
07118
07119 if (b == rtti_binfo
07120 || (b && binfo_for_vbase (BINFO_TYPE (b), BINFO_TYPE (rtti_binfo))))
07121
07122
07123
07124 vtbl = last;
07125
07126
07127 }
07128 else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo))
07129 return inits;
07130
07131 if (!vtbl)
07132 {
07133 tree index;
07134 int non_fn_entries;
07135
07136
07137 inits = build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
07138 &non_fn_entries);
07139
07140
07141 vtbl = TREE_PURPOSE (l);
07142 vtbl = build_address (vtbl);
07143
07144
07145
07146
07147 gcc_assert (TREE_CODE (vtbl) == ADDR_EXPR);
07148 TREE_TYPE (vtbl) = vtbl_ptr_type_node;
07149 index = size_binop (PLUS_EXPR,
07150 size_int (non_fn_entries),
07151 size_int (list_length (TREE_VALUE (l))));
07152 index = size_binop (MULT_EXPR,
07153 TYPE_SIZE_UNIT (vtable_entry_type),
07154 index);
07155 vtbl = build2 (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
07156 }
07157
07158 if (ctor_vtbl_p)
07159
07160
07161
07162 BINFO_VTABLE (binfo) = tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo));
07163 else if (BINFO_PRIMARY_P (binfo) && BINFO_VIRTUAL_P (binfo))
07164 inits = NULL_TREE;
07165 else
07166
07167 BINFO_VTABLE (binfo) = vtbl;
07168
07169 return inits;
07170 }
07171
07172 static GTY(()) tree abort_fndecl_addr;
07173
07174
07175
07176
07177
07178
07179
07180
07181
07182
07183
07184
07185
07186
07187
07188
07189
07190
07191
07192
07193
07194
07195
07196
07197 static tree
07198 build_vtbl_initializer (tree binfo,
07199 tree orig_binfo,
07200 tree t,
07201 tree rtti_binfo,
07202 int* non_fn_entries_p)
07203 {
07204 tree v, b;
07205 tree vfun_inits;
07206 vtbl_init_data vid;
07207 unsigned ix;
07208 tree vbinfo;
07209 VEC(tree,gc) *vbases;
07210
07211
07212 memset (&vid, 0, sizeof (vid));
07213 vid.binfo = binfo;
07214 vid.derived = t;
07215 vid.rtti_binfo = rtti_binfo;
07216 vid.last_init = &vid.inits;
07217 vid.primary_vtbl_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
07218 vid.ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
07219 vid.generate_vcall_entries = true;
07220
07221 vid.index = ssize_int(-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
07222
07223
07224 build_rtti_vtbl_entries (binfo, &vid);
07225
07226
07227
07228
07229 vid.fns = VEC_alloc (tree, gc, 32);
07230
07231 build_vcall_and_vbase_vtbl_entries (binfo, &vid);
07232
07233
07234
07235 for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
07236 VEC_iterate (tree, vbases, ix, vbinfo); ix++)
07237 BINFO_VTABLE_PATH_MARKED (vbinfo) = 0;
07238
07239
07240 if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
07241 {
07242 tree cur, *prev;
07243
07244 for (prev = &vid.inits; (cur = *prev); prev = &TREE_CHAIN (cur))
07245 {
07246 tree add = cur;
07247 int i;
07248
07249 for (i = 1; i < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++i)
07250 add = tree_cons (NULL_TREE,
07251 build1 (NOP_EXPR, vtable_entry_type,
07252 null_pointer_node),
07253 add);
07254 *prev = add;
07255 }
07256 }
07257
07258 if (non_fn_entries_p)
07259 *non_fn_entries_p = list_length (vid.inits);
07260
07261
07262
07263 vfun_inits = NULL_TREE;
07264 for (v = BINFO_VIRTUALS (orig_binfo); v; v = TREE_CHAIN (v))
07265 {
07266 tree delta;
07267 tree vcall_index;
07268 tree fn, fn_original;
07269 tree init = NULL_TREE;
07270
07271 fn = BV_FN (v);
07272 fn_original = fn;
07273 if (DECL_THUNK_P (fn))
07274 {
07275 if (!DECL_NAME (fn))
07276 finish_thunk (fn);
07277 if (THUNK_ALIAS (fn))
07278 {
07279 fn = THUNK_ALIAS (fn);
07280 BV_FN (v) = fn;
07281 }
07282 fn_original = THUNK_TARGET (fn);
07283 }
07284
07285
07286
07287
07288
07289
07290
07291
07292
07293
07294
07295 for (b = binfo; ; b = get_primary_binfo (b))
07296 {
07297
07298 if (look_for_overrides_here (BINFO_TYPE (b), fn_original))
07299 break;
07300
07301
07302
07303 if (BINFO_LOST_PRIMARY_P (b))
07304 {
07305 init = size_zero_node;
07306 break;
07307 }
07308 }
07309
07310 if (! init)
07311 {
07312
07313
07314 delta = BV_DELTA (v);
07315 vcall_index = BV_VCALL_INDEX (v);
07316
07317 gcc_assert (TREE_CODE (delta) == INTEGER_CST);
07318 gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
07319
07320
07321
07322 if (DECL_PURE_VIRTUAL_P (fn_original))
07323 {
07324 fn = abort_fndecl;
07325 if (abort_fndecl_addr == NULL)
07326 abort_fndecl_addr = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
07327 init = abort_fndecl_addr;
07328 }
07329 else
07330 {
07331 if (!integer_zerop (delta) || vcall_index)
07332 {
07333 fn = make_thunk (fn, 1, delta, vcall_index);
07334 if (!DECL_NAME (fn))
07335 finish_thunk (fn);
07336 }
07337
07338
07339 init = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
07340 }
07341 }
07342
07343
07344 if (TARGET_VTABLE_USES_DESCRIPTORS)
07345 {
07346 int i;
07347 if (init == size_zero_node)
07348 for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
07349 vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
07350 else
07351 for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
07352 {
07353 tree fdesc = build2 (FDESC_EXPR, vfunc_ptr_type_node,
07354 TREE_OPERAND (init, 0),
07355 build_int_cst (NULL_TREE, i));
07356 TREE_CONSTANT (fdesc) = 1;
07357 TREE_INVARIANT (fdesc) = 1;
07358
07359 vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits);
07360 }
07361 }
07362 else
07363 vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
07364 }
07365
07366
07367
07368 vfun_inits = nreverse (vfun_inits);
07369
07370
07371 vid.inits = nreverse (vid.inits);
07372
07373
07374 return chainon (vid.inits, vfun_inits);
07375 }
07376
07377
07378
07379
07380 static void
07381 build_vcall_and_vbase_vtbl_entries (tree binfo, vtbl_init_data* vid)
07382 {
07383 tree b;
07384
07385
07386
07387 b = get_primary_binfo (binfo);
07388 if (b)
07389 build_vcall_and_vbase_vtbl_entries (b, vid);
07390
07391
07392 build_vbase_offset_vtbl_entries (binfo, vid);
07393
07394 build_vcall_offset_vtbl_entries (binfo, vid);
07395 }
07396
07397
07398
07399
07400
07401
07402 static void
07403 build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
07404 {
07405 tree vbase;
07406 tree t;
07407 tree non_primary_binfo;
07408
07409
07410
07411 if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
07412 return;
07413
07414 t = vid->derived;
07415
07416
07417
07418
07419 non_primary_binfo = binfo;
07420 while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
07421 {
07422 tree b;
07423
07424
07425
07426
07427
07428 if (BINFO_VIRTUAL_P (non_primary_binfo))
07429 {
07430 non_primary_binfo = vid->binfo;
07431 break;
07432 }
07433
07434 b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
07435 if (get_primary_binfo (b) != non_primary_binfo)
07436 break;
07437 non_primary_binfo = b;
07438 }
07439
07440
07441 for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
07442 vbase;
07443 vbase = TREE_CHAIN (vbase))
07444 {
07445 tree b;
07446 tree delta;
07447
07448 if (!BINFO_VIRTUAL_P (vbase))
07449 continue;
07450
07451
07452
07453 b = copied_binfo (vbase, binfo);
07454
07455
07456
07457 if (BINFO_VTABLE_PATH_MARKED (b))
07458 continue;
07459 BINFO_VTABLE_PATH_MARKED (b) = 1;
07460
07461
07462 delta = size_binop (MULT_EXPR,
07463 vid->index,
07464 convert (ssizetype,
07465 TYPE_SIZE_UNIT (vtable_entry_type)));
07466 if (vid->primary_vtbl_p)
07467 BINFO_VPTR_FIELD (b) = delta;
07468
07469 if (binfo != TYPE_BINFO (t))
07470
07471 gcc_assert (tree_int_cst_equal (delta, BINFO_VPTR_FIELD (vbase)));
07472
07473
07474 vid->index = size_binop (MINUS_EXPR, vid->index,
07475 ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
07476
07477
07478
07479
07480
07481 delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));
07482
07483 *vid->last_init
07484 = build_tree_list (NULL_TREE,
07485 fold_build1 (NOP_EXPR,
07486 vtable_entry_type,
07487 delta));
07488 vid->last_init = &TREE_CHAIN (*vid->last_init);
07489 }
07490 }
07491
07492
07493
07494
07495
07496 static void
07497 build_vcall_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
07498 {
07499
07500
07501
07502 if (BINFO_VIRTUAL_P (binfo) || binfo == TYPE_BINFO (vid->derived))
07503 {
07504
07505
07506
07507
07508
07509
07510
07511
07512
07513
07514
07515
07516
07517
07518
07519
07520
07521
07522 vid->vbase = binfo;
07523
07524
07525 if (!BINFO_VIRTUAL_P (binfo))
07526 vid->generate_vcall_entries = false;
07527
07528 add_vcall_offset_vtbl_entries_r (binfo, vid);
07529 }
07530 }
07531
07532
07533
07534 static void
07535 add_vcall_offset_vtbl_entries_r (tree binfo, vtbl_init_data* vid)
07536 {
07537 int i;
07538 tree primary_binfo;
07539 tree base_binfo;
07540
07541
07542
07543
07544
07545 if (BINFO_VIRTUAL_P (binfo) && vid->vbase != binfo)
07546 return;
07547
07548
07549 primary_binfo = get_primary_binfo (binfo);
07550 if (primary_binfo)
07551 add_vcall_offset_vtbl_entries_r (primary_binfo, vid);
07552
07553
07554 add_vcall_offset_vtbl_entries_1 (binfo, vid);
07555
07556
07557 for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
07558 if (base_binfo != primary_binfo)
07559 add_vcall_offset_vtbl_entries_r (base_binfo, vid);
07560 }
07561
07562
07563
07564 static void
07565 add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
07566 {
07567
07568 if (abi_version_at_least (2))
07569 {
07570 tree orig_fn;
07571
07572
07573
07574 for (orig_fn = TYPE_METHODS (BINFO_TYPE (binfo));
07575 orig_fn;
07576 orig_fn = TREE_CHAIN (orig_fn))
07577 if (DECL_VINDEX (orig_fn))
07578 add_vcall_offset (orig_fn, binfo, vid);
07579 }
07580 else
07581 {
07582 tree derived_virtuals;
07583 tree base_virtuals;
07584 tree orig_virtuals;
07585
07586
07587 tree non_primary_binfo;
07588
07589
07590
07591
07592 non_primary_binfo = binfo;
07593 while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
07594 {
07595 tree b;
07596
07597
07598
07599
07600
07601
07602
07603 if (BINFO_VIRTUAL_P (non_primary_binfo))
07604 {
07605 gcc_assert (non_primary_binfo == vid->vbase);
07606 non_primary_binfo = vid->binfo;
07607 break;
07608 }
07609
07610 b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
07611 if (get_primary_binfo (b) != non_primary_binfo)
07612 break;
07613 non_primary_binfo = b;
07614 }
07615
07616 if (vid->ctor_vtbl_p)
07617
07618
07619 non_primary_binfo
07620 = original_binfo (non_primary_binfo, vid->rtti_binfo);
07621
07622 for (base_virtuals = BINFO_VIRTUALS (binfo),
07623 derived_virtuals = BINFO_VIRTUALS (non_primary_binfo),
07624 orig_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
07625 base_virtuals;
07626 base_virtuals = TREE_CHAIN (base_virtuals),
07627 derived_virtuals = TREE_CHAIN (derived_virtuals),
07628 orig_virtuals = TREE_CHAIN (orig_virtuals))
07629 {
07630 tree orig_fn;
07631
07632
07633
07634 orig_fn = BV_FN (orig_virtuals);
07635
07636
07637
07638
07639 if (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), DECL_CONTEXT (orig_fn)))
07640 continue;
07641
07642 add_vcall_offset (orig_fn, binfo, vid);
07643 }
07644 }
07645 }
07646
07647
07648
07649 static void
07650 add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
07651 {
07652 size_t i;
07653 tree vcall_offset;
07654 tree derived_entry;
07655
07656
07657
07658
07659
07660 for (i = 0; VEC_iterate (tree, vid->fns, i, derived_entry); ++i)
07661 {
07662 if (same_signature_p (derived_entry, orig_fn)
07663
07664
07665 || (DECL_DESTRUCTOR_P (derived_entry)
07666 && DECL_DESTRUCTOR_P (orig_fn)))
07667 return;
07668 }
07669
07670
07671
07672
07673 if (vid->binfo == TYPE_BINFO (vid->derived))
07674 {
07675 tree_pair_p elt = VEC_safe_push (tree_pair_s, gc,
07676 CLASSTYPE_VCALL_INDICES (vid->derived),
07677 NULL);
07678 elt->purpose = orig_fn;
07679 elt->value = vid->index;
07680 }
07681
07682
07683
07684 vid->index = size_binop (MINUS_EXPR, vid->index,
07685 ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
07686
07687
07688 VEC_safe_push (tree, gc, vid->fns, orig_fn);
07689
07690 if (vid->generate_vcall_entries)
07691 {
07692 tree base;
07693 tree fn;
07694
07695
07696 fn = find_final_overrider (vid->rtti_binfo, binfo, orig_fn);
07697 if (fn == error_mark_node)
07698 vcall_offset = build1 (NOP_EXPR, vtable_entry_type,
07699 integer_zero_node);
07700 else
07701 {
07702 base = TREE_VALUE (fn);
07703
07704
07705
07706
07707
07708 vcall_offset = size_diffop (BINFO_OFFSET (base),
07709 BINFO_OFFSET (vid->binfo));
07710 vcall_offset = fold_build1 (NOP_EXPR, vtable_entry_type,
07711 vcall_offset);
07712 }
07713
07714 *vid->last_init = build_tree_list (NULL_TREE, vcall_offset);
07715 vid->last_init = &TREE_CHAIN (*vid->last_init);
07716 }
07717 }
07718
07719
07720
07721
07722
07723 static void
07724 build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
07725 {
07726 tree b;
07727 tree t;
07728 tree basetype;
07729 tree offset;
07730 tree decl;
07731 tree init;
07732
07733 basetype = BINFO_TYPE (binfo);
07734 t = BINFO_TYPE (vid->rtti_binfo);
07735
07736
07737
07738 b = binfo;
07739 while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (b))
07740 && !BINFO_LOST_PRIMARY_P (b))
07741 {
07742 tree primary_base;
07743
07744 primary_base = get_primary_binfo (b);
07745 gcc_assert (BINFO_PRIMARY_P (primary_base)
07746 && BINFO_INHERITANCE_CHAIN (primary_base) == b);
07747 b = primary_base;
07748 }
07749 offset = size_diffop (BINFO_OFFSET (vid->rtti_binfo), BINFO_OFFSET (b));
07750
07751
07752 if (flag_rtti)
07753 decl = build_address (get_tinfo_decl (t));
07754 else
07755 decl = integer_zero_node;
07756
07757
07758
07759 init = build_nop (vfunc_ptr_type_node, decl);
07760 *vid->last_init = build_tree_list (NULL_TREE, init);
07761 vid->last_init = &TREE_CHAIN (*vid->last_init);
07762
07763
07764
07765
07766 init = build_nop (vfunc_ptr_type_node, offset);
07767 *vid->last_init = build_tree_list (NULL_TREE, init);
07768 vid->last_init = &TREE_CHAIN (*vid->last_init);
07769 }
07770
07771
07772
07773
07774 tree
07775 cp_fold_obj_type_ref (tree ref, tree known_type)
07776 {
07777 HOST_WIDE_INT index = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1);
07778 HOST_WIDE_INT i = 0;
07779 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
07780 tree fndecl;
07781
07782 while (i != index)
07783 {
07784 i += (TARGET_VTABLE_USES_DESCRIPTORS
07785 ? TARGET_VTABLE_USES_DESCRIPTORS : 1);
07786 v = TREE_CHAIN (v);
07787 }
07788
07789 fndecl = BV_FN (v);
07790
07791 #ifdef ENABLE_CHECKING
07792 gcc_assert (tree_int_cst_equal (OBJ_TYPE_REF_TOKEN (ref),
07793 DECL_VINDEX (fndecl)));
07794 #endif
07795
07796 cgraph_node (fndecl)->local.vtable_method = true;
07797
07798 return build_address (fndecl);
07799 }
07800
07801 #include "gt-cp-class.h"