Commit bbd15aac by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (flag_new_abi): Move.

	* cp-tree.h (flag_new_abi): Move.
	(flag_use_cxa_atexit): Likewise.
	(flag_honor_std): Likewise.
	(flag_rtti): Likewise.
	(vbase_offsets_in_vtable_p): Define.
	(vptrs_present_everywhere_p): Likewise.
	(TYPE_CONTAINS_VPTR_P): Likewise.
	(dfs_walk_real): Declare.
	* class.c (build_vbase_pointer_fields): Check
	vbase_offsets_in_vtable_p.
	(dfs_build_vbase_offset_vtbl_entries): Record the vbase indices in
	BINFO_VPTR_FIELD.
	(build_vbase_offset_vtbl_entries): Simplify.
	(build_vbase_offset_vtbl_entries): Adjust.
	(build_vbase_pointer): Add ability to look up vbase offsets in
	vtable.
	(start_vtable): New function.
	(add_virtual_function): Use it.
	(determine_primary_base): Use TYPE_CONTAINS_VPTR_P.
	(num_extra_vtbl_entries): Use vbase_offsets_in_vtable_p.
	(build_vtbl_initializer): Take the type of the complete object as
	input.  Use it to correctly calculate vbase offsets.
	(dfs_finish_vtbls): Pass the complete type to
	build_vtbl_initializer.
	(check_bases_and_members): Use TYPE_CONTAINS_VPTR_P.
	(create_vtable_ptr): Create a vtable even if there are no
	new virtual functions, under the new ABI.
	(finish_struct_1): Likewise.
	(get_vfield_name): Use TYPE_CONTAINS_VPTR_P.
	* decl.c (exapnd_static_init): Remove call to
	preserve_initializer.
	* decl2.c (mark_vtable_entries): Tweak to handle vbase offsets in
	vtables.
	* init.c (initialize_vtbl_ptrs): Initialize them in pre-order.
	(expand_virtual_init): Use vbase_offsets_in_vtable_p.
	(construct_virtual_bases): Don't initialize virtual base pointers
	under the new ABI.
	(build_aggr_init): Clean up comment.
	(expand_aggr_init_1): Likewise.
	* rtti.c (expand_class_desc): Store the virtual function table
	index where the vbase offset lives in the offset field.
	* search.c (dfs_walk_real): Make it global.
	(dfs_debug_mark): Use TYPE_CONTAINS_VPTR_P.
	* tree.c (make_binfo): Don't clear BINFO_VPTR_FIELD.

	* tinfo.h (USItype): Make it signed under the new ABI.
	* tinfo.cc (convert_to_base): New function.  Encapsulate base
	conversion logic here.
	(__class_type_info::do_upcast): Use it.
	(__class_type_info::do_dyncast): Likewise.
	(__class_type_info::do_find_public_subobj): Likewise.

From-SVN: r31452
parent 2a198bc4
2000-01-16 Mark Mitchell <mark@codesourcery.com> 2000-01-16 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (flag_new_abi): Move.
(flag_use_cxa_atexit): Likewise.
(flag_honor_std): Likewise.
(flag_rtti): Likewise.
(vbase_offsets_in_vtable_p): Define.
(vptrs_present_everywhere_p): Likewise.
(TYPE_CONTAINS_VPTR_P): Likewise.
(dfs_walk_real): Declare.
* class.c (build_vbase_pointer_fields): Check
vbase_offsets_in_vtable_p.
(dfs_build_vbase_offset_vtbl_entries): Record the vbase indices in
BINFO_VPTR_FIELD.
(build_vbase_offset_vtbl_entries): Simplify.
(build_vbase_offset_vtbl_entries): Adjust.
(build_vbase_pointer): Add ability to look up vbase offsets in
vtable.
(start_vtable): New function.
(add_virtual_function): Use it.
(determine_primary_base): Use TYPE_CONTAINS_VPTR_P.
(num_extra_vtbl_entries): Use vbase_offsets_in_vtable_p.
(build_vtbl_initializer): Take the type of the complete object as
input. Use it to correctly calculate vbase offsets.
(dfs_finish_vtbls): Pass the complete type to
build_vtbl_initializer.
(check_bases_and_members): Use TYPE_CONTAINS_VPTR_P.
(create_vtable_ptr): Create a vtable even if there are no
new virtual functions, under the new ABI.
(finish_struct_1): Likewise.
(get_vfield_name): Use TYPE_CONTAINS_VPTR_P.
* decl.c (exapnd_static_init): Remove call to
preserve_initializer.
* decl2.c (mark_vtable_entries): Tweak to handle vbase offsets in
vtables.
* init.c (initialize_vtbl_ptrs): Initialize them in pre-order.
(expand_virtual_init): Use vbase_offsets_in_vtable_p.
(construct_virtual_bases): Don't initialize virtual base pointers
under the new ABI.
(build_aggr_init): Clean up comment.
(expand_aggr_init_1): Likewise.
* rtti.c (expand_class_desc): Store the virtual function table
index where the vbase offset lives in the offset field.
* search.c (dfs_walk_real): Make it global.
(dfs_debug_mark): Use TYPE_CONTAINS_VPTR_P.
* tree.c (make_binfo): Don't clear BINFO_VPTR_FIELD.
* tinfo.h (USItype): Make it signed under the new ABI.
* tinfo.cc (convert_to_base): New function. Encapsulate base
conversion logic here.
(__class_type_info::do_upcast): Use it.
(__class_type_info::do_dyncast): Likewise.
(__class_type_info::do_find_public_subobj): Likewise.
* init.c (construct_virtual_bases): Don't look up the addresses of * init.c (construct_virtual_bases): Don't look up the addresses of
virtual bases at run-time. virtual bases at run-time.
......
...@@ -115,7 +115,7 @@ static tree resolve_address_of_overloaded_function PROTO((tree, tree, int, ...@@ -115,7 +115,7 @@ static tree resolve_address_of_overloaded_function PROTO((tree, tree, int,
int, tree)); int, tree));
static void build_vtable_entry_ref PROTO((tree, tree, tree)); static void build_vtable_entry_ref PROTO((tree, tree, tree));
static tree build_vtable_entry_for_fn PROTO((tree, tree)); static tree build_vtable_entry_for_fn PROTO((tree, tree));
static tree build_vtbl_initializer PROTO((tree)); static tree build_vtbl_initializer PROTO((tree, tree));
static int count_fields PROTO((tree)); static int count_fields PROTO((tree));
static int add_fields_to_vec PROTO((tree, tree, int)); static int add_fields_to_vec PROTO((tree, tree, int));
static void check_bitfield_decl PROTO((tree)); static void check_bitfield_decl PROTO((tree));
...@@ -145,7 +145,8 @@ static void remove_base_fields PROTO((tree)); ...@@ -145,7 +145,8 @@ static void remove_base_fields PROTO((tree));
static tree dfs_set_offset_for_shared_vbases PROTO((tree, void *)); static tree dfs_set_offset_for_shared_vbases PROTO((tree, void *));
static tree dfs_set_offset_for_unshared_vbases PROTO((tree, void *)); static tree dfs_set_offset_for_unshared_vbases PROTO((tree, void *));
static tree dfs_build_vbase_offset_vtbl_entries PROTO((tree, void *)); static tree dfs_build_vbase_offset_vtbl_entries PROTO((tree, void *));
static tree build_vbase_offset_vtbl_entries PROTO((tree)); static tree build_vbase_offset_vtbl_entries PROTO((tree, tree));
static void start_vtable PROTO((tree, int *));
/* Variables shared between class.c and call.c. */ /* Variables shared between class.c and call.c. */
...@@ -178,9 +179,12 @@ build_vbase_pointer_fields (rec, empty_p) ...@@ -178,9 +179,12 @@ build_vbase_pointer_fields (rec, empty_p)
tree decl; tree decl;
int i; int i;
/* Handle basetypes almost like fields, but record their /* Under the new ABI, there are no vbase pointers in the object.
offsets differently. */ Instead, the offsets are stored in the vtable. */
if (vbase_offsets_in_vtable_p ())
return NULL_TREE;
/* Loop over the baseclasses, adding vbase pointers as needed. */
for (i = 0; i < n_baseclasses; i++) for (i = 0; i < n_baseclasses; i++)
{ {
register tree base_binfo = TREE_VEC_ELT (binfos, i); register tree base_binfo = TREE_VEC_ELT (binfos, i);
...@@ -251,10 +255,27 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data) ...@@ -251,10 +255,27 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data)
else if (TREE_VIA_VIRTUAL (binfo)) else if (TREE_VIA_VIRTUAL (binfo))
{ {
tree init; tree init;
tree vbase;
/* Remember the index to the vbase offset for this virtual
base. */
vbase = BINFO_FOR_VBASE (TREE_TYPE (binfo), TREE_PURPOSE (list));
if (!TREE_VALUE (list))
BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
else
{
BINFO_VPTR_FIELD (vbase) = TREE_PURPOSE (TREE_VALUE (list));
BINFO_VPTR_FIELD (vbase) = ssize_binop (MINUS_EXPR,
BINFO_VPTR_FIELD (vbase),
integer_one_node);
}
/* And record the offset at which this virtual base lies in the
vtable. */
init = BINFO_OFFSET (binfo); init = BINFO_OFFSET (binfo);
init = build1 (NOP_EXPR, vtable_entry_type, init); TREE_VALUE (list) = tree_cons (BINFO_VPTR_FIELD (vbase),
TREE_VALUE (list) = tree_cons (NULL_TREE, init, TREE_VALUE (list)); init,
TREE_VALUE (list));
} }
SET_BINFO_VTABLE_PATH_MARKED (binfo); SET_BINFO_VTABLE_PATH_MARKED (binfo);
...@@ -262,69 +283,46 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data) ...@@ -262,69 +283,46 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data)
return NULL_TREE; return NULL_TREE;
} }
/* Returns the initializers for the vbase offset entries in the /* Returns the initializers for the vbase offset entries in the vtable
vtable, in reverse order. */ for BINFO (which is part of the class hierarchy dominated by T), in
reverse order. */
static tree static tree
build_vbase_offset_vtbl_entries (binfo) build_vbase_offset_vtbl_entries (binfo, t)
tree binfo; tree binfo;
tree t;
{ {
tree type;
tree inits; tree inits;
tree init; tree init;
tree list;
/* Under the old ABI, pointers to virtual bases are stored in each /* Under the old ABI, pointers to virtual bases are stored in each
object. */ object. */
if (!flag_new_abi) if (!vbase_offsets_in_vtable_p ())
return NULL_TREE; return NULL_TREE;
/* If there are no virtual baseclasses, then there is nothing to /* If there are no virtual baseclasses, then there is nothing to
do. */ do. */
type = BINFO_TYPE (binfo); if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
if (!TYPE_USES_VIRTUAL_BASECLASSES (type))
return NULL_TREE; return NULL_TREE;
inits = NULL_TREE; inits = NULL_TREE;
/* Under the new ABI, the vtable contains offsets to all virtual /* The offsets are allocated in the reverse order of a
bases. The ABI specifies different layouts depending on whether depth-first left-to-right traversal of the hierarchy. We use
or not *all* of the bases of this type are virtual. */ BINFO_VTABLE_PATH_MARKED because we are ourselves during a
if (CLASSTYPE_N_BASECLASSES (type) dfs_walk, and so BINFO_MARKED is already in use. */
== list_length (CLASSTYPE_VBASECLASSES (type))) list = build_tree_list (t, NULL_TREE);
{ TREE_TYPE (list) = binfo;
/* In this case, the offsets are allocated from right to left of dfs_walk (binfo,
the declaration order in which the virtual bases appear. */ dfs_build_vbase_offset_vtbl_entries,
int i; dfs_vtable_path_unmarked_real_bases_queue_p,
list);
for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i) dfs_walk (binfo,
{ dfs_vtable_path_unmark,
tree vbase = BINFO_BASETYPE (binfo, i); dfs_vtable_path_marked_real_bases_queue_p,
init = BINFO_OFFSET (vbase); list);
init = build1 (NOP_EXPR, vtable_entry_type, init); inits = nreverse (TREE_VALUE (list));
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 now got offsets in the right oder. However, the offsets
we've stored are offsets from the beginning of the complete we've stored are offsets from the beginning of the complete
...@@ -334,9 +332,13 @@ build_vbase_offset_vtbl_entries (binfo) ...@@ -334,9 +332,13 @@ build_vbase_offset_vtbl_entries (binfo)
tree exp = TREE_VALUE (init); tree exp = TREE_VALUE (init);
exp = ssize_binop (MINUS_EXPR, exp, BINFO_OFFSET (binfo)); exp = ssize_binop (MINUS_EXPR, exp, BINFO_OFFSET (binfo));
exp = build1 (NOP_EXPR, vtable_entry_type, TREE_VALUE (init)); exp = build1 (NOP_EXPR, vtable_entry_type, exp);
exp = fold (exp); exp = fold (exp);
TREE_CONSTANT (exp) = 1; TREE_CONSTANT (exp) = 1;
/* The dfs_build_vbase_offset_vtbl_entries routine uses the
TREE_PURPOSE to scribble in. But, we need to clear it now so
that the values are not perceived as labeled initializers. */
TREE_PURPOSE (init) = NULL_TREE;
TREE_VALUE (init) = exp; TREE_VALUE (init) = exp;
} }
...@@ -344,16 +346,41 @@ build_vbase_offset_vtbl_entries (binfo) ...@@ -344,16 +346,41 @@ build_vbase_offset_vtbl_entries (binfo)
} }
/* Returns a pointer to the virtual base class of EXP that has the /* Returns a pointer to the virtual base class of EXP that has the
indicated TYPE. */ indicated TYPE. EXP is of class type, not a pointer type. */
static tree static tree
build_vbase_pointer (exp, type) build_vbase_pointer (exp, type)
tree exp, type; tree exp, type;
{ {
char *name; if (vbase_offsets_in_vtable_p ())
FORMAT_VBASE_NAME (name, type); {
tree vbase;
return build_component_ref (exp, get_identifier (name), NULL_TREE, 0); tree vbase_ptr;
/* Find the shared copy of TYPE; that's where the vtable offset
is recorded. */
vbase = BINFO_FOR_VBASE (type, TREE_TYPE (exp));
/* Find the virtual function table pointer. */
vbase_ptr = build_vfield_ref (exp, TREE_TYPE (exp));
/* Compute the location where the offset will lie. */
vbase_ptr = build_binary_op (PLUS_EXPR,
vbase_ptr,
BINFO_VPTR_FIELD (vbase));
vbase_ptr = build1 (NOP_EXPR,
build_pointer_type (ptrdiff_type_node),
vbase_ptr);
/* Add the contents of this location to EXP. */
return build (PLUS_EXPR,
build_pointer_type (type),
build_unary_op (ADDR_EXPR, exp, /*noconvert=*/0),
build1 (INDIRECT_REF, ptrdiff_type_node, vbase_ptr));
}
else
{
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. /* Build multi-level access to EXPR using hierarchy path PATH.
...@@ -1100,6 +1127,25 @@ get_vtable_entry_n (virtuals, n) ...@@ -1100,6 +1127,25 @@ get_vtable_entry_n (virtuals, n)
return virtuals; return 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. */
static void
start_vtable (t, has_virtual_p)
tree t;
int *has_virtual_p;
{
if (*has_virtual_p == 0 && ! CLASSTYPE_COM_INTERFACE (t))
{
if (flag_vtable_thunks)
*has_virtual_p = 2;
else
*has_virtual_p = 1;
}
}
/* Add a virtual function to all the appropriate vtables for the class /* 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 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 allocate a new slot in our table. If it is error_mark_node, we
...@@ -1139,13 +1185,7 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t) ...@@ -1139,13 +1185,7 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t)
/* If we are using thunks, use two slots at the front, one /* If we are using thunks, use two slots at the front, one
for the offset pointer, one for the tdesc pointer. for the offset pointer, one for the tdesc pointer.
For ARM-style vtables, use the same slot for both. */ For ARM-style vtables, use the same slot for both. */
if (*has_virtual == 0 && ! CLASSTYPE_COM_INTERFACE (t)) start_vtable (t, has_virtual);
{
if (flag_vtable_thunks)
*has_virtual = 2;
else
*has_virtual = 1;
}
/* Build a new INT_CST for this DECL_VINDEX. */ /* Build a new INT_CST for this DECL_VINDEX. */
{ {
...@@ -1767,7 +1807,7 @@ determine_primary_base (t, has_virtual_p) ...@@ -1767,7 +1807,7 @@ determine_primary_base (t, has_virtual_p)
tree base_binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i); tree base_binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i);
tree basetype = BINFO_TYPE (base_binfo); tree basetype = BINFO_TYPE (base_binfo);
if (TYPE_POLYMORPHIC_P (basetype)) if (TYPE_CONTAINS_VPTR_P (basetype))
{ {
/* Even a virtual baseclass can contain our RTTI /* Even a virtual baseclass can contain our RTTI
information. But, we prefer a non-virtual polymorphic information. But, we prefer a non-virtual polymorphic
...@@ -2287,9 +2327,8 @@ num_extra_vtbl_entries (binfo) ...@@ -2287,9 +2327,8 @@ num_extra_vtbl_entries (binfo)
tree type; tree type;
int entries; int entries;
/* Under the old ABI, there are no entries at negative offsets. */ /* Under the old ABI, there are no entries at negative offsets. */
if (!flag_new_abi) if (!vbase_offsets_in_vtable_p ())
return size_zero_node; return size_zero_node;
type = BINFO_TYPE (binfo); type = BINFO_TYPE (binfo);
...@@ -2317,18 +2356,20 @@ size_extra_vtbl_entries (binfo) ...@@ -2317,18 +2356,20 @@ size_extra_vtbl_entries (binfo)
return fold (offset); return fold (offset);
} }
/* Construct the initializer for BINFOs virtual function table. */ /* Construct the initializer for BINFOs virtual function table. BINFO
is part of the hierarchy dominated by T. */
static tree static tree
build_vtbl_initializer (binfo) build_vtbl_initializer (binfo, t)
tree binfo; tree binfo;
tree t;
{ {
tree v = BINFO_VIRTUALS (binfo); tree v = BINFO_VIRTUALS (binfo);
tree inits = NULL_TREE; tree inits = NULL_TREE;
tree type = BINFO_TYPE (binfo); tree type = BINFO_TYPE (binfo);
/* Add entries to the vtable for offsets to our virtual bases. */ /* Add entries to the vtable for offsets to our virtual bases. */
inits = build_vbase_offset_vtbl_entries (binfo); inits = build_vbase_offset_vtbl_entries (binfo, t);
/* Process the RTTI stuff at the head of the list. If we're not /* 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 using vtable thunks, then the RTTI entry is just an ordinary
...@@ -2397,7 +2438,7 @@ build_vtbl_initializer (binfo) ...@@ -2397,7 +2438,7 @@ build_vtbl_initializer (binfo)
static tree static tree
dfs_finish_vtbls (binfo, data) dfs_finish_vtbls (binfo, data)
tree binfo; tree binfo;
void *data ATTRIBUTE_UNUSED; void *data;
{ {
if (!BINFO_PRIMARY_MARKED_P (binfo) if (!BINFO_PRIMARY_MARKED_P (binfo)
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)) && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
...@@ -2409,7 +2450,7 @@ dfs_finish_vtbls (binfo, data) ...@@ -2409,7 +2450,7 @@ dfs_finish_vtbls (binfo, data)
decl = BINFO_VTABLE (binfo); decl = BINFO_VTABLE (binfo);
context = DECL_CONTEXT (decl); context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = 0; DECL_CONTEXT (decl) = 0;
DECL_INITIAL (decl) = build_vtbl_initializer (binfo); DECL_INITIAL (decl) = build_vtbl_initializer (binfo, (tree) data);
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0); cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context; DECL_CONTEXT (decl) = context;
} }
...@@ -4112,9 +4153,9 @@ check_bases_and_members (t, empty_p) ...@@ -4112,9 +4153,9 @@ check_bases_and_members (t, empty_p)
/* Check all the method declarations. */ /* Check all the method declarations. */
check_methods (t); check_methods (t);
/* A nearly-empty class has to be polymorphic; a nearly empty class /* A nearly-empty class has to be vptr-containing; a nearly empty
contains a vptr. */ class contains just a vptr. */
if (!TYPE_POLYMORPHIC_P (t)) if (!TYPE_CONTAINS_VPTR_P (t))
CLASSTYPE_NEARLY_EMPTY_P (t) = 0; CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
/* Do some bookkeeping that will guide the generation of implicitly /* Do some bookkeeping that will guide the generation of implicitly
...@@ -4177,6 +4218,12 @@ create_vtable_ptr (t, empty_p, has_virtual_p, ...@@ -4177,6 +4218,12 @@ create_vtable_ptr (t, empty_p, has_virtual_p,
add_virtual_function (pending_virtuals_p, pending_hard_virtuals_p, add_virtual_function (pending_virtuals_p, pending_hard_virtuals_p,
has_virtual_p, fn, t); has_virtual_p, fn, t);
/* 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 /* If we couldn't find an appropriate base class, create a new field
here. */ here. */
if (*has_virtual_p && !TYPE_VFIELD (t)) if (*has_virtual_p && !TYPE_VFIELD (t))
...@@ -4771,7 +4818,7 @@ finish_struct_1 (t) ...@@ -4771,7 +4818,7 @@ finish_struct_1 (t)
TYPE_VFIELD (t) = vfield; TYPE_VFIELD (t) = vfield;
} }
if (flag_rtti && TYPE_POLYMORPHIC_P (t) && !pending_hard_virtuals) if (flag_rtti && TYPE_CONTAINS_VPTR_P (t) && !pending_hard_virtuals)
modify_all_vtables (t, NULL_TREE); modify_all_vtables (t, NULL_TREE);
for (pending_hard_virtuals = nreverse (pending_hard_virtuals); for (pending_hard_virtuals = nreverse (pending_hard_virtuals);
...@@ -4802,9 +4849,9 @@ finish_struct_1 (t) ...@@ -4802,9 +4849,9 @@ finish_struct_1 (t)
} }
} }
/* Under our model of GC, every C++ class gets its own virtual /* If necessary, create the vtable for this class. */
function table, at least virtually. */ if (pending_virtuals
if (pending_virtuals) || (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ()))
{ {
pending_virtuals = nreverse (pending_virtuals); pending_virtuals = nreverse (pending_virtuals);
/* We must enter these virtuals into the table. */ /* We must enter these virtuals into the table. */
...@@ -4836,6 +4883,8 @@ finish_struct_1 (t) ...@@ -4836,6 +4883,8 @@ finish_struct_1 (t)
CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
} }
/* If we didn't need a new vtable, see if we should copy one from
the base. */
else if (CLASSTYPE_HAS_PRIMARY_BASE_P (t)) else if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
{ {
tree binfo = CLASSTYPE_PRIMARY_BINFO (t); tree binfo = CLASSTYPE_PRIMARY_BINFO (t);
...@@ -4855,7 +4904,7 @@ finish_struct_1 (t) ...@@ -4855,7 +4904,7 @@ finish_struct_1 (t)
CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
} }
if (TYPE_POLYMORPHIC_P (t)) if (TYPE_CONTAINS_VPTR_P (t))
{ {
CLASSTYPE_VSIZE (t) = has_virtual; CLASSTYPE_VSIZE (t) = has_virtual;
if (CLASSTYPE_HAS_PRIMARY_BASE_P (t)) if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
...@@ -6004,7 +6053,7 @@ get_vfield_name (type) ...@@ -6004,7 +6053,7 @@ get_vfield_name (type)
char *buf; char *buf;
while (BINFO_BASETYPES (binfo) while (BINFO_BASETYPES (binfo)
&& TYPE_POLYMORPHIC_P (BINFO_TYPE (BINFO_BASETYPE (binfo, 0))) && TYPE_CONTAINS_VPTR_P (BINFO_TYPE (BINFO_BASETYPE (binfo, 0)))
&& ! TREE_VIA_VIRTUAL (BINFO_BASETYPE (binfo, 0))) && ! TREE_VIA_VIRTUAL (BINFO_BASETYPE (binfo, 0)))
binfo = BINFO_BASETYPE (binfo, 0); binfo = BINFO_BASETYPE (binfo, 0);
......
...@@ -177,7 +177,44 @@ Boston, MA 02111-1307, USA. */ ...@@ -177,7 +177,44 @@ Boston, MA 02111-1307, USA. */
#define RECORD_OR_UNION_TYPE_CHECK(NODE) NODE #define RECORD_OR_UNION_TYPE_CHECK(NODE) NODE
#endif #endif
/* ABI control. */
/* Nonzero to enable experimental ABI changes. */
extern int flag_new_abi;
/* Nonzero to use __cxa_atexit, rather than atexit, to register
destructors for local statics and global objects. */
extern int flag_use_cxa_atexit;
/* Nonzero to not ignore namespace std. */
extern int flag_honor_std;
/* Nonzero means generate 'rtti' that give run-time type information. */
extern int flag_rtti;
/* Nonzero if virtual base class offsets are stored in the virtual
function table. Zero if, instead, a pointer to the virtual base is
stored in the object itself. */
#define vbase_offsets_in_vtable_p() (flag_new_abi)
/* Nonzero if a derived class that needs a vptr should always get one,
even if a non-primary base class already has one. For example,
given:
struct S { int i; virtual void f(); };
struct T : virtual public S {};
one could either reuse the vptr in `S' for `T', or create a new
vptr for `T'. If this flag is nonzero we choose the latter
alternative; otherwise, we choose the former. */
#define vptrs_present_everywhere_p() (flag_new_abi)
/* Language-dependent contents of an identifier. */ /* Language-dependent contents of an identifier. */
struct lang_identifier struct lang_identifier
...@@ -2156,6 +2193,12 @@ struct lang_decl ...@@ -2156,6 +2193,12 @@ struct lang_decl
polymorphic class. */ polymorphic class. */
#define TYPE_POLYMORPHIC_P(NODE) (TREE_LANG_FLAG_2 (NODE)) #define TYPE_POLYMORPHIC_P(NODE) (TREE_LANG_FLAG_2 (NODE))
/* Nonzero if this class has a virtual function table pointer. */
#define TYPE_CONTAINS_VPTR_P(NODE) \
(TYPE_POLYMORPHIC_P (NODE) \
|| (vbase_offsets_in_vtable_p () \
&& TYPE_USES_VIRTUAL_BASECLASSES (NODE)))
extern int flag_new_for_scope; extern int flag_new_for_scope;
/* This flag is true of a local VAR_DECL if it was declared in a for /* This flag is true of a local VAR_DECL if it was declared in a for
...@@ -3160,10 +3203,6 @@ extern struct pending_inline *pending_inlines; ...@@ -3160,10 +3203,6 @@ extern struct pending_inline *pending_inlines;
extern int flag_this_is_variable; extern int flag_this_is_variable;
/* Nonzero means generate 'rtti' that give run-time type information. */
extern int flag_rtti;
/* Nonzero means do emit exported implementations of functions even if /* Nonzero means do emit exported implementations of functions even if
they can be inlined. */ they can be inlined. */
...@@ -3187,19 +3226,6 @@ extern int flag_implicit_templates; ...@@ -3187,19 +3226,6 @@ extern int flag_implicit_templates;
extern int flag_weak; extern int flag_weak;
/* Nonzero to enable experimental ABI changes. */
extern int flag_new_abi;
/* Nonzero to use __cxa_atexit, rather than atexit, to register
destructors for local statics and global objects. */
extern int flag_use_cxa_atexit;
/* Nonzero to not ignore namespace std. */
extern int flag_honor_std;
/* Nonzero if we should expand functions calls inline at the tree /* Nonzero if we should expand functions calls inline at the tree
level, rather than at the RTL level. */ level, rather than at the RTL level. */
...@@ -3961,6 +3987,11 @@ extern tree dfs_walk PROTO((tree, ...@@ -3961,6 +3987,11 @@ extern tree dfs_walk PROTO((tree,
tree (*)(tree, void *), tree (*)(tree, void *),
tree (*) (tree, void *), tree (*) (tree, void *),
void *)); void *));
extern tree dfs_walk_real PROTO ((tree,
tree (*) (tree, void *),
tree (*) (tree, void *),
tree (*) (tree, void *),
void *));
extern tree dfs_unmark PROTO((tree, void *)); extern tree dfs_unmark PROTO((tree, void *));
extern tree dfs_vbase_unmark PROTO((tree, void *)); extern tree dfs_vbase_unmark PROTO((tree, void *));
extern tree dfs_vtable_path_unmark PROTO((tree, void *)); extern tree dfs_vtable_path_unmark PROTO((tree, void *));
......
...@@ -8201,15 +8201,7 @@ expand_static_init (decl, init) ...@@ -8201,15 +8201,7 @@ expand_static_init (decl, init)
finish_if_stmt (); finish_if_stmt ();
} }
else else
{ static_aggregates = tree_cons (init, decl, static_aggregates);
/* This code takes into account memory allocation policy of
`start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING does not
hold for this object, then we must make permanent the storage
currently in the temporary obstack. */
if (!TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
preserve_initializer ();
static_aggregates = tree_cons (init, decl, static_aggregates);
}
} }
/* Finish the declaration of a catch-parameter. */ /* Finish the declaration of a catch-parameter. */
......
...@@ -2296,8 +2296,9 @@ mark_vtable_entries (decl) ...@@ -2296,8 +2296,9 @@ mark_vtable_entries (decl)
fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries) fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries)
: FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)));
if (TREE_CODE (fnaddr) == NOP_EXPR) if (TREE_CODE (fnaddr) != ADDR_EXPR)
/* RTTI offset. */ /* This entry is an offset: a virtual base class offset, a
virtual call offset, and RTTI offset, etc. */
continue; continue;
fn = TREE_OPERAND (fnaddr, 0); fn = TREE_OPERAND (fnaddr, 0);
......
...@@ -119,8 +119,12 @@ initialize_vtbl_ptrs (type, addr) ...@@ -119,8 +119,12 @@ initialize_vtbl_ptrs (type, addr)
{ {
tree list = build_tree_list (type, addr); tree list = build_tree_list (type, addr);
dfs_walk (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, /* Walk through the hierarchy, initializing the vptr in each base
dfs_unmarked_real_bases_queue_p, list); class. We do these in pre-order because under the new ABI we
can't find the virtual bases for a class until we've initialized
the vtbl for that class. */
dfs_walk_real (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs,
NULL, dfs_unmarked_real_bases_queue_p, list);
dfs_walk (TYPE_BINFO (type), dfs_unmark, dfs_walk (TYPE_BINFO (type), dfs_unmark,
dfs_marked_real_bases_queue_p, type); dfs_marked_real_bases_queue_p, type);
if (TYPE_USES_VIRTUAL_BASECLASSES (type)) if (TYPE_USES_VIRTUAL_BASECLASSES (type))
...@@ -657,7 +661,7 @@ expand_virtual_init (binfo, decl) ...@@ -657,7 +661,7 @@ expand_virtual_init (binfo, decl)
vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl); vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
/* Under the new ABI, we need to point into the middle of the /* Under the new ABI, we need to point into the middle of the
vtable. */ vtable. */
if (flag_new_abi) if (vbase_offsets_in_vtable_p ())
vtbl = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, vtbl = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
size_extra_vtbl_entries (binfo)); size_extra_vtbl_entries (binfo));
...@@ -720,7 +724,7 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) ...@@ -720,7 +724,7 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
/* Construct the virtual base-classes of THIS_REF (whose address is /* Construct the virtual base-classes of THIS_REF (whose address is
THIS_PTR). The object has the indicated TYPE. The construction THIS_PTR). The object has the indicated TYPE. The construction
actually takes place only if FLAG is non-zero. INIT_LIST is list actually takes place only if FLAG is non-zero. INIT_LIST is list
of initialization for constructor to perform. */ of initializations for constructors to perform. */
static void static void
construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) construct_virtual_bases (type, this_ref, this_ptr, init_list, flag)
...@@ -731,21 +735,25 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) ...@@ -731,21 +735,25 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag)
tree flag; tree flag;
{ {
tree vbases; tree vbases;
tree result;
tree if_stmt;
/* If there are no virtual baseclasses, we shouldn't even be here. */ /* If there are no virtual baseclasses, we shouldn't even be here. */
my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621); my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621);
/* First set the pointers in our object that tell us where to find /* First set the pointers in our object that tell us where to find
our virtual baseclasses. */ our virtual baseclasses. */
if_stmt = begin_if_stmt (); if (!vbase_offsets_in_vtable_p ())
finish_if_stmt_cond (flag, if_stmt); {
result = init_vbase_pointers (type, this_ptr); tree if_stmt;
if (result) tree result;
finish_expr_stmt (build_compound_expr (result));
finish_then_clause (if_stmt); if_stmt = begin_if_stmt ();
finish_if_stmt (); finish_if_stmt_cond (flag, if_stmt);
result = init_vbase_pointers (type, this_ptr);
if (result)
finish_expr_stmt (build_compound_expr (result));
finish_then_clause (if_stmt);
finish_if_stmt ();
}
/* Now, run through the baseclasses, initializing each. */ /* Now, run through the baseclasses, initializing each. */
for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; for (vbases = CLASSTYPE_VBASECLASSES (type); vbases;
...@@ -1019,11 +1027,6 @@ finish_init_stmts (stmt_expr, compound_stmt) ...@@ -1019,11 +1027,6 @@ finish_init_stmts (stmt_expr, compound_stmt)
If `init' is a CONSTRUCTOR, then we emit a warning message, If `init' is a CONSTRUCTOR, then we emit a warning message,
explaining that such initializations are invalid. explaining that such initializations are invalid.
ALIAS_THIS is nonzero iff we are initializing something which is
essentially an alias for current_class_ref. In this case, the base
constructor may move it on us, and we must keep track of such
deviations.
If INIT resolves to a CALL_EXPR which happens to return If INIT resolves to a CALL_EXPR which happens to return
something of the type we are looking for, then we know something of the type we are looking for, then we know
that we can safely use that call to perform the that we can safely use that call to perform the
...@@ -1217,8 +1220,6 @@ expand_default_init (binfo, true_exp, exp, init, flags) ...@@ -1217,8 +1220,6 @@ expand_default_init (binfo, true_exp, exp, init, flags)
from TRUE_EXP. In constructors, we don't know anything about from TRUE_EXP. In constructors, we don't know anything about
the value being initialized. the value being initialized.
ALIAS_THIS serves the same purpose it serves for expand_aggr_init.
FLAGS is just passes to `build_method_call'. See that function for FLAGS is just passes to `build_method_call'. See that function for
its description. */ its description. */
......
/* RunTime Type Identification /* RunTime Type Identification
Copyright (C) 1995, 96-97, 1998, 1999 Free Software Foundation, Inc. Copyright (C) 1995, 96-97, 1998, 1999, 2000 Free Software Foundation, Inc.
Mostly written by Jason Merrill (jason@cygnus.com). Mostly written by Jason Merrill (jason@cygnus.com).
This file is part of GNU CC. This file is part of GNU CC.
...@@ -811,7 +811,8 @@ expand_class_desc (tdecl, type) ...@@ -811,7 +811,8 @@ expand_class_desc (tdecl, type)
(type_info_type_node, (type_info_type_node,
TYPE_QUAL_CONST))); TYPE_QUAL_CONST)));
fields [1] = build_lang_decl fields [1] = build_lang_decl
(FIELD_DECL, NULL_TREE, unsigned_intSI_type_node); (FIELD_DECL, NULL_TREE,
flag_new_abi ? intSI_type_node : unsigned_intSI_type_node);
DECL_BIT_FIELD (fields[1]) = 1; DECL_BIT_FIELD (fields[1]) = 1;
DECL_FIELD_SIZE (fields[1]) = 29; DECL_FIELD_SIZE (fields[1]) = 29;
...@@ -839,15 +840,26 @@ expand_class_desc (tdecl, type) ...@@ -839,15 +840,26 @@ expand_class_desc (tdecl, type)
if (TREE_VIA_VIRTUAL (binfo)) if (TREE_VIA_VIRTUAL (binfo))
{ {
tree t = BINFO_TYPE (binfo); if (!vbase_offsets_in_vtable_p ())
const char *name; {
tree field; tree t = BINFO_TYPE (binfo);
const char *name;
FORMAT_VBASE_NAME (name, t); tree field;
field = lookup_field (type, get_identifier (name), 0, 0);
offset = size_binop (FLOOR_DIV_EXPR, FORMAT_VBASE_NAME (name, t);
DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT)); field = lookup_field (type, get_identifier (name), 0, 0);
offset = convert (sizetype, offset); offset = size_binop (FLOOR_DIV_EXPR,
DECL_FIELD_BITPOS (field),
size_int (BITS_PER_UNIT));
offset = convert (sizetype, offset);
}
else
{
/* Under the new ABI, we store the vtable offset at which
the virtual base offset can be found. */
tree vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), type);
offset = convert (sizetype, BINFO_VPTR_FIELD (vbase));
}
} }
else else
offset = BINFO_OFFSET (binfo); offset = BINFO_OFFSET (binfo);
......
...@@ -126,11 +126,6 @@ static tree bfs_walk ...@@ -126,11 +126,6 @@ static tree bfs_walk
void *)); void *));
static tree lookup_field_queue_p PROTO((tree, void *)); static tree lookup_field_queue_p PROTO((tree, void *));
static tree lookup_field_r PROTO((tree, void *)); static tree lookup_field_r PROTO((tree, void *));
static tree dfs_walk_real PROTO ((tree,
tree (*) (tree, void *),
tree (*) (tree, void *),
tree (*) (tree, void *),
void *));
static tree get_virtuals_named_this_r PROTO ((tree, void *)); static tree get_virtuals_named_this_r PROTO ((tree, void *));
static tree context_for_name_lookup PROTO ((tree)); static tree context_for_name_lookup PROTO ((tree));
static tree canonical_binfo PROTO ((tree)); static tree canonical_binfo PROTO ((tree));
...@@ -1773,7 +1768,7 @@ bfs_walk (binfo, fn, qfn, data) ...@@ -1773,7 +1768,7 @@ bfs_walk (binfo, fn, qfn, data)
performed, and PREFN is called in preorder, while POSTFN is called performed, and PREFN is called in preorder, while POSTFN is called
in postorder. */ in postorder. */
static tree tree
dfs_walk_real (binfo, prefn, postfn, qfn, data) dfs_walk_real (binfo, prefn, postfn, qfn, data)
tree binfo; tree binfo;
tree (*prefn) PROTO((tree, void *)); tree (*prefn) PROTO((tree, void *));
...@@ -3200,9 +3195,9 @@ maybe_suppress_debug_info (t) ...@@ -3200,9 +3195,9 @@ maybe_suppress_debug_info (t)
TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
else if (CLASSTYPE_INTERFACE_KNOWN (t)) else if (CLASSTYPE_INTERFACE_KNOWN (t))
/* Don't set it. */; /* Don't set it. */;
/* If the class has virtual functions, write out the debug info /* If the class has a vtable, write out the debug info along with
along with the vtable. */ the vtable. */
else if (TYPE_POLYMORPHIC_P (t)) else if (TYPE_CONTAINS_VPTR_P (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
/* Otherwise, just emit the debug info normally. */ /* Otherwise, just emit the debug info normally. */
......
// Methods for type_info for -*- C++ -*- Run Time Type Identification. // Methods for type_info for -*- C++ -*- Run Time Type Identification.
// Copyright (C) 1994, 1996, 1998, 1999 Free Software Foundation // Copyright (C) 1994, 1996, 1998, 1999, 2000 Free Software Foundation
// This file is part of GNU CC. // This file is part of GNU CC.
...@@ -31,6 +31,34 @@ ...@@ -31,6 +31,34 @@
#include "tinfo.h" #include "tinfo.h"
#include "new" // for placement new #include "new" // for placement new
namespace
{
// ADDR is a pointer to an object. Convert it to a pointer to a base,
// using OFFSET.
inline void*
convert_to_base (void *addr, bool is_virtual, USItype offset)
{
if (!addr)
return NULL;
if (!is_virtual)
return (char *) addr + offset;
#ifdef __GXX_ABI_VERSION
// Under the new ABI, the offset gives us an index into the vtable,
// which contains an offset to the virtual base. The vptr is always
// the first thing in the object.
std::ptrdiff_t *vtable = *((std::ptrdiff_t **) addr);
return ((char *) addr) + vtable[offset];
#else
// Under the old ABI, the offset gives us the address of a pointer
// to the virtual base.
return *((void **) ((char *) addr + offset));
#endif
}
}
// This file contains the minimal working set necessary to link with code // This file contains the minimal working set necessary to link with code
// that uses virtual functions and -frtti but does not actually use RTTI // that uses virtual functions and -frtti but does not actually use RTTI
// functionality. // functionality.
...@@ -254,14 +282,11 @@ do_upcast (sub_kind access_path, ...@@ -254,14 +282,11 @@ do_upcast (sub_kind access_path,
upcast_result result2; upcast_result result2;
void *p = objptr; void *p = objptr;
sub_kind sub_access = access_path; sub_kind sub_access = access_path;
if (p) p = convert_to_base (p,
p = (char *)p + base_list[i].offset; base_list[i].is_virtual,
base_list[i].offset);
if (base_list[i].is_virtual) if (base_list[i].is_virtual)
{ sub_access = sub_kind (sub_access | contained_virtual_mask);
if (p)
p = *(void **)p;
sub_access = sub_kind (sub_access | contained_virtual_mask);
}
if (base_list[i].access != PUBLIC) if (base_list[i].access != PUBLIC)
sub_access = sub_kind (sub_access & ~contained_public_mask); sub_access = sub_kind (sub_access & ~contained_public_mask);
if (base_list[i].base->do_upcast (sub_access, target, p, result2)) if (base_list[i].base->do_upcast (sub_access, target, p, result2))
...@@ -344,13 +369,13 @@ do_dyncast (int boff, sub_kind access_path, ...@@ -344,13 +369,13 @@ do_dyncast (int boff, sub_kind access_path,
for (size_t i = n_bases; i--;) for (size_t i = n_bases; i--;)
{ {
dyncast_result result2; dyncast_result result2;
void *p = (char *)objptr + base_list[i].offset; void *p;
sub_kind sub_access = access_path; sub_kind sub_access = access_path;
p = convert_to_base (objptr,
base_list[i].is_virtual,
base_list[i].offset);
if (base_list[i].is_virtual) if (base_list[i].is_virtual)
{ sub_access = sub_kind (sub_access | contained_virtual_mask);
p = *(void **)p;
sub_access = sub_kind (sub_access | contained_virtual_mask);
}
if (base_list[i].access != PUBLIC) if (base_list[i].access != PUBLIC)
sub_access = sub_kind (sub_access & ~contained_public_mask); sub_access = sub_kind (sub_access & ~contained_public_mask);
...@@ -492,13 +517,15 @@ do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *s ...@@ -492,13 +517,15 @@ do_find_public_subobj (int boff, const type_info &subtype, void *objptr, void *s
{ {
if (base_list[i].access != PUBLIC) if (base_list[i].access != PUBLIC)
continue; // Not public, can't be here. continue; // Not public, can't be here.
void *p = (char *)objptr + base_list[i].offset; void *p;
if (base_list[i].is_virtual)
{ if (base_list[i].is_virtual && boff == -1)
if (boff == -1) // Not a virtual base, so can't be here.
continue; // Not a virtual base, so can't be here. continue;
p = *(void **)p;
} p = convert_to_base (objptr,
base_list[i].is_virtual,
base_list[i].offset);
sub_kind base_kind = base_list[i].base->do_find_public_subobj sub_kind base_kind = base_list[i].base->do_find_public_subobj
(boff, subtype, p, subptr); (boff, subtype, p, subptr);
......
// RTTI support internals for -*- C++ -*- // RTTI support internals for -*- C++ -*-
// Copyright (C) 1994, 1995, 1996, 1998, 1999 Free Software Foundation // Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000 Free Software Foundation
#include "typeinfo" #include "typeinfo"
...@@ -167,7 +167,11 @@ public: ...@@ -167,7 +167,11 @@ public:
// type_info for a general class. // type_info for a general class.
#ifdef __GXX_ABI_VERSION
typedef int USItype __attribute__ ((mode (SI)));
#else
typedef unsigned int USItype __attribute__ ((mode (SI))); typedef unsigned int USItype __attribute__ ((mode (SI)));
#endif
struct __class_type_info : public __user_type_info { struct __class_type_info : public __user_type_info {
enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 }; enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 };
......
...@@ -860,7 +860,6 @@ make_binfo (offset, binfo, vtable, virtuals) ...@@ -860,7 +860,6 @@ make_binfo (offset, binfo, vtable, virtuals)
BINFO_OFFSET (new_binfo) = offset; BINFO_OFFSET (new_binfo) = offset;
BINFO_VTABLE (new_binfo) = vtable; BINFO_VTABLE (new_binfo) = vtable;
BINFO_VIRTUALS (new_binfo) = virtuals; BINFO_VIRTUALS (new_binfo) = virtuals;
BINFO_VPTR_FIELD (new_binfo) = NULL_TREE;
if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE) if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE)
BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo)); BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment