diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-12-21 02:11:10 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-12-21 02:11:10 +0000 |
commit | 3ef397c1c6defdd895e5b1f41931176fe7706133 (patch) | |
tree | 1baa694ed75cd886a2915d1c87150fa270a1062e /gcc | |
parent | 4c6b7393dcb6c97b57b5268dc84542369d5b367f (diff) | |
download | gcc-3ef397c1c6defdd895e5b1f41931176fe7706133.zip gcc-3ef397c1c6defdd895e5b1f41931176fe7706133.tar.gz gcc-3ef397c1c6defdd895e5b1f41931176fe7706133.tar.bz2 |
cp-tree.h (CLASSTYPE_VFIELD_PARENT): Update comments.
1999-12-20 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (CLASSTYPE_VFIELD_PARENT): Update comments.
(CLASSTYPE_HAS_PRIMARY_BASE_P): New macro.
(CLASSTYPE_PRIMARY_BINFO): Likewise.
* class.c (check_methods): Don't set TYPE_HAS_COMPLEX_INIT_REF,
TYPE_NEEDS_CONSTRUCTING, and CLASSTYPE_NON_AGGREGATE here.
(check_bases_and_members): Set them here instead.
(create_vtable_ptr): New function, split out from ...
(finish_struct_1): ... here. Use it. Tidy. Use
CLASSTYPE_HAS_PRIMARY_BASE_P and CLASSTYPE_PRIMARY_BINFO.
* search.c (dfs_init_vbase_pointers): Handle seeing TYPE_VFIELD as
the first field in the class.
* tree.c (layout_basetypes): Use CLASSTYPE_N_BASECLASSES. Handle
seeing TYPE_VFIELD as the first field in the class.
From-SVN: r31042
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cp/class.c | 220 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 23 | ||||
-rw-r--r-- | gcc/cp/search.c | 17 | ||||
-rw-r--r-- | gcc/cp/tree.c | 38 |
5 files changed, 182 insertions, 130 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2e23f2f..9fa4269 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,19 @@ 1999-12-20 Mark Mitchell <mark@codesourcery.com> + * cp-tree.h (CLASSTYPE_VFIELD_PARENT): Update comments. + (CLASSTYPE_HAS_PRIMARY_BASE_P): New macro. + (CLASSTYPE_PRIMARY_BINFO): Likewise. + * class.c (check_methods): Don't set TYPE_HAS_COMPLEX_INIT_REF, + TYPE_NEEDS_CONSTRUCTING, and CLASSTYPE_NON_AGGREGATE here. + (check_bases_and_members): Set them here instead. + (create_vtable_ptr): New function, split out from ... + (finish_struct_1): ... here. Use it. Tidy. Use + CLASSTYPE_HAS_PRIMARY_BASE_P and CLASSTYPE_PRIMARY_BINFO. + * search.c (dfs_init_vbase_pointers): Handle seeing TYPE_VFIELD as + the first field in the class. + * tree.c (layout_basetypes): Use CLASSTYPE_N_BASECLASSES. Handle + seeing TYPE_VFIELD as the first field in the class. + * cp-tree.h (TYPE_VIRTUAL_P): Rename to ... (TYPE_POLYMORPHIC_P): ... this. (TYPE_USES_COMPLEX_INHERITANCE): Rename to ... diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 02b034a..14c67af 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -133,6 +133,7 @@ static void check_methods PROTO((tree)); static void remove_zero_width_bit_fields PROTO((tree)); static void check_bases PROTO((tree, int *, int *, int *)); static void check_bases_and_members PROTO((tree, int *)); +static void create_vtable_ptr PROTO((tree, int *, int *, int *, tree *, tree *)); /* Variables shared between class.c and call.c. */ @@ -3897,18 +3898,13 @@ build_base_fields (rec, empty_p) /* Go through the TYPE_METHODS of T issuing any appropriate diagnostics, figuring out which methods override which other - methods, and so forth. Returns non-zero if this class has any - virtual methods. */ + methods, and so forth. */ static void check_methods (t) tree t; { tree x; - int has_virtual; - - /* Assume there are no virtual methods. */ - has_virtual = 0; for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) { @@ -3933,21 +3929,12 @@ check_methods (t) Save this in auxiliary field for later overloading. */ if (DECL_VINDEX (x)) { - has_virtual = 1; + TYPE_POLYMORPHIC_P (t) = 1; if (DECL_ABSTRACT_VIRTUAL_P (x)) CLASSTYPE_ABSTRACT_VIRTUALS (t) = tree_cons (NULL_TREE, x, CLASSTYPE_ABSTRACT_VIRTUALS (t)); } } - - /* A class with virtual functions needs constructing because, if - nothing else, the vtable pointer must be initialized. */ - TYPE_HAS_COMPLEX_INIT_REF (t) |= has_virtual; - TYPE_NEEDS_CONSTRUCTING (t) |= has_virtual; - /* [dcl.init.aggr] - - An aggregate is a ... class ... with ... no virtual functions. */ - CLASSTYPE_NON_AGGREGATE (t) |= has_virtual; } /* Remove all zero-width bit-fields from T. */ @@ -4014,10 +4001,15 @@ check_bases_and_members (t, empty_p) /* Do some bookkeeping that will guide the generation of implicitly declared member functions. */ TYPE_HAS_COMPLEX_INIT_REF (t) - |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)); + |= (TYPE_HAS_INIT_REF (t) + || TYPE_USES_VIRTUAL_BASECLASSES (t) + || TYPE_POLYMORPHIC_P (t)); TYPE_NEEDS_CONSTRUCTING (t) - |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)); - CLASSTYPE_NON_AGGREGATE (t) |= TYPE_HAS_CONSTRUCTOR (t); + |= (TYPE_HAS_CONSTRUCTOR (t) + || TYPE_USES_VIRTUAL_BASECLASSES (t) + || TYPE_POLYMORPHIC_P (t)); + CLASSTYPE_NON_AGGREGATE (t) |= (TYPE_HAS_CONSTRUCTOR (t) + || TYPE_POLYMORPHIC_P (t)); CLASSTYPE_NON_POD_P (t) |= (CLASSTYPE_NON_AGGREGATE (t) || TYPE_HAS_DESTRUCTOR (t) || TYPE_HAS_ASSIGN_REF (t)); @@ -4044,6 +4036,84 @@ check_bases_and_members (t, empty_p) } } +/* If T needs a pointer to its virtual function table, set TYPE_VFIELD + accordingly, and, if necessary, add the TYPE_VFIELD to the + TYPE_FIELDS list. */ + +static void +create_vtable_ptr (t, empty_p, has_virtual_p, max_has_virtual_p, + pending_virtuals_p, pending_hard_virtuals_p) + tree t; + int *empty_p; + int *has_virtual_p; + int *max_has_virtual_p; + tree *pending_virtuals_p; + tree *pending_hard_virtuals_p; +{ + tree fn; + + /* If possible, we reuse the virtual function table pointer from one + of our base classes. */ + if (CLASSTYPE_N_BASECLASSES (t)) + { + struct base_info base_info; + + /* Remember where we got our vfield from. */ + CLASSTYPE_VFIELD_PARENT (t) = finish_base_struct (t, &base_info); + *has_virtual_p = base_info.has_virtual; + *max_has_virtual_p = base_info.max_has_virtual; + TYPE_VFIELD (t) = base_info.vfield; + CLASSTYPE_VFIELDS (t) = base_info.vfields; + CLASSTYPE_RTTI (t) = base_info.rtti; + } + + /* Loop over the virtual functions, adding them to our various + vtables. */ + for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + if (DECL_VINDEX (fn)) + add_virtual_function (pending_virtuals_p, pending_hard_virtuals_p, + has_virtual_p, fn, t); + + /* If we couldn't find an appropriate base class, create a new field + here. */ + if (*has_virtual_p && !TYPE_VFIELD (t)) + { + /* We build this decl with vtbl_ptr_type_node, which is a + `vtable_entry_type*'. It might seem more precise to use + `vtable_entry_type (*)[N]' where N is the number of firtual + functions. However, that would require the vtable pointer in + base classes to have a different type than the vtable pointer + in derived classes. We could make that happen, but that + still wouldn't solve all the problems. In particular, the + type-based alias analysis code would decide that assignments + to the base class vtable pointer can't alias assignments to + the derived class vtable pointer, since they have different + types. Thus, in an derived class destructor, where the base + class constructor was inlined, we could generate bad code for + setting up the vtable pointer. + + Therefore, we use one type for all vtable pointers. We still + use a type-correct type; it's just doesn't indicate the array + bounds. That's better than using `void*' or some such; it's + cleaner, and it let's the alias analysis code know that these + stores cannot alias stores to void*! */ + TYPE_VFIELD (t) + = build_vtbl_or_vbase_field (get_vfield_name (t), + get_identifier (VFIELD_BASE), + vtbl_ptr_type_node, + t, + empty_p); + + /* Add the new field to the list of fields in this class. */ + TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), TYPE_VFIELD (t)); + + /* We can't yet add this new field to the list of all virtual + function table pointers in this class. The + modify_all_vtables function depends on this not being done. + So, it is done later, in finish_struct_1. */ + } +} + /* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration (or C++ class declaration). @@ -4080,14 +4150,8 @@ finish_struct_1 (t) int max_has_virtual; tree pending_virtuals = NULL_TREE; tree pending_hard_virtuals = NULL_TREE; - tree vfield; - tree vfields; int n_fields = 0; - - /* The index of the first base class which has virtual - functions. Only applied to non-virtual baseclasses. */ - int first_vfn_base_index; - + tree vfield; int n_baseclasses; int empty = 1; tree inline_friends; @@ -4110,11 +4174,9 @@ finish_struct_1 (t) TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; - first_vfn_base_index = -1; + CLASSTYPE_VFIELD_PARENT (t) = -1; has_virtual = 0; max_has_virtual = 0; - vfield = NULL_TREE; - vfields = NULL_TREE; CLASSTYPE_RTTI (t) = NULL_TREE; n_baseclasses = CLASSTYPE_N_BASECLASSES (t); @@ -4129,59 +4191,9 @@ finish_struct_1 (t) TYPE_FIELDS (t) = chainon (build_base_fields (t, &empty), TYPE_FIELDS (t)); - if (n_baseclasses > 0) - { - struct base_info base_info; - - first_vfn_base_index = finish_base_struct (t, &base_info); - /* Remember where we got our vfield from. */ - CLASSTYPE_VFIELD_PARENT (t) = first_vfn_base_index; - has_virtual = base_info.has_virtual; - max_has_virtual = base_info.max_has_virtual; - vfield = base_info.vfield; - TYPE_VFIELD (t) = vfield; - vfields = base_info.vfields; - CLASSTYPE_VFIELDS (t) = vfields; - CLASSTYPE_RTTI (t) = base_info.rtti; - } - - /* Loop over the virtual functions, adding them to our various - vtables. */ - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) - if (DECL_VINDEX (x)) - add_virtual_function (&pending_virtuals, &pending_hard_virtuals, - &has_virtual, x, t); - - if (vfield == NULL_TREE && has_virtual) - { - /* We build this decl with vtbl_ptr_type_node, which is a - `vtable_entry_type*'. It might seem more precise to use - `vtable_entry_type (*)[N]' where N is the number of firtual - functions. However, that would require the vtable pointer in - base classes to have a different type than the vtable pointer - in derived classes. We could make that happen, but that - still wouldn't solve all the problems. In particular, the - type-based alias analysis code would decide that assignments - to the base class vtable pointer can't alias assignments to - the derived class vtable pointer, since they have different - types. Thus, in an derived class destructor, where the base - class constructor was inlined, we could generate bad code for - setting up the vtable pointer. - - Therefore, we use one type for all vtable pointers. We still - use a type-correct type; it's just doesn't indicate the array - bounds. That's better than using `void*' or some such; it's - cleaner, and it let's the alias analysis code know that these - stores cannot alias stores to void*! */ - vfield = build_vtbl_or_vbase_field (get_vfield_name (t), - get_identifier (VFIELD_BASE), - vtbl_ptr_type_node, - t, - &empty); - TYPE_VFIELD (t) = vfield; - TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), vfield); - vfields = chainon (vfields, build_tree_list (NULL_TREE, t)); - } + /* Create a pointer to our virtual function table. */ + create_vtable_ptr (t, &empty, &has_virtual, &max_has_virtual, + &pending_virtuals, &pending_hard_virtuals); /* CLASSTYPE_INLINE_FRIENDS is really TYPE_NONCOPIED_PARTS. Thus, we have to save this before we start modifying @@ -4205,6 +4217,11 @@ finish_struct_1 (t) TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1; } + /* Let the back-end lay out the type. Note that at this point we + have only included non-virtual base-classes; we will lay out the + virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after + this call are not necessarily correct; they are just the size and + alignment when no virtual base clases are used. */ layout_type (t); /* If we added an extra field to make this class non-empty, remove @@ -4212,6 +4229,10 @@ finish_struct_1 (t) if (empty) TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t)); + /* Delete all zero-width bit-fields from the list of fields. Now + that the type is laid out they are no longer important. */ + remove_zero_width_bit_fields (t); + /* Remember the size and alignment of the class before adding the virtual bases. */ if (empty && flag_new_abi) @@ -4232,16 +4253,11 @@ finish_struct_1 (t) /* Now fix up any virtual base class types that we left lying around. We must get these done before we try to lay out the virtual function table. */ - pending_hard_virtuals = nreverse (pending_hard_virtuals); if (n_baseclasses) /* layout_basetypes will remove the base subobject fields. */ max_has_virtual = layout_basetypes (t, max_has_virtual); - /* Delete all zero-width bit-fields from the list of fields. Now - that we have layed out the type they are no longer important. */ - remove_zero_width_bit_fields (t); - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) { tree vbases; @@ -4275,6 +4291,7 @@ finish_struct_1 (t) /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we might need to know it for setting up the offsets in the vtable (or in thunks) below. */ + vfield = TYPE_VFIELD (t); if (vfield != NULL_TREE && DECL_FIELD_CONTEXT (vfield) != t) { @@ -4293,9 +4310,6 @@ finish_struct_1 (t) TYPE_VFIELD (t) = vfield; } - /* If this vtbl pointer is new, add it to the list of vtbl - pointers in this class. */ - if (has_virtual > max_has_virtual) max_has_virtual = has_virtual; if (max_has_virtual > 0) @@ -4335,7 +4349,7 @@ finish_struct_1 (t) { pending_virtuals = nreverse (pending_virtuals); /* We must enter these virtuals into the table. */ - if (first_vfn_base_index < 0) + if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) { if (! CLASSTYPE_COM_INTERFACE (t)) { @@ -4357,7 +4371,7 @@ finish_struct_1 (t) function table, but we will wait until later this function. */ if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t))) - build_vtable (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index), t); + build_vtable (CLASSTYPE_PRIMARY_BINFO (t), t); } /* If this type has basetypes with constructors, then those @@ -4367,9 +4381,10 @@ finish_struct_1 (t) CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; } - else if (first_vfn_base_index >= 0) + else if (CLASSTYPE_HAS_PRIMARY_BASE_P (t)) { - tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index); + tree binfo = CLASSTYPE_PRIMARY_BINFO (t); + /* This class contributes nothing new to the virtual function table. However, it may have declared functions which went into the virtual function table "inherited" from the @@ -4385,10 +4400,10 @@ finish_struct_1 (t) CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; } - if (max_has_virtual || first_vfn_base_index >= 0) + if (max_has_virtual || CLASSTYPE_HAS_PRIMARY_BASE_P (t)) { CLASSTYPE_VSIZE (t) = has_virtual; - if (first_vfn_base_index >= 0) + if (CLASSTYPE_HAS_PRIMARY_BASE_P (t)) { if (pending_virtuals) TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), @@ -4410,8 +4425,6 @@ finish_struct_1 (t) layout_type (atype); - TYPE_VFIELD (t) = vfield; - /* We may have to grow the vtable. */ if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype) { @@ -4425,9 +4438,12 @@ finish_struct_1 (t) DECL_ALIGN (TYPE_BINFO_VTABLE (t))); } } - else if (first_vfn_base_index >= 0) - TYPE_VFIELD (t) = vfield; - CLASSTYPE_VFIELDS (t) = vfields; + + /* If we created a new vtbl pointer for this class, add it to the + list. */ + if (TYPE_VFIELD (t) && CLASSTYPE_VFIELD_PARENT (t) == -1) + CLASSTYPE_VFIELDS (t) + = chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t)); finish_struct_bits (t, max_has_virtual); @@ -4488,7 +4504,7 @@ finish_struct_1 (t) a place to find them. */ TYPE_NONCOPIED_PARTS (t) = tree_cons (default_conversion (TYPE_BINFO_VTABLE (t)), - vfield, TYPE_NONCOPIED_PARTS (t)); + TYPE_VFIELD (t), TYPE_NONCOPIED_PARTS (t)); if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t) && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1)) == NULL_TREE) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3708dfa..995bc51 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1382,13 +1382,26 @@ struct lang_type nested member class templates. */ #define CLASSTYPE_TAGS(NODE) (TYPE_LANG_SPECIFIC(NODE)->tags) -/* If this class has any bases, this is the number of the base class from - which our VFIELD is based, -1 otherwise. If this class has no base - classes, this is not used. - In D : B1, B2, PARENT would be 0, if D's vtable came from B1, - 1, if D's vtable came from B2. */ +/* If this value is non-negative, it is the index (in the + TYPE_BINFO_BASETYPES) for the base-class whose vtable pointer we + are reusing. For example, in D : B1, B2, PARENT would be 0, if D's + vtable came from B1, 1, if D's vtable came from B2. */ #define CLASSTYPE_VFIELD_PARENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfield_parent) +/* Nonzero if NODE has a primary base class, i.e., a base class with + which it shares the virtual fucntion table pointer. */ +#define CLASSTYPE_HAS_PRIMARY_BASE_P(NODE) \ + (CLASSTYPE_VFIELD_PARENT (NODE) != -1) + +/* If non-NULL, this is the binfo for the primary base class, i.e., + the base class which contains the virtual function table pointer + for this class. */ +#define CLASSTYPE_PRIMARY_BINFO(NODE) \ + (CLASSTYPE_HAS_PRIMARY_BASE_P (NODE) \ + ? TREE_VEC_ELT (TYPE_BINFO_BASETYPES (NODE), \ + CLASSTYPE_VFIELD_PARENT (NODE)) \ + : NULL_TREE) + /* The number of virtual functions defined for this _CLASSTYPE node. */ #define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->vsize) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 60f9405..8ee63f1 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2432,18 +2432,11 @@ dfs_init_vbase_pointers (binfo, data) { struct vbase_info *vi = (struct vbase_info *) data; tree type = BINFO_TYPE (binfo); - tree fields = TYPE_FIELDS (type); + tree fields; tree this_vbase_ptr; CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); -#if 0 - /* See finish_struct_1 for when we can enable this. */ - /* If we have a vtable pointer first, skip it. */ - if (VFIELD_NAME_P (DECL_NAME (fields))) - fields = TREE_CHAIN (fields); -#endif - if (BINFO_INHERITANCE_CHAIN (binfo)) { this_vbase_ptr = TREE_CHAIN (BINFO_INHERITANCE_CHAIN (binfo)); @@ -2457,6 +2450,14 @@ dfs_init_vbase_pointers (binfo, data) else this_vbase_ptr = TREE_CHAIN (binfo); + /* We're going to iterate through all the pointers to virtual + base-classes. They come at the beginning of the class. */ + fields = TYPE_FIELDS (type); + if (fields == TYPE_VFIELD (type)) + /* If the first field is the vtbl pointer (as happens in the new + ABI), skip it. */ + fields = TREE_CHAIN (fields); + if (fields == NULL_TREE || DECL_NAME (fields) == NULL_TREE || ! VBASE_NAME_P (DECL_NAME (fields))) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index cd837e6..39447ee 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -693,15 +693,7 @@ propagate_binfo_offsets (binfo, offset) break; } -#if 0 - if (BINFO_OFFSET_ZEROP (base_binfo)) - BINFO_OFFSET (base_binfo) = offset; - else - BINFO_OFFSET (base_binfo) - = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset); -#else BINFO_OFFSET (base_binfo) = offset; -#endif propagate_binfo_offsets (base_binfo, offset); @@ -759,9 +751,9 @@ layout_basetypes (rec, max) int max; { tree binfos = TYPE_BINFO_BASETYPES (rec); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - + 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; @@ -835,27 +827,43 @@ layout_basetypes (rec, max) size_int (BITS_PER_UNIT)); } - /* Now propagate offset information throughout the lattice. */ + /* 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); - tree field = TYPE_FIELDS (rec); if (TREE_VIA_VIRTUAL (base_binfo)) continue; - my_friendly_assert (TREE_TYPE (field) == basetype, 23897); + 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)), + = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (*field)), BITS_PER_UNIT)); propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo)); - TYPE_FIELDS (rec) = TREE_CHAIN (field); + + /* Remove this field. */ + *field = TREE_CHAIN (*field); } for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types; |