+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ 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 <mark@codesourcery.com>
* parser.c (cp_parser_set_decl_spec_type): Fix thinko.
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)
/* 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;
/* 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;
}
/* 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)))
{
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
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,
/* 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)
{
/* 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;
}
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)
/* 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",
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. */
{
tree v, b;
tree vfun_inits;
- tree vbase;
vtbl_init_data vid;
+ unsigned ix;
+ tree vbinfo;
/* Initialize VID. */
memset (&vid, 0, sizeof (vid));
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)
#include "function.h"
#include "hashtab.h"
#include "splay-tree.h"
+#include "vec.h"
#include "varray.h"
-
#include "c-common.h"
#include "name-lookup.h"
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
tree vcall_indices;
tree vtables;
tree typeinfo_var;
- tree vbases;
+ VEC (tree) *vbases;
binding_table nested_udts;
tree as_base;
tree pure_virtuals;
#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.) */
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,
/* 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;
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
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++;
}
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)
{
/* 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))
{
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)
{
/* 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]
/* 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,
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);
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,
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. */
/* 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);
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))
{
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
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;
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.
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)
{
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);
}