From 8026246fa2c7841f839987fef0117b18bfd374fe Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 3 Jan 2000 06:56:21 +0000 Subject: [PATCH] cp-tree.h (CLASSTYPE_VFIELDS): Move definition. 2000-01-02 Mark Mitchell * cp-tree.h (CLASSTYPE_VFIELDS): Move definition. (BINFO_PRIMARY_MARKED_P): Use flag 5. (SET_BINFO_PRIMARY_MARKED_P): Likewise. (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise. (unmark_primary_bases): Remove declaration. (unmarkedp): Declare. (dfs_vbase_unmark): Likewise. * class.c (determine_primary_base): Return immediately if there are no base classes. Call mark_primary_bases here. (modify_all_direct_vtables): Remove. (modify_all_indirect_vtables): Remove. (dfs_modify_vtables_queue_p): New function. (dfs_modify_vtables): New function. (modify_all_vtables): Use them. (build_base_fields): Build FIELD_DECLs for primary virtual base classes. (create_vtable_ptr): Don't call determine_primary_base here. (dfs_mark_primary_bases_and_set_vbase_offsets): Rename to ... (dfs_set_offset_for_vbases): ... this. (layout_virtual_bases): Use it. (layout_class_type): Call determine_primary_base here. * search.c (unmarkedp): Make it global. (shared_marked_p): Simplify. (shared_unmarked_p): Likewise. (dfs_primary_bases_queue_p): Remove. (dfs_unmark_primary_bases): Likewise. (unmark_primary_bases): Likewise. (mark_primary_bases): Simplify. (get_pure_virtuals): Don't call mark_primary_bases here. (dfs_vbase_unmark): New function. (get_vbase_types): Simplify. From-SVN: r31175 --- gcc/cp/ChangeLog | 35 +++++++- gcc/cp/class.c | 205 +++++++++++++++++++++-------------------------- gcc/cp/cp-tree.h | 31 ++++--- gcc/cp/search.c | 112 +++++++------------------- 4 files changed, 177 insertions(+), 206 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6d5d7d32d36..6dc83940d52 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,37 @@ 2000-01-02 Mark Mitchell + * cp-tree.h (CLASSTYPE_VFIELDS): Move definition. + (BINFO_PRIMARY_MARKED_P): Use flag 5. + (SET_BINFO_PRIMARY_MARKED_P): Likewise. + (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise. + (unmark_primary_bases): Remove declaration. + (unmarkedp): Declare. + (dfs_vbase_unmark): Likewise. + * class.c (determine_primary_base): Return immediately if there + are no base classes. Call mark_primary_bases here. + (modify_all_direct_vtables): Remove. + (modify_all_indirect_vtables): Remove. + (dfs_modify_vtables_queue_p): New function. + (dfs_modify_vtables): New function. + (modify_all_vtables): Use them. + (build_base_fields): Build FIELD_DECLs for primary virtual base + classes. + (create_vtable_ptr): Don't call determine_primary_base here. + (dfs_mark_primary_bases_and_set_vbase_offsets): Rename to ... + (dfs_set_offset_for_vbases): ... this. + (layout_virtual_bases): Use it. + (layout_class_type): Call determine_primary_base here. + * search.c (unmarkedp): Make it global. + (shared_marked_p): Simplify. + (shared_unmarked_p): Likewise. + (dfs_primary_bases_queue_p): Remove. + (dfs_unmark_primary_bases): Likewise. + (unmark_primary_bases): Likewise. + (mark_primary_bases): Simplify. + (get_pure_virtuals): Don't call mark_primary_bases here. + (dfs_vbase_unmark): New function. + (get_vbase_types): Simplify. + * class.c (struct base_info): Remove. (determine_primary_base): Take has_virtual_p rather than a base_info as input. Don't calculate max_has_virtual. @@ -9,7 +41,7 @@ (layout_basetypes): Likewise. (layout_class_type): Remove max_has_virtual_p argument. (finish_struct_1): Remove max_has_virtual. - + * cp-tree.h (dfs_mark_primary_bases_queue_p): New function. (layout_basetypes): Remove. * class.c (propagate_binfo_offsets): Moved here from tree.c. @@ -145,7 +177,6 @@ (build_vtbl_initializer): Likewise. (override_one_vtable): Likewise. (check_methods): Likewise. - * decl.c (duplicate_decls): Likewise. (redeclaration_error_message): Likewise. (lang_mark_tree): Likewise. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index edb0e3d3529..0a8fbf7a620 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -102,9 +102,9 @@ static void check_for_override PROTO((tree, tree)); static tree get_class_offset_1 PROTO((tree, tree, tree, tree, tree)); static tree get_class_offset PROTO((tree, tree, tree, tree)); static void modify_one_vtable PROTO((tree, tree, tree)); +static tree dfs_modify_vtables_queue_p PROTO((tree, void *)); +static tree dfs_modify_vtables PROTO((tree, void *)); static void modify_all_vtables PROTO((tree, tree)); -static void modify_all_direct_vtables PROTO((tree, int, tree, tree)); -static void modify_all_indirect_vtables PROTO((tree, int, int, tree, tree)); static void determine_primary_base PROTO((tree, int *)); static void finish_struct_methods PROTO((tree)); static void maybe_warn_about_overly_private_class PROTO ((tree)); @@ -138,7 +138,7 @@ static void fixup_inline_methods PROTO((tree)); static void set_primary_base PROTO((tree, int, int *)); static void propagate_binfo_offsets PROTO((tree, tree)); static void layout_basetypes PROTO((tree)); -static tree dfs_mark_primary_bases_and_set_vbase_offsets PROTO((tree, void *)); +static tree dfs_set_offset_for_vbases PROTO((tree, void *)); static void layout_virtual_bases PROTO((tree)); static void remove_base_fields PROTO((tree)); @@ -1651,6 +1651,10 @@ determine_primary_base (t, has_virtual_p) { int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); + /* If there are no baseclasses, there is certainly no primary base. */ + if (n_baseclasses == 0) + return; + *has_virtual_p = 0; for (i = 0; i < n_baseclasses; i++) @@ -1666,7 +1670,9 @@ determine_primary_base (t, has_virtual_p) if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype); - /* A virtual baseclass can't be the primary base. */ + /* A virtual baseclass can't be the primary base under the + old ABI. And under the new ABI we still prefer a + non-virtual base. */ if (TREE_VIA_VIRTUAL (base_binfo)) continue; @@ -1698,6 +1704,11 @@ determine_primary_base (t, has_virtual_p) if (!TYPE_VFIELD (t)) CLASSTYPE_VFIELD_PARENT (t) = -1; + + /* Now that we know what the primary base class is, we can run + through the entire hierarchy marking the primary bases for future + reference. */ + mark_primary_bases (t); } /* Set memoizing fields and bits of T (and its variants) for later @@ -2479,29 +2490,63 @@ modify_one_vtable (binfo, t, fndecl) } } -/* These are the ones that are not through virtual base classes. */ +/* Called from modify_all_vtables via dfs_walk. */ + +static tree +dfs_modify_vtables_queue_p (binfo, data) + tree binfo; + void *data; +{ + tree list = (tree) data; + + if (TREE_VIA_VIRTUAL (binfo)) + binfo = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list)); + + return (TREE_ADDRESSABLE (list) + ? markedp (binfo, NULL) + : unmarkedp (binfo, NULL)); +} + +/* Called from modify_all_vtables via dfs_walk. */ + +static tree +dfs_modify_vtables (binfo, data) + tree binfo; + void *data; +{ + if (/* There's no need to modify the vtable for a primary base; + we're not going to use that vtable anyhow. */ + !BINFO_PRIMARY_MARKED_P (binfo) + /* Similarly, a base without a vtable needs no modification. */ + && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) + { + tree list = (tree) data; + + if (TREE_VIA_VIRTUAL (binfo)) + binfo = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list)); + modify_one_vtable (binfo, TREE_PURPOSE (list), TREE_VALUE (list)); + } + + SET_BINFO_MARKED (binfo); + + return NULL_TREE; +} static void -modify_all_direct_vtables (binfo, do_self, t, fndecl) - tree binfo; - int do_self; - tree t, fndecl; +modify_all_vtables (t, fndecl) + tree t; + tree fndecl; { - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; + tree list; - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) - modify_one_vtable (binfo, t, fndecl); - - 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)) - modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl); - } + list = build_tree_list (t, fndecl); + dfs_walk (TYPE_BINFO (t), dfs_modify_vtables, dfs_modify_vtables_queue_p, + list); + /* Let dfs_modify_vtables_queue_p know to check that the mark is + present before queueing a base, rather than checking to see that + it is *not* present. */ + TREE_ADDRESSABLE (list) = 1; + dfs_walk (TYPE_BINFO (t), dfs_unmark, dfs_modify_vtables_queue_p, list); } /* Fixup all the delta entries in this one vtable that need updating. */ @@ -2595,47 +2640,6 @@ fixup_vtable_deltas (binfo, init_self, t) fixup_vtable_deltas1 (binfo, t); } -/* These are the ones that are through virtual base classes. */ - -static void -modify_all_indirect_vtables (binfo, do_self, via_virtual, t, fndecl) - tree binfo; - int do_self, via_virtual; - tree t, fndecl; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (do_self && via_virtual && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) - modify_one_vtable (binfo, t, fndecl); - - 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)) - { - via_virtual = 1; - base_binfo = BINFO_FOR_VBASE (BINFO_TYPE (base_binfo), t); - } - modify_all_indirect_vtables (base_binfo, is_not_base_vtable, via_virtual, t, fndecl); - } -} - -static void -modify_all_vtables (t, fndecl) - tree t; - tree fndecl; -{ - /* Do these first, so that we will make use of any non-virtual class's - vtable, over a virtual classes vtable. */ - modify_all_direct_vtables (TYPE_BINFO (t), 1, t, fndecl); - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - modify_all_indirect_vtables (TYPE_BINFO (t), 1, 0, t, fndecl); -} - /* Here, we already know that they match in every respect. All we have to check is where they had their declarations. */ @@ -3765,7 +3769,11 @@ build_base_fields (rec, empty_p) location information. */ continue; - if (TREE_VIA_VIRTUAL (base_binfo)) + /* A primary virtual base class is allocated just like any other + base class, but a non-primary virtual base is allocated + later, in layout_basetypes. */ + if (TREE_VIA_VIRTUAL (base_binfo) + && i != CLASSTYPE_VFIELD_PARENT (rec)) continue; decl = build_lang_decl (FIELD_DECL, NULL_TREE, basetype); @@ -3998,12 +4006,6 @@ create_vtable_ptr (t, empty_p, has_virtual_p, { tree fn; - /* If possible, we reuse the virtual function table pointer from one - of our base classes. */ - if (CLASSTYPE_N_BASECLASSES (t)) - /* Remember where we got our vfield from. */ - determine_primary_base (t, has_virtual_p); - /* Loop over the virtual functions, adding them to our various vtables. */ for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) @@ -4270,31 +4272,21 @@ remove_base_fields (t) /* Called via dfs_walk from layout_virtual_bases. */ static tree -dfs_mark_primary_bases_and_set_vbase_offsets (binfo, data) +dfs_set_offset_for_vbases (binfo, data) tree binfo; void *data; { - if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) + /* If this is a primary virtual base that we have not encountered + before, give it an offset. */ + if (TREE_VIA_VIRTUAL (binfo) + && BINFO_PRIMARY_MARKED_P (binfo) + && !BINFO_MARKED (binfo)) { - int i; - tree base_binfo; + tree vbase; - i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - base_binfo = BINFO_BASETYPE (binfo, i); - - /* If this is a virtual base class, and we've just now - discovered it to be a primary base, then reuse this copy as - the virtual base class for the complete object. */ - if (TREE_VIA_VIRTUAL (base_binfo) - && !BINFO_PRIMARY_MARKED_P (base_binfo)) - { - tree vbase; - - vbase = BINFO_FOR_VBASE (BINFO_TYPE (base_binfo), (tree) data); - BINFO_OFFSET (vbase) = BINFO_OFFSET (base_binfo); - } - - SET_BINFO_PRIMARY_MARKED_P (BINFO_BASETYPE (binfo, i)); + vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), (tree) data); + BINFO_OFFSET (vbase) = BINFO_OFFSET (binfo); + SET_BINFO_VBASE_MARKED (binfo); } SET_BINFO_MARKED (binfo); @@ -4312,15 +4304,6 @@ layout_virtual_bases (t) tree vbase; int dsize; - /* Mark the primary base classes. Only virtual bases that are not - also primary base classes need to be laid out (since otherwise we - can just reuse one of the places in the hierarchy where the - virtual base already occurs.) */ - dfs_walk (TYPE_BINFO (t), - dfs_mark_primary_bases_and_set_vbase_offsets, - dfs_mark_primary_bases_queue_p, - t); - /* DSIZE is the size of the class without the virtual bases. */ dsize = TREE_INT_CST_LOW (TYPE_SIZE (t)); /* Make every class have alignment of at least one. */ @@ -4349,27 +4332,19 @@ layout_virtual_bases (t) take it's address and get something different for each base. */ dsize += MAX (BITS_PER_UNIT, TREE_INT_CST_LOW (CLASSTYPE_SIZE (basetype))); - - /* Now that we've laid out this virtual base class, some of - the remaining virtual bases might have been implicitly laid - out as well -- they could be primary base classes of - classes in BASETYPE. */ - dfs_walk (vbase, - dfs_mark_primary_bases_and_set_vbase_offsets, - dfs_mark_primary_bases_queue_p, - t); } - /* We're done with the various marks, now, so clear them. */ - unmark_primary_bases (t); - dfs_walk (TYPE_BINFO (t), dfs_unmark, markedp, 0); - /* Now, make sure that the total size of the type is a multiple of its alignment. */ dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t); TYPE_SIZE (t) = size_int (dsize); TYPE_SIZE_UNIT (t) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (t), size_int (BITS_PER_UNIT)); + + /* Run through the hierarchy now, setting up all the BINFO_OFFSETs + for those virtual base classes that we did not allocate above. */ + dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_vbases, unmarkedp, t); + dfs_walk (TYPE_BINFO (t), dfs_vbase_unmark, markedp, NULL); } /* Finish the work of layout_record, now taking virtual bases into account. @@ -4431,6 +4406,10 @@ layout_class_type (t, empty_p, has_virtual_p, tree *pending_virtuals_p; tree *pending_hard_virtuals_p; { + /* If possible, we reuse the virtual function table pointer from one + of our base classes. */ + determine_primary_base (t, has_virtual_p); + /* Add pointers to all of our virtual base-classes. */ TYPE_FIELDS (t) = chainon (build_vbase_pointer_fields (t, empty_p), TYPE_FIELDS (t)); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a83dc15a2c0..e5daa86505c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1,5 +1,5 @@ /* Definitions for C++ parsing and type checking. - Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1987, 92-97, 1998, 1999, 2000 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -1415,9 +1415,6 @@ struct lang_type #define BINFO_FOR_VBASE(T, C) \ (binfo_member (T, CLASSTYPE_VBASECLASSES (C))) -/* The virtual function pointer fields that this type contains. */ -#define CLASSTYPE_VFIELDS(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfields) - /* Number of direct baseclasses of NODE. */ #define CLASSTYPE_N_BASECLASSES(NODE) \ (BINFO_N_BASETYPES (TYPE_BINFO (NODE))) @@ -1563,20 +1560,35 @@ struct lang_type #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) +#define BINFO_PRIMARY_MARKED_P(NODE) \ + (TREE_VIA_VIRTUAL (NODE) \ + ? CLASSTYPE_MARKED5 (BINFO_TYPE (NODE)) \ + : TREE_LANG_FLAG_5 (NODE)) /* Mark NODE as a primary base class. */ -#define SET_BINFO_PRIMARY_MARKED_P(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE) +#define SET_BINFO_PRIMARY_MARKED_P(NODE) \ + (TREE_VIA_VIRTUAL (NODE) \ + ? SET_CLASSTYPE_MARKED5 (BINFO_TYPE (NODE)) \ + : (TREE_LANG_FLAG_5 (NODE) = 1)) /* Clear the primary base class mark. */ -#define CLEAR_BINFO_PRIMARY_MARKED_P(NODE) \ - CLEAR_BINFO_VTABLE_PATH_MARKED (NODE) +#define CLEAR_BINFO_PRIMARY_MARKED_P(NODE) \ + (TREE_VIA_VIRTUAL (NODE) \ + ? CLEAR_CLASSTYPE_MARKED5 (BINFO_TYPE (NODE)) \ + : (TREE_LANG_FLAG_5 (NODE) = 0)) /* Used by various search routines. */ #define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) /* Accessor macros for the vfield slots in structures. */ +/* The virtual function pointer fields that this type contains. For a + vfield defined just for this class, or from a primary base, the + TREE_PURPOSE is NULL. Otherwise, the TREE_PURPOSE is the BINFO for + the class containing the vfield. The TREE_VALUE is the class where + the vfield was first defined. */ +#define CLASSTYPE_VFIELDS(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfields) + /* Get the assoc info that caused this vfield to exist. */ #define VF_BINFO_VALUE(NODE) TREE_PURPOSE (NODE) @@ -3908,10 +3920,11 @@ extern tree dfs_walk PROTO((tree, tree (*) (tree, void *), void *)); extern tree dfs_unmark PROTO((tree, void *)); +extern tree dfs_vbase_unmark PROTO((tree, void *)); extern tree markedp PROTO((tree, void *)); +extern tree unmarkedp PROTO((tree, void *)); extern tree dfs_mark_primary_bases_queue_p 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 079a653130a..130f9bf232f 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1,6 +1,6 @@ /* Breadth-first and depth-first routines for searching multiple-inheritance lattice for GNU C++. - Copyright (C) 1987, 89, 92-97, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1987, 89, 92-97, 1998, 1999, 2000 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -95,7 +95,6 @@ static void expand_upcast_fixups static void fixup_virtual_upcast_offsets PROTO((tree, tree, int, int, tree, tree, tree, tree, tree *)); -static tree unmarkedp PROTO((tree, void *)); static tree marked_vtable_pathp PROTO((tree, void *)); static tree unmarked_vtable_pathp PROTO((tree, void *)); static tree marked_new_vtablep PROTO((tree, void *)); @@ -152,7 +151,6 @@ 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. */ @@ -777,7 +775,7 @@ shared_marked_p (binfo, data) void *data; { binfo = canonical_binfo (binfo); - return markedp (binfo, data) ? binfo : NULL_TREE; + return markedp (binfo, data); } /* If BINFO is not marked, return a canonical version of BINFO. @@ -789,7 +787,7 @@ shared_unmarked_p (binfo, data) void *data; { binfo = canonical_binfo (binfo); - return unmarkedp (binfo, data) ? binfo : NULL_TREE; + return unmarkedp (binfo, data); } /* Called from access_in_type via dfs_walk. Calculate the access to @@ -2124,65 +2122,15 @@ dfs_mark_primary_bases (binfo, data) return NULL_TREE; } -/* Called via dfs_walk from mark_primary_bases. */ - -tree -dfs_mark_primary_bases_queue_p (binfo, data) - tree binfo; - void *data ATTRIBUTE_UNUSED; -{ - /* Don't walk into virtual baseclasses that are not primary - bases. */ - if (TREE_VIA_VIRTUAL (binfo)) - { - tree derived_class; - tree primary_base; - - derived_class = BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)); - primary_base = CLASSTYPE_PRIMARY_BINFO (derived_class); - if (!primary_base || !same_type_p (BINFO_TYPE (primary_base), - BINFO_TYPE (binfo))) - return NULL_TREE; - } - - /* But do walk into everything else. */ - return binfo; -} - /* 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.) */ + dominated by BINFO that are primary bases. */ void mark_primary_bases (type) tree type; { - dfs_walk (TYPE_BINFO (type), - dfs_mark_primary_bases, - dfs_mark_primary_bases_queue_p, - 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); + dfs_walk (TYPE_BINFO (type), dfs_mark_primary_bases, unmarkedp, NULL); + dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, NULL); } /* Called via dfs_walk from dfs_get_pure_virtuals. */ @@ -2219,8 +2167,8 @@ dfs_get_pure_virtuals (binfo, data) = tree_cons (NULL_TREE, TREE_VALUE (virtuals), CLASSTYPE_PURE_VIRTUALS (type)); } - - CLEAR_BINFO_MARKED (binfo); + + SET_BINFO_MARKED (binfo); return NULL_TREE; } @@ -2236,17 +2184,15 @@ get_pure_virtuals (type) /* 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); + dfs_walk (TYPE_BINFO (type), dfs_get_pure_virtuals, unmarkedp, type); + dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, 0); + /* Put the pure virtuals in dfs order. */ CLASSTYPE_PURE_VIRTUALS (type) = nreverse (CLASSTYPE_PURE_VIRTUALS (type)); @@ -2317,14 +2263,15 @@ convert_pointer_to_single_level (to_type, expr) return NULL_TREE; } -tree markedp (binfo, data) +tree +markedp (binfo, data) tree binfo; void *data ATTRIBUTE_UNUSED; { return BINFO_MARKED (binfo) ? binfo : NULL_TREE; } -static tree +tree unmarkedp (binfo, data) tree binfo; void *data ATTRIBUTE_UNUSED; @@ -2415,6 +2362,17 @@ dfs_unmark (binfo, data) return NULL_TREE; } +/* Clear both BINFO_MARKED and BINFO_VBASE_MARKED. */ + +tree +dfs_vbase_unmark (binfo, data) + tree binfo; + void *data ATTRIBUTE_UNUSED; +{ + CLEAR_BINFO_VBASE_MARKED (binfo); + return dfs_unmark (binfo, data); +} + #if 0 static void dfs_mark_vtable_path (binfo) tree binfo; @@ -2973,23 +2931,13 @@ void get_vbase_types (type) tree type; { - tree vbase_types; - tree vbases; - tree binfo; - - binfo = TYPE_BINFO (type); - vbase_types = NULL_TREE; - dfs_walk (binfo, dfs_get_vbase_types, unmarkedp, &vbase_types); - dfs_walk (binfo, dfs_unmark, markedp, 0); + CLASSTYPE_VBASECLASSES (type) = NULL_TREE; + dfs_walk (TYPE_BINFO (type), dfs_get_vbase_types, unmarkedp, + &CLASSTYPE_VBASECLASSES (type)); /* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now reverse it so that we get normal dfs ordering. */ - vbase_types = nreverse (vbase_types); - - /* unmark marked vbases */ - for (vbases = vbase_types; vbases; vbases = TREE_CHAIN (vbases)) - CLEAR_BINFO_VBASE_MARKED (vbases); - - CLASSTYPE_VBASECLASSES (type) = vbase_types; + CLASSTYPE_VBASECLASSES (type) = nreverse (CLASSTYPE_VBASECLASSES (type)); + dfs_walk (TYPE_BINFO (type), dfs_vbase_unmark, markedp, 0); } /* Debug info for C++ classes can get very large; try to avoid