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;
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:
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_list = (tree *) xcalloc (cd.max_depth, sizeof (tree));
+ /* The virtual depth cannot be greater than the number of virtual
+ bases. */
+ ffod.vpath_list = (tree *) xcalloc
+ (VEC_length (tree, CLASSTYPE_VBASECLASSES (BINFO_TYPE (derived))),
+ sizeof (tree));
ffod.vpath = ffod.vpath_list;
dfs_walk_real (derived,
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
#define UNIFY_ALLOW_MAX_CORRECTION 128
-#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
- virtual, or a base class of a virtual
- base. */
-#define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current
- type with the desired type. */
-
static void push_access_scope (tree);
static void pop_access_scope (tree);
static int resolve_overloaded_unification (tree, tree, tree, tree,
static void set_current_access_from_decl (tree);
static void check_default_tmpl_args (tree, tree, int, int);
static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
-static tree get_template_base_recursive (tree, tree, tree, tree, tree, int);
+static tree get_template_base_r (tree, void *);
static tree get_template_base (tree, tree, tree, tree);
static int verify_class_unification (tree, tree, tree);
static tree try_class_unification (tree, tree, tree, tree);
return arg;
}
-/* Subroutine of get_template_base. RVAL, if non-NULL, is a base we
- have already discovered to be satisfactory. ARG_BINFO is the binfo
- for the base class of ARG that we are currently examining. */
+typedef struct get_template_base_data_s
+{
+ /* Parameters for unification. */
+ tree tparms;
+ tree targs;
+ tree parm;
+ /* Base we've found to be satisfactory. */
+ tree rval;
+} get_template_base_data;
+
+/* Called from get_template_base via dfs_walk. */
static tree
-get_template_base_recursive (tree tparms,
- tree targs,
- tree parm,
- tree arg_binfo,
- tree rval,
- int flags)
-{
- tree base_binfo;
- int i;
- tree arg = BINFO_TYPE (arg_binfo);
+get_template_base_r (tree arg_binfo,
+ void *data_)
+{
+ get_template_base_data *data = data_;
- if (!(flags & GTB_IGNORE_TYPE))
+ /* Do not look at the most derived binfo -- that's not a proper
+ base. */
+ if (BINFO_INHERITANCE_CHAIN (arg_binfo))
{
- tree r = try_class_unification (tparms, targs,
- parm, arg);
-
- /* If there is more than one satisfactory baseclass, then:
-
- [temp.deduct.call]
-
- If they yield more than one possible deduced A, the type
- deduction fails.
+ tree r = try_class_unification (data->tparms, data->targs,
+ data->parm, BINFO_TYPE (arg_binfo));
- applies. */
- if (r && rval && !same_type_p (r, rval))
- return error_mark_node;
- else if (r)
- rval = r;
- }
+ if (r)
+ {
+ /* If there is more than one satisfactory baseclass, then:
- /* Process base types. */
- for (i = 0; BINFO_BASE_ITERATE (arg_binfo, i, base_binfo); i++)
- {
- int this_virtual;
+ [temp.deduct.call]
- /* Skip this base, if we've already seen it. */
- if (BINFO_MARKED (base_binfo))
- continue;
+ If they yield more than one possible deduced A, the type
+ deduction fails.
- this_virtual =
- (flags & GTB_VIA_VIRTUAL) || BINFO_VIRTUAL_P (base_binfo);
-
- /* When searching for a non-virtual, we cannot mark virtually
- found binfos. */
- if (! this_virtual)
- BINFO_MARKED (base_binfo) = 1;
-
- rval = get_template_base_recursive (tparms, targs,
- parm,
- base_binfo,
- rval,
- GTB_VIA_VIRTUAL * this_virtual);
-
- /* If we discovered more than one matching base class, we can
- stop now. */
- if (rval == error_mark_node)
- return error_mark_node;
+ applies. */
+ if (data->rval && !same_type_p (r, data->rval))
+ {
+ data->rval = NULL_TREE;
+ /* Terminate the walk with any non-NULL value. */
+ return r;
+ }
+
+ data->rval = r;
+ }
}
- return rval;
+ return NULL_TREE;
}
/* Given a template type PARM and a class type ARG, find the unique
static tree
get_template_base (tree tparms, tree targs, tree parm, tree arg)
{
- tree rval;
+ get_template_base_data data;
tree arg_binfo;
gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
if (!arg_binfo)
/* The type could not be completed. */
return NULL_TREE;
-
- rval = get_template_base_recursive (tparms, targs,
- parm, arg_binfo,
- NULL_TREE,
- GTB_IGNORE_TYPE);
- /* Since get_template_base_recursive marks the bases classes, we
- must unmark them here. */
- dfs_walk (arg_binfo, dfs_unmark, markedp, 0);
+ data.tparms = tparms;
+ data.targs = targs;
+ data.parm = parm;
+ data.rval = NULL_TREE;
+
+ dfs_walk_real (arg_binfo, get_template_base_r, 0, 0, &data);
- return rval;
+ return data.rval;
}
/* Returns the level of DECL, which declares a template parameter. */
a class of the form template-id, A can be a
pointer to a derived class pointed to by the
deduced A. */
- t = get_template_base (tparms, targs,
- parm, arg);
+ t = get_template_base (tparms, targs, parm, arg);
- if (! t || t == error_mark_node)
+ if (!t)
return 1;
}
}
};
static int is_subobject_of_p (tree, tree);
-static tree dfs_check_overlap (tree, void *);
-static tree dfs_no_overlap_yet (tree, int, void *);
static base_kind lookup_base_r (tree, tree, base_access, bool, tree *);
static int dynamic_cast_base_recurse (tree, tree, bool, tree *);
static tree dfs_debug_unmarkedp (tree, int, void *);
return list;
}
-struct overlap_info
-{
- tree compare_type;
- int found_overlap;
-};
-
-/* Check whether the empty class indicated by EMPTY_BINFO is also present
- at offset 0 in COMPARE_TYPE, and set found_overlap if so. */
-
-static tree
-dfs_check_overlap (tree empty_binfo, void *data)
-{
- struct overlap_info *oi = (struct overlap_info *) data;
- tree binfo;
-
- for (binfo = TYPE_BINFO (oi->compare_type);
- ;
- binfo = BINFO_BASE_BINFO (binfo, 0))
- {
- if (BINFO_TYPE (binfo) == BINFO_TYPE (empty_binfo))
- {
- oi->found_overlap = 1;
- break;
- }
- else if (!BINFO_N_BASE_BINFOS (binfo))
- break;
- }
-
- return NULL_TREE;
-}
-
-/* Trivial function to stop base traversal when we find something. */
-
-static tree
-dfs_no_overlap_yet (tree derived, int ix, void *data)
-{
- tree binfo = BINFO_BASE_BINFO (derived, ix);
- struct overlap_info *oi = (struct overlap_info *) data;
-
- return !oi->found_overlap ? binfo : NULL_TREE;
-}
-
-/* Returns nonzero if EMPTY_TYPE or any of its bases can also be found at
- offset 0 in NEXT_TYPE. Used in laying out empty base class subobjects. */
-
-int
-types_overlap_p (tree empty_type, tree next_type)
-{
- struct overlap_info oi;
-
- if (! IS_AGGR_TYPE (next_type))
- return 0;
- oi.compare_type = next_type;
- oi.found_overlap = 0;
- dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap,
- dfs_no_overlap_yet, &oi);
- return oi.found_overlap;
-}
-
/* Returns the binfo of the first direct or indirect virtual base derived
from BINFO, or NULL if binfo is not via virtual. */