static void check_for_override (tree, tree);
static tree dfs_modify_vtables (tree, void *);
static tree modify_all_vtables (tree, tree);
-static void determine_primary_base (tree);
+static void determine_primary_bases (tree);
static void finish_struct_methods (tree);
static void maybe_warn_about_overly_private_class (tree);
static int method_name_cmp (const void *, const void *);
static void layout_class_type (tree, tree *);
static void fixup_pending_inline (tree);
static void fixup_inline_methods (tree);
-static void set_primary_base (tree, tree);
static void propagate_binfo_offsets (tree, tree);
static void layout_virtual_bases (record_layout_info, splay_tree);
static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
static void build_vcall_and_vbase_vtbl_entries (tree,
vtbl_init_data *);
-static void mark_primary_bases (tree);
static void clone_constructors_and_destructors (tree);
static tree build_clone (tree, tree);
static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
if (want_pointer)
probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
- my_friendly_assert (code == MINUS_EXPR
- ? same_type_p (BINFO_TYPE (binfo), probe)
- : code == PLUS_EXPR
- ? same_type_p (BINFO_TYPE (d_binfo), probe)
- : false, 20010723);
+ gcc_assert (code == MINUS_EXPR
+ ? same_type_p (BINFO_TYPE (binfo), probe)
+ : code == PLUS_EXPR
+ ? same_type_p (BINFO_TYPE (d_binfo), probe)
+ : false);
if (binfo == d_binfo)
/* Nothing to do. */
expr = build_indirect_ref (expr, NULL);
expr = build_simple_base_path (expr, binfo);
if (want_pointer)
- expr = build_unary_op (ADDR_EXPR, expr, 0);
+ expr = build_address (expr);
target_type = TREE_TYPE (expr);
goto out;
}
t = TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived)));
t = build_pointer_type (t);
v_offset = convert (t, current_vtt_parm);
- v_offset = build (PLUS_EXPR, t, v_offset,
- BINFO_VPTR_INDEX (derived));
+ v_offset = build2 (PLUS_EXPR, t, v_offset,
+ BINFO_VPTR_INDEX (derived));
v_offset = build_indirect_ref (v_offset, NULL);
}
else
v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
TREE_TYPE (TREE_TYPE (expr)));
- v_offset = build (PLUS_EXPR, TREE_TYPE (v_offset),
- v_offset, BINFO_VPTR_FIELD (v_binfo));
+ v_offset = build2 (PLUS_EXPR, TREE_TYPE (v_offset),
+ v_offset, BINFO_VPTR_FIELD (v_binfo));
v_offset = build1 (NOP_EXPR,
build_pointer_type (ptrdiff_type_node),
v_offset);
BINFO_OFFSET (v_binfo)));
if (!integer_zerop (offset))
- v_offset = build (code, ptrdiff_type_node, v_offset, offset);
+ v_offset = build2 (code, ptrdiff_type_node, v_offset, offset);
if (fixed_type_p < 0)
/* Negative fixed_type_p means this is a constructor or destructor;
virtual base layout is fixed in in-charge [cd]tors, but not in
base [cd]tors. */
- offset = build (COND_EXPR, ptrdiff_type_node,
- build (EQ_EXPR, boolean_type_node,
- current_in_charge_parm, integer_zero_node),
- v_offset,
- BINFO_OFFSET (binfo));
+ offset = build3 (COND_EXPR, ptrdiff_type_node,
+ build2 (EQ_EXPR, boolean_type_node,
+ current_in_charge_parm, integer_zero_node),
+ v_offset,
+ BINFO_OFFSET (binfo));
else
offset = v_offset;
}
expr = build1 (NOP_EXPR, ptr_target_type, expr);
if (!integer_zerop (offset))
- expr = build (code, ptr_target_type, expr, offset);
+ expr = build2 (code, ptr_target_type, expr, offset);
else
null_test = NULL;
build_simple_base_path (tree expr, tree binfo)
{
tree type = BINFO_TYPE (binfo);
- tree d_binfo;
+ tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
tree field;
- /* For primary virtual bases, we can't just follow
- BINFO_INHERITANCE_CHAIN. */
- d_binfo = BINFO_PRIMARY_BASE_OF (binfo);
- if (d_binfo == NULL_TREE)
- d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
-
if (d_binfo == NULL_TREE)
{
- if (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) != type)
- abort ();
+ gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type);
return expr;
}
field; field = TREE_CHAIN (field))
/* Is this the base field created by build_base_field? */
if (TREE_CODE (field) == FIELD_DECL
- && TREE_TYPE (field) == type
- && DECL_ARTIFICIAL (field)
- && DECL_IGNORED_P (field))
+ && DECL_FIELD_IS_BASE (field)
+ && TREE_TYPE (field) == type)
return build_class_member_access_expr (expr, field,
NULL_TREE, false);
/* Didn't find the base field?!? */
- abort ();
+ gcc_unreachable ();
}
/* Convert OBJECT to the base TYPE. If CHECK_ACCESS is true, an error
pointer_type = build_pointer_type (expr_type);
expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1);
if (!integer_zerop (BINFO_OFFSET (base)))
- expr = build (PLUS_EXPR, pointer_type, expr,
- build_nop (pointer_type, BINFO_OFFSET (base)));
+ expr = build2 (PLUS_EXPR, pointer_type, expr,
+ build_nop (pointer_type, BINFO_OFFSET (base)));
expr = build_nop (build_pointer_type (BINFO_TYPE (base)), expr);
expr = build1 (INDIRECT_REF, BINFO_TYPE (base), expr);
}
build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1));
/* Remember this as a method reference, for later devirtualization. */
- aref = build (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);
+ aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);
return aref;
}
return mangle_vtt_for_type (type);
}
+/* DECL is an entity associated with TYPE, like a virtual table or an
+ implicitly generated constructor. Determine whether or not DECL
+ should have external or internal linkage at the object file
+ level. This routine does not deal with COMDAT linkage and other
+ similar complexities; it simply sets TREE_PUBLIC if it possible for
+ entities in other translation units to contain copies of DECL, in
+ the abstract. */
+
+void
+set_linkage_according_to_type (tree type, tree decl)
+{
+ /* If TYPE involves a local class in a function with internal
+ linkage, then DECL should have internal linkage too. Other local
+ classes have no linkage -- but if their containing functions
+ have external linkage, it makes sense for DECL to have external
+ linkage too. That will allow template definitions to be merged,
+ for example. */
+ if (no_linkage_check (type, /*relaxed_p=*/true))
+ {
+ TREE_PUBLIC (decl) = 0;
+ DECL_INTERFACE_KNOWN (decl) = 1;
+ }
+ else
+ TREE_PUBLIC (decl) = 1;
+}
+
/* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE.
(For a secondary vtable for B-in-D, CLASS_TYPE should be D, not B.)
Use NAME for the name of the vtable, and VTABLE_TYPE for its type. */
DECL_VIRTUAL_P (decl) = 1;
DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
DECL_VTABLE_OR_VTT_P (decl) = 1;
-
/* At one time the vtable info was grabbed 2 words at a time. This
fails on sparc unless you have 8-byte alignment. (tiemann) */
DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
DECL_ALIGN (decl));
-
- import_export_vtable (decl, class_type, 0);
+ set_linkage_according_to_type (class_type, decl);
+ /* The vtable has not been defined -- yet. */
+ DECL_EXTERNAL (decl) = 1;
+ DECL_NOT_REALLY_EXTERN (decl) = 1;
+
+ if (write_symbols == DWARF2_DEBUG)
+ /* Mark the VAR_DECL node representing the vtable itself as a
+ "gratuitous" one, thereby forcing dwarfout.c to ignore it. It
+ is rather important that such things be ignored because any
+ effort to actually generate DWARF for them will run into
+ trouble when/if we encounter code like:
+
+ #pragma interface
+ struct S { virtual void member (); };
+
+ because the artificial declaration of the vtable itself (as
+ manufactured by the g++ front end) will say that the vtable is
+ a static member of `S' but only *after* the debug output for
+ the definition of `S' has already been output. This causes
+ grief because the DWARF entry for the definition of the vtable
+ will try to refer back to an earlier *declaration* of the
+ vtable as a static member of `S' and there won't be one. We
+ might be able to arrange to have the "vtable static member"
+ attached to the member list for `S' before the debug info for
+ `S' get written (which would solve the problem) but that would
+ require more intrusive changes to the g++ front end. */
+ DECL_IGNORED_P (decl) = 1;
return decl;
}
}
else
{
- my_friendly_assert (TREE_TYPE (decl) == vtbl_type_node, 20000118);
+ gcc_assert (TREE_TYPE (decl) == vtbl_type_node);
virtuals = NULL_TREE;
}
add_method (tree type, tree method)
{
int using;
- size_t len;
- size_t slot;
+ unsigned slot;
tree overload;
int template_conv_p;
VEC(tree) *method_vec;
bool complete_p;
+ bool insert_p = false;
+ tree current_fns;
if (method == error_mark_node)
return;
CLASSTYPE_METHOD_VEC (type) = method_vec;
}
- len = VEC_length (tree, method_vec);
-
/* Constructors and destructors go in special slots. */
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
slot = CLASSTYPE_CONSTRUCTOR_SLOT;
}
else
{
- bool insert_p = true;
bool conv_p = DECL_CONV_FN_P (method);
tree m;
+ insert_p = true;
/* See if we already have an entry with this name. */
for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
- (m = VEC_iterate (tree, method_vec, slot));
+ VEC_iterate (tree, method_vec, slot, m);
++slot)
{
m = OVL_CURRENT (m);
&& DECL_NAME (m) > DECL_NAME (method))
break;
}
-
- /* If we need a new slot, make room. */
- if (insert_p)
- {
- /* We expect to add few methods in the COMPLETE_P case, so
- just make room for one more method. */
- if (complete_p)
- VEC_reserve (tree, method_vec, 1);
- if (slot == len)
- VEC_safe_push (tree, method_vec, NULL_TREE);
- else
- VEC_safe_insert (tree, method_vec, slot, NULL_TREE);
- len++;
- /* Inserting a new slot may have caused the vector to be
- reallocated. */
- CLASSTYPE_METHOD_VEC (type) = method_vec;
- }
}
-
+ current_fns = insert_p ? NULL_TREE : VEC_index (tree, method_vec, slot);
+
if (processing_template_decl)
/* TYPE is a template class. Don't issue any errors now; wait
until instantiation time to complain. */
tree fns;
/* Check to see if we've already got this method. */
- for (fns = VEC_index (tree, method_vec, slot);
- fns;
- fns = OVL_NEXT (fns))
+ for (fns = current_fns; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
tree parms1;
}
/* Add the new binding. */
- overload = build_overload (method, VEC_index (tree, method_vec, slot));
- if (!DECL_CONSTRUCTOR_P (method)
- && !DECL_DESTRUCTOR_P (method)
- && !complete_p)
+ overload = build_overload (method, current_fns);
+
+ if (slot >= CLASSTYPE_FIRST_CONVERSION_SLOT && !complete_p)
push_class_level_binding (DECL_NAME (method), overload);
- /* Actually insert the new method. */
- VEC_replace (tree, method_vec, slot, overload);
+ if (insert_p)
+ {
+ /* We only expect to add few methods in the COMPLETE_P case, so
+ just make room for one more method in that case. */
+ if (VEC_reserve (tree, method_vec, complete_p ? 1 : -1))
+ CLASSTYPE_METHOD_VEC (type) = method_vec;
+ if (slot == VEC_length (tree, method_vec))
+ VEC_quick_push (tree, method_vec, overload);
+ else
+ VEC_quick_insert (tree, method_vec, slot, overload);
+ }
+ else
+ /* Replace the current slot. */
+ VEC_replace (tree, method_vec, slot, overload);
}
/* Subroutines of finish_struct. */
if (!DECL_LANG_SPECIFIC (fdecl))
retrofit_lang_decl (fdecl);
- my_friendly_assert (!DECL_DISCRIMINATOR_P (fdecl), 20030624);
+ gcc_assert (!DECL_DISCRIMINATOR_P (fdecl));
elem = purpose_member (t, DECL_ACCESS (fdecl));
if (elem)
int* cant_have_const_ctor_p,
int* no_const_asn_ref_p)
{
- int n_baseclasses;
int i;
int seen_non_virtual_nearly_empty_base_p;
- tree binfos;
+ tree base_binfo;
+ tree binfo;
- binfos = BINFO_BASE_BINFOS (TYPE_BINFO (t));
- n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
seen_non_virtual_nearly_empty_base_p = 0;
- for (i = 0; i < n_baseclasses; ++i)
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
{
- tree base_binfo;
- tree basetype;
-
- /* Figure out what base we're looking at. */
- base_binfo = TREE_VEC_ELT (binfos, i);
- basetype = TREE_TYPE (base_binfo);
+ tree basetype = TREE_TYPE (base_binfo);
- my_friendly_assert (COMPLETE_TYPE_P (basetype), 20040714);
+ gcc_assert (COMPLETE_TYPE_P (basetype));
/* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P
here because the case of virtual functions but non-virtual
}
}
-/* Set BINFO_PRIMARY_BASE_OF for all binfos in the hierarchy
- dominated by TYPE that are primary bases. */
+/* Determine all the primary bases within T. Sets BINFO_PRIMARY_BASE_P for
+ those that are primaries. Sets BINFO_LOST_PRIMARY_P for those
+ that have had a nearly-empty virtual primary base stolen by some
+ other base in the heirarchy. Determines CLASSTYPE_PRIMARY_BASE for
+ T. */
static void
-mark_primary_bases (tree type)
+determine_primary_bases (tree t)
{
- tree binfo;
-
- /* Walk the bases in inheritance graph order. */
- for (binfo = TYPE_BINFO (type); binfo; binfo = TREE_CHAIN (binfo))
+ unsigned i;
+ tree primary = NULL_TREE;
+ tree type_binfo = TYPE_BINFO (t);
+ tree base_binfo;
+
+ /* Determine the primary bases of our bases. */
+ for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
+ base_binfo = TREE_CHAIN (base_binfo))
{
- tree base_binfo = get_primary_binfo (binfo);
+ tree primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (base_binfo));
- if (!base_binfo)
- /* Not a dynamic base. */;
- else if (BINFO_PRIMARY_P (base_binfo))
- BINFO_LOST_PRIMARY_P (binfo) = 1;
- else
+ /* See if we're the non-virtual primary of our inheritance
+ chain. */
+ if (!BINFO_VIRTUAL_P (base_binfo))
{
- BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
- /* A virtual binfo might have been copied from within
- another hierarchy. As we're about to use it as a primary
- base, make sure the offsets match. */
- if (BINFO_VIRTUAL_P (base_binfo))
- {
- tree delta = size_diffop (convert (ssizetype,
- BINFO_OFFSET (binfo)),
- convert (ssizetype,
- BINFO_OFFSET (base_binfo)));
+ tree parent = BINFO_INHERITANCE_CHAIN (base_binfo);
+ tree parent_primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (parent));
- propagate_binfo_offsets (base_binfo, delta);
- }
+ if (parent_primary
+ && BINFO_TYPE (base_binfo) == BINFO_TYPE (parent_primary))
+ /* We are the primary binfo. */
+ BINFO_PRIMARY_P (base_binfo) = 1;
}
- }
-}
-
-/* Make the BINFO the primary base of T. */
-
-static void
-set_primary_base (tree t, tree binfo)
-{
- tree basetype;
-
- CLASSTYPE_PRIMARY_BINFO (t) = binfo;
- basetype = BINFO_TYPE (binfo);
- BINFO_VTABLE (TYPE_BINFO (t)) = BINFO_VTABLE (TYPE_BINFO (basetype));
- BINFO_VIRTUALS (TYPE_BINFO (t)) = BINFO_VIRTUALS (TYPE_BINFO (basetype));
- TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
-}
-
-/* Determine the primary class for T. */
-
-static void
-determine_primary_base (tree t)
-{
- unsigned i, n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
- tree type_binfo;
- tree vbase_binfo;
-
- /* If there are no baseclasses, there is certainly no primary base. */
- if (n_baseclasses == 0)
- return;
-
- type_binfo = TYPE_BINFO (t);
-
- for (i = 0; i < n_baseclasses; i++)
- {
- tree base_binfo = BINFO_BASE_BINFO (type_binfo, i);
- tree basetype = BINFO_TYPE (base_binfo);
-
- if (TYPE_CONTAINS_VPTR_P (basetype))
+ /* Determine if we have a virtual primary base, and mark it so.
+ */
+ if (primary && BINFO_VIRTUAL_P (primary))
{
- /* We prefer a non-virtual base, although a virtual one will
- do. */
- if (BINFO_VIRTUAL_P (base_binfo))
- continue;
+ tree this_primary = copied_binfo (primary, base_binfo);
- if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
- {
- set_primary_base (t, base_binfo);
- CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
- }
+ if (BINFO_PRIMARY_P (this_primary))
+ /* Someone already claimed this base. */
+ BINFO_LOST_PRIMARY_P (base_binfo) = 1;
else
{
- tree vfields;
-
- /* Only add unique vfields, and flatten them out as we go. */
- for (vfields = CLASSTYPE_VFIELDS (basetype);
- vfields;
- vfields = TREE_CHAIN (vfields))
- if (VF_BINFO_VALUE (vfields) == NULL_TREE
- || ! BINFO_VIRTUAL_P (VF_BINFO_VALUE (vfields)))
- CLASSTYPE_VFIELDS (t)
- = tree_cons (base_binfo,
- VF_BASETYPE_VALUE (vfields),
- CLASSTYPE_VFIELDS (t));
+ tree delta;
+
+ BINFO_PRIMARY_P (this_primary) = 1;
+ BINFO_INHERITANCE_CHAIN (this_primary) = base_binfo;
+
+ /* A virtual binfo might have been copied from within
+ another hierarchy. As we're about to use it as a
+ primary base, make sure the offsets match. */
+ delta = size_diffop (convert (ssizetype,
+ BINFO_OFFSET (base_binfo)),
+ convert (ssizetype,
+ BINFO_OFFSET (this_primary)));
+
+ propagate_binfo_offsets (this_primary, delta);
}
}
}
- if (!TYPE_VFIELD (t))
- CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
-
- /* Find the indirect primary bases - those virtual bases which are primary
- bases of something else in this hierarchy. */
- for (i = 0; (vbase_binfo = VEC_iterate
- (tree, CLASSTYPE_VBASECLASSES (t), i)); i++)
+ /* First look for a dynamic direct non-virtual base. */
+ for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, base_binfo); i++)
{
- unsigned j;
+ tree basetype = BINFO_TYPE (base_binfo);
- /* 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)
+ if (TYPE_CONTAINS_VPTR_P (basetype) && !BINFO_VIRTUAL_P (base_binfo))
{
- unsigned k;
- tree base_vbase_binfo;
- tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), j));
-
- for (k = 0; (base_vbase_binfo = VEC_iterate
- (tree, CLASSTYPE_VBASECLASSES (basetype), k)); k++)
- {
- 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've discovered that this virtual base is an indirect
- primary base, then we can move on to the next virtual
- base. */
- if (BINFO_INDIRECT_PRIMARY_P (vbase_binfo))
- break;
+ primary = base_binfo;
+ goto found;
}
}
/* A "nearly-empty" virtual base class can be the primary base
- class, if no non-virtual polymorphic base can be found. */
- if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
+ class, if no non-virtual polymorphic base can be found. Look for
+ a nearly-empty virtual dynamic base that is not already a primary
+ base of something in the heirarchy. If there is no such base,
+ just pick the first nearly-empty virtual base. */
+
+ for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
+ base_binfo = TREE_CHAIN (base_binfo))
+ if (BINFO_VIRTUAL_P (base_binfo)
+ && CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (base_binfo)))
+ {
+ if (!BINFO_PRIMARY_P (base_binfo))
+ {
+ /* Found one that is not primary. */
+ primary = base_binfo;
+ goto found;
+ }
+ else if (!primary)
+ /* Remember the first candidate. */
+ primary = base_binfo;
+ }
+
+ found:
+ /* If we've got a primary base, use it. */
+ if (primary)
{
- /* If not NULL, this is the best primary base candidate we have
- found so far. */
- tree candidate = NULL_TREE;
- tree base_binfo;
-
- /* Loop over the baseclasses. */
- for (base_binfo = TYPE_BINFO (t);
- base_binfo;
- base_binfo = TREE_CHAIN (base_binfo))
+ tree basetype = BINFO_TYPE (primary);
+
+ CLASSTYPE_PRIMARY_BINFO (t) = primary;
+ if (BINFO_PRIMARY_P (primary))
+ /* We are stealing a primary base. */
+ BINFO_LOST_PRIMARY_P (BINFO_INHERITANCE_CHAIN (primary)) = 1;
+ BINFO_PRIMARY_P (primary) = 1;
+ if (BINFO_VIRTUAL_P (primary))
{
- tree basetype = BINFO_TYPE (base_binfo);
+ tree delta;
- if (BINFO_VIRTUAL_P (base_binfo)
- && CLASSTYPE_NEARLY_EMPTY_P (basetype))
- {
- /* If this is not an indirect primary base, then it's
- definitely our primary base. */
- if (!BINFO_INDIRECT_PRIMARY_P (base_binfo))
- {
- candidate = base_binfo;
- break;
- }
-
- /* If this is an indirect primary base, it still could be
- our primary base -- unless we later find there's another
- nearly-empty virtual base that isn't an indirect
- primary base. */
- if (!candidate)
- candidate = base_binfo;
- }
+ BINFO_INHERITANCE_CHAIN (primary) = type_binfo;
+ /* A virtual binfo might have been copied from within
+ another hierarchy. As we're about to use it as a primary
+ base, make sure the offsets match. */
+ delta = size_diffop (ssize_int (0),
+ convert (ssizetype, BINFO_OFFSET (primary)));
+
+ propagate_binfo_offsets (primary, delta);
}
-
- /* If we've got a primary base, use it. */
- if (candidate)
- {
- set_primary_base (t, candidate);
- CLASSTYPE_VFIELDS (t)
- = copy_list (CLASSTYPE_VFIELDS (BINFO_TYPE (candidate)));
- }
+
+ primary = TYPE_BINFO (basetype);
+
+ TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
+ BINFO_VTABLE (type_binfo) = BINFO_VTABLE (primary);
+ BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary);
}
-
- /* Mark the primary base classes at this point. */
- mark_primary_bases (t);
}
\f
/* Set memoizing fields and bits of T (and its variants) for later
static void
finish_struct_bits (tree t)
{
- int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
-
+ tree variants;
+
/* Fix up variants (if any). */
- tree variants = TYPE_NEXT_VARIANT (t);
- while (variants)
+ for (variants = TYPE_NEXT_VARIANT (t);
+ variants;
+ variants = TYPE_NEXT_VARIANT (variants))
{
/* These fields are in the _TYPE part of the node, not in
the TYPE_LANG_SPECIFIC component, so they are not shared. */
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (variants)
= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t);
TYPE_POLYMORPHIC_P (variants) = TYPE_POLYMORPHIC_P (t);
- TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t);
+ TYPE_USES_VIRTUAL_BASECLASSES (variants)
+ = TYPE_USES_VIRTUAL_BASECLASSES (t);
TYPE_BINFO (variants) = TYPE_BINFO (t);
TYPE_FIELDS (variants) = TYPE_FIELDS (t);
TYPE_SIZE (variants) = TYPE_SIZE (t);
TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
-
- variants = TYPE_NEXT_VARIANT (variants);
}
- if (n_baseclasses && TYPE_POLYMORPHIC_P (t))
+ if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
/* For a class w/o baseclasses, `finish_struct' has set
CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition).
Similarly for a class whose base classes do not have vtables.
constructors/destructors we want to use the code below that
issues error messages specifically referring to
constructors/destructors.) */
- int i;
+ unsigned i;
tree binfo = TYPE_BINFO (t);
- for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++)
+ for (i = 0; i != BINFO_N_BASE_BINFOS (binfo); i++)
if (BINFO_BASE_ACCESS (binfo, i) != access_private_node)
{
has_nonprivate_method = 1;
/* The type conversion ops have to live at the front of the vec, so we
can't sort them. */
for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
- (fn = VEC_iterate (tree, method_vec, slot));
+ VEC_iterate (tree, method_vec, slot, fn);
++slot)
if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
break;
VEC(tree) *method_vec;
int slot, len;
- if (!TYPE_METHODS (t))
- {
- /* Clear these for safety; perhaps some parsing error could set
- these incorrectly. */
- TYPE_HAS_CONSTRUCTOR (t) = 0;
- TYPE_HAS_DESTRUCTOR (t) = 0;
- CLASSTYPE_METHOD_VEC (t) = NULL;
- return;
- }
-
method_vec = CLASSTYPE_METHOD_VEC (t);
- my_friendly_assert (method_vec, 19991215);
+ if (!method_vec)
+ return;
+
len = VEC_length (tree, method_vec);
/* First fill in entry 0 with the constructors, entry 1 with destructors,
/* The type conversion ops have to live at the front of the vec, so we
can't sort them. */
- for (slot = 2;
- (fn_fields = VEC_iterate (tree, method_vec, slot));
+ for (slot = CLASSTYPE_FIRST_CONVERSION_SLOT;
+ VEC_iterate (tree, method_vec, slot, fn_fields);
++slot)
if (!DECL_CONV_FN_P (OVL_CURRENT (fn_fields)))
break;
return false;
}
+typedef struct count_depth_data {
+ /* The depth of the current subobject, with "1" as the depth of the
+ most derived object in the hierarchy. */
+ size_t depth;
+ /* The maximum depth found so far. */
+ size_t max_depth;
+} count_depth_data;
+
+/* Called from find_final_overrider via dfs_walk. */
+
+static tree
+dfs_depth_post (tree binfo ATTRIBUTE_UNUSED, void *data)
+{
+ count_depth_data *cd = (count_depth_data *) data;
+ if (cd->depth > cd->max_depth)
+ cd->max_depth = cd->depth;
+ cd->depth--;
+ return NULL_TREE;
+}
+
+/* Called from find_final_overrider via dfs_walk. */
+
+static tree
+dfs_depth_q (tree derived, int i, void *data)
+{
+ count_depth_data *cd = (count_depth_data *) data;
+ cd->depth++;
+ return BINFO_BASE_BINFO (derived, i);
+}
+
typedef struct find_final_overrider_data_s {
/* The function for which we are trying to find a final overrider. */
tree fn;
tree most_derived_type;
/* The candidate overriders. */
tree candidates;
- /* Binfos which inherited virtually on the current path. */
- tree vpath;
+ /* Each entry in this array is the next-most-derived class for a
+ virtual base class along the current path. */
+ tree *vpath_list;
+ /* A pointer one past the top of the VPATH_LIST. */
+ tree *vpath;
} find_final_overrider_data;
-/* Called from find_final_overrider via dfs_walk. */
+/* Add the overrider along the current path to FFOD->CANDIDATES.
+ Returns true if an overrider was found; false otherwise. */
-static tree
-dfs_find_final_overrider (tree binfo, void* data)
+static bool
+dfs_find_final_overrider_1 (tree binfo,
+ tree *vpath,
+ find_final_overrider_data *ffod)
{
- find_final_overrider_data *ffod = (find_final_overrider_data *) data;
+ tree method;
- if (binfo == ffod->declaring_base)
+ /* If BINFO is not the most derived type, try a more derived class.
+ A definition there will overrider a definition here. */
+ if (!same_type_p (BINFO_TYPE (binfo), ffod->most_derived_type))
{
- /* We've found a path to the declaring base. Walk the path from
- derived to base, looking for an overrider for FN. */
- tree path, probe, vpath;
+ tree derived;
+
+ if (BINFO_VIRTUAL_P (binfo))
+ derived = *--vpath;
+ else
+ derived = BINFO_INHERITANCE_CHAIN (binfo);
+ if (dfs_find_final_overrider_1 (derived, vpath, ffod))
+ return true;
+ }
- /* Build the path, using the inheritance chain and record of
- virtual inheritance. */
- for (path = NULL_TREE, probe = binfo, vpath = ffod->vpath;;)
+ method = look_for_overrides_here (BINFO_TYPE (binfo), ffod->fn);
+ if (method)
+ {
+ tree *candidate = &ffod->candidates;
+
+ /* Remove any candidates overridden by this new function. */
+ while (*candidate)
{
- path = tree_cons (NULL_TREE, probe, path);
- if (same_type_p (BINFO_TYPE (probe), ffod->most_derived_type))
- break;
- if (BINFO_VIRTUAL_P (probe))
- {
- probe = TREE_VALUE (vpath);
- vpath = TREE_CHAIN (vpath);
- }
+ /* If *CANDIDATE overrides METHOD, then METHOD
+ cannot override anything else on the list. */
+ if (base_derived_from (TREE_VALUE (*candidate), binfo))
+ return true;
+ /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
+ if (base_derived_from (binfo, TREE_VALUE (*candidate)))
+ *candidate = TREE_CHAIN (*candidate);
else
- probe = BINFO_INHERITANCE_CHAIN (probe);
- }
- /* Now walk path, looking for overrides. */
- for (; path; path = TREE_CHAIN (path))
- {
- tree method = look_for_overrides_here
- (BINFO_TYPE (TREE_VALUE (path)), ffod->fn);
-
- if (method)
- {
- tree *candidate = &ffod->candidates;
- path = TREE_VALUE (path);
-
- /* Remove any candidates overridden by this new function. */
- while (*candidate)
- {
- /* If *CANDIDATE overrides METHOD, then METHOD
- cannot override anything else on the list. */
- if (base_derived_from (TREE_VALUE (*candidate), path))
- return NULL_TREE;
- /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
- if (base_derived_from (path, TREE_VALUE (*candidate)))
- *candidate = TREE_CHAIN (*candidate);
- else
- candidate = &TREE_CHAIN (*candidate);
- }
-
- /* Add the new function. */
- ffod->candidates = tree_cons (method, path, ffod->candidates);
- break;
- }
+ candidate = &TREE_CHAIN (*candidate);
}
+
+ /* Add the new function. */
+ ffod->candidates = tree_cons (method, binfo, ffod->candidates);
+ return true;
}
+ return false;
+}
+
+/* Called from find_final_overrider via dfs_walk. */
+
+static tree
+dfs_find_final_overrider (tree binfo, void* data)
+{
+ find_final_overrider_data *ffod = (find_final_overrider_data *) data;
+
+ if (binfo == ffod->declaring_base)
+ dfs_find_final_overrider_1 (binfo, ffod->vpath, ffod);
+
return NULL_TREE;
}
find_final_overrider_data *ffod = (find_final_overrider_data *) data;
if (BINFO_VIRTUAL_P (binfo))
- ffod->vpath = tree_cons (NULL_TREE, derived, ffod->vpath);
+ *ffod->vpath++ = derived;
return binfo;
}
{
find_final_overrider_data *ffod = (find_final_overrider_data *) data;
- if (BINFO_VIRTUAL_P (binfo) && TREE_CHAIN (ffod->vpath))
- ffod->vpath = TREE_CHAIN (ffod->vpath);
+ if (BINFO_VIRTUAL_P (binfo))
+ ffod->vpath--;
return NULL_TREE;
}
find_final_overrider (tree derived, tree binfo, tree fn)
{
find_final_overrider_data ffod;
+ count_depth_data cd;
/* Getting this right is a little tricky. This is valid:
different overriders along any two, then there is a problem. */
if (DECL_THUNK_P (fn))
fn = THUNK_TARGET (fn);
-
+
+ /* Determine the depth of the hierarchy. */
+ cd.depth = 0;
+ cd.max_depth = 0;
+ dfs_walk (derived, dfs_depth_post, dfs_depth_q, &cd);
+
ffod.fn = fn;
ffod.declaring_base = binfo;
ffod.most_derived_type = BINFO_TYPE (derived);
ffod.candidates = NULL_TREE;
- ffod.vpath = NULL_TREE;
+ ffod.vpath_list = (tree *) xcalloc (cd.max_depth, sizeof (tree));
+ ffod.vpath = ffod.vpath_list;
dfs_walk_real (derived,
dfs_find_final_overrider,
dfs_find_final_overrider_q,
&ffod);
+ free (ffod.vpath_list);
+
/* If there was no winner, issue an error message. */
if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
{
static tree
get_vcall_index (tree fn, tree type)
{
- tree v;
+ VEC (tree_pair_s) *indices = CLASSTYPE_VCALL_INDICES (type);
+ tree_pair_p p;
+ unsigned ix;
- for (v = CLASSTYPE_VCALL_INDICES (type); v; v = TREE_CHAIN (v))
- if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (TREE_PURPOSE (v)))
- || same_signature_p (fn, TREE_PURPOSE (v)))
- break;
+ for (ix = 0; VEC_iterate (tree_pair_s, indices, ix, p); ix++)
+ if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (p->purpose))
+ || same_signature_p (fn, p->purpose))
+ return p->value;
/* There should always be an appropriate index. */
- my_friendly_assert (v, 20021103);
-
- return TREE_VALUE (v);
+ gcc_unreachable ();
}
/* Update an entry in the vtable for BINFO, which is in the hierarchy
calling FN through BINFO. */
for (b = binfo; ; b = get_primary_binfo (b))
{
- my_friendly_assert (b, 20021227);
+ gcc_assert (b);
if (look_for_overrides_here (BINFO_TYPE (b), target_fn))
break;
if (DECL_THUNK_P (fn))
{
- my_friendly_assert (DECL_RESULT_THUNK_P (fn), 20031211);
+ gcc_assert (DECL_RESULT_THUNK_P (fn));
fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn));
virtual_offset = THUNK_VIRTUAL_OFFSET (fn);
}
fixed_offset, virtual_offset);
}
else
- my_friendly_assert (!DECL_THUNK_P (fn), 20021231);
+ gcc_assert (!DECL_THUNK_P (fn));
/* Assume that we will produce a thunk that convert all the way to
the final overrider, and not to an intermediate virtual base. */
static tree
dfs_modify_vtables (tree binfo, void* data)
{
+ tree t = (tree) data;
+
if (/* There's no need to modify the vtable for a non-virtual
primary base; we're not going to use that vtable anyhow.
We do still need to do this for virtual primary bases, as they
could become non-primary in a construction vtable. */
(!BINFO_PRIMARY_P (binfo) || BINFO_VIRTUAL_P (binfo))
/* Similarly, a base without a vtable needs no modification. */
- && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
+ && TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo))
+ /* Don't do the primary vtable, if it's new. */
+ && (BINFO_TYPE (binfo) != t || CLASSTYPE_HAS_PRIMARY_BASE_P (t)))
{
- tree t = (tree) data;
tree virtuals;
tree old_virtuals;
unsigned ix;
/* We go through each separately named virtual function. */
for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
- (fns = VEC_iterate (tree, method_vec, i));
+ VEC_iterate (tree, method_vec, i, fns);
++i)
{
tree fn;
tree name;
tree fndecl;
tree base_fndecls;
+ tree base_binfo;
+ tree binfo;
int j;
/* All functions in this slot in the CLASSTYPE_METHOD_VEC will
base_fndecls = NULL_TREE;
/* Iterate through all of the base classes looking for possibly
hidden functions. */
- for (j = 0; j < BINFO_N_BASE_BINFOS (TYPE_BINFO (t)); j++)
+ for (binfo = TYPE_BINFO (t), j = 0;
+ BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
{
- tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), j));
+ tree basetype = BINFO_TYPE (base_binfo);
base_fndecls = chainon (get_basefndecls (name, basetype),
base_fndecls);
}
/* Default constructor. */
if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor)
{
- default_fn = implicitly_declare_fn (sfk_constructor, t, /*const_p=*/0);
- TREE_CHAIN (default_fn) = implicit_fns;
- implicit_fns = default_fn;
+ TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
+ CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
}
/* Copy constructor. */
if (! TYPE_HAS_INIT_REF (t) && ! TYPE_FOR_JAVA (t))
{
- /* ARM 12.18: You get either X(X&) or X(const X&), but
- not both. --Chip */
- default_fn
- = implicitly_declare_fn (sfk_copy_constructor, t,
- /*const_p=*/!cant_have_const_cctor);
- TREE_CHAIN (default_fn) = implicit_fns;
- implicit_fns = default_fn;
+ TYPE_HAS_INIT_REF (t) = 1;
+ TYPE_HAS_CONST_INIT_REF (t) = !cant_have_const_cctor;
+ CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
+ TYPE_HAS_CONSTRUCTOR (t) = 1;
}
/* If there is no assignment operator, one will be created if and
of the parameter to the assignment operator will be a const or
non-const reference. */
if (!TYPE_HAS_ASSIGN_REF (t) && !TYPE_FOR_JAVA (t))
- TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment;
+ {
+ TYPE_HAS_ASSIGN_REF (t) = 1;
+ TYPE_HAS_CONST_ASSIGN_REF (t) = !cant_have_const_assignment;
+ CLASSTYPE_LAZY_ASSIGNMENT_OP (t) = 1;
+ }
/* Now, hook all of the new functions on to TYPE_METHODS,
and add them to the CLASSTYPE_METHOD_VEC. */
/* Iterate through the direct base classes of TYPE. */
if (!type_binfo)
type_binfo = TYPE_BINFO (type);
- for (i = 0; i < BINFO_N_BASE_BINFOS (type_binfo); ++i)
+ for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, binfo); i++)
{
tree binfo_offset;
- binfo = BINFO_BASE_BINFO (type_binfo, i);
-
if (abi_version_at_least (2)
&& BINFO_VIRTUAL_P (binfo))
continue;
if (abi_version_at_least (2) && CLASSTYPE_VBASECLASSES (type))
{
unsigned ix;
+ VEC (tree) *vbases;
/* 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 (ix = 0; (binfo = VEC_iterate
- (tree, CLASSTYPE_VBASECLASSES (type), ix)); ix++)
+ for (vbases = CLASSTYPE_VBASECLASSES (type), ix = 0;
+ VEC_iterate (tree, vbases, ix, binfo); ix++)
{
r = walk_subobject_offsets (binfo,
f,
tree vbase = get_primary_binfo (type_binfo);
if (vbase && BINFO_VIRTUAL_P (vbase)
- && BINFO_PRIMARY_BASE_OF (vbase) == type_binfo)
+ && BINFO_PRIMARY_P (vbase)
+ && BINFO_INHERITANCE_CHAIN (vbase) == type_binfo)
{
r = (walk_subobject_offsets
(vbase, f, offset,
bool atend = false;
/* This routine should only be used for empty classes. */
- my_friendly_assert (is_empty_class (basetype), 20000321);
+ gcc_assert (is_empty_class (basetype));
alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype));
if (!integer_zerop (BINFO_OFFSET (binfo)))
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
DECL_IGNORED_P (decl) = 1;
+ DECL_FIELD_IS_BASE (decl) = 1;
/* Try to place the field. It may take more than one try if we
have a hard time placing the field without putting two
check_for_override (x, t);
if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
cp_error_at ("initializer specified for non-virtual method `%D'", x);
-
/* The name of the field is the original field name
Save this in auxiliary field for later overloading. */
if (DECL_VINDEX (x))
/* Create the RTL for this function. */
SET_DECL_RTL (clone, NULL_RTX);
- rest_of_decl_compilation (clone, NULL, /*top_level=*/1, at_eof);
+ rest_of_decl_compilation (clone, /*top_level=*/1, at_eof);
/* Make it easy to find the CLONE given the FN. */
TREE_CHAIN (clone) = TREE_CHAIN (fn);
}
else
{
- my_friendly_assert (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn), 20000411);
+ gcc_assert (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
/* For each destructor, we need three variants: an in-charge
version, a not-in-charge version, and an in-charge deleting
decl_parms = TREE_CHAIN (decl_parms),
clone_parms = TREE_CHAIN (clone_parms))
{
- my_friendly_assert (same_type_p (TREE_TYPE (decl_parms),
- TREE_TYPE (clone_parms)), 20010424);
+ gcc_assert (same_type_p (TREE_TYPE (decl_parms),
+ TREE_TYPE (clone_parms)));
if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms))
{
break;
}
}
- my_friendly_assert (!clone_parms, 20010424);
+ gcc_assert (!clone_parms);
}
}
tree fns;
bool has_two_argument_delete_p = false;
- my_friendly_assert (CLASS_TYPE_P (type), 20010712);
+ gcc_assert (CLASS_TYPE_P (type));
/* If there's a non-trivial destructor, we need a cookie. In order
to iterate through the array calling the destructor for each
{
int i;
tree primary_binfo;
+ tree base_binfo;
/* Update BINFO's offset. */
BINFO_OFFSET (binfo)
/* Find the primary base class. */
primary_binfo = get_primary_binfo (binfo);
+ if (primary_binfo && BINFO_INHERITANCE_CHAIN (primary_binfo) == binfo)
+ propagate_binfo_offsets (primary_binfo, offset);
+
/* Scan all of the bases, pushing the BINFO_OFFSET adjust
downwards. */
- for (i = -1; i < BINFO_N_BASE_BINFOS (binfo); ++i)
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
{
- tree base_binfo;
-
- /* On the first time through the loop, do the primary base.
- Because the primary base need not be an immediate base, we
- must handle the primary base specially. */
- if (i == -1)
- {
- if (!primary_binfo)
- continue;
-
- base_binfo = primary_binfo;
- }
- else
- {
- base_binfo = BINFO_BASE_BINFO (binfo, i);
- /* Don't do the primary base twice. */
- if (base_binfo == primary_binfo)
- continue;
- }
+ /* Don't do the primary base twice. */
+ if (base_binfo == primary_binfo)
+ continue;
- /* Skip virtual bases that aren't our canonical primary base. */
- if (BINFO_VIRTUAL_P (base_binfo)
- && BINFO_PRIMARY_BASE_OF (base_binfo) != binfo)
+ if (BINFO_VIRTUAL_P (base_binfo))
continue;
propagate_binfo_offsets (base_binfo, offset);
end_of_class (tree t, int include_virtuals_p)
{
tree result = size_zero_node;
+ VEC (tree) *vbases;
tree binfo;
+ tree base_binfo;
tree offset;
int i;
- for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (t)); ++i)
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
{
- binfo = BINFO_BASE_BINFO (TYPE_BINFO (t), i);
-
if (!include_virtuals_p
- && BINFO_VIRTUAL_P (binfo)
- && BINFO_PRIMARY_BASE_OF (binfo) != TYPE_BINFO (t))
+ && BINFO_VIRTUAL_P (base_binfo)
+ && (!BINFO_PRIMARY_P (base_binfo)
+ || BINFO_INHERITANCE_CHAIN (base_binfo) != TYPE_BINFO (t)))
continue;
- offset = end_of_base (binfo);
+ offset = end_of_base (base_binfo);
if (INT_CST_LT_UNSIGNED (result, offset))
result = offset;
}
/* G++ 3.2 did not check indirect virtual bases. */
if (abi_version_at_least (2) && include_virtuals_p)
- for (i = 0; (binfo = VEC_iterate
- (tree, CLASSTYPE_VBASECLASSES (t), i)); i++)
+ for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
+ VEC_iterate (tree, vbases, i, base_binfo); i++)
{
- offset = end_of_base (binfo);
+ offset = end_of_base (base_binfo);
if (INT_CST_LT_UNSIGNED (result, offset))
result = offset;
}
warn_about_ambiguous_bases (tree t)
{
int i;
+ VEC (tree) *vbases;
tree basetype;
tree binfo;
+ tree base_binfo;
/* Check direct bases. */
- for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (t)); ++i)
+ for (binfo = TYPE_BINFO (t), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
{
- basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), i));
+ basetype = BINFO_TYPE (base_binfo);
if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
/* Check for ambiguous virtual bases. */
if (extra_warnings)
- for (i = 0; (binfo = VEC_iterate
- (tree, CLASSTYPE_VBASECLASSES (t), i)); i++)
+ for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
+ VEC_iterate (tree, vbases, i, binfo); i++)
{
basetype = BINFO_TYPE (binfo);
rli->bitpos = round_down (rli->bitpos, BITS_PER_UNIT);
else
/* The size should have been rounded to a whole byte. */
- my_friendly_assert (tree_int_cst_equal (rli->bitpos,
- round_down (rli->bitpos,
- BITS_PER_UNIT)),
- 20030903);
+ gcc_assert (tree_int_cst_equal
+ (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT)));
rli->bitpos
= size_binop (PLUS_EXPR,
rli->bitpos,
/* Start laying out the record. */
rli = start_record_layout (t);
- /* If possible, we reuse the virtual function table pointer from one
- of our base classes. */
- determine_primary_base (t);
+ /* Mark all the primary bases in the hierarchy. */
+ determine_primary_bases (t);
/* Create a pointer to our virtual function table. */
vptr = create_vtable_ptr (t, virtuals_p);
if (COMPLETE_TYPE_P (t))
{
- if (IS_AGGR_TYPE (t))
- error ("redefinition of `%#T'", t);
- else
- abort ();
+ gcc_assert (IS_AGGR_TYPE (t));
+ error ("redefinition of `%#T'", t);
popclass ();
return;
}
{
tree primary = CLASSTYPE_PRIMARY_BINFO (t);
- my_friendly_assert (same_type_p (DECL_FIELD_CONTEXT (vfield),
- BINFO_TYPE (primary)),
- 20010726);
+ gcc_assert (same_type_p (DECL_FIELD_CONTEXT (vfield),
+ BINFO_TYPE (primary)));
/* The vtable better be at the start. */
- my_friendly_assert (integer_zerop (DECL_FIELD_OFFSET (vfield)),
- 20010726);
- my_friendly_assert (integer_zerop (BINFO_OFFSET (primary)),
- 20010726);
+ gcc_assert (integer_zerop (DECL_FIELD_OFFSET (vfield)));
+ gcc_assert (integer_zerop (BINFO_OFFSET (primary)));
vfield = copy_decl (vfield);
DECL_FIELD_CONTEXT (vfield) = t;
TYPE_VFIELD (t) = vfield;
}
else
- my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726);
+ gcc_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t);
virtuals = modify_all_vtables (t, nreverse (virtuals));
- /* If we created a new vtbl pointer for this class, add it to the
- list. */
- if (TYPE_VFIELD (t) && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
- CLASSTYPE_VFIELDS (t)
- = chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
-
/* If necessary, create the primary vtable for this class. */
if (virtuals || TYPE_CONTAINS_VPTR_P (t))
{
tree fn;
if (BINFO_VTABLE (TYPE_BINFO (t)))
- my_friendly_assert (DECL_VIRTUAL_P (BINFO_VTABLE (TYPE_BINFO (t))),
- 20000116);
+ gcc_assert (DECL_VIRTUAL_P (BINFO_VTABLE (TYPE_BINFO (t))));
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
- my_friendly_assert (BINFO_VIRTUALS (TYPE_BINFO (t)) == NULL_TREE,
- 20000116);
+ gcc_assert (BINFO_VIRTUALS (TYPE_BINFO (t)) == NULL_TREE);
/* Add entries for virtual functions introduced by this class. */
BINFO_VIRTUALS (TYPE_BINFO (t))
thunk base function. */
DECL_VINDEX (fndecl) = NULL_TREE;
else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
- DECL_VINDEX (fndecl) = build_shared_int_cst (vindex);
+ DECL_VINDEX (fndecl) = build_int_cst (NULL_TREE, vindex);
}
}
n_fields = count_fields (TYPE_FIELDS (t));
if (n_fields > 7)
{
- struct sorted_fields_type *field_vec = ggc_alloc (sizeof (struct sorted_fields_type)
- + n_fields * sizeof (tree));
+ struct sorted_fields_type *field_vec = GGC_NEWVAR
+ (struct sorted_fields_type,
+ sizeof (struct sorted_fields_type) + n_fields * sizeof (tree));
field_vec->len = n_fields;
add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
qsort (field_vec->elts, n_fields, sizeof (tree),
DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
}
- if (TYPE_HAS_CONSTRUCTOR (t))
- {
- tree vfields = CLASSTYPE_VFIELDS (t);
-
- for (vfields = CLASSTYPE_VFIELDS (t);
- vfields; vfields = TREE_CHAIN (vfields))
- /* Mark the fact that constructor for T could affect anybody
- inheriting from T who wants to initialize vtables for
- VFIELDS's type. */
- if (VF_BINFO_VALUE (vfields))
- TREE_ADDRESSABLE (vfields) = 1;
- }
-
/* Make the rtl for any new vtables we have created, and unmark
the base types we marked. */
finish_vtbls (t);
return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
case ADDR_EXPR:
+ instance = TREE_OPERAND (instance, 0);
if (nonnull)
- *nonnull = 1;
- return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
+ {
+ /* Just because we see an ADDR_EXPR doesn't mean we're dealing
+ with a real object -- given &p->f, p can still be null. */
+ tree t = get_base_address (instance);
+ /* ??? Probably should check DECL_WEAK here. */
+ if (t && DECL_P (t))
+ *nonnull = 1;
+ }
+ return fixed_type_or_null (instance, nonnull, cdtorp);
case COMPONENT_REF:
+ /* If this component is really a base class reference, then the field
+ itself isn't definitive. */
+ if (DECL_FIELD_IS_BASE (TREE_OPERAND (instance, 1)))
+ return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull, cdtorp);
return fixed_type_or_null (TREE_OPERAND (instance, 1), nonnull, cdtorp);
case VAR_DECL:
/* By the time we get here, we should be seeing only real
pointer-to-member types, not the internal POINTER_TYPE to
METHOD_TYPE representation. */
- my_friendly_assert (!(TREE_CODE (target_type) == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (target_type))
- == METHOD_TYPE)), 0);
+ gcc_assert (TREE_CODE (target_type) != POINTER_TYPE
+ || TREE_CODE (TREE_TYPE (target_type)) != METHOD_TYPE);
- my_friendly_assert (is_overloaded_fn (overload), 20030910);
+ gcc_assert (is_overloaded_fn (overload));
/* Check that the TARGET_TYPE is reasonable. */
if (TYPE_PTRFN_P (target_type))
case CONVERT_EXPR:
case SAVE_EXPR:
case CONSTRUCTOR:
- abort ();
- return error_mark_node;
+ gcc_unreachable ();
case INDIRECT_REF:
case ARRAY_REF:
if (addr != error_mark_node
&& TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
/* Do not lose object's side effects. */
- addr = build (COMPOUND_EXPR, TREE_TYPE (addr),
- TREE_OPERAND (rhs, 0), addr);
+ addr = build2 (COMPOUND_EXPR, TREE_TYPE (addr),
+ TREE_OPERAND (rhs, 0), addr);
return addr;
}
/* This can happen if we are forming a pointer-to-member for a
member template. */
- my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0);
+ gcc_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR);
/* Fall through. */
case TREE_LIST:
/* Now we should have a baselink. */
- my_friendly_assert (BASELINK_P (rhs), 990412);
+ gcc_assert (BASELINK_P (rhs));
return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags);
case CALL_EXPR:
/* This is too hard for now. */
- abort ();
- return error_mark_node;
+ gcc_unreachable ();
case PLUS_EXPR:
case MINUS_EXPR:
return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags);
}
- case ENTRY_VALUE_EXPR:
- abort ();
- return error_mark_node;
case ERROR_MARK:
return error_mark_node;
default:
- abort ();
- return error_mark_node;
+ gcc_unreachable ();
}
+ return error_mark_node;
}
\f
/* Return the name of the virtual function pointer field
char *buf;
for (binfo = TYPE_BINFO (type);
- BINFO_BASE_BINFOS (binfo);
+ BINFO_N_BASE_BINFOS (binfo);
binfo = base_binfo)
{
base_binfo = BINFO_BASE_BINFO (binfo, 0);
if (CLASS_TYPE_P (type))
{
tree field;
+ tree binfo;
+ tree base_binfo;
int i;
- for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); ++i)
- if (contains_empty_class_p
- (BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type), i))))
+ for (binfo = TYPE_BINFO (type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ if (contains_empty_class_p (BINFO_TYPE (base_binfo)))
return true;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
return NULL_TREE;
decl = BINFO_VTABLE (binfo);
if (decl && TREE_CODE (decl) == PLUS_EXPR)
{
- my_friendly_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR,
- 2000403);
+ gcc_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR);
decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
}
if (decl)
- my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 20000403);
+ gcc_assert (TREE_CODE (decl) == VAR_DECL);
return decl;
}
int indent)
{
int indented = 0;
- tree base_binfos;
+ tree base_binfo;
+ int i;
indented = maybe_indent_hierarchy (stream, indent, 0);
fprintf (stream, "%s (0x%lx) ",
- type_as_string (binfo, TFF_PLAIN_IDENTIFIER),
+ type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER),
(unsigned long) binfo);
if (binfo != igo)
{
fprintf (stream, "\n");
indented = 0;
- if (BINFO_PRIMARY_BASE_OF (binfo))
+ if (BINFO_PRIMARY_P (binfo))
{
indented = maybe_indent_hierarchy (stream, indent + 3, indented);
fprintf (stream, " primary-for %s (0x%lx)",
- type_as_string (BINFO_PRIMARY_BASE_OF (binfo),
+ type_as_string (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
TFF_PLAIN_IDENTIFIER),
- (unsigned long)BINFO_PRIMARY_BASE_OF (binfo));
+ (unsigned long)BINFO_INHERITANCE_CHAIN (binfo));
}
if (BINFO_LOST_PRIMARY_P (binfo))
{
if (indented)
fprintf (stream, "\n");
}
-
- base_binfos = BINFO_BASE_BINFOS (binfo);
- if (base_binfos)
- {
- int ix, n;
-
- n = TREE_VEC_LENGTH (base_binfos);
- for (ix = 0; ix != n; ix++)
- {
- tree base_binfo = TREE_VEC_ELT (base_binfos, ix);
- igo = dump_class_hierarchy_r (stream, flags, base_binfo,
- igo, indent + 2);
- }
- }
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ igo = dump_class_hierarchy_r (stream, flags, base_binfo, igo, indent + 2);
return igo;
}
fprintf (stream, "%s for %s",
ctor_vtbl_p ? "Construction vtable" : "Vtable",
- type_as_string (binfo, TFF_PLAIN_IDENTIFIER));
+ type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER));
if (ctor_vtbl_p)
{
if (!BINFO_VIRTUAL_P (binfo))
static void
initialize_array (tree decl, tree inits)
{
- tree context;
-
- context = DECL_CONTEXT (decl);
- DECL_CONTEXT (decl) = NULL_TREE;
DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits);
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
- DECL_CONTEXT (decl) = context;
}
/* Build the VTT (virtual table table) for T.
inits = &TREE_CHAIN (*inits);
if (top_level_p)
{
- my_friendly_assert (!BINFO_VPTR_INDEX (binfo), 20010129);
+ gcc_assert (!BINFO_VPTR_INDEX (binfo));
BINFO_VPTR_INDEX (binfo) = *index;
}
*index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));
/* Recursively add the secondary VTTs for non-virtual bases. */
- for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); ++i)
- {
- b = BINFO_BASE_BINFO (binfo, i);
- if (!BINFO_VIRTUAL_P (b))
- inits = build_vtt_inits (BINFO_BASE_BINFO (binfo, i), t,
- inits, index);
- }
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
+ if (!BINFO_VIRTUAL_P (b))
+ inits = build_vtt_inits (BINFO_BASE_BINFO (binfo, i), t, inits, index);
/* Add secondary virtual pointers for all subobjects of BINFO with
either virtual bases or reachable along a virtual path, except
{
*inits = nreverse (secondary_vptrs);
inits = &TREE_CHAIN (secondary_vptrs);
- my_friendly_assert (*inits == NULL_TREE, 20000517);
+ gcc_assert (*inits == NULL_TREE);
}
/* Add the secondary VTTs for virtual bases. */
index = TREE_TYPE (l);
if (top_level_p)
{
- my_friendly_assert (!BINFO_VPTR_INDEX (binfo), 20010129);
+ gcc_assert (!BINFO_VPTR_INDEX (binfo));
BINFO_VPTR_INDEX (binfo) = index;
}
TREE_TYPE (l) = size_binop (PLUS_EXPR, index,
/* It's a primary virtual base, and this is not the construction
vtable. Find the base this is primary of in the inheritance graph,
and use that base's vtable now. */
- while (BINFO_PRIMARY_BASE_OF (binfo))
- binfo = BINFO_PRIMARY_BASE_OF (binfo);
+ while (BINFO_PRIMARY_P (binfo))
+ binfo = BINFO_INHERITANCE_CHAIN (binfo);
}
init = binfo_ctor_vtable (binfo);
TREE_VALUE (l) = tree_cons (NULL_TREE, init, TREE_VALUE (l));
if (IDENTIFIER_GLOBAL_VALUE (id))
return;
- my_friendly_assert (!same_type_p (BINFO_TYPE (binfo), t), 20010124);
+ gcc_assert (!same_type_p (BINFO_TYPE (binfo), t));
/* Build a version of VTBL (with the wrong type) for use in
constructing the addresses of secondary vtables in the
construction vtable group. */
tree inits)
{
int i;
+ tree base_binfo;
int ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
- my_friendly_assert (same_type_p (BINFO_TYPE (binfo),
- BINFO_TYPE (orig_binfo)),
- 20000517);
+ gcc_assert (same_type_p (BINFO_TYPE (binfo), BINFO_TYPE (orig_binfo)));
/* If it doesn't have a vptr, we don't do anything. */
if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
secondary vtable lies from the primary vtable. We can't use
dfs_walk here because we need to iterate through bases of BINFO
and RTTI_BINFO simultaneously. */
- for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); ++i)
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
{
- tree base_binfo = BINFO_BASE_BINFO (binfo, i);
-
/* Skip virtual bases. */
if (BINFO_VIRTUAL_P (base_binfo))
continue;
RTTI_BINFO.
3) We are primary to something not a base of RTTI_BINFO. */
- tree b = BINFO_PRIMARY_BASE_OF (binfo);
+ tree b;
tree last = NULL_TREE;
/* First, look through the bases we are primary to for RTTI_BINFO
or a virtual base. */
- for (; b; b = BINFO_PRIMARY_BASE_OF (b))
+ b = binfo;
+ while (BINFO_PRIMARY_P (b))
{
+ b = BINFO_INHERITANCE_CHAIN (b);
last = b;
if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
- break;
+ goto found;
}
/* If we run out of primary links, keep looking down our
inheritance chain; we might be an indirect primary. */
- if (b == NULL_TREE)
- for (b = last; b; b = BINFO_INHERITANCE_CHAIN (b))
- if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
- break;
-
+ for (b = last; b; b = BINFO_INHERITANCE_CHAIN (b))
+ if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
+ break;
+ found:
+
/* If we found RTTI_BINFO, this is case 1. If we found a virtual
base B and it is a base of RTTI_BINFO, this is case 2. In
either case, we share our vtable with LAST, i.e. the
index = size_binop (MULT_EXPR,
TYPE_SIZE_UNIT (vtable_entry_type),
index);
- vtbl = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
+ vtbl = build2 (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
}
if (ctor_vtbl_p)
vtbl_init_data vid;
unsigned ix;
tree vbinfo;
-
+ VEC (tree) *vbases;
+
/* Initialize VID. */
memset (&vid, 0, sizeof (vid));
vid.binfo = binfo;
vid.ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
vid.generate_vcall_entries = true;
/* The first vbase or vcall offset is at index -3 in the vtable. */
- vid.index = ssize_int (-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
+ vid.index = ssize_int(-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
/* Add entries to the vtable for RTTI. */
build_rtti_vtbl_entries (binfo, &vid);
/* Clear BINFO_VTABLE_PATH_MARKED; it's set by
build_vbase_offset_vtbl_entries. */
- for (ix = 0; (vbinfo = VEC_iterate
- (tree, CLASSTYPE_VBASECLASSES (t), ix)); ix++)
+ for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
+ VEC_iterate (tree, vbases, ix, vbinfo); ix++)
BINFO_VTABLE_PATH_MARKED (vbinfo) = 0;
/* If the target requires padding between data entries, add that now. */
delta = BV_DELTA (v);
vcall_index = BV_VCALL_INDEX (v);
- my_friendly_assert (TREE_CODE (delta) == INTEGER_CST, 19990727);
- my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 19990727);
+ gcc_assert (TREE_CODE (delta) == INTEGER_CST);
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
/* You can't call an abstract virtual function; it's abstract.
So, we replace these functions with __pure_virtual. */
else
for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
{
- tree fdesc = build (FDESC_EXPR, vfunc_ptr_type_node,
- TREE_OPERAND (init, 0),
- build_int_2 (i, 0));
+ tree fdesc = build2 (FDESC_EXPR, vfunc_ptr_type_node,
+ TREE_OPERAND (init, 0),
+ build_int_cst (NULL_TREE, i));
TREE_CONSTANT (fdesc) = 1;
TREE_INVARIANT (fdesc) = 1;
BINFO_VPTR_FIELD (b) = delta;
if (binfo != TYPE_BINFO (t))
- {
- /* The vbase offset had better be the same. */
- my_friendly_assert (tree_int_cst_equal (delta,
- BINFO_VPTR_FIELD (vbase)),
- 20030202);
- }
+ /* The vbase offset had better be the same. */
+ gcc_assert (tree_int_cst_equal (delta, BINFO_VPTR_FIELD (vbase)));
/* The next vbase will come at a more negative offset. */
vid->index = size_binop (MINUS_EXPR, vid->index,
{
int i;
tree primary_binfo;
+ tree base_binfo;
/* Don't walk into virtual bases -- except, of course, for the
virtual base for which we are building vcall offsets. Any
add_vcall_offset_vtbl_entries_1 (binfo, vid);
/* Scan the non-primary bases of BINFO. */
- for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); ++i)
- {
- tree base_binfo;
-
- base_binfo = BINFO_BASE_BINFO (binfo, i);
- if (base_binfo != primary_binfo)
- add_vcall_offset_vtbl_entries_r (base_binfo, vid);
- }
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
+ if (base_binfo != primary_binfo)
+ add_vcall_offset_vtbl_entries_r (base_binfo, vid);
}
/* Called from build_vcall_offset_vtbl_entries_r. */
might be a lost primary, so just skip down to vid->binfo. */
if (BINFO_VIRTUAL_P (non_primary_binfo))
{
- if (non_primary_binfo != vid->vbase)
- abort ();
+ gcc_assert (non_primary_binfo == vid->vbase);
non_primary_binfo = vid->binfo;
break;
}
the vtable for the most derived class, remember the vcall
offset. */
if (vid->binfo == TYPE_BINFO (vid->derived))
- CLASSTYPE_VCALL_INDICES (vid->derived)
- = tree_cons (orig_fn, vid->index,
- CLASSTYPE_VCALL_INDICES (vid->derived));
-
+ {
+ tree_pair_p elt = VEC_safe_push (tree_pair_s,
+ CLASSTYPE_VCALL_INDICES (vid->derived),
+ NULL);
+ elt->purpose = orig_fn;
+ elt->value = vid->index;
+ }
+
/* The next vcall offset will be found at a more negative
offset. */
vid->index = size_binop (MINUS_EXPR, vid->index,
tree primary_base;
primary_base = get_primary_binfo (b);
- my_friendly_assert (BINFO_PRIMARY_BASE_OF (primary_base) == b, 20010127);
+ gcc_assert (BINFO_PRIMARY_P (primary_base)
+ && BINFO_INHERITANCE_CHAIN (primary_base) == b);
b = primary_base;
}
offset = size_diffop (BINFO_OFFSET (vid->rtti_binfo), BINFO_OFFSET (b));
fndecl = BV_FN (v);
#ifdef ENABLE_CHECKING
- if (!tree_int_cst_equal (OBJ_TYPE_REF_TOKEN (ref), DECL_VINDEX (fndecl)))
- abort ();
+ gcc_assert (tree_int_cst_equal (OBJ_TYPE_REF_TOKEN (ref),
+ DECL_VINDEX (fndecl)));
#endif
return build_address (fndecl);
}
+