Commit 3c9d6359 by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.

	* cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.
	(CANONICAL_BINFO): New macro.
	(BINFO_NEW_VTABLE_MARKED): Use it.
	(SET_BINFO_NEW_VTABLE_MARKED): Likewise.
	(CLEAR_BINFO_NEW_VTABLE_MARKED): Likewise.
	* class.c (dfs_build_vbase_offset_vtbl_entries): Use BINFO_TYPE,
	not TREE_TYPE.
	(build_primary_vtable): Adjust usage of BINFO_NEW_VTABLE_MARKED.
	(build_secondary_vtable): Likewise.
	(dfs_finish_vtbls): Likewise.
	(dfs_accumulate_vtbl_inits): Likewise.
	(accumulate_vtbl_inits): New function.
	(finish_vtbls): Make sure that virtual bases come after
	non-virtual bases in the vtable group.
	(record_base_offsets): Don't save and restore TREE_VIA_VIRTUAL.
	(finish_struct_1): Adjust usage of BINFO_NEW_VTABLE_MARKED.
	* search.c (struct vbase_info): Move definition.
	(marked_new_vtable_p): Adjust usage of BINFO_NEW_VTABLE_MARKED.
	(unmarked_new_vtable_p): Likewise.
	(dfs_mark_vtable_path): Remove.
	(dfs_mark_new_vtable): Remove.
	(dfs_unmark_new_vtable): Likewise.
	(dfs_clear_search_slot): Likewise.
	(dfs_find_vbases):  Adjust usage of BINFO_NEW_VTABLE_MARKED.
	(dfs_clear_vbase_slots): Likewise.
	(init_vbase_pointers): LIkewise.

From-SVN: r32689
parent 26356fee
2000-03-22 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.
(CANONICAL_BINFO): New macro.
(BINFO_NEW_VTABLE_MARKED): Use it.
(SET_BINFO_NEW_VTABLE_MARKED): Likewise.
(CLEAR_BINFO_NEW_VTABLE_MARKED): Likewise.
* class.c (dfs_build_vbase_offset_vtbl_entries): Use BINFO_TYPE,
not TREE_TYPE.
(build_primary_vtable): Adjust usage of BINFO_NEW_VTABLE_MARKED.
(build_secondary_vtable): Likewise.
(dfs_finish_vtbls): Likewise.
(dfs_accumulate_vtbl_inits): Likewise.
(accumulate_vtbl_inits): New function.
(finish_vtbls): Make sure that virtual bases come after
non-virtual bases in the vtable group.
(record_base_offsets): Don't save and restore TREE_VIA_VIRTUAL.
(finish_struct_1): Adjust usage of BINFO_NEW_VTABLE_MARKED.
* search.c (struct vbase_info): Move definition.
(marked_new_vtable_p): Adjust usage of BINFO_NEW_VTABLE_MARKED.
(unmarked_new_vtable_p): Likewise.
(dfs_mark_vtable_path): Remove.
(dfs_mark_new_vtable): Remove.
(dfs_unmark_new_vtable): Likewise.
(dfs_clear_search_slot): Likewise.
(dfs_find_vbases): Adjust usage of BINFO_NEW_VTABLE_MARKED.
(dfs_clear_vbase_slots): Likewise.
(init_vbase_pointers): LIkewise.
2000-03-22 Jason Merrill <jason@casey.cygnus.com> 2000-03-22 Jason Merrill <jason@casey.cygnus.com>
* typeck.c (type_after_usual_arithmetic_conversions): Prefer a * typeck.c (type_after_usual_arithmetic_conversions): Prefer a
......
...@@ -161,6 +161,7 @@ static tree dfs_search_base_offsets PARAMS ((tree, void *)); ...@@ -161,6 +161,7 @@ static tree dfs_search_base_offsets PARAMS ((tree, void *));
static int layout_conflict_p PARAMS ((tree, varray_type)); static int layout_conflict_p PARAMS ((tree, varray_type));
static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int)); static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
static void layout_empty_base PARAMS ((tree, tree, varray_type)); static void layout_empty_base PARAMS ((tree, tree, varray_type));
static void accumulate_vtbl_inits PARAMS ((tree, tree));
/* Variables shared between class.c and call.c. */ /* Variables shared between class.c and call.c. */
...@@ -276,7 +277,7 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data) ...@@ -276,7 +277,7 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data)
/* Remember the index to the vbase offset for this virtual /* Remember the index to the vbase offset for this virtual
base. */ base. */
vbase = BINFO_FOR_VBASE (TREE_TYPE (binfo), TREE_PURPOSE (list)); vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list));
if (!TREE_VALUE (list)) if (!TREE_VALUE (list))
BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0); BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
else else
...@@ -1072,7 +1073,7 @@ build_primary_vtable (binfo, type) ...@@ -1072,7 +1073,7 @@ build_primary_vtable (binfo, type)
{ {
tree offset; tree offset;
if (BINFO_NEW_VTABLE_MARKED (binfo)) if (BINFO_NEW_VTABLE_MARKED (binfo, type))
/* We have already created a vtable for this base, so there's /* We have already created a vtable for this base, so there's
no need to do it again. */ no need to do it again. */
return 0; return 0;
...@@ -1106,7 +1107,7 @@ build_primary_vtable (binfo, type) ...@@ -1106,7 +1107,7 @@ build_primary_vtable (binfo, type)
TYPE_BINFO_VIRTUALS (type) = virtuals; TYPE_BINFO_VIRTUALS (type) = virtuals;
binfo = TYPE_BINFO (type); binfo = TYPE_BINFO (type);
SET_BINFO_NEW_VTABLE_MARKED (binfo); SET_BINFO_NEW_VTABLE_MARKED (binfo, type);
return 1; return 1;
} }
...@@ -1147,14 +1148,14 @@ build_secondary_vtable (binfo, for_type) ...@@ -1147,14 +1148,14 @@ build_secondary_vtable (binfo, for_type)
current_class_type), current_class_type),
170); 170);
if (BINFO_NEW_VTABLE_MARKED (binfo)) if (BINFO_NEW_VTABLE_MARKED (binfo, current_class_type))
/* We already created a vtable for this base. There's no need to /* We already created a vtable for this base. There's no need to
do it again. */ do it again. */
return 0; return 0;
/* Remember that we've created a vtable for this BINFO, so that we /* Remember that we've created a vtable for this BINFO, so that we
don't try to do so again. */ don't try to do so again. */
SET_BINFO_NEW_VTABLE_MARKED (binfo); SET_BINFO_NEW_VTABLE_MARKED (binfo, current_class_type);
/* Make fresh virtual list, so we can smash it later. */ /* Make fresh virtual list, so we can smash it later. */
BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo)); BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
...@@ -2760,13 +2761,15 @@ dfs_finish_vtbls (binfo, data) ...@@ -2760,13 +2761,15 @@ dfs_finish_vtbls (binfo, data)
tree binfo; tree binfo;
void *data; void *data;
{ {
tree t = (tree) data;
if (!BINFO_PRIMARY_MARKED_P (binfo) if (!BINFO_PRIMARY_MARKED_P (binfo)
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)) && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
&& BINFO_NEW_VTABLE_MARKED (binfo)) && BINFO_NEW_VTABLE_MARKED (binfo, t))
initialize_vtable (binfo, initialize_vtable (binfo,
build_vtbl_initializer (binfo, (tree) data)); build_vtbl_initializer (binfo, t));
CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
SET_BINFO_MARKED (binfo); SET_BINFO_MARKED (binfo);
return NULL_TREE; return NULL_TREE;
...@@ -2781,15 +2784,16 @@ dfs_accumulate_vtbl_inits (binfo, data) ...@@ -2781,15 +2784,16 @@ dfs_accumulate_vtbl_inits (binfo, data)
tree binfo; tree binfo;
void *data; void *data;
{ {
tree l;
tree t;
l = (tree) data;
t = TREE_PURPOSE (l);
if (!BINFO_PRIMARY_MARKED_P (binfo) if (!BINFO_PRIMARY_MARKED_P (binfo)
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)) && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
&& BINFO_NEW_VTABLE_MARKED (binfo)) && BINFO_NEW_VTABLE_MARKED (binfo, t))
{ {
tree l;
tree t;
l = (tree) data;
t = TREE_PURPOSE (l);
/* If this is a secondary vtable, record its location. */ /* If this is a secondary vtable, record its location. */
if (binfo != TYPE_BINFO (t)) if (binfo != TYPE_BINFO (t))
...@@ -2807,19 +2811,34 @@ dfs_accumulate_vtbl_inits (binfo, data) ...@@ -2807,19 +2811,34 @@ dfs_accumulate_vtbl_inits (binfo, data)
size_int (list_length (TREE_VALUE (l))))); size_int (list_length (TREE_VALUE (l)))));
} }
/* Add the initializers for this vtable to the initailizers for /* Add the initializers for this vtable to the initializers for
the other vtables we've already got. */ the other vtables we've already got. */
TREE_VALUE (l) TREE_VALUE (l)
= chainon (TREE_VALUE (l), = chainon (TREE_VALUE (l),
build_vtbl_initializer (binfo, t)); build_vtbl_initializer (binfo, t));
} }
CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
SET_BINFO_MARKED (binfo);
return NULL_TREE; return NULL_TREE;
} }
/* Add the vtbl initializers for BINFO (and its non-primary,
non-virtual bases) to the list of INITS. */
static void
accumulate_vtbl_inits (binfo, inits)
tree binfo;
tree inits;
{
/* Walk the BINFO and its bases. */
dfs_walk_real (binfo,
dfs_accumulate_vtbl_inits,
NULL,
dfs_skip_vbases,
inits);
}
/* Create all the necessary vtables for T and its base classes. */ /* Create all the necessary vtables for T and its base classes. */
static void static void
...@@ -2829,26 +2848,31 @@ finish_vtbls (t) ...@@ -2829,26 +2848,31 @@ finish_vtbls (t)
if (merge_primary_and_secondary_vtables_p ()) if (merge_primary_and_secondary_vtables_p ())
{ {
tree list; tree list;
tree vbase;
/* Under the new ABI, we lay out the primary and secondary /* Under the new ABI, we lay out the primary and secondary
vtables in one contiguous vtable. The primary vtable is vtables in one contiguous vtable. The primary vtable is
first, followed by the secondary vtables as encountered in a first, followed by the non-virtual secondary vtables in
pre-order depth-first left-to-right traversal. */ inheritance graph order. */
list = build_tree_list (t, NULL_TREE); list = build_tree_list (t, NULL_TREE);
dfs_walk_real (TYPE_BINFO (t), accumulate_vtbl_inits (TYPE_BINFO (t), list);
dfs_accumulate_vtbl_inits, /* Then come the virtual bases, also in inheritance graph
NULL, order. */
dfs_unmarked_real_bases_queue_p, for (vbase = CLASSTYPE_VBASECLASSES (t);
list); vbase;
vbase = TREE_CHAIN (vbase))
accumulate_vtbl_inits (vbase, list);
if (TYPE_BINFO_VTABLE (t)) if (TYPE_BINFO_VTABLE (t))
initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list)); initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
} }
else else
dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls, {
dfs_unmarked_real_bases_queue_p, t); dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls,
dfs_unmarked_real_bases_queue_p, t);
dfs_walk (TYPE_BINFO (t), dfs_unmark, dfs_walk (TYPE_BINFO (t), dfs_unmark,
dfs_marked_real_bases_queue_p, t); dfs_marked_real_bases_queue_p, t);
}
} }
/* True if we should override the given BASE_FNDECL with the given /* True if we should override the given BASE_FNDECL with the given
...@@ -4142,17 +4166,10 @@ record_base_offsets (binfo, base_offsets) ...@@ -4142,17 +4166,10 @@ record_base_offsets (binfo, base_offsets)
tree binfo; tree binfo;
varray_type *base_offsets; varray_type *base_offsets;
{ {
int virtual_p;
/* If BINFO is virtual, we still want to mention its offset in
BASE_OFFSETS. */
virtual_p = TREE_VIA_VIRTUAL (binfo);
TREE_VIA_VIRTUAL (binfo) = 0;
dfs_walk (binfo, dfs_walk (binfo,
dfs_record_base_offsets, dfs_record_base_offsets,
dfs_skip_vbases, dfs_skip_vbases,
base_offsets); base_offsets);
TREE_VIA_VIRTUAL (binfo) = virtual_p;
} }
/* Returns non-NULL if there is already an entry in DATA (which is /* Returns non-NULL if there is already an entry in DATA (which is
...@@ -5308,7 +5325,7 @@ finish_struct_1 (t) ...@@ -5308,7 +5325,7 @@ finish_struct_1 (t)
} }
build_primary_vtable (NULL_TREE, t); build_primary_vtable (NULL_TREE, t);
} }
else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t))) else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t))
/* Here we know enough to change the type of our virtual /* Here we know enough to change the type of our virtual
function table, but we will wait until later this function. */ function table, but we will wait until later this function. */
build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t); build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
......
...@@ -1566,10 +1566,19 @@ struct lang_type ...@@ -1566,10 +1566,19 @@ struct lang_type
(also distinct from the copies in the TYPE_BINFO hierarchy.) */ (also distinct from the copies in the TYPE_BINFO hierarchy.) */
#define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases) #define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases)
/* The BINFO (if any) for the virtual baseclass T of the class C. */ /* The BINFO (if any) for the virtual baseclass T of the class C from
the CLASSTYPE_VBASECLASSES list. */
#define BINFO_FOR_VBASE(T, C) \ #define BINFO_FOR_VBASE(T, C) \
(binfo_member (T, CLASSTYPE_VBASECLASSES (C))) (binfo_member (T, CLASSTYPE_VBASECLASSES (C)))
/* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the
BINFO_FOR_VBASE. C is the most derived class for the hierarchy
containing BINFO. */
#define CANONICAL_BINFO(BINFO, C) \
(TREE_VIA_VIRTUAL (BINFO) \
? BINFO_FOR_VBASE (BINFO_TYPE (BINFO), C) \
: BINFO)
/* Number of direct baseclasses of NODE. */ /* Number of direct baseclasses of NODE. */
#define CLASSTYPE_N_BASECLASSES(NODE) \ #define CLASSTYPE_N_BASECLASSES(NODE) \
(BINFO_N_BASETYPES (TYPE_BINFO (NODE))) (BINFO_N_BASETYPES (TYPE_BINFO (NODE)))
...@@ -1704,11 +1713,14 @@ struct lang_type ...@@ -1704,11 +1713,14 @@ struct lang_type
#define SET_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=1)) #define SET_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=1))
#define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=0)) #define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=0))
/* Nonzero means that this class has a new vtable. */ /* Nonzero means B (a BINFO) needs a new vtable. B is part of the
#define BINFO_NEW_VTABLE_MARKED(NODE) \ hierarchy dominated by C. */
(TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):TREE_LANG_FLAG_4(NODE)) #define BINFO_NEW_VTABLE_MARKED(B, C) \
#define SET_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=1)) (TREE_LANG_FLAG_4 (CANONICAL_BINFO (B, C)))
#define CLEAR_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=0)) #define SET_BINFO_NEW_VTABLE_MARKED(B, C) \
(BINFO_NEW_VTABLE_MARKED (B, C) = 1)
#define CLEAR_BINFO_NEW_VTABLE_MARKED(B, C) \
(BINFO_NEW_VTABLE_MARKED (B, C) = 0)
/* Nonzero means this class has done dfs_pushdecls. */ /* Nonzero means this class has done dfs_pushdecls. */
#define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE) #define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
......
...@@ -76,6 +76,15 @@ pop_stack_level (stack) ...@@ -76,6 +76,15 @@ pop_stack_level (stack)
#define search_level stack_level #define search_level stack_level
static struct search_level *search_stack; static struct search_level *search_stack;
struct vbase_info
{
/* The class dominating the hierarchy. */
tree type;
tree decl_ptr;
tree inits;
tree vbase_types;
};
static tree next_baselink PARAMS ((tree)); static tree next_baselink PARAMS ((tree));
static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *)); static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *));
static tree lookup_field_1 PARAMS ((tree, tree)); static tree lookup_field_1 PARAMS ((tree, tree));
...@@ -2537,17 +2546,21 @@ unmarked_vtable_pathp (binfo, data) ...@@ -2537,17 +2546,21 @@ unmarked_vtable_pathp (binfo, data)
static tree static tree
marked_new_vtablep (binfo, data) marked_new_vtablep (binfo, data)
tree binfo; tree binfo;
void *data ATTRIBUTE_UNUSED; void *data;
{ {
return BINFO_NEW_VTABLE_MARKED (binfo) ? binfo : NULL_TREE; struct vbase_info *vi = (struct vbase_info *) data;
return BINFO_NEW_VTABLE_MARKED (binfo, vi->type) ? binfo : NULL_TREE;
} }
static tree static tree
unmarked_new_vtablep (binfo, data) unmarked_new_vtablep (binfo, data)
tree binfo; tree binfo;
void *data ATTRIBUTE_UNUSED; void *data;
{ {
return !BINFO_NEW_VTABLE_MARKED (binfo) ? binfo : NULL_TREE; struct vbase_info *vi = (struct vbase_info *) data;
return !BINFO_NEW_VTABLE_MARKED (binfo, vi->type) ? binfo : NULL_TREE;
} }
static tree static tree
...@@ -2614,31 +2627,7 @@ dfs_vtable_path_unmark (binfo, data) ...@@ -2614,31 +2627,7 @@ dfs_vtable_path_unmark (binfo, data)
return NULL_TREE; return NULL_TREE;
} }
#if 0
static void
dfs_mark_vtable_path (binfo) tree binfo;
{ SET_BINFO_VTABLE_PATH_MARKED (binfo); }
static void
dfs_mark_new_vtable (binfo) tree binfo;
{ SET_BINFO_NEW_VTABLE_MARKED (binfo); }
static void
dfs_unmark_new_vtable (binfo) tree binfo;
{ CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); }
static void
dfs_clear_search_slot (binfo) tree binfo;
{ CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
#endif
struct vbase_info
{
tree decl_ptr;
tree inits;
tree vbase_types;
};
/* Attach to the type of the virtual base class, the pointer to the /* Attach to the type of the virtual base class, the pointer to the
virtual base class. */ virtual base class. */
...@@ -2668,7 +2657,7 @@ dfs_find_vbases (binfo, data) ...@@ -2668,7 +2657,7 @@ dfs_find_vbases (binfo, data)
} }
} }
SET_BINFO_VTABLE_PATH_MARKED (binfo); SET_BINFO_VTABLE_PATH_MARKED (binfo);
SET_BINFO_NEW_VTABLE_MARKED (binfo); SET_BINFO_NEW_VTABLE_MARKED (binfo, vi->type);
return NULL_TREE; return NULL_TREE;
} }
...@@ -2737,12 +2726,14 @@ dfs_init_vbase_pointers (binfo, data) ...@@ -2737,12 +2726,14 @@ dfs_init_vbase_pointers (binfo, data)
static tree static tree
dfs_clear_vbase_slots (binfo, data) dfs_clear_vbase_slots (binfo, data)
tree binfo; tree binfo;
void *data ATTRIBUTE_UNUSED; void *data;
{ {
tree type = BINFO_TYPE (binfo); tree type = BINFO_TYPE (binfo);
struct vbase_info *vi = (struct vbase_info *) data;
CLASSTYPE_SEARCH_SLOT (type) = 0; CLASSTYPE_SEARCH_SLOT (type) = 0;
CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, vi->type);
return NULL_TREE; return NULL_TREE;
} }
...@@ -2760,6 +2751,7 @@ init_vbase_pointers (type, decl_ptr) ...@@ -2760,6 +2751,7 @@ init_vbase_pointers (type, decl_ptr)
/* Find all the virtual base classes, marking them for later /* Find all the virtual base classes, marking them for later
initialization. */ initialization. */
vi.type = type;
vi.decl_ptr = decl_ptr; vi.decl_ptr = decl_ptr;
vi.vbase_types = CLASSTYPE_VBASECLASSES (type); vi.vbase_types = CLASSTYPE_VBASECLASSES (type);
vi.inits = NULL_TREE; vi.inits = NULL_TREE;
...@@ -2773,7 +2765,7 @@ init_vbase_pointers (type, decl_ptr) ...@@ -2773,7 +2765,7 @@ init_vbase_pointers (type, decl_ptr)
marked_vtable_pathp, marked_vtable_pathp,
&vi); &vi);
dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0); dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, &vi);
flag_this_is_variable = old_flag; flag_this_is_variable = old_flag;
return vi.inits; return vi.inits;
} }
...@@ -3088,12 +3080,13 @@ expand_indirect_vtbls_init (binfo, decl_ptr) ...@@ -3088,12 +3080,13 @@ expand_indirect_vtbls_init (binfo, decl_ptr)
{ {
tree vbases = CLASSTYPE_VBASECLASSES (type); tree vbases = CLASSTYPE_VBASECLASSES (type);
struct vbase_info vi; struct vbase_info vi;
vi.type = type;
vi.decl_ptr = decl_ptr; vi.decl_ptr = decl_ptr;
vi.vbase_types = vbases; vi.vbase_types = vbases;
dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi); dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi);
fixup_all_virtual_upcast_offsets (type, vi.decl_ptr); fixup_all_virtual_upcast_offsets (type, vi.decl_ptr);
dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0); dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, &vi);
} }
} }
......
// Test various aspects of vtable layout.
// Special g++ Options: -fno-strict-aliasing
// Origin: Mark Mitchell <mark@codesourcery.com>
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
struct S0
{
virtual void h ()
{
}
int k;
};
struct S1
{
virtual void f ()
{
}
int i;
};
struct S2 : virtual public S0
{
virtual void g ()
{
}
int j;
};
struct S3
{
virtual void k ()
{
}
int l;
};
struct S4 : public virtual S1, public S2, public S3
{
};
inline void* vtable (void *object)
{
// The vptr is always the first part of the object.
return * (void **) object;
}
int main ()
{
// The vtable layout order for S4 should consist of S4's primary
// vtable (shared with S2), followed by the vtable for S3 (because
// it is a non-virtual base). Then, these should be followed by the
// the vtables for S1 and S0, which are virtual.
S4 s4;
S0 *s0 = &s4;
S1 *s1 = &s4;
S2 *s2 = &s4;
S3 *s3 = &s4;
if (vtable (&s4) != vtable (s2))
return 1;
if (vtable (s2) >= vtable (s3))
return 2;
if (vtable (s3) >= vtable (s1))
return 3;
if (vtable (s1) >= vtable (s0))
return 4;
}
#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
int main ()
{
}
#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
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