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;
}
DECL_EXTERNAL (decl) = 1;
DECL_NOT_REALLY_EXTERN (decl) = 1;
- if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
+ 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
require more intrusive changes to the g++ front end. */
DECL_IGNORED_P (decl) = 1;
- /* The vtable's visibility is the class visibility. There is no way
- to override the visibility for just the vtable. */
- DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
- DECL_VISIBILITY_SPECIFIED (decl) = CLASSTYPE_VISIBILITY_SPECIFIED (class_type);
-
return decl;
}
}
else
{
- my_friendly_assert (TREE_TYPE (decl) == vtbl_type_node, 20000118);
+ gcc_assert (TREE_TYPE (decl) == vtbl_type_node);
virtuals = NULL_TREE;
}
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)
{
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 parent = BINFO_INHERITANCE_CHAIN (base_binfo);
+ tree parent_primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (parent));
+
+ if (parent_primary
+ && BINFO_TYPE (base_binfo) == BINFO_TYPE (parent_primary))
+ /* We are the primary binfo. */
+ BINFO_PRIMARY_P (base_binfo) = 1;
+ }
+ /* Determine if we have a virtual primary base, and mark it so.
+ */
+ if (primary && BINFO_VIRTUAL_P (primary))
+ {
+ tree this_primary = copied_binfo (primary, base_binfo);
+
+ if (BINFO_PRIMARY_P (this_primary))
+ /* Someone already claimed this base. */
+ BINFO_LOST_PRIMARY_P (base_binfo) = 1;
+ else
{
- tree delta = size_diffop (convert (ssizetype,
- BINFO_OFFSET (binfo)),
- convert (ssizetype,
- BINFO_OFFSET (base_binfo)));
+ 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 (base_binfo, delta);
+ propagate_binfo_offsets (this_primary, delta);
}
}
}
-}
-
-/* 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 = TYPE_BINFO (t);
- tree vbase_binfo;
- tree base_binfo;
- VEC(tree) *vbases;
-
- /* If there are no baseclasses, there is certainly no primary base. */
- if (n_baseclasses == 0)
- return;
+ /* First look for a dynamic direct non-virtual base. */
for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, base_binfo); i++)
{
tree basetype = BINFO_TYPE (base_binfo);
- if (TYPE_CONTAINS_VPTR_P (basetype))
+ if (TYPE_CONTAINS_VPTR_P (basetype) && !BINFO_VIRTUAL_P (base_binfo))
{
- /* We prefer a non-virtual base, although a virtual one will
- do. */
- if (BINFO_VIRTUAL_P (base_binfo))
- continue;
-
- if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
- set_primary_base (t, base_binfo);
- }
- }
-
- 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 (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
- VEC_iterate (tree, vbases, i, vbase_binfo); i++)
- {
- 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 (j = 0; BINFO_BASE_ITERATE (type_binfo, j, base_binfo); j++)
- {
- unsigned k;
- VEC (tree) *base_vbases;
- tree base_vbase_binfo;
- tree basetype = BINFO_TYPE (base_binfo);
-
- for (base_vbases = CLASSTYPE_VBASECLASSES (basetype), k = 0;
- VEC_iterate (tree, base_vbases, k, base_vbase_binfo); 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);
-
- 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;
- }
+ tree delta;
- /* 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);
+
+ 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
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;
- /* Build the path, using the inheritance chain and record of
- virtual inheritance. */
- for (path = NULL_TREE, probe = binfo, vpath = ffod->vpath;;)
+ if (BINFO_VIRTUAL_P (binfo))
+ derived = *--vpath;
+ else
+ derived = BINFO_INHERITANCE_CHAIN (binfo);
+ if (dfs_find_final_overrider_1 (derived, vpath, ffod))
+ return true;
+ }
+
+ 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))
{
return p->value;
/* There should always be an appropriate index. */
- abort ();
-
- return NULL_TREE;
+ 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. */
continue;
if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
- {
- /* Apply the class's visibility attribute to static members
- which do not have a visibility attribute. */
- if (! lookup_attribute ("visibility", DECL_ATTRIBUTES (x)))
- {
- if (visibility_options.inlines_hidden && DECL_INLINE (x))
- {
- DECL_VISIBILITY (x) = VISIBILITY_HIDDEN;
- DECL_VISIBILITY_SPECIFIED (x) = 1;
- }
- else
- {
- DECL_VISIBILITY (x) = CLASSTYPE_VISIBILITY (current_class_type);
- DECL_VISIBILITY_SPECIFIED (x) = CLASSTYPE_VISIBILITY_SPECIFIED (current_class_type);
- }
- }
-
- continue;
- }
+ continue;
/* Now it can only be a FIELD_DECL. */
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);
-
- /* Apply the class's visibility attribute to methods which do
- not have a visibility attribute. */
- if (! lookup_attribute ("visibility", DECL_ATTRIBUTES (x)))
- {
- if (visibility_options.inlines_hidden && DECL_INLINE (x))
- {
- DECL_VISIBILITY (x) = VISIBILITY_HIDDEN;
- DECL_VISIBILITY_SPECIFIED (x) = 1;
- }
- else
- {
- DECL_VISIBILITY (x) = CLASSTYPE_VISIBILITY (current_class_type);
- DECL_VISIBILITY_SPECIFIED (x) = CLASSTYPE_VISIBILITY_SPECIFIED (current_class_type);
- }
- }
-
/* 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
/* Find the primary base class. */
primary_binfo = get_primary_binfo (binfo);
- if (primary_binfo && BINFO_PRIMARY_BASE_OF (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
BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
{
if (!include_virtuals_p
- && BINFO_VIRTUAL_P (base_binfo)
- && BINFO_PRIMARY_BASE_OF (base_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 (base_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));
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);
}
}
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
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;
}
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))
{
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));
{
*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 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)))
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)
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);
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,
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;
}
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);