diff options
author | Mark Mitchell <mark@codesourcery.com> | 2000-03-28 19:27:15 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2000-03-28 19:27:15 +0000 |
commit | da3d4dfa91a591ace5286a262e7cc817a60b5827 (patch) | |
tree | 3d2b3ff39b53629e00a55e4fccb013b1edbff512 /gcc/cp/class.c | |
parent | 65a0aad55d6e7d02cc09f8d869ff9cb7555544b4 (diff) | |
download | gcc-da3d4dfa91a591ace5286a262e7cc817a60b5827.zip gcc-da3d4dfa91a591ace5286a262e7cc817a60b5827.tar.gz gcc-da3d4dfa91a591ace5286a262e7cc817a60b5827.tar.bz2 |
Put RTTI entries at negative offsets in new ABI.
* class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
vbase offset at index -3, not -1.
(build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
(dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
(build_rtti_vtbl_entries): New function.
(set_rtti_entry): Remove.
(build_primary_vtable): Don't use it.
(build_secondary_vtable): Likewise.
(start_vtable): Remove.
(first_vfun_index): New function.
(set_vindex): Likewise.
(add_virtual_function): Don't call start_vtable. Do call
set_vindex.
(set_primary_base): Rename parameter.
(determine_primary_base): Likewise.
(num_vfun_entries): Don't use skip_rtti_stuff.
(num_extra_vtbl_entries): Include RTTI information.
(build_vtbl_initializer): Use build_rtti_vtbl_entries.
(skip_rtti_stuff): Remove.
(dfs_modify_vtables): Don't use it.
(modify_all_vtables): Don't use start_vtable. Do use set_vindex.
(layout_nonempty_base_or_field): Update size handling.
(create_vtable_ptr): Tweak.
(layout_class_type): Adjust parameter names.
(finish_struct_1): Simplify.
* cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
(skip_rtti_stuff): Remove.
(first_vfun_index): New function.
(dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
(dfs_vtable_path_marked_real_bases_queue_p): Remove.
(marked_vtable_pathp): Declare.
(unmarked_vtable_pathp): Likewise.
* error.c (dump_expr): Use first_vfun_index to calculate vtable
offsets.
* rtti.c (build_headof): Look for RTTI at negative offsets.
(get_tinfo_decl_dynamic): Likewise.
(tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
here.
(create_pseudo_type_info): Do it here instead. Adjust so that
vptr points at first virtual function.
* search.c (marked_vtable_pathp): Make it global.
(unmarked_vtable_pathp): Likewise.
(dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
(dfs_vtable_path_marked_real_bases_queue_p): Likewise.
(dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
(get_pure_virtuals): Likewise.
(expand_upcast_fixups): Likewise.
* tree.c (debug_binfo): Likewise.
* tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
negative offset.
From-SVN: r32787
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 400 |
1 files changed, 170 insertions, 230 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1e48e89..a0bbf7f 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -80,7 +80,6 @@ static tree build_vtable_entry PARAMS ((tree, tree, tree)); static tree get_vtable_name PARAMS ((tree)); static tree get_derived_offset PARAMS ((tree, tree)); static tree get_basefndecls PARAMS ((tree, tree)); -static void set_rtti_entry PARAMS ((tree, tree, tree)); static int build_primary_vtable PARAMS ((tree, tree)); static int build_secondary_vtable PARAMS ((tree, tree)); static tree dfs_finish_vtbls PARAMS ((tree, void *)); @@ -142,7 +141,6 @@ static tree dfs_vcall_offset_queue_p PARAMS ((tree, void *)); static tree dfs_build_vcall_offset_vtbl_entries PARAMS ((tree, void *)); static tree build_vcall_offset_vtbl_entries PARAMS ((tree, tree)); static tree dfs_count_virtuals PARAMS ((tree, void *)); -static void start_vtable PARAMS ((tree, int *)); static void layout_vtable_decl PARAMS ((tree, int)); static int num_vfun_entries PARAMS ((tree)); static tree dfs_find_final_overrider PARAMS ((tree, void *)); @@ -162,6 +160,8 @@ static int layout_conflict_p PARAMS ((tree, varray_type)); static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int)); static void layout_empty_base PARAMS ((tree, tree, varray_type)); static void accumulate_vtbl_inits PARAMS ((tree, tree)); +static void set_vindex PARAMS ((tree, tree, int *)); +static tree build_rtti_vtbl_entries PARAMS ((tree, tree)); /* Variables shared between class.c and call.c. */ @@ -279,7 +279,7 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data) base. */ vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list)); if (!TREE_VALUE (list)) - BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0); + BINFO_VPTR_FIELD (vbase) = build_int_2 (-3, 0); else { BINFO_VPTR_FIELD (vbase) = TREE_PURPOSE (TREE_VALUE (list)); @@ -333,11 +333,11 @@ build_vbase_offset_vtbl_entries (binfo, t) TREE_TYPE (list) = binfo; dfs_walk (binfo, dfs_build_vbase_offset_vtbl_entries, - dfs_vtable_path_unmarked_real_bases_queue_p, + unmarked_vtable_pathp, list); dfs_walk (binfo, dfs_vtable_path_unmark, - dfs_vtable_path_marked_real_bases_queue_p, + marked_vtable_pathp, list); inits = nreverse (TREE_VALUE (list)); @@ -405,9 +405,7 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) /* We chain the offsets on in reverse order. That's correct -- build_vtbl_initializer will straighten them out. */ - for (virtuals = skip_rtti_stuff (binfo, - BINFO_TYPE (binfo), - NULL); + for (virtuals = BINFO_VIRTUALS (binfo); virtuals; virtuals = TREE_CHAIN (virtuals)) { @@ -486,6 +484,82 @@ build_vcall_offset_vtbl_entries (binfo, t) return vod.inits; } +/* Return vtbl initializers for the RTTI entries coresponding to the + BINFO's vtable. BINFO is a part of the hierarchy dominated by + T. */ + +static tree +build_rtti_vtbl_entries (binfo, t) + tree binfo; + tree t; +{ + tree b; + tree basetype; + tree inits; + tree offset; + tree decl; + tree init; + + basetype = BINFO_TYPE (binfo); + inits = NULL_TREE; + + /* For a COM object there is no RTTI entry. */ + if (CLASSTYPE_COM_INTERFACE (basetype)) + return inits; + + /* To find the complete object, we will first convert to our most + primary base, and then add the offset in the vtbl to that value. */ + b = binfo; + while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (b))) + b = BINFO_BASETYPE (b, + CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (b))); + offset = size_diffop (size_zero_node, BINFO_OFFSET (b)); + + /* Add the offset-to-top entry. */ + if (flag_vtable_thunks) + { + /* Convert the offset to look like a function pointer, so that + we can put it in the vtable. */ + init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); + TREE_CONSTANT (init) = 1; + inits = tree_cons (NULL_TREE, init, inits); + } + + /* The second entry is, in the case of the new ABI, the address of + the typeinfo object, or, in the case of the old ABI, a function + which returns a typeinfo object. */ + if (new_abi_rtti_p ()) + { + if (flag_rtti) + decl = build_unary_op (ADDR_EXPR, get_tinfo_decl (t), 0); + else + decl = integer_zero_node; + + /* Convert the declaration to a type that can be stored in the + vtable. */ + init = build1 (NOP_EXPR, vfunc_ptr_type_node, decl); + TREE_CONSTANT (init) = 1; + } + else + { + if (flag_rtti) + decl = get_tinfo_decl (t); + else + decl = abort_fndecl; + + /* Convert the declaration to a type that can be stored in the + vtable. */ + init = build1 (ADDR_EXPR, vfunc_ptr_type_node, decl); + TREE_CONSTANT (init) = 1; + init = build_vtable_entry (offset, integer_zero_node, init); + } + + /* Hook the RTTI declaration onto the list. */ + inits = tree_cons (NULL_TREE, init, inits); + + return inits; +} + /* Returns a pointer to the virtual base class of EXP that has the indicated TYPE. EXP is of class type, not a pointer type. */ @@ -945,47 +1019,6 @@ get_derived_offset (binfo, type) return size_binop (MINUS_EXPR, offset1, offset2); } -/* Update the rtti info for this class. */ - -static void -set_rtti_entry (virtuals, offset, type) - tree virtuals, offset, type; -{ - tree decl; - - if (CLASSTYPE_COM_INTERFACE (type)) - return; - - if (flag_rtti) - decl = get_tinfo_decl (type); - else if (!new_abi_rtti_p ()) - /* If someone tries to get RTTI information for a type compiled - without RTTI, they're out of luck. By calling __pure_virtual - in this case, we give a small clue as to what went wrong. We - could consider having a __no_typeinfo function as well, for a - more specific hint. */ - decl = abort_fndecl; - else - /* For the new-abi, we just point to the type_info object. */ - decl = NULL_TREE; - - if (flag_vtable_thunks) - { - /* The first slot holds the offset. */ - BV_DELTA (virtuals) = offset; - BV_VCALL_INDEX (virtuals) = integer_zero_node; - - /* The next node holds the decl. */ - virtuals = TREE_CHAIN (virtuals); - offset = ssize_int (0); - } - - /* This slot holds the function to call. */ - BV_DELTA (virtuals) = offset; - BV_VCALL_INDEX (virtuals) = integer_zero_node; - BV_FN (virtuals) = decl; -} - /* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE. Use NAME for the name of the vtable, and VTABLE_TYPE for its type. */ @@ -1067,8 +1100,6 @@ build_primary_vtable (binfo, type) if (binfo) { - tree offset; - if (BINFO_NEW_VTABLE_MARKED (binfo, type)) /* We have already created a vtable for this base, so there's no need to do it again. */ @@ -1079,11 +1110,6 @@ build_primary_vtable (binfo, type) DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo))); DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (BINFO_VTABLE (binfo))); - - /* Now do rtti stuff. */ - offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE); - offset = size_diffop (size_zero_node, offset); - set_rtti_entry (virtuals, offset, type); } else { @@ -1171,10 +1197,6 @@ build_secondary_vtable (binfo, for_type) else offset = BINFO_OFFSET (binfo); - set_rtti_entry (BINFO_VIRTUALS (binfo), - size_diffop (size_zero_node, offset), - for_type); - /* In the new ABI, secondary vtables are laid out as part of the same structure as the primary vtable. */ if (merge_primary_and_secondary_vtables_p ()) @@ -1349,42 +1371,52 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals) } } -/* Call this function whenever its known that a vtable for T is going - to be needed. It's safe to call it more than once. *HAS_VIRTUAL_P - is initialized to the number of slots that are reserved at the - beginning of the vtable for RTTI information. */ +/* Return the index (in the virtual function table) of the first + virtual function. */ + +int +first_vfun_index (t) + tree t; +{ + /* Under the old ABI, the offset-to-top and RTTI entries are at + indices zero and one; under the new ABI, the first virtual + function is at index zero. */ + if (!CLASSTYPE_COM_INTERFACE (t) && !flag_new_abi) + return flag_vtable_thunks ? 2 : 1; + + return 0; +} + +/* Set DECL_VINDEX for DECL. VINDEX_P is the number of virtual + functions present in the vtable so far. */ static void -start_vtable (t, has_virtual_p) +set_vindex (t, decl, vfuns_p) tree t; - int *has_virtual_p; + tree decl; + int *vfuns_p; { - if (*has_virtual_p == 0 && ! CLASSTYPE_COM_INTERFACE (t)) - { - /* If we are using thunks, use two slots at the front, one - for the offset pointer, one for the tdesc pointer. - For ARM-style vtables, use the same slot for both. */ - if (flag_vtable_thunks) - *has_virtual_p = 2; - else - *has_virtual_p = 1; - } + int vindex; + + vindex = (*vfuns_p)++; + vindex += first_vfun_index (t); + DECL_VINDEX (decl) = build_shared_int_cst (vindex); } /* Add a virtual function to all the appropriate vtables for the class T. DECL_VINDEX(X) should be error_mark_node, if we want to allocate a new slot in our table. If it is error_mark_node, we know that no other function from another vtable is overridden by X. - HAS_VIRTUAL keeps track of how many virtuals there are in our main - vtable for the type, and we build upon the NEW_VIRTUALS list + VFUNS_P keeps track of how many virtuals there are in our + main vtable for the type, and we build upon the NEW_VIRTUALS list and return it. */ static void add_virtual_function (new_virtuals_p, overridden_virtuals_p, - has_virtual, fndecl, t) + vfuns_p, fndecl, t) tree *new_virtuals_p; tree *overridden_virtuals_p; - int *has_virtual; + int *vfuns_p; tree fndecl; tree t; /* Structure type. */ { @@ -1409,10 +1441,8 @@ add_virtual_function (new_virtuals_p, overridden_virtuals_p, /* We remember that this was the base sub-object for rtti. */ CLASSTYPE_RTTI (t) = t; - start_vtable (t, has_virtual); - /* Now assign virtual dispatch information. */ - DECL_VINDEX (fndecl) = build_shared_int_cst ((*has_virtual)++); + set_vindex (t, fndecl, vfuns_p); DECL_VIRTUAL_CONTEXT (fndecl) = t; /* Save the state we've computed on the NEW_VIRTUALS list. */ @@ -1969,10 +1999,10 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p, /* Make the Ith baseclass of T its primary base. */ static void -set_primary_base (t, i, has_virtual_p) +set_primary_base (t, i, vfuns_p) tree t; int i; - int *has_virtual_p; + int *vfuns_p; { tree basetype; @@ -1982,15 +2012,15 @@ set_primary_base (t, i, has_virtual_p) TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); TYPE_VFIELD (t) = TYPE_VFIELD (basetype); CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype); - *has_virtual_p = CLASSTYPE_VSIZE (basetype); + *vfuns_p = CLASSTYPE_VSIZE (basetype); } /* Determine the primary class for T. */ static void -determine_primary_base (t, has_virtual_p) +determine_primary_base (t, vfuns_p) tree t; - int *has_virtual_p; + int *vfuns_p; { int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); @@ -1998,7 +2028,7 @@ determine_primary_base (t, has_virtual_p) if (n_baseclasses == 0) return; - *has_virtual_p = 0; + *vfuns_p = 0; for (i = 0; i < n_baseclasses; i++) { @@ -2021,7 +2051,7 @@ determine_primary_base (t, has_virtual_p) if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) { - set_primary_base (t, i, has_virtual_p); + set_primary_base (t, i, vfuns_p); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype)); } else @@ -2039,8 +2069,8 @@ determine_primary_base (t, has_virtual_p) VF_BASETYPE_VALUE (vfields), CLASSTYPE_VFIELDS (t)); - if (*has_virtual_p == 0) - set_primary_base (t, i, has_virtual_p); + if (*vfuns_p == 0) + set_primary_base (t, i, vfuns_p); } } } @@ -2060,7 +2090,7 @@ determine_primary_base (t, has_virtual_p) if (TREE_VIA_VIRTUAL (base_binfo) && CLASSTYPE_NEARLY_EMPTY_P (basetype)) { - set_primary_base (t, i, has_virtual_p); + set_primary_base (t, i, vfuns_p); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype)); break; } @@ -2557,9 +2587,7 @@ static int num_vfun_entries (binfo) tree binfo; { - return list_length (skip_rtti_stuff (binfo, - BINFO_TYPE (binfo), - NULL)); + return list_length (BINFO_VIRTUALS (binfo)); } /* Called from num_extra_vtbl_entries via dfs_walk. */ @@ -2609,7 +2637,19 @@ num_extra_vtbl_entries (binfo) entries += vod.offsets; } - return entries ? size_int (entries) : size_zero_node; + /* When laying out COM-compatible classes, there are no RTTI + entries. */ + if (CLASSTYPE_COM_INTERFACE (type)) + ; + /* When using vtable thunks, there are two RTTI entries: the "offset + to top" value and the RTTI entry itself. */ + else if (flag_vtable_thunks) + entries += 2; + /* When not using vtable thunks there is only a single entry. */ + else + entries += 1; + + return size_int (entries); } /* Returns the offset (in bytes) from the beginning of BINFO's vtable @@ -2636,7 +2676,6 @@ build_vtbl_initializer (binfo, t) { tree v = BINFO_VIRTUALS (binfo); tree inits = NULL_TREE; - tree type = BINFO_TYPE (binfo); /* Add entries to the vtable that indicate how to adjust the this pointer when calling a virtual function in this class. */ @@ -2646,48 +2685,8 @@ build_vtbl_initializer (binfo, t) inits = chainon (build_vbase_offset_vtbl_entries (binfo, t), inits); - /* Process the RTTI stuff at the head of the list. If we're not - using vtable thunks, then the RTTI entry is just an ordinary - function, and we can process it just like the other virtual - function entries. */ - if (!CLASSTYPE_COM_INTERFACE (type) && flag_vtable_thunks) - { - tree offset; - tree init; - - /* The first entry is an offset. */ - offset = TREE_PURPOSE (v); - my_friendly_assert (TREE_CODE (offset) == INTEGER_CST, - 19990727); - - /* Convert the offset to look like a function pointer, so that - we can put it in the vtable. */ - init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); - TREE_CONSTANT (init) = 1; - inits = tree_cons (NULL_TREE, init, inits); - - v = TREE_CHAIN (v); - - if (new_abi_rtti_p ()) - { - tree decl = TREE_VALUE (v); - - if (decl) - decl = build_unary_op (ADDR_EXPR, decl, 0); - else - decl = integer_zero_node; - decl = build1 (NOP_EXPR, vfunc_ptr_type_node, decl); - TREE_CONSTANT (decl) = 1; - decl = build_vtable_entry (integer_zero_node, integer_zero_node, - decl); - inits = tree_cons (NULL_TREE, decl, inits); - - v = TREE_CHAIN (v); - } - /* In the old abi the second entry (the tdesc pointer) is - just an ordinary function, so it can be dealt with like the - virtual functions. */ - } + /* Add entries to the vtable for RTTI. */ + inits = chainon (build_rtti_vtbl_entries (binfo, t), inits); /* Go through all the ordinary virtual functions, building up initializers. */ @@ -3048,43 +3047,6 @@ find_final_overrider (t, binfo, fn) return build_tree_list (ffod.overriding_fn, ffod.overriding_base); } -/* Return the BINFO_VIRTUALS list for BINFO, without the RTTI stuff at - the front. If non-NULL, N is set to the number of entries - skipped. */ - -tree -skip_rtti_stuff (binfo, t, n) - tree binfo; - tree t; - HOST_WIDE_INT *n; -{ - tree virtuals; - - if (CLASSTYPE_COM_INTERFACE (t)) - return 0; - - if (n) - *n = 0; - virtuals = BINFO_VIRTUALS (binfo); - if (virtuals) - { - /* We always reserve a slot for the offset/tdesc entry. */ - if (n) - ++*n; - virtuals = TREE_CHAIN (virtuals); - } - if (flag_vtable_thunks && virtuals) - { - /* The second slot is reserved for the tdesc pointer when thunks - are used. */ - if (n) - ++*n; - virtuals = TREE_CHAIN (virtuals); - } - - return virtuals; -} - /* Called via dfs_walk. Returns BINFO if BINFO has the same type as DATA (which is really an _TYPE node). */ @@ -3125,10 +3087,8 @@ dfs_modify_vtables (binfo, data) /* Now, go through each of the virtual functions in the virtual function table for BINFO. Find the final overrider, and update the BINFO_VIRTUALS list appropriately. */ - for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL), - old_virtuals = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (binfo)), - BINFO_TYPE (binfo), - NULL); + for (virtuals = BINFO_VIRTUALS (binfo), + old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo))); virtuals; virtuals = TREE_CHAIN (virtuals), old_virtuals = TREE_CHAIN (old_virtuals)) @@ -3138,17 +3098,16 @@ dfs_modify_vtables (binfo, data) tree overrider; tree vindex; tree delta; - HOST_WIDE_INT vindex_val, i; - + HOST_WIDE_INT vindex_val; + HOST_WIDE_INT i; /* Find the function which originally caused this vtable entry to be present. */ fn = BV_FN (old_virtuals); vindex = DECL_VINDEX (fn); b = dfs_walk (binfo, dfs_find_base, NULL, DECL_VIRTUAL_CONTEXT (fn)); - fn = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (b)), - BINFO_TYPE (b), - &i); + fn = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (b))); + i = first_vfun_index (BINFO_TYPE (b)); vindex_val = tree_low_cst (vindex, 0); while (i < vindex_val) { @@ -3195,9 +3154,9 @@ dfs_modify_vtables (binfo, data) which should therefore be appended to the end of the vtable for T. */ static tree -modify_all_vtables (t, has_virtual_p, overridden_virtuals) +modify_all_vtables (t, vfuns_p, overridden_virtuals) tree t; - int *has_virtual_p; + int *vfuns_p; tree overridden_virtuals; { tree binfo; @@ -3224,11 +3183,8 @@ modify_all_vtables (t, has_virtual_p, overridden_virtuals) if (BINFO_VIRTUALS (binfo) && !value_member (fn, BINFO_VIRTUALS (binfo))) { - /* We know we need a vtable for this class now. */ - start_vtable (t, has_virtual_p); /* Set the vtable index. */ - DECL_VINDEX (fn) - = build_shared_int_cst ((*has_virtual_p)++); + set_vindex (t, fn, vfuns_p); /* We don't need to convert to a base class when calling this function. */ DECL_VIRTUAL_CONTEXT (fn) = t; @@ -4220,9 +4176,10 @@ layout_nonempty_base_or_field (rli, decl, binfo, v) /* Now that we know where it wil be placed, update its BINFO_OFFSET. */ - offset = convert (ssizetype, byte_position (decl)); + offset = byte_position (decl); if (binfo) - propagate_binfo_offsets (binfo, offset); + propagate_binfo_offsets (binfo, + convert (ssizetype, offset)); /* We have to check to see whether or not there is already something of the same type at the offset we're about to use. @@ -4243,7 +4200,7 @@ layout_nonempty_base_or_field (rli, decl, binfo, v) { /* Undo the propogate_binfo_offsets call. */ offset = size_diffop (size_zero_node, offset); - propagate_binfo_offsets (binfo, offset); + propagate_binfo_offsets (binfo, convert (ssizetype, offset)); /* Strip off the size allocated to this field. That puts us at the first place we could have put the field with @@ -4601,11 +4558,11 @@ check_bases_and_members (t, empty_p) responsibility to do that. */ static tree -create_vtable_ptr (t, empty_p, has_virtual_p, +create_vtable_ptr (t, empty_p, vfuns_p, new_virtuals_p, overridden_virtuals_p) tree t; int *empty_p; - int *has_virtual_p; + int *vfuns_p; tree *new_virtuals_p; tree *overridden_virtuals_p; { @@ -4616,17 +4573,15 @@ create_vtable_ptr (t, empty_p, has_virtual_p, for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) if (DECL_VINDEX (fn)) add_virtual_function (new_virtuals_p, overridden_virtuals_p, - has_virtual_p, fn, t); + vfuns_p, fn, t); - /* Even if there weren't any new virtual functions, we might need a + /* If we couldn't find an appropriate base class, create a new field + here. Even if there weren't any new virtual functions, we might need a new virtual function table if we're supposed to include vptrs in all classes that need them. */ - if (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ()) - start_vtable (t, has_virtual_p); - - /* If we couldn't find an appropriate base class, create a new field - here. */ - if (*has_virtual_p && !TYPE_VFIELD (t)) + if (!TYPE_VFIELD (t) + && (*vfuns_p + || (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ()))) { /* We build this decl with vtbl_ptr_type_node, which is a `vtable_entry_type*'. It might seem more precise to use @@ -4972,11 +4927,11 @@ end_of_class (t, include_virtuals_p) pointer. */ static void -layout_class_type (t, empty_p, has_virtual_p, +layout_class_type (t, empty_p, vfuns_p, new_virtuals_p, overridden_virtuals_p) tree t; int *empty_p; - int *has_virtual_p; + int *vfuns_p; tree *new_virtuals_p; tree *overridden_virtuals_p; { @@ -4995,10 +4950,10 @@ layout_class_type (t, empty_p, has_virtual_p, /* If possible, we reuse the virtual function table pointer from one of our base classes. */ - determine_primary_base (t, has_virtual_p); + determine_primary_base (t, vfuns_p); /* Create a pointer to our virtual function table. */ - vptr = create_vtable_ptr (t, empty_p, has_virtual_p, + vptr = create_vtable_ptr (t, empty_p, vfuns_p, new_virtuals_p, overridden_virtuals_p); /* Under the new ABI, the vptr is always the first thing in the @@ -5215,7 +5170,7 @@ finish_struct_1 (t) tree t; { tree x; - int has_virtual; + int vfuns; /* The NEW_VIRTUALS is a TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. Each of these functions is a virtual function declared in T that does not override any virtual function from a @@ -5246,7 +5201,7 @@ finish_struct_1 (t) TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; CLASSTYPE_VFIELD_PARENT (t) = -1; - has_virtual = 0; + vfuns = 0; CLASSTYPE_RTTI (t) = NULL_TREE; /* Do end-of-class semantic processing: checking the validity of the @@ -5254,7 +5209,7 @@ finish_struct_1 (t) check_bases_and_members (t, &empty); /* Layout the class itself. */ - layout_class_type (t, &empty, &has_virtual, + layout_class_type (t, &empty, &vfuns, &new_virtuals, &overridden_virtuals); /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we @@ -5278,7 +5233,7 @@ finish_struct_1 (t) } overridden_virtuals - = modify_all_vtables (t, &has_virtual, nreverse (overridden_virtuals)); + = modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals)); /* If necessary, create the primary vtable for this class. */ if (new_virtuals @@ -5288,22 +5243,7 @@ finish_struct_1 (t) new_virtuals = nreverse (new_virtuals); /* We must enter these virtuals into the table. */ if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) - { - if (! CLASSTYPE_COM_INTERFACE (t)) - { - /* The second slot is for the tdesc pointer when thunks - are used. */ - if (flag_vtable_thunks) - new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals); - - /* The first slot is for the rtti offset. */ - new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals); - - set_rtti_entry (new_virtuals, - convert (ssizetype, integer_zero_node), t); - } - build_primary_vtable (NULL_TREE, t); - } + build_primary_vtable (NULL_TREE, t); else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t)) /* Here we know enough to change the type of our virtual function table, but we will wait until later this function. */ @@ -5346,7 +5286,7 @@ finish_struct_1 (t) my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE, 20000116); - CLASSTYPE_VSIZE (t) = has_virtual; + CLASSTYPE_VSIZE (t) = vfuns; /* Entries for virtual functions defined in the primary base are followed by entries for new functions unique to this class. */ TYPE_BINFO_VIRTUALS (t) |