From: Nathan Sidwell Date: Mon, 28 Jun 2004 10:34:42 +0000 (+0000) Subject: Use vector API for vbase list. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=58c42dc28354d5857a5d905d505127eb5624111f;p=gcc.git Use vector API for vbase list. * cp-tree.h: Include vec.h (DEF_VEC_P (tree)): New type. (struct lang_type_class): Change vbase's member type. (binfo_for_vbase): Declare. * class.c (determine_primary_base, base_derived_from, update_vtable_entry_for_fn, walk_subobject_offsets, end_of_class, warn_about_ambiguous_bases, dfs_accumulate_vtbl_inits, build_vtbl_initializer): Adjust. * decl.c (xref_basetypes): Adjust, accumulate upper bound of vbases. * init.c (sort_mem_initializers, expand_member_init, push_base_cleanups): Adjust. * method.c (do_build_copy_constructor): Adjust. * search.c (get_pure_virtuals, copied_binfo, original_binfo): Adjust. (binfo_for_vbase): New. * tree.c (copy_base_binfos): Adjust. From-SVN: r83770 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 756bc919d02..14527cadeb6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2004-06-28 Nathan Sidwell + + Use vector API for vbase list. + * cp-tree.h: Include vec.h + (DEF_VEC_P (tree)): New type. + (struct lang_type_class): Change vbase's member type. + (binfo_for_vbase): Declare. + * class.c (determine_primary_base, base_derived_from, + update_vtable_entry_for_fn, walk_subobject_offsets, end_of_class, + warn_about_ambiguous_bases, dfs_accumulate_vtbl_inits, + build_vtbl_initializer): Adjust. + * decl.c (xref_basetypes): Adjust, accumulate upper bound of + vbases. + * init.c (sort_mem_initializers, expand_member_init, + push_base_cleanups): Adjust. + * method.c (do_build_copy_constructor): Adjust. + * search.c (get_pure_virtuals, copied_binfo, original_binfo): Adjust. + (binfo_for_vbase): New. + * tree.c (copy_base_binfos): Adjust. + 2004-06-28 Mark Mitchell * parser.c (cp_parser_set_decl_spec_type): Fix thinko. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index c2d654123f5..8f188c494b9 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1344,9 +1344,9 @@ set_primary_base (tree t, tree binfo) static void determine_primary_base (tree t) { - int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); - tree vbases; + unsigned i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); tree type_binfo; + tree vbase_binfo; /* If there are no baseclasses, there is certainly no primary base. */ if (n_baseclasses == 0) @@ -1394,29 +1394,26 @@ determine_primary_base (tree t) /* Find the indirect primary bases - those virtual bases which are primary bases of something else in this hierarchy. */ - for (vbases = CLASSTYPE_VBASECLASSES (t); - vbases; - vbases = TREE_CHAIN (vbases)) + for (i = 0; (vbase_binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (t), i)); i++) { - tree vbase_binfo = TREE_VALUE (vbases); + unsigned j; - /* See if this virtual base is an indirect primary base. To be so, - it must be a primary base within the hierarchy of one of our - direct bases. */ - for (i = 0; i < n_baseclasses; ++i) + /* See if this virtual base is an indirect primary base. To be + so, it must be a primary base within the hierarchy of one of + our direct bases. */ + for (j = 0; j != n_baseclasses; ++j) { - tree basetype = TYPE_BINFO_BASETYPE (t, i); - tree v; - - for (v = CLASSTYPE_VBASECLASSES (basetype); - v; - v = TREE_CHAIN (v)) + unsigned k; + tree base_vbase_binfo; + tree basetype = TYPE_BINFO_BASETYPE (t, j); + + for (k = 0; (base_vbase_binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (basetype), k)); k++) { - tree base_vbase = TREE_VALUE (v); - - if (BINFO_PRIMARY_P (base_vbase) - && same_type_p (BINFO_TYPE (base_vbase), - BINFO_TYPE (vbase_binfo))) + if (BINFO_PRIMARY_P (base_vbase_binfo) + && same_type_p (BINFO_TYPE (base_vbase_binfo), + BINFO_TYPE (vbase_binfo))) { BINFO_INDIRECT_PRIMARY_P (vbase_binfo) = 1; break; @@ -1923,9 +1920,8 @@ base_derived_from (tree derived, tree base) /* If we meet a virtual base, we can't follow the inheritance any more. See if the complete type of DERIVED contains such a virtual base. */ - return purpose_member (BINFO_TYPE (probe), - CLASSTYPE_VBASECLASSES (BINFO_TYPE (derived))) - != NULL_TREE; + return (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (derived)) + != NULL_TREE); } return false; } @@ -2169,10 +2165,8 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals, /* Find the equivalent binfo within the return type of the overriding function. We will want the vbase offset from there. */ - virtual_offset = - TREE_VALUE (purpose_member - (BINFO_TYPE (virtual_offset), - CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return)))); + virtual_offset = binfo_for_vbase (BINFO_TYPE (virtual_offset), + TREE_TYPE (over_return)); else if (!same_type_p (TREE_TYPE (over_return), TREE_TYPE (base_return))) { @@ -3314,9 +3308,9 @@ walk_subobject_offsets (tree type, return r; } - if (abi_version_at_least (2)) + if (abi_version_at_least (2) && CLASSTYPE_VBASECLASSES (type)) { - tree vbase; + unsigned ix; /* Iterate through the virtual base classes of TYPE. In G++ 3.2, we included virtual bases in the direct base class @@ -3324,11 +3318,9 @@ walk_subobject_offsets (tree type, correct offsets for virtual bases are only known when working with the most derived type. */ if (vbases_p) - for (vbase = CLASSTYPE_VBASECLASSES (type); - vbase; - vbase = TREE_CHAIN (vbase)) + for (ix = 0; (binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (type), ix)); ix++) { - binfo = TREE_VALUE (vbase); r = walk_subobject_offsets (binfo, f, size_binop (PLUS_EXPR, @@ -3345,7 +3337,8 @@ walk_subobject_offsets (tree type, /* We still have to walk the primary base, if it is virtual. (If it is non-virtual, then it was walked above.) */ - vbase = get_primary_binfo (type_binfo); + tree vbase = get_primary_binfo (type_binfo); + if (vbase && TREE_VIA_VIRTUAL (vbase) && BINFO_PRIMARY_BASE_OF (vbase) == type_binfo) { @@ -4525,11 +4518,10 @@ end_of_class (tree t, int include_virtuals_p) /* G++ 3.2 did not check indirect virtual bases. */ if (abi_version_at_least (2) && include_virtuals_p) - for (binfo = CLASSTYPE_VBASECLASSES (t); - binfo; - binfo = TREE_CHAIN (binfo)) + for (i = 0; (binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (t), i)); i++) { - offset = end_of_base (TREE_VALUE (binfo)); + offset = end_of_base (binfo); if (INT_CST_LT_UNSIGNED (result, offset)) result = offset; } @@ -4551,8 +4543,8 @@ static void warn_about_ambiguous_bases (tree t) { int i; - tree vbases; tree basetype; + tree binfo; /* Check direct bases. */ for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i) @@ -4566,11 +4558,10 @@ warn_about_ambiguous_bases (tree t) /* Check for ambiguous virtual bases. */ if (extra_warnings) - for (vbases = CLASSTYPE_VBASECLASSES (t); - vbases; - vbases = TREE_CHAIN (vbases)) + for (i = 0; (binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (t), i)); i++) { - basetype = BINFO_TYPE (TREE_VALUE (vbases)); + basetype = BINFO_TYPE (binfo); if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL)) warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", @@ -7272,8 +7263,7 @@ dfs_accumulate_vtbl_inits (tree binfo, either case, we share our vtable with LAST, i.e. the derived-most base within B of which we are a primary. */ if (b == rtti_binfo - || (b && purpose_member (BINFO_TYPE (b), - CLASSTYPE_VBASECLASSES (BINFO_TYPE (rtti_binfo))))) + || (b && binfo_for_vbase (BINFO_TYPE (b), BINFO_TYPE (rtti_binfo)))) /* Just set our BINFO_VTABLE to point to LAST, as we may not have set LAST's BINFO_VTABLE yet. We'll extract the actual vptr in binfo_ctor_vtable after everything's been set up. */ @@ -7351,8 +7341,9 @@ build_vtbl_initializer (tree binfo, { tree v, b; tree vfun_inits; - tree vbase; vtbl_init_data vid; + unsigned ix; + tree vbinfo; /* Initialize VID. */ memset (&vid, 0, sizeof (vid)); @@ -7375,12 +7366,12 @@ build_vtbl_initializer (tree binfo, VARRAY_TREE_INIT (vid.fns, 32, "fns"); /* Add the vcall and vbase offset entries. */ build_vcall_and_vbase_vtbl_entries (binfo, &vid); + /* Clear BINFO_VTABLE_PATH_MARKED; it's set by build_vbase_offset_vtbl_entries. */ - for (vbase = CLASSTYPE_VBASECLASSES (t); - vbase; - vbase = TREE_CHAIN (vbase)) - BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase)) = 0; + for (ix = 0; (vbinfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (t), ix)); ix++) + BINFO_VTABLE_PATH_MARKED (vbinfo) = 0; /* If the target requires padding between data entries, add that now. */ if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 54bb0e3bb20..c2a943e9066 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -27,8 +27,8 @@ Boston, MA 02111-1307, USA. */ #include "function.h" #include "hashtab.h" #include "splay-tree.h" +#include "vec.h" #include "varray.h" - #include "c-common.h" #include "name-lookup.h" @@ -1017,6 +1017,8 @@ struct lang_type_header GTY(()) BOOL_BITFIELD has_const_assign_ref : 1; }; +DEF_VEC_P (tree); + /* This structure provides additional information above and beyond what is provide in the ordinary tree_type. In the past, we used it for the types of class types, template parameters types, typename @@ -1087,7 +1089,7 @@ struct lang_type_class GTY(()) tree vcall_indices; tree vtables; tree typeinfo_var; - tree vbases; + VEC (tree) *vbases; binding_table nested_udts; tree as_base; tree pure_virtuals; @@ -1305,7 +1307,7 @@ struct lang_type GTY(()) #define CLASSTYPE_PRIMARY_BINFO(NODE) \ (LANG_TYPE_CLASS_CHECK (NODE)->primary_base) -/* A chain of BINFOs for the direct and indirect virtual base classes +/* A vector of BINFOs for the direct and indirect virtual base classes that this type uses in a post-order depth-first left-to-right order. (In other words, these bases appear in the order that they should be initialized.) */ @@ -4121,6 +4123,7 @@ extern tree context_for_name_lookup (tree); extern tree lookup_conversions (tree); extern tree binfo_for_vtable (tree); extern tree binfo_from_vbase (tree); +extern tree binfo_for_vbase (tree, tree); extern tree look_for_overrides_here (tree, tree); extern int check_final_overrider (tree, tree); extern tree dfs_walk (tree, diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 838f22bd55a..11616c02dfc 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9044,7 +9044,7 @@ xref_basetypes (tree ref, tree base_list) /* In the declaration `A : X, Y, ... Z' we mark all the types (A, X, Y, ..., Z) so we can check for duplicates. */ tree *basep; - + unsigned max_vbases = 0; int i; enum tag_types tag_code; @@ -9093,6 +9093,8 @@ xref_basetypes (tree ref, tree base_list) tree basetype = TREE_VALUE (base_list); tree base_binfo; + if (via_virtual) + max_vbases++; if (access == access_default_node) /* The base of a derived struct is public by default. */ access = (tag_code == class_type @@ -9169,6 +9171,8 @@ xref_basetypes (tree ref, tree base_list) base as well. */ TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) |= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype); + max_vbases += VEC_length + (tree, CLASSTYPE_VBASECLASSES (basetype)); } i++; } @@ -9176,6 +9180,8 @@ xref_basetypes (tree ref, tree base_list) TREE_VEC_LENGTH (accesses) = TREE_VEC_LENGTH (binfos) = i; else BINFO_BASEACCESSES (binfo) = BINFO_BASETYPES (binfo) = NULL_TREE; + if (max_vbases) + CLASSTYPE_VBASECLASSES (ref) = VEC_alloc (tree, max_vbases); if (i > 1) { @@ -9189,7 +9195,6 @@ xref_basetypes (tree ref, tree base_list) /* Copy the base binfos, collect the virtual bases and set the inheritance order chain. */ copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE); - CLASSTYPE_VBASECLASSES (ref) = nreverse (CLASSTYPE_VBASECLASSES (ref)); if (TYPE_FOR_JAVA (ref)) { diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 425a853186d..c96e14d8070 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -468,9 +468,12 @@ sort_mem_initializers (tree t, tree mem_inits) TREE_VALUE will be the constructor arguments, or NULL if no explicit initialization was provided. */ sorted_inits = NULL_TREE; + /* Process the virtual bases. */ - for (base = CLASSTYPE_VBASECLASSES (t); base; base = TREE_CHAIN (base)) - sorted_inits = tree_cons (TREE_VALUE (base), NULL_TREE, sorted_inits); + for (i = 0; (base = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (t), i)); i++) + sorted_inits = tree_cons (base, NULL_TREE, sorted_inits); + /* Process the direct bases. */ for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i) { @@ -988,13 +991,7 @@ expand_member_init (tree name) /* Look for a virtual base -- unless the direct base is itself virtual. */ if (!direct_binfo || !TREE_VIA_VIRTUAL (direct_binfo)) - { - virtual_binfo - = purpose_member (basetype, - CLASSTYPE_VBASECLASSES (current_class_type)); - if (virtual_binfo) - virtual_binfo = TREE_VALUE (virtual_binfo); - } + virtual_binfo = binfo_for_vbase (basetype, current_class_type); /* [class.base.init] @@ -2874,27 +2871,23 @@ push_base_cleanups (void) /* Run destructors for all virtual baseclasses. */ if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) { - tree vbases; tree cond = (condition_conversion (build (BIT_AND_EXPR, integer_type_node, current_in_charge_parm, integer_two_node))); - vbases = CLASSTYPE_VBASECLASSES (current_class_type); - /* The CLASSTYPE_VBASECLASSES list is in initialization + /* The CLASSTYPE_VBASECLASSES vector is in initialization order, which is also the right order for pushing cleanups. */ - for (; vbases; - vbases = TREE_CHAIN (vbases)) + for (i = 0; (binfos = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (current_class_type), i)); + i++) { - tree vbase = TREE_VALUE (vbases); - tree base_type = BINFO_TYPE (vbase); - - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (base_type)) + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (binfos))) { expr = build_special_member_call (current_class_ref, base_dtor_identifier, NULL_TREE, - vbase, + binfos, (LOOKUP_NORMAL | LOOKUP_NONVIRTUAL)); expr = build (COND_EXPR, void_type_node, cond, @@ -2948,17 +2941,19 @@ push_base_cleanups (void) tree build_vbase_delete (tree type, tree decl) { - tree vbases = CLASSTYPE_VBASECLASSES (type); + unsigned ix; + tree binfo; tree result; tree addr = build_unary_op (ADDR_EXPR, decl, 0); my_friendly_assert (addr != error_mark_node, 222); - for (result = convert_to_void (integer_zero_node, NULL); - vbases; vbases = TREE_CHAIN (vbases)) + result = convert_to_void (integer_zero_node, NULL); + for (ix = 0; (binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (type), ix)); ix++) { tree base_addr = convert_force - (build_pointer_type (BINFO_TYPE (TREE_VALUE (vbases))), addr, 0); + (build_pointer_type (BINFO_TYPE (binfo)), addr, 0); tree base_delete = build_delete (TREE_TYPE (base_addr), base_addr, sfk_base_destructor, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index adda8da26bc..774f8c0dff1 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -523,17 +523,17 @@ do_build_copy_constructor (tree fndecl) tree member_init_list = NULL_TREE; int cvquals = cp_type_quals (TREE_TYPE (parm)); int i; + tree binfo; /* Initialize all the base-classes with the parameter converted to their type so that we get their copy constructor and not another constructor that takes current_class_type. We must deal with the binfo's directly as a direct base might be inaccessible due to ambiguity. */ - for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; - t = TREE_CHAIN (t)) + for (i = 0; (binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (current_class_type), i)); + i++) { - tree binfo = TREE_VALUE (t); - member_init_list = tree_cons (binfo, build_tree_list (NULL_TREE, diff --git a/gcc/cp/search.c b/gcc/cp/search.c index ca86b13dedb..4bf87a3a73d 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1921,7 +1921,8 @@ dfs_get_pure_virtuals (tree binfo, void *data) void get_pure_virtuals (tree type) { - tree vbases; + unsigned ix; + tree binfo; /* Clear the CLASSTYPE_PURE_VIRTUALS list; whatever is already there is going to be overridden. */ @@ -1938,14 +1939,12 @@ get_pure_virtuals (tree 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)) + for (ix = 0; (binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (type), ix)); ix++) { tree virtuals; - - for (virtuals = BINFO_VIRTUALS (TREE_VALUE (vbases)); - virtuals; + + for (virtuals = BINFO_VIRTUALS (binfo); virtuals; virtuals = TREE_CHAIN (virtuals)) { tree base_fndecl = BV_FN (virtuals); @@ -2532,10 +2531,8 @@ copied_binfo (tree binfo, tree here) for (t = here; BINFO_INHERITANCE_CHAIN (t); t = BINFO_INHERITANCE_CHAIN (t)) continue; - - result = purpose_member (BINFO_TYPE (binfo), - CLASSTYPE_VBASECLASSES (BINFO_TYPE (t))); - result = TREE_VALUE (result); + + result = binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (t)); } else if (BINFO_INHERITANCE_CHAIN (binfo)) { @@ -2566,6 +2563,19 @@ copied_binfo (tree binfo, tree here) return result; } +tree +binfo_for_vbase (tree base, tree t) +{ + unsigned ix; + tree binfo; + + for (ix = 0; (binfo = VEC_iterate + (tree, CLASSTYPE_VBASECLASSES (t), ix)); ix++) + if (BINFO_TYPE (binfo) == base) + return binfo; + return NULL; +} + /* BINFO is some base binfo of HERE, within some other hierarchy. Return the equivalent binfo, but in the hierarchy dominated by HERE. This is the inverse of copied_binfo. If BINFO @@ -2579,12 +2589,9 @@ original_binfo (tree binfo, tree here) if (BINFO_TYPE (binfo) == BINFO_TYPE (here)) result = here; else if (TREE_VIA_VIRTUAL (binfo)) - { - result = purpose_member (BINFO_TYPE (binfo), - CLASSTYPE_VBASECLASSES (BINFO_TYPE (here))); - if (result) - result = TREE_VALUE (result); - } + result = (CLASSTYPE_VBASECLASSES (BINFO_TYPE (here)) + ? binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (here)) + : NULL_TREE); else if (BINFO_INHERITANCE_CHAIN (binfo)) { tree base_binfos; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 4ae07798dee..8ef808ce3b1 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -571,8 +571,8 @@ canonical_type_variant (tree t) derived TYPE. PREV is the previous binfo, whose TREE_CHAIN we make point to this binfo. We return the last BINFO created. - The CLASSTYPE_VBASECLASSES list of T is constructed in reverse - order (pre-order, depth-first, right-to-left). You must nreverse it. + The CLASSTYPE_VBASECLASSES vector of T is constructed in the correct + order. The BINFO_INHERITANCE of a virtual base class points to the binfo og the most derived type. @@ -613,12 +613,7 @@ copy_base_binfos (tree binfo, tree t, tree prev) BINFO_DEPENDENT_BASE_P (new_binfo) = 1; } else if (TREE_VIA_VIRTUAL (base_binfo)) - { - new_binfo = purpose_member (BINFO_TYPE (base_binfo), - CLASSTYPE_VBASECLASSES (t)); - if (new_binfo) - new_binfo = TREE_VALUE (new_binfo); - } + new_binfo = binfo_for_vbase (BINFO_TYPE (base_binfo), t); if (!new_binfo) { @@ -628,9 +623,7 @@ copy_base_binfos (tree binfo, tree t, tree prev) prev = copy_base_binfos (new_binfo, t, prev); if (TREE_VIA_VIRTUAL (base_binfo)) { - CLASSTYPE_VBASECLASSES (t) - = tree_cons (BINFO_TYPE (new_binfo), new_binfo, - CLASSTYPE_VBASECLASSES (t)); + VEC_quick_push (tree, CLASSTYPE_VBASECLASSES (t), new_binfo); TREE_VIA_VIRTUAL (new_binfo) = 1; BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t); }