From 80fd5f4866ae9e4b8f8c7a0350c7938fe8ab817e Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sun, 2 Jan 2000 19:41:09 +0000 Subject: [PATCH] cp-tree.h (dfs_mark_primary_bases_queue_p): New function. * cp-tree.h (dfs_mark_primary_bases_queue_p): New function. (layout_basetypes): Remove. * class.c (propagate_binfo_offsets): Moved here from tree.c. Update to handle primary virtual bases. (remove_base_fields): New function, split out from layout_basetypes. (dfs_mark_primary_bases_and_set_vbase_offsets): New function. (layout_virtual_bases): New function, split out from layout_basetypes. Update to handle primary virtual bases. (layout_basetypes): Moved here from tree.c. Use remove_base_fields and layout_virtual_bases. * search.c (dfs_mark_primary_bases_queue_p): New function. (mark_primary_bases): Use it. * tree.c (CEIL): Remove. (propagate_binfo_offsets): Remove. (layout_basetypes): Remove. From-SVN: r31168 --- gcc/cp/ChangeLog | 19 +++ gcc/cp/class.c | 319 +++++++++++++++++++++++++++++++++++++++++++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/search.c | 29 ++++- gcc/cp/tree.c | 245 ------------------------------------ 5 files changed, 366 insertions(+), 248 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d1762d63c9e..c023f90f754 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +2000-01-02 Mark Mitchell + + * cp-tree.h (dfs_mark_primary_bases_queue_p): New function. + (layout_basetypes): Remove. + * class.c (propagate_binfo_offsets): Moved here from tree.c. + Update to handle primary virtual bases. + (remove_base_fields): New function, split out from + layout_basetypes. + (dfs_mark_primary_bases_and_set_vbase_offsets): New function. + (layout_virtual_bases): New function, split out from + layout_basetypes. Update to handle primary virtual bases. + (layout_basetypes): Moved here from tree.c. Use + remove_base_fields and layout_virtual_bases. + * search.c (dfs_mark_primary_bases_queue_p): New function. + (mark_primary_bases): Use it. + * tree.c (CEIL): Remove. + (propagate_binfo_offsets): Remove. + (layout_basetypes): Remove. + 2000-01-01 Mark Mitchell * cp-tree.h (skip_rtti_stuff): Adjust prototype. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index fe5d29685dd..7d22db8f463 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -138,6 +138,11 @@ static void layout_class_type PROTO((tree, int *, int *, int *, tree *, tree *)) static void fixup_pending_inline PROTO((struct pending_inline *)); static void fixup_inline_methods PROTO((tree)); static void set_primary_base PROTO((tree, int, int *)); +static void propagate_binfo_offsets PROTO((tree, tree)); +static int layout_basetypes PROTO((tree, int)); +static tree dfs_mark_primary_bases_and_set_vbase_offsets PROTO((tree, void *)); +static int layout_virtual_bases PROTO((tree, int)); +static void remove_base_fields PROTO((tree)); /* Variables shared between class.c and call.c. */ @@ -4143,6 +4148,320 @@ fixup_inline_methods (type) CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE; } +/* Add OFFSET to all base types of T. + + OFFSET, which is a type offset, is number of bytes. + + Note that we don't have to worry about having two paths to the + same base type, since this type owns its association list. */ + +static void +propagate_binfo_offsets (binfo, offset) + tree binfo; + tree offset; +{ + tree binfos = BINFO_BASETYPES (binfo); + int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; + + if (flag_new_abi) + { + for (i = 0; i < n_baselinks; ++i) + { + tree base_binfo; + + /* Figure out which base we're looking at. */ + base_binfo = TREE_VEC_ELT (binfos, i); + + /* Skip non-primary virtual bases. Their BINFO_OFFSET + doesn't matter since they are always reached by using + offsets looked up at run-time. */ + if (TREE_VIA_VIRTUAL (base_binfo) + && i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) + continue; + + /* Whatever offset this class used to have in its immediate + derived class, it is now at OFFSET more bytes in its + final derived class, since the immediate derived class is + already at the indicated OFFSET. */ + BINFO_OFFSET (base_binfo) + = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset); + + propagate_binfo_offsets (base_binfo, offset); + } + } + else + { + /* This algorithm, used for the old ABI, is neither simple, nor + general. For example, it mishandles the case of: + + struct A; + struct B : public A; + struct C : public B; + + if B is at offset zero in C, but A is not in offset zero in + B. In that case, it sets the BINFO_OFFSET for A to zero. + (This sitution arises in the new ABI if B has virtual + functions, but A does not.) Rather than change this + algorithm, and risking breaking the old ABI, it is preserved + here. */ + for (i = 0; i < n_baselinks; /* note increment is done in the + loop. */) + { + tree base_binfo = TREE_VEC_ELT (binfos, i); + + if (TREE_VIA_VIRTUAL (base_binfo)) + i += 1; + else + { + int j; + tree delta = NULL_TREE; + + for (j = i+1; j < n_baselinks; j++) + if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j))) + { + /* The next basetype offset must take into account + the space between the classes, not just the + size of each class. */ + delta = size_binop (MINUS_EXPR, + BINFO_OFFSET (TREE_VEC_ELT (binfos, + j)), + BINFO_OFFSET (base_binfo)); + break; + } + + BINFO_OFFSET (base_binfo) = offset; + + propagate_binfo_offsets (base_binfo, offset); + + /* Go to our next class that counts for offset + propagation. */ + i = j; + if (i < n_baselinks) + offset = size_binop (PLUS_EXPR, offset, delta); + } + } + } +} + +/* Remove the FIELD_DECLs created for T's base classes in + build_base_fields. Simultaneously, update BINFO_OFFSET for all the + bases, except for non-primary virtual baseclasses. */ + +static void +remove_base_fields (t) + tree t; +{ + int i; + tree *field; + + /* Now propagate offset information throughout the lattice. + Simultaneously, remove the temporary FIELD_DECLS we created in + build_base_fields to refer to base types. */ + field = &TYPE_FIELDS (t); + if (TYPE_VFIELD (t) == *field) + { + /* If this class did not have a primary base, we create a + virtual function table pointer. It will be the first thing + in the class, under the new ABI. Skip it; the base fields + will follow it. */ + my_friendly_assert (flag_new_abi + && !CLASSTYPE_HAS_PRIMARY_BASE_P (t), + 19991218); + field = &TREE_CHAIN (*field); + } + + for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++) + { + register tree base_binfo = BINFO_BASETYPE (TYPE_BINFO (t), i); + register tree basetype = BINFO_TYPE (base_binfo); + + /* We treat a primary virtual base class just like an ordinary + base class. But, non-primary virtual bases are laid out + later. */ + if (TREE_VIA_VIRTUAL (base_binfo) && i != CLASSTYPE_VFIELD_PARENT (t)) + continue; + + my_friendly_assert (TREE_TYPE (*field) == basetype, 23897); + + if (get_base_distance (basetype, t, 0, (tree*)0) == -2) + cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", + basetype, t); + + BINFO_OFFSET (base_binfo) + = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (*field)), + BITS_PER_UNIT)); + propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo)); + + /* Remove this field. */ + *field = TREE_CHAIN (*field); + } +} + +/* Called via dfs_walk from layout_virtual_bases. */ + +static tree +dfs_mark_primary_bases_and_set_vbase_offsets (binfo, data) + tree binfo; + void *data; +{ + if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) + { + int i; + tree base_binfo; + + i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); + base_binfo = BINFO_BASETYPE (binfo, i); + + /* If this is a virtual base class, and we've just now + discovered it to be a primary base, then reuse this copy as + the virtual base class for the complete object. */ + if (TREE_VIA_VIRTUAL (base_binfo) + && !BINFO_PRIMARY_MARKED_P (base_binfo)) + { + tree vbase; + + vbase = BINFO_FOR_VBASE (BINFO_TYPE (base_binfo), (tree) data); + BINFO_OFFSET (vbase) = BINFO_OFFSET (base_binfo); + } + + SET_BINFO_PRIMARY_MARKED_P (BINFO_BASETYPE (binfo, i)); + } + + SET_BINFO_MARKED (binfo); + + return NULL_TREE; +} + +/* Set BINFO_OFFSET for all of the virtual bases for T. Update + TYPE_ALIGN and TYPE_SIZE for T. Return the maximum of MAX and the + largest CLASSTYPE_VSIZE for any of the virtual bases. */ + +static int +layout_virtual_bases (t, max) + tree t; + int max; +{ + tree vbase; + int dsize; + + /* Mark the primary base classes. Only virtual bases that are not + also primary base classes need to be laid out (since otherwise we + can just reuse one of the places in the hierarchy where the + virtual base already occurs.) */ + dfs_walk (TYPE_BINFO (t), + dfs_mark_primary_bases_and_set_vbase_offsets, + dfs_mark_primary_bases_queue_p, + t); + + /* DSIZE is the size of the class without the virtual bases. */ + dsize = TREE_INT_CST_LOW (TYPE_SIZE (t)); + /* Make every class have alignment of at least one. */ + TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT); + + for (vbase = CLASSTYPE_VBASECLASSES (t); + vbase; + vbase = TREE_CHAIN (vbase)) + if (!BINFO_PRIMARY_MARKED_P (vbase)) + { + /* This virtual base is not a primary base of any class in the + hierarchy, so we have to add space for it. */ + tree basetype; + unsigned int desired_align; + + basetype = BINFO_TYPE (vbase); + desired_align = TYPE_ALIGN (basetype); + TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), desired_align); + + /* Add padding so that we can put the virtual base class at an + appropriately aligned offset. */ + dsize = CEIL (dsize, desired_align) * desired_align; + /* And compute the offset of the virtual base. */ + BINFO_OFFSET (vbase) = size_int (CEIL (dsize, BITS_PER_UNIT)); + /* Every virtual baseclass takes a least a UNIT, so that we can + take it's address and get something different for each base. */ + dsize += MAX (BITS_PER_UNIT, + TREE_INT_CST_LOW (CLASSTYPE_SIZE (basetype))); + + /* Now that we've laid out this virtual base class, some of + the remaining virtual bases might have been implicitly laid + out as well -- they could be primary base classes of + classes in BASETYPE. */ + dfs_walk (vbase, + dfs_mark_primary_bases_and_set_vbase_offsets, + dfs_mark_primary_bases_queue_p, + t); + + /* While we're here, see if this new virtual base class has + more virtual functions than we expected. */ + max = MAX (CLASSTYPE_VSIZE (basetype), max); + } + + /* We're done with the various marks, now, so clear them. */ + unmark_primary_bases (t); + dfs_walk (TYPE_BINFO (t), dfs_unmark, markedp, 0); + + /* Now, make sure that the total size of the type is a multiple of + its alignment. */ + dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t); + TYPE_SIZE (t) = size_int (dsize); + TYPE_SIZE_UNIT (t) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (t), + size_int (BITS_PER_UNIT)); + + return max; +} + +/* Finish the work of layout_record, now taking virtual bases into account. + Also compute the actual offsets that our base classes will have. + This must be performed after the fields are laid out, since virtual + baseclasses must lay down at the end of the record. + + Returns the maximum number of virtual functions any of the + baseclasses provide. */ + +static int +layout_basetypes (rec, max) + tree rec; + int max; +{ + tree vbase_types; + +#ifdef STRUCTURE_SIZE_BOUNDARY + /* Packed structures don't need to have minimum size. */ + if (! TYPE_PACKED (rec)) + TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), STRUCTURE_SIZE_BOUNDARY); +#endif + + /* Remove the FIELD_DECLs we created for baseclasses in + build_base_fields. Simultaneously, update the BINFO_OFFSETs for + everything in the hierarcy except non-primary virtual bases. */ + remove_base_fields (rec); + + /* Allocate the virtual base classes. */ + max = layout_virtual_bases (rec, max); + + /* Get all the virtual base types that this type uses. The + TREE_VALUE slot holds the virtual baseclass type. Note that + get_vbase_types makes copies of the virtual base BINFOs, so that + the vbase_types are unshared. */ + for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types; + vbase_types = TREE_CHAIN (vbase_types)) + { + BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec); + unshare_base_binfos (vbase_types); + propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types)); + + if (extra_warnings) + { + tree basetype = BINFO_TYPE (vbase_types); + if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) + cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", + basetype, rec); + } + } + + return max; +} + /* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate BINFO_OFFSETs for all of the base-classes. Position the vtable pointer. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index db9a5e4a361..a83dc15a2c0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3909,6 +3909,7 @@ extern tree dfs_walk PROTO((tree, void *)); extern tree dfs_unmark PROTO((tree, void *)); extern tree markedp PROTO((tree, void *)); +extern tree dfs_mark_primary_bases_queue_p PROTO((tree, void *)); extern void mark_primary_bases PROTO((tree)); extern void unmark_primary_bases PROTO((tree)); @@ -4028,7 +4029,6 @@ extern tree break_out_calls PROTO((tree)); extern tree build_cplus_method_type PROTO((tree, tree, tree)); extern tree build_cplus_staticfn_type PROTO((tree, tree, tree)); extern tree build_cplus_array_type PROTO((tree, tree)); -extern int layout_basetypes PROTO((tree, int)); extern tree hash_tree_cons PROTO((tree, tree, tree)); extern tree hash_tree_chain PROTO((tree, tree)); extern tree hash_chainon PROTO((tree, tree)); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index c22391db6a3..079a653130a 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2104,7 +2104,7 @@ get_matching_virtual (binfo, fndecl, dtorp) } } -/* Called via dfs_walk from mark_nonprimary_bases. */ +/* Called via dfs_walk from mark_primary_bases. */ static tree dfs_mark_primary_bases (binfo, data) @@ -2124,6 +2124,31 @@ dfs_mark_primary_bases (binfo, data) return NULL_TREE; } +/* Called via dfs_walk from mark_primary_bases. */ + +tree +dfs_mark_primary_bases_queue_p (binfo, data) + tree binfo; + void *data ATTRIBUTE_UNUSED; +{ + /* Don't walk into virtual baseclasses that are not primary + bases. */ + if (TREE_VIA_VIRTUAL (binfo)) + { + tree derived_class; + tree primary_base; + + derived_class = BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)); + primary_base = CLASSTYPE_PRIMARY_BINFO (derived_class); + if (!primary_base || !same_type_p (BINFO_TYPE (primary_base), + BINFO_TYPE (binfo))) + return NULL_TREE; + } + + /* But do walk into everything else. */ + return binfo; +} + /* Set BINFO_PRIMARY_MARKED_P for all binfos in the hierarchy dominated by TYPE that are primary bases. (In addition, BINFO_MARKED is set for all classes in the hierarchy; callers @@ -2135,7 +2160,7 @@ mark_primary_bases (type) { dfs_walk (TYPE_BINFO (type), dfs_mark_primary_bases, - unmarkedp, + dfs_mark_primary_bases_queue_p, NULL); } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index f5e24740200..a951b5f7197 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -37,7 +37,6 @@ static tree build_cplus_array_type_1 PROTO((tree, tree)); static void list_hash_add PROTO((int, tree)); static int list_hash PROTO((tree, tree, tree)); static tree list_hash_lookup PROTO((int, tree, tree, tree)); -static void propagate_binfo_offsets PROTO((tree, tree)); static cp_lvalue_kind lvalue_p_1 PROTO((tree, int)); static tree no_linkage_helper PROTO((tree *, int *, void *)); static tree build_srcloc PROTO((char *, int)); @@ -48,8 +47,6 @@ static tree cp_unsave_r PROTO ((tree *, int *, void *)); static void cp_unsave PROTO((tree *)); static tree build_target_expr PROTO((tree, tree)); -#define CEIL(x,y) (((x) + (y) - 1) / (y)) - /* If REF is an lvalue, returns the kind of lvalue that REF is. Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is non-zero, rvalues of class type are considered lvalues. */ @@ -656,100 +653,6 @@ canonical_type_variant (t) return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), CP_TYPE_QUALS (t)); } -/* Add OFFSET to all base types of T. - - OFFSET, which is a type offset, is number of bytes. - - Note that we don't have to worry about having two paths to the - same base type, since this type owns its association list. */ - -static void -propagate_binfo_offsets (binfo, offset) - tree binfo; - tree offset; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - if (flag_new_abi) - { - for (i = 0; i < n_baselinks; ++i) - { - tree base_binfo; - - /* Figure out which base we're looking at. */ - base_binfo = TREE_VEC_ELT (binfos, i); - - /* Skip virtual bases. Their BINFO_OFFSET doesn't matter - since they are always reached by using offsets looked up - at run-time. */ - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - /* Whatever offset this class used to have in its immediate - derived class, it is now at OFFSET more bytes in its - final derived class, since the immediate derived class is - already at the indicated OFFSET. */ - BINFO_OFFSET (base_binfo) - = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset); - - propagate_binfo_offsets (base_binfo, offset); - } - } - else - { - /* This algorithm, used for the old ABI, is neither simple, nor - general. For example, it mishandles the case of: - - struct A; - struct B : public A; - struct C : public B; - - if B is at offset zero in C, but A is not in offset zero in - B. In that case, it sets the BINFO_OFFSET for A to zero. - (This sitution arises in the new ABI if B has virtual - functions, but A does not.) Rather than change this - algorithm, and risking breaking the old ABI, it is preserved - here. */ - for (i = 0; i < n_baselinks; /* note increment is done in the - loop. */) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - if (TREE_VIA_VIRTUAL (base_binfo)) - i += 1; - else - { - int j; - tree delta = NULL_TREE; - - for (j = i+1; j < n_baselinks; j++) - if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j))) - { - /* The next basetype offset must take into account - the space between the classes, not just the - size of each class. */ - delta = size_binop (MINUS_EXPR, - BINFO_OFFSET (TREE_VEC_ELT (binfos, - j)), - BINFO_OFFSET (base_binfo)); - break; - } - - BINFO_OFFSET (base_binfo) = offset; - - propagate_binfo_offsets (base_binfo, offset); - - /* Go to our next class that counts for offset - propagation. */ - i = j; - if (i < n_baselinks) - offset = size_binop (PLUS_EXPR, offset, delta); - } - } - } -} - /* Makes new binfos for the indirect bases under BINFO, and updates BINFO_OFFSET for them and their bases. */ @@ -782,154 +685,6 @@ unshare_base_binfos (binfo) } } -/* Finish the work of layout_record, now taking virtual bases into account. - Also compute the actual offsets that our base classes will have. - This must be performed after the fields are laid out, since virtual - baseclasses must lay down at the end of the record. - - Returns the maximum number of virtual functions any of the - baseclasses provide. */ - -int -layout_basetypes (rec, max) - tree rec; - int max; -{ - tree binfos = TYPE_BINFO_BASETYPES (rec); - int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (rec); - tree vbase_types; - tree *field; - - unsigned int record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec)); - unsigned int desired_align; - - /* Record size so far is CONST_SIZE bits, where CONST_SIZE is an integer. */ - register unsigned int const_size = 0; - unsigned int nonvirtual_const_size; - -#ifdef STRUCTURE_SIZE_BOUNDARY - /* Packed structures don't need to have minimum size. */ - if (! TYPE_PACKED (rec)) - record_align = MAX (record_align, STRUCTURE_SIZE_BOUNDARY); -#endif - - /* Get all the virtual base types that this type uses. The - TREE_VALUE slot holds the virtual baseclass type. Note that - get_vbase_types makes copies of the virtual base BINFOs, so that - the vbase_types are unshared. */ - vbase_types = CLASSTYPE_VBASECLASSES (rec); - - my_friendly_assert (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST, 19970302); - const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec)); - - nonvirtual_const_size = const_size; - - while (vbase_types) - { - tree basetype = BINFO_TYPE (vbase_types); - tree offset; - - desired_align = TYPE_ALIGN (basetype); - record_align = MAX (record_align, desired_align); - - if (const_size == 0) - offset = integer_zero_node; - else - { - /* Give each virtual base type the alignment it wants. */ - const_size = CEIL (const_size, desired_align) * desired_align; - offset = size_int (CEIL (const_size, BITS_PER_UNIT)); - } - - if (CLASSTYPE_VSIZE (basetype) > max) - max = CLASSTYPE_VSIZE (basetype); - BINFO_OFFSET (vbase_types) = offset; - - /* Every virtual baseclass takes a least a UNIT, so that we can - take it's address and get something different for each base. */ - const_size += MAX (BITS_PER_UNIT, - TREE_INT_CST_LOW (CLASSTYPE_SIZE (basetype))); - - vbase_types = TREE_CHAIN (vbase_types); - } - - if (const_size) - { - /* Because a virtual base might take a single byte above, - we have to re-adjust the total size to make sure it is - a multiple of the alignment. */ - /* Give the whole object the alignment it wants. */ - const_size = CEIL (const_size, record_align) * record_align; - } - - /* Set the alignment in the complete type. We don't set CLASSTYPE_ALIGN - here, as that is for this class, without any virtual base classes. */ - TYPE_ALIGN (rec) = record_align; - if (const_size != nonvirtual_const_size) - { - TYPE_SIZE (rec) = size_int (const_size); - TYPE_SIZE_UNIT (rec) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (rec), - size_int (BITS_PER_UNIT)); - } - - /* Now propagate offset information throughout the lattice. - Simultaneously, remove the temporary FIELD_DECLS we created in - build_base_fields to refer to base types. */ - field = &TYPE_FIELDS (rec); - if (TYPE_VFIELD (rec) == *field) - { - /* If this class did not have a primary base, we create a - virtual function table pointer. It will be the first thing - in the class, under the new ABI. Skip it; the base fields - will follow it. */ - my_friendly_assert (flag_new_abi - && !CLASSTYPE_HAS_PRIMARY_BASE_P (rec), - 19991218); - field = &TREE_CHAIN (*field); - } - - for (i = 0; i < n_baseclasses; i++) - { - register tree base_binfo = TREE_VEC_ELT (binfos, i); - register tree basetype = BINFO_TYPE (base_binfo); - - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - my_friendly_assert (TREE_TYPE (*field) == basetype, 23897); - - if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) - cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", - basetype, rec); - - BINFO_OFFSET (base_binfo) - = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (*field)), - BITS_PER_UNIT)); - propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo)); - - /* Remove this field. */ - *field = TREE_CHAIN (*field); - } - - for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types; - vbase_types = TREE_CHAIN (vbase_types)) - { - BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec); - unshare_base_binfos (vbase_types); - propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types)); - - if (extra_warnings) - { - tree basetype = BINFO_TYPE (vbase_types); - if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) - cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", - basetype, rec); - } - } - - return max; -} - /* Hashing of lists so that we don't make duplicates. The entry point is `list_hash_canon'. */ -- 2.30.2