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.
......
...@@ -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