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