static tree dfs_dcast_hint_pre (tree, void *);
static tree dfs_dcast_hint_post (tree, void *);
static tree dfs_debug_mark (tree, void *);
-static tree dfs_walk_once_r (tree, tree (*pre_fn) (tree, void *),
- tree (*post_fn) (tree, void *), void *data);
-static void dfs_unmark_r (tree);
static int check_hidden_convs (tree, int, int, tree, tree, tree);
static tree split_conversions (tree, tree, tree, tree);
static int lookup_conversions_r (tree, int, int,
static int look_for_overrides_r (tree, tree);
static tree lookup_field_r (tree, void *);
static tree dfs_accessible_post (tree, void *);
-static tree dfs_walk_once_accessible_r (tree, bool, bool,
- tree (*pre_fn) (tree, void *),
- tree (*post_fn) (tree, void *),
- void *data);
static tree dfs_walk_once_accessible (tree, bool,
tree (*pre_fn) (tree, void *),
tree (*post_fn) (tree, void *),
static tree
dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
- tree (*post_fn) (tree, void *), void *data)
+ tree (*post_fn) (tree, void *), hash_set<tree> *pset,
+ void *data)
{
tree rval;
unsigned ix;
for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
{
if (BINFO_VIRTUAL_P (base_binfo))
- {
- if (BINFO_MARKED (base_binfo))
- continue;
- BINFO_MARKED (base_binfo) = 1;
- }
+ if (pset->add (base_binfo))
+ continue;
- rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, data);
+ rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, pset, data);
if (rval)
return rval;
}
return NULL_TREE;
}
-/* Worker for dfs_walk_once. Recursively unmark the virtual base binfos of
- BINFO. */
-
-static void
-dfs_unmark_r (tree binfo)
-{
- unsigned ix;
- tree base_binfo;
-
- /* Process the basetypes. */
- for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
- {
- if (BINFO_VIRTUAL_P (base_binfo))
- {
- if (!BINFO_MARKED (base_binfo))
- continue;
- BINFO_MARKED (base_binfo) = 0;
- }
- /* Only walk, if it can contain more virtual bases. */
- if (CLASSTYPE_VBASECLASSES (BINFO_TYPE (base_binfo)))
- dfs_unmark_r (base_binfo);
- }
-}
-
/* Like dfs_walk_all, except that binfos are not multiply walked. For
non-diamond shaped hierarchies this is the same as dfs_walk_all.
For diamond shaped hierarchies we must mark the virtual bases, to
rval = dfs_walk_all (binfo, pre_fn, post_fn, data);
else
{
- rval = dfs_walk_once_r (binfo, pre_fn, post_fn, data);
- if (!BINFO_INHERITANCE_CHAIN (binfo))
- {
- /* We are at the top of the hierarchy, and can use the
- CLASSTYPE_VBASECLASSES list for unmarking the virtual
- bases. */
- vec<tree, va_gc> *vbases;
- unsigned ix;
- tree base_binfo;
-
- for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
- vec_safe_iterate (vbases, ix, &base_binfo); ix++)
- BINFO_MARKED (base_binfo) = 0;
- }
- else
- dfs_unmark_r (binfo);
+ hash_set<tree> pset;
+ rval = dfs_walk_once_r (binfo, pre_fn, post_fn, &pset, data);
}
active--;
indicates whether bases should be marked during traversal. */
static tree
-dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
+dfs_walk_once_accessible_r (tree binfo, bool friends_p, hash_set<tree> *pset,
tree (*pre_fn) (tree, void *),
tree (*post_fn) (tree, void *), void *data)
{
/* Find the next child binfo to walk. */
for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
{
- bool mark = once && BINFO_VIRTUAL_P (base_binfo);
+ bool mark = pset && BINFO_VIRTUAL_P (base_binfo);
- if (mark && BINFO_MARKED (base_binfo))
+ if (mark && pset->contains (base_binfo))
continue;
/* If the base is inherited via private or protected
}
if (mark)
- BINFO_MARKED (base_binfo) = 1;
+ pset->add (base_binfo);
- rval = dfs_walk_once_accessible_r (base_binfo, friends_p, once,
+ rval = dfs_walk_once_accessible_r (base_binfo, friends_p, pset,
pre_fn, post_fn, data);
if (rval)
return rval;
tree (*pre_fn) (tree, void *),
tree (*post_fn) (tree, void *), void *data)
{
- bool diamond_shaped = CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo));
- tree rval = dfs_walk_once_accessible_r (binfo, friends_p, diamond_shaped,
+ hash_set<tree> *pset = NULL;
+ if (CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo)))
+ pset = new hash_set<tree>;
+ tree rval = dfs_walk_once_accessible_r (binfo, friends_p, pset,
pre_fn, post_fn, data);
- if (diamond_shaped)
- {
- if (!BINFO_INHERITANCE_CHAIN (binfo))
- {
- /* We are at the top of the hierarchy, and can use the
- CLASSTYPE_VBASECLASSES list for unmarking the virtual
- bases. */
- vec<tree, va_gc> *vbases;
- unsigned ix;
- tree base_binfo;
-
- for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
- vec_safe_iterate (vbases, ix, &base_binfo); ix++)
- BINFO_MARKED (base_binfo) = 0;
- }
- else
- dfs_unmark_r (binfo);
- }
+ if (pset)
+ delete pset;
return rval;
}