cp-tree.h (CLASSTYPE_N_BASECLASSES): Use BINFO_N_BASETYPES.

* cp-tree.h (CLASSTYPE_N_BASECLASSES): Use BINFO_N_BASETYPES.
	(BINFO_PRIMARY_MARKED_P): New macro.
	(SET_BINFO_PRIMARY_MARKED_P): Likewise.
	(CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
	(mark_primary_bases): New function.
	(unmark_primary_bases): Likewise.
	* search.c (get_abstract_virtuals_1): Remove.
	(dfs_mark_primary_bases): New function.
	(mark_primary_bases): Likewise.
	(dfs_unmark_primary_bases): Likewise.
	(unmark_primary_bases): Likewise.
	(dfs_get_pure_virtuals): Likewise.

From-SVN: r31164
This commit is contained in:
Mark Mitchell 2000-01-02 04:34:22 +00:00
parent 07b7a812fd
commit 99a6c6f408
2 changed files with 118 additions and 47 deletions

View File

@ -1420,8 +1420,7 @@ struct lang_type
/* Number of direct baseclasses of NODE. */
#define CLASSTYPE_N_BASECLASSES(NODE) \
(TYPE_BINFO_BASETYPES (NODE) ? \
TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES(NODE)) : 0)
(BINFO_N_BASETYPES (TYPE_BINFO (NODE)))
/* Used for keeping search-specific information. Any search routine
which uses this must define what exactly this slot is used for. */
@ -1563,6 +1562,16 @@ struct lang_type
#define SET_BINFO_PUSHDECLS_MARKED(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE)
#define CLEAR_BINFO_PUSHDECLS_MARKED(NODE) CLEAR_BINFO_VTABLE_PATH_MARKED (NODE)
/* Nonzero if this BINFO has been marked as a primary base class. */
#define BINFO_PRIMARY_MARKED_P(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
/* Mark NODE as a primary base class. */
#define SET_BINFO_PRIMARY_MARKED_P(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE)
/* Clear the primary base class mark. */
#define CLEAR_BINFO_PRIMARY_MARKED_P(NODE) \
CLEAR_BINFO_VTABLE_PATH_MARKED (NODE)
/* Used by various search routines. */
#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE)
@ -2533,7 +2542,7 @@ extern int flag_new_for_scope;
to `struct S {}; typedef struct S S;' in C. This macro will hold
for the typedef indicated in this example. Note that in C++, there
is a second implicit typedef for each class, in the scope of `S'
itself, so that you can `S::S'. This macro does *not* hold for
itself, so that you can say `S::S'. This macro does *not* hold for
those typedefs. */
#define DECL_IMPLICIT_TYPEDEF_P(NODE) \
(TREE_CODE ((NODE)) == TYPE_DECL && DECL_LANG_FLAG_2 ((NODE)))
@ -3900,6 +3909,8 @@ extern tree dfs_walk PROTO((tree,
void *));
extern tree dfs_unmark PROTO((tree, void *));
extern tree markedp PROTO((tree, void *));
extern void mark_primary_bases PROTO((tree));
extern void unmark_primary_bases PROTO((tree));
/* in semantics.c */
extern void finish_expr_stmt PROTO((tree));

View File

@ -75,7 +75,6 @@ pop_stack_level (stack)
#define search_level stack_level
static struct search_level *search_stack;
static tree get_abstract_virtuals_1 PROTO((tree, int, tree));
static tree next_baselink PROTO((tree));
static tree get_vbase_1 PROTO((tree, tree, unsigned int *));
static tree convert_pointer_to_vbase PROTO((tree, tree));
@ -152,6 +151,8 @@ static int friend_accessible_p PROTO ((tree, tree, tree, tree));
static void setup_class_bindings PROTO ((tree, int));
static int template_self_reference_p PROTO ((tree, tree));
static void fixup_all_virtual_upcast_offsets PROTO ((tree, tree));
static tree dfs_mark_primary_bases PROTO((tree, void *));
static tree dfs_unmark_primary_bases PROTO((tree, void *));
/* Allocate a level of searching. */
@ -2103,46 +2104,100 @@ get_matching_virtual (binfo, fndecl, dtorp)
}
}
/* Return the list of virtual functions which are abstract in type
TYPE that come from non virtual base classes. See
expand_direct_vtbls_init for the style of search we do. */
/* Called via dfs_walk from mark_nonprimary_bases. */
static tree
get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals)
dfs_mark_primary_bases (binfo, data)
tree binfo;
int do_self;
tree abstract_virtuals;
void *data ATTRIBUTE_UNUSED;
{
tree binfos = BINFO_BASETYPES (binfo);
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
{
int i;
for (i = 0; i < n_baselinks; i++)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
int is_not_base_vtable
= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
if (! TREE_VIA_VIRTUAL (base_binfo))
abstract_virtuals
= get_abstract_virtuals_1 (base_binfo, is_not_base_vtable,
abstract_virtuals);
i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
SET_BINFO_PRIMARY_MARKED_P (BINFO_BASETYPE (binfo, i));
}
/* Should we use something besides CLASSTYPE_VFIELDS? */
if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
SET_BINFO_MARKED (binfo);
return NULL_TREE;
}
/* Set BINFO_PRIMARY_MARKED_P for all binfos in the hierarchy
dominated by TYPE that are primary bases. (In addition,
BINFO_MARKED is set for all classes in the hierarchy; callers
should clear BINFO_MARKED.) */
void
mark_primary_bases (type)
tree type;
{
dfs_walk (TYPE_BINFO (type),
dfs_mark_primary_bases,
unmarkedp,
NULL);
}
/* Called from unmark_primary_bases via dfs_walk. */
static tree
dfs_unmark_primary_bases (binfo, data)
tree binfo;
void *data ATTRIBUTE_UNUSED;
{
CLEAR_BINFO_PRIMARY_MARKED_P (binfo);
return NULL_TREE;
}
/* Clear BINFO_PRIMARY_MARKED_P for all binfo in the hierarchy
dominated by TYPE. */
void
unmark_primary_bases (type)
tree type;
{
dfs_walk (TYPE_BINFO (type), dfs_unmark_primary_bases, NULL, NULL);
}
/* Called via dfs_walk from dfs_get_pure_virtuals. */
static tree
dfs_get_pure_virtuals (binfo, data)
tree binfo;
void *data;
{
/* We're not interested in primary base classes; the derived class
of which they are a primary base will contain the information we
need. */
if (!BINFO_PRIMARY_MARKED_P (binfo))
{
tree type = (tree) data;
tree shared_binfo;
tree virtuals;
/* If this is a virtual base class, then use the shared binfo
since that is the only place where BINFO_VIRTUALS is valid;
the various copies in the main hierarchy are not updated when
vtables are created. */
shared_binfo = (TREE_VIA_VIRTUAL (binfo)
? BINFO_FOR_VBASE (BINFO_TYPE (binfo), type)
: binfo);
virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL);
while (virtuals)
{
tree base_fndecl = TREE_VALUE (virtuals);
if (DECL_PURE_VIRTUAL_P (base_fndecl))
abstract_virtuals = tree_cons (NULL_TREE, base_fndecl,
abstract_virtuals);
virtuals = TREE_CHAIN (virtuals);
}
for (virtuals = skip_rtti_stuff (shared_binfo,
BINFO_TYPE (shared_binfo),
NULL);
virtuals;
virtuals = TREE_CHAIN (virtuals))
if (DECL_PURE_VIRTUAL_P (TREE_VALUE (virtuals)))
CLASSTYPE_PURE_VIRTUALS (type)
= tree_cons (NULL_TREE, TREE_VALUE (virtuals),
CLASSTYPE_PURE_VIRTUALS (type));
}
return abstract_virtuals;
CLEAR_BINFO_MARKED (binfo);
return NULL_TREE;
}
/* Set CLASSTYPE_PURE_VIRTUALS for TYPE. */
@ -2152,31 +2207,36 @@ get_pure_virtuals (type)
tree type;
{
tree vbases;
tree abstract_virtuals = NULL;
/* First get all from non-virtual bases. */
abstract_virtuals
= get_abstract_virtuals_1 (TYPE_BINFO (type), 1, abstract_virtuals);
/* Clear the CLASSTYPE_PURE_VIRTUALS list; whatever is already there
is going to be overridden. */
CLASSTYPE_PURE_VIRTUALS (type) = NULL_TREE;
/* Find all the primary bases. */
mark_primary_bases (type);
/* Now, run through all the bases which are not primary bases, and
collect the pure virtual functions. We look at the vtable in
each class to determine what pure virtual functions are present.
(A primary base is not interesting because the derived class of
which it is a primary base will contain vtable entries for the
pure virtuals in the base class. */
dfs_walk (TYPE_BINFO (type), dfs_get_pure_virtuals, markedp, type);
/* Now, clear the BINFO_PRIMARY_MARKED_P bit. */
unmark_primary_bases (type);
/* Put the pure virtuals in dfs order. */
CLASSTYPE_PURE_VIRTUALS (type) = nreverse (CLASSTYPE_PURE_VIRTUALS (type));
for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases))
{
tree virtuals;
virtuals = skip_rtti_stuff (vbases, BINFO_TYPE (vbases), NULL);
tree virtuals = skip_rtti_stuff (vbases, BINFO_TYPE (vbases), NULL);
while (virtuals)
{
tree base_fndecl = TREE_VALUE (virtuals);
if (DECL_NEEDS_FINAL_OVERRIDER_P (base_fndecl))
cp_error ("`%#D' needs a final overrider", base_fndecl);
else if (DECL_PURE_VIRTUAL_P (base_fndecl))
abstract_virtuals = tree_cons (NULL_TREE, base_fndecl,
abstract_virtuals);
virtuals = TREE_CHAIN (virtuals);
}
}
CLASSTYPE_PURE_VIRTUALS (type) = nreverse (abstract_virtuals);
}
static tree