This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: tidy up class.c a little
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH: tidy up class.c a little
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Sun, 16 Jan 2000 09:38:42 -0800
- Organization: CodeSourcery, LLC
This patch just moves around some code in class.c to group the code
that handles virtual base class layout together.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2000-01-16 Mark Mitchell <mark@codesourcery.com>
* class.c (build_vbase_pointer): Relocate.
(build_vbase_pointer_fields): Likewise.
(dfs_build_vbase_offset_vtbl_entries): Likewise.
(build_vbase_offset_vtbl_entries): Likewise.
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.233
diff -c -p -r1.233 class.c
*** class.c 2000/01/16 16:59:43 1.233
--- class.c 2000/01/16 17:32:54
*************** int n_build_method_call = 0;
*** 160,224 ****
int n_inner_fields_searched = 0;
#endif
! /* Virtual baseclass things. */
static tree
! build_vbase_pointer (exp, type)
! tree exp, type;
{
! char *name;
! FORMAT_VBASE_NAME (name, type);
! return build_component_ref (exp, get_identifier (name), NULL_TREE, 0);
}
! #if 0
! /* Is the type of the EXPR, the complete type of the object?
! If we are going to be wrong, we must be conservative, and return 0. */
! static int
! complete_type_p (expr)
! tree expr;
{
! tree type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
! while (1)
{
! switch (TREE_CODE (expr))
! {
! case SAVE_EXPR:
! case INDIRECT_REF:
! case ADDR_EXPR:
! case NOP_EXPR:
! case CONVERT_EXPR:
! expr = TREE_OPERAND (expr, 0);
! continue;
! case CALL_EXPR:
! if (! TREE_HAS_CONSTRUCTOR (expr))
! break;
! /* fall through... */
! case VAR_DECL:
! case FIELD_DECL:
! if (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
! && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (expr)))
! && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type)
! return 1;
! /* fall through... */
! case TARGET_EXPR:
! case PARM_DECL:
! if (IS_AGGR_TYPE (TREE_TYPE (expr))
! && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type)
! return 1;
! /* fall through... */
! case PLUS_EXPR:
! default:
! break;
}
- break;
}
! return 0;
}
! #endif
/* Build multi-level access to EXPR using hierarchy path PATH.
CODE is PLUS_EXPR if we are going with the grain,
--- 160,360 ----
int n_inner_fields_searched = 0;
#endif
! /* Virtual base class layout. */
+ /* Returns a list of virtual base class pointers as a chain of
+ FIELD_DECLS. */
+
static tree
! build_vbase_pointer_fields (rec, empty_p)
! tree rec;
! int *empty_p;
{
! /* Chain to hold all the new FIELD_DECLs which point at virtual
! base classes. */
! tree vbase_decls = NULL_TREE;
! tree binfos = TYPE_BINFO_BASETYPES (rec);
! int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
! tree decl;
! int i;
! /* Handle basetypes almost like fields, but record their
! offsets differently. */
!
! for (i = 0; i < n_baseclasses; i++)
! {
! register tree base_binfo = TREE_VEC_ELT (binfos, i);
! register tree basetype = BINFO_TYPE (base_binfo);
!
! if (TYPE_SIZE (basetype) == 0)
! /* This error is now reported in xref_tag, thus giving better
! location information. */
! continue;
!
! /* All basetypes are recorded in the association list of the
! derived type. */
!
! if (TREE_VIA_VIRTUAL (base_binfo))
! {
! int j;
! const char *name;
!
! /* The offset for a virtual base class is only used in computing
! virtual function tables and for initializing virtual base
! pointers. It is built once `get_vbase_types' is called. */
!
! /* If this basetype can come from another vbase pointer
! without an additional indirection, we will share
! that pointer. If an indirection is involved, we
! make our own pointer. */
! for (j = 0; j < n_baseclasses; j++)
! {
! tree other_base_binfo = TREE_VEC_ELT (binfos, j);
! if (! TREE_VIA_VIRTUAL (other_base_binfo)
! && BINFO_FOR_VBASE (basetype, BINFO_TYPE (other_base_binfo)))
! goto got_it;
! }
! FORMAT_VBASE_NAME (name, basetype);
! decl = build_vtbl_or_vbase_field (get_identifier (name),
! get_identifier (VTABLE_BASE),
! build_pointer_type (basetype),
! rec,
! empty_p);
! BINFO_VPTR_FIELD (base_binfo) = decl;
! TREE_CHAIN (decl) = vbase_decls;
! vbase_decls = decl;
! *empty_p = 0;
!
! got_it:
! /* The space this decl occupies has already been accounted for. */
! ;
! }
! }
!
! return vbase_decls;
}
! /* Called from build_vbase_offset_vtbl_entries via dfs_walk. */
! static tree
! dfs_build_vbase_offset_vtbl_entries (binfo, data)
! tree binfo;
! void *data;
{
! tree list = (tree) data;
!
! if (TREE_TYPE (list) == binfo)
! /* The TREE_TYPE of LIST is the base class from which we started
! walking. If that BINFO is virtual it's not a virtual baseclass
! of itself. */
! ;
! else if (TREE_VIA_VIRTUAL (binfo))
{
! tree init;
! init = BINFO_OFFSET (binfo);
! init = build1 (NOP_EXPR, vtable_entry_type, init);
! TREE_VALUE (list) = tree_cons (NULL_TREE, init, TREE_VALUE (list));
! }
!
! SET_BINFO_VTABLE_PATH_MARKED (binfo);
!
! return NULL_TREE;
! }
!
! /* Returns the initializers for the vbase offset entries in the
! vtable, in reverse order. */
!
! static tree
! build_vbase_offset_vtbl_entries (binfo)
! tree binfo;
! {
! tree type;
! tree inits;
! tree init;
!
! /* Under the old ABI, pointers to virtual bases are stored in each
! object. */
! if (!flag_new_abi)
! return NULL_TREE;
!
! /* If there are no virtual baseclasses, then there is nothing to
! do. */
! type = BINFO_TYPE (binfo);
! if (!TYPE_USES_VIRTUAL_BASECLASSES (type))
! return NULL_TREE;
!
! inits = NULL_TREE;
!
! /* Under the new ABI, the vtable contains offsets to all virtual
! bases. The ABI specifies different layouts depending on whether
! or not *all* of the bases of this type are virtual. */
! if (CLASSTYPE_N_BASECLASSES (type)
! == list_length (CLASSTYPE_VBASECLASSES (type)))
! {
! /* In this case, the offsets are allocated from right to left of
! the declaration order in which the virtual bases appear. */
! int i;
!
! for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
! {
! tree vbase = BINFO_BASETYPE (binfo, i);
! init = BINFO_OFFSET (vbase);
! init = build1 (NOP_EXPR, vtable_entry_type, init);
! inits = tree_cons (NULL_TREE, init, inits);
}
}
! else
! {
! tree list;
!
! /* While in this case, the offsets are allocated in the reverse
! order of a depth-first left-to-right traversal of the
! hierarchy. We use BINFO_VTABLE_PATH_MARKED because we are
! ourselves during a dfs_walk, and so BINFO_MARKED is already
! in use. */
! list = build_tree_list (type, NULL_TREE);
! TREE_TYPE (list) = binfo;
! dfs_walk (binfo,
! dfs_build_vbase_offset_vtbl_entries,
! dfs_vtable_path_unmarked_real_bases_queue_p,
! list);
! dfs_walk (binfo,
! dfs_vtable_path_unmark,
! dfs_vtable_path_marked_real_bases_queue_p,
! list);
! inits = nreverse (TREE_VALUE (list));
! }
!
! /* We've now got offsets in the right oder. However, the offsets
! we've stored are offsets from the beginning of the complete
! object, and we need offsets from this BINFO. */
! for (init = inits; init; init = TREE_CHAIN (init))
! {
! tree exp = TREE_VALUE (init);
!
! exp = ssize_binop (MINUS_EXPR, exp, BINFO_OFFSET (binfo));
! exp = build1 (NOP_EXPR, vtable_entry_type, TREE_VALUE (init));
! exp = fold (exp);
! TREE_CONSTANT (exp) = 1;
! TREE_VALUE (init) = exp;
! }
!
! return inits;
}
!
! /* Returns a pointer to the virtual base class of EXP that has the
! indicated TYPE. */
!
! static tree
! build_vbase_pointer (exp, type)
! tree exp, type;
! {
! char *name;
! FORMAT_VBASE_NAME (name, type);
!
! return build_component_ref (exp, get_identifier (name), NULL_TREE, 0);
! }
/* Build multi-level access to EXPR using hierarchy path PATH.
CODE is PLUS_EXPR if we are going with the grain,
*************** build_vbase_path (code, type, expr, path
*** 377,382 ****
--- 513,519 ----
return build1 (NOP_EXPR, type, expr);
}
+
/* Virtual function things. */
/* Build an entry in the virtual function table.
*************** size_extra_vtbl_entries (binfo)
*** 2180,2287 ****
return fold (offset);
}
- /* Called from build_vbase_offset_vtbl_entries via dfs_walk. */
-
- static tree
- dfs_build_vbase_offset_vtbl_entries (binfo, data)
- tree binfo;
- void *data;
- {
- tree list = (tree) data;
-
- if (TREE_TYPE (list) == binfo)
- /* The TREE_TYPE of LIST is the base class from which we started
- walking. If that BINFO is virtual it's not a virtual baseclass
- of itself. */
- ;
- else if (TREE_VIA_VIRTUAL (binfo))
- {
- tree init;
-
- init = BINFO_OFFSET (binfo);
- init = build1 (NOP_EXPR, vtable_entry_type, init);
- TREE_VALUE (list) = tree_cons (NULL_TREE, init, TREE_VALUE (list));
- }
-
- SET_BINFO_VTABLE_PATH_MARKED (binfo);
-
- return NULL_TREE;
- }
-
- /* Returns the initializers for the vbase offset entries in the
- vtable, in reverse order. */
-
- static tree
- build_vbase_offset_vtbl_entries (binfo)
- tree binfo;
- {
- tree type;
- tree inits;
- tree init;
-
- type = BINFO_TYPE (binfo);
- if (!TYPE_USES_VIRTUAL_BASECLASSES (type))
- return NULL_TREE;
-
- inits = NULL_TREE;
-
- /* Under the new ABI, the vtable contains offsets to all virtual
- bases. The ABI specifies different layouts depending on whether
- or not *all* of the bases of this type are virtual. */
- if (CLASSTYPE_N_BASECLASSES (type)
- == list_length (CLASSTYPE_VBASECLASSES (type)))
- {
- /* In this case, the offsets are allocated from right to left of
- the declaration order in which the virtual bases appear. */
- int i;
-
- for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
- {
- tree vbase = BINFO_BASETYPE (binfo, i);
- init = BINFO_OFFSET (vbase);
- init = build1 (NOP_EXPR, vtable_entry_type, init);
- inits = tree_cons (NULL_TREE, init, inits);
- }
- }
- else
- {
- tree list;
-
- /* While in this case, the offsets are allocated in the reverse
- order of a depth-first left-to-right traversal of the
- hierarchy. We use BINFO_VTABLE_PATH_MARKED because we are
- ourselves during a dfs_walk, and so BINFO_MARKED is already
- in use. */
- list = build_tree_list (type, NULL_TREE);
- TREE_TYPE (list) = binfo;
- dfs_walk (binfo,
- dfs_build_vbase_offset_vtbl_entries,
- dfs_vtable_path_unmarked_real_bases_queue_p,
- list);
- dfs_walk (binfo,
- dfs_vtable_path_unmark,
- dfs_vtable_path_marked_real_bases_queue_p,
- list);
- inits = nreverse (TREE_VALUE (list));
- }
-
- /* We've now got offsets in the right oder. However, the offsets
- we've stored are offsets from the beginning of the complete
- object, and we need offsets from this BINFO. */
- for (init = inits; init; init = TREE_CHAIN (init))
- {
- tree exp = TREE_VALUE (init);
-
- exp = ssize_binop (MINUS_EXPR, exp, BINFO_OFFSET (binfo));
- exp = build1 (NOP_EXPR, vtable_entry_type, TREE_VALUE (init));
- exp = fold (exp);
- TREE_CONSTANT (exp) = 1;
- TREE_VALUE (init) = exp;
- }
-
- return inits;
- }
-
/* Construct the initializer for BINFOs virtual function table. */
static tree
--- 2317,2322 ----
*************** build_vtbl_initializer (binfo)
*** 2292,2299 ****
tree inits = NULL_TREE;
tree type = BINFO_TYPE (binfo);
! if (flag_new_abi)
! inits = build_vbase_offset_vtbl_entries (binfo);
/* 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
--- 2327,2334 ----
tree inits = NULL_TREE;
tree type = BINFO_TYPE (binfo);
! /* Add entries to the vtable for offsets to our virtual bases. */
! inits = build_vbase_offset_vtbl_entries (binfo);
/* 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
*************** build_vtbl_or_vbase_field (name, assembl
*** 3797,3873 ****
/* Return it. */
return field;
- }
-
- /* Returns list of virtual base class pointers in a FIELD_DECL chain. */
-
- static tree
- build_vbase_pointer_fields (rec, empty_p)
- tree rec;
- int *empty_p;
- {
- /* Chain to hold all the new FIELD_DECLs which point at virtual
- base classes. */
- tree vbase_decls = NULL_TREE;
- tree binfos = TYPE_BINFO_BASETYPES (rec);
- int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec);
- tree decl;
- int i;
-
- /* Handle basetypes almost like fields, but record their
- offsets differently. */
-
- for (i = 0; i < n_baseclasses; i++)
- {
- register tree base_binfo = TREE_VEC_ELT (binfos, i);
- register tree basetype = BINFO_TYPE (base_binfo);
-
- if (TYPE_SIZE (basetype) == 0)
- /* This error is now reported in xref_tag, thus giving better
- location information. */
- continue;
-
- /* All basetypes are recorded in the association list of the
- derived type. */
-
- if (TREE_VIA_VIRTUAL (base_binfo))
- {
- int j;
- const char *name;
-
- /* The offset for a virtual base class is only used in computing
- virtual function tables and for initializing virtual base
- pointers. It is built once `get_vbase_types' is called. */
-
- /* If this basetype can come from another vbase pointer
- without an additional indirection, we will share
- that pointer. If an indirection is involved, we
- make our own pointer. */
- for (j = 0; j < n_baseclasses; j++)
- {
- tree other_base_binfo = TREE_VEC_ELT (binfos, j);
- if (! TREE_VIA_VIRTUAL (other_base_binfo)
- && BINFO_FOR_VBASE (basetype, BINFO_TYPE (other_base_binfo)))
- goto got_it;
- }
- FORMAT_VBASE_NAME (name, basetype);
- decl = build_vtbl_or_vbase_field (get_identifier (name),
- get_identifier (VTABLE_BASE),
- build_pointer_type (basetype),
- rec,
- empty_p);
- BINFO_VPTR_FIELD (base_binfo) = decl;
- TREE_CHAIN (decl) = vbase_decls;
- vbase_decls = decl;
- *empty_p = 0;
-
- got_it:
- /* The space this decl occupies has already been accounted for. */
- ;
- }
- }
-
- return vbase_decls;
}
/* If the empty base field in DECL overlaps with a base of the same type in
--- 3832,3837 ----