From: Mark Mitchell Date: Sun, 2 Jan 2000 04:34:22 +0000 (+0000) Subject: cp-tree.h (CLASSTYPE_N_BASECLASSES): Use BINFO_N_BASETYPES. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=99a6c6f4080775d4495b2c1a298232fe0bcfae9f;p=gcc.git 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 --- diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 24ff231c605..db9a5e4a361 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index d6269e378e4..c22391db6a3 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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; - - for (i = 0; i < n_baselinks; i++) + if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) { - 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); + int i; + + 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); + + 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)); + } + + CLEAR_BINFO_MARKED (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); - } - } - return abstract_virtuals; + 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