summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-01-16 17:38:06 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-01-16 17:38:06 +0000
commite1ddff7076cf9eba3d4b0c73d84233c34803a814 (patch)
treee704e42467630b915211a422f75b73d90647f032 /gcc
parent342a8222a0890b8b84e0c29d0156602adf7a464b (diff)
downloadgcc-e1ddff7076cf9eba3d4b0c73d84233c34803a814.tar.gz
* class.c (build_vbase_pointer): Relocate.
(build_vbase_pointer_fields): Likewise. (dfs_build_vbase_offset_vtbl_entries): Likewise. (build_vbase_offset_vtbl_entries): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31442 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/class.c406
2 files changed, 190 insertions, 221 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e4850d6cd5b..99147e2aae4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
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.
+
* decl.c (init_decl_processing): Complain if -fnew-abi
-fno-vtable-thunks is used.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 2502b85ec75..a557292757d 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -160,65 +160,201 @@ int n_build_method_call = 0;
int n_inner_fields_searched = 0;
#endif
-/* Virtual baseclass things. */
+/* Virtual base class layout. */
+
+/* Returns a list of virtual base class pointers as a chain of
+ FIELD_DECLS. */
static tree
-build_vbase_pointer (exp, type)
- tree exp, type;
+build_vbase_pointer_fields (rec, empty_p)
+ tree rec;
+ int *empty_p;
{
- char *name;
- FORMAT_VBASE_NAME (name, type);
+ /* 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;
- return build_component_ref (exp, get_identifier (name), NULL_TREE, 0);
+ /* 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 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. */
+/* Called from build_vbase_offset_vtbl_entries via dfs_walk. */
-static int
-complete_type_p (expr)
- tree expr;
+static tree
+dfs_build_vbase_offset_vtbl_entries (binfo, data)
+ tree binfo;
+ void *data;
{
- tree type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
- while (1)
+ 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))
{
- 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;
+ tree init;
- 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;
+ 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);
}
- break;
}
- return 0;
+ 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);
}
-#endif
/* Build multi-level access to EXPR using hierarchy path PATH.
CODE is PLUS_EXPR if we are going with the grain,
@@ -377,6 +513,7 @@ build_vbase_path (code, type, expr, path, nonnull)
return build1 (NOP_EXPR, type, expr);
}
+
/* Virtual function things. */
/* Build an entry in the virtual function table.
@@ -2180,108 +2317,6 @@ size_extra_vtbl_entries (binfo)
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
@@ -2292,8 +2327,8 @@ build_vtbl_initializer (binfo)
tree inits = NULL_TREE;
tree type = BINFO_TYPE (binfo);
- if (flag_new_abi)
- inits = build_vbase_offset_vtbl_entries (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
@@ -3799,77 +3834,6 @@ build_vtbl_or_vbase_field (name, assembler_name, type, class_type,
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
NEWDECL, which is either another base field or the first data field of
the class, pad the base just before NEWDECL and return 1. Otherwise,