cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
* cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove. * class.c (update_vtable_entry_for_fn): Correct logic for deciding where to emit thunks. (build_vtt): Adjust call to build_vtt_inits. (build_vtt_inits): Add parameter to indicate whether or not sub-VTTs for virtual bases should be included. Adjust handling of construction vtables. (get_matching_base): New function. (dfs_build_vtt_inits): Rename to ... (dfs_build_secondary_vptr_vtt_inits): Adjust handling of construction vtables. (dfs_fixup_binfo_vtbls): Likewise. (build_ctor_vtbl_groups): Build construction vtables for virtual bases, too. (accumulate_vtbl_inits): Tweak logic for deciding whether or not to build construction vtbls. (dfs_accumulate_vtbl_inits): Adjust handling of construction vtables. * pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified types correctly. From-SVN: r34765
This commit is contained in:
parent
6883b3aeca
commit
9ccf654155
@ -1,3 +1,27 @@
|
||||
2000-06-28 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
|
||||
* class.c (update_vtable_entry_for_fn): Correct logic for deciding
|
||||
where to emit thunks.
|
||||
(build_vtt): Adjust call to build_vtt_inits.
|
||||
(build_vtt_inits): Add parameter to indicate whether or not
|
||||
sub-VTTs for virtual bases should be included. Adjust handling of
|
||||
construction vtables.
|
||||
(get_matching_base): New function.
|
||||
(dfs_build_vtt_inits): Rename to ...
|
||||
(dfs_build_secondary_vptr_vtt_inits): Adjust handling of
|
||||
construction vtables.
|
||||
(dfs_fixup_binfo_vtbls): Likewise.
|
||||
(build_ctor_vtbl_groups): Build construction vtables for virtual
|
||||
bases, too.
|
||||
(accumulate_vtbl_inits): Tweak logic for deciding whether or not
|
||||
to build construction vtbls.
|
||||
(dfs_accumulate_vtbl_inits): Adjust handling of
|
||||
construction vtables.
|
||||
|
||||
* pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified
|
||||
types correctly.
|
||||
|
||||
2000-06-27 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* decl.c (grokfndecl): Set DECL_CONTEXT for static functions too.
|
||||
|
145
gcc/cp/class.c
145
gcc/cp/class.c
@ -190,10 +190,11 @@ static void update_vtable_entry_for_fn PARAMS ((tree, tree, tree, tree *));
|
||||
static tree copy_virtuals PARAMS ((tree));
|
||||
static void build_ctor_vtbl_group PARAMS ((tree, tree));
|
||||
static void build_vtt PARAMS ((tree));
|
||||
static tree *build_vtt_inits PARAMS ((tree, tree, tree *, tree *));
|
||||
static tree dfs_build_vtt_inits PARAMS ((tree, void *));
|
||||
static tree *build_vtt_inits PARAMS ((tree, tree, int, tree *, tree *));
|
||||
static tree dfs_build_secondary_vptr_vtt_inits PARAMS ((tree, void *));
|
||||
static tree dfs_fixup_binfo_vtbls PARAMS ((tree, void *));
|
||||
static int indirect_primary_base_p PARAMS ((tree, tree));
|
||||
static tree get_matching_base PARAMS ((tree, tree));
|
||||
|
||||
/* Variables shared between class.c and call.c. */
|
||||
|
||||
@ -2643,7 +2644,7 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
|
||||
|
||||
/* Assume that we will produce a thunk that convert all the way to
|
||||
the final overrider, and not to an intermediate virtual base. */
|
||||
virtual_base = NULL_TREE;
|
||||
virtual_base = NULL_TREE;
|
||||
|
||||
/* Assume that we will always generate thunks with the vtables that
|
||||
reference them. */
|
||||
@ -2659,7 +2660,8 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
|
||||
/* If we find BINFO, then the final overrider is in a class
|
||||
derived from BINFO, so the thunks can be generated with
|
||||
the final overrider. */
|
||||
if (same_type_p (BINFO_TYPE (b), BINFO_TYPE (binfo)))
|
||||
if (!virtual_base
|
||||
&& same_type_p (BINFO_TYPE (b), BINFO_TYPE (binfo)))
|
||||
generate_thunk_with_vtable_p = 0;
|
||||
|
||||
/* If we find the final overrider, then we can stop
|
||||
@ -6627,7 +6629,8 @@ build_vtt (t)
|
||||
/* Build up the initializers for the VTT. */
|
||||
inits = NULL_TREE;
|
||||
index = size_zero_node;
|
||||
build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);
|
||||
build_vtt_inits (TYPE_BINFO (t), t, /*virtual_vtts_p=*/1,
|
||||
&inits, &index);
|
||||
|
||||
/* If we didn't need a VTT, we're done. */
|
||||
if (!inits)
|
||||
@ -6643,15 +6646,45 @@ build_vtt (t)
|
||||
initialize_array (vtt, inits);
|
||||
}
|
||||
|
||||
/* Recursively build the VTT-initializer for BINFO (which is in the
|
||||
hierarchy dominated by T). INITS points to the end of the
|
||||
initializer list to date. INDEX is the VTT index where the next
|
||||
element will be placed. */
|
||||
/* The type corresponding to BINFO is a base class of T, but BINFO is
|
||||
in the base class hierarchy of a class derived from T. Return the
|
||||
base, in T's hierarchy, that corresponds to BINFO. */
|
||||
|
||||
static tree *
|
||||
build_vtt_inits (binfo, t, inits, index)
|
||||
static tree
|
||||
get_matching_base (binfo, t)
|
||||
tree binfo;
|
||||
tree t;
|
||||
{
|
||||
tree derived;
|
||||
int i;
|
||||
|
||||
if (same_type_p (BINFO_TYPE (binfo), t))
|
||||
return binfo;
|
||||
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
return binfo_for_vbase (BINFO_TYPE (binfo), t);
|
||||
|
||||
derived = get_matching_base (BINFO_INHERITANCE_CHAIN (binfo), t);
|
||||
for (i = 0; i < BINFO_N_BASETYPES (derived); ++i)
|
||||
if (same_type_p (BINFO_TYPE (BINFO_BASETYPE (derived, i)),
|
||||
BINFO_TYPE (binfo)))
|
||||
return BINFO_BASETYPE (derived, i);
|
||||
|
||||
my_friendly_abort (20000628);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Recursively build the VTT-initializer for BINFO (which is in the
|
||||
hierarchy dominated by T). If VIRTUAL_VTTS_P is non-zero, then
|
||||
sub-VTTs for virtual bases are included. INITS points to the end
|
||||
of the initializer list to date. INDEX is the VTT index where the
|
||||
next element will be placed. */
|
||||
|
||||
static tree *
|
||||
build_vtt_inits (binfo, t, virtual_vtts_p, inits, index)
|
||||
tree binfo;
|
||||
tree t;
|
||||
int virtual_vtts_p;
|
||||
tree *inits;
|
||||
tree *index;
|
||||
{
|
||||
@ -6679,7 +6712,7 @@ build_vtt_inits (binfo, t, inits, index)
|
||||
/* Add the address of the primary vtable for the complete object. */
|
||||
init = BINFO_VTABLE (binfo);
|
||||
if (TREE_CODE (init) == TREE_LIST)
|
||||
init = TREE_PURPOSE (init);
|
||||
init = TREE_VALUE (init);
|
||||
*inits = build_tree_list (NULL_TREE, init);
|
||||
inits = &TREE_CHAIN (*inits);
|
||||
BINFO_VPTR_INDEX (binfo) = *index;
|
||||
@ -6690,23 +6723,23 @@ build_vtt_inits (binfo, t, inits, index)
|
||||
{
|
||||
b = BINFO_BASETYPE (binfo, i);
|
||||
if (!TREE_VIA_VIRTUAL (b))
|
||||
inits = build_vtt_inits (BINFO_BASETYPE (binfo, i), t, inits,
|
||||
index);
|
||||
inits = build_vtt_inits (BINFO_BASETYPE (binfo, i), t,
|
||||
/*virtuals_vtts_p=*/0,
|
||||
inits, index);
|
||||
}
|
||||
|
||||
/* Add secondary virtual pointers for all subobjects of BINFO with
|
||||
either virtual bases or virtual functions overridden along a
|
||||
virtual path between the declaration and D, except subobjects
|
||||
that are non-virtual primary bases. */
|
||||
secondary_vptrs = build_tree_list (BINFO_TYPE (binfo), NULL_TREE);
|
||||
secondary_vptrs = tree_cons (t, NULL_TREE, BINFO_TYPE (binfo));
|
||||
TREE_TYPE (secondary_vptrs) = *index;
|
||||
dfs_walk_real (binfo,
|
||||
dfs_build_vtt_inits,
|
||||
dfs_build_secondary_vptr_vtt_inits,
|
||||
NULL,
|
||||
dfs_unmarked_real_bases_queue_p,
|
||||
secondary_vptrs);
|
||||
dfs_walk (binfo, dfs_fixup_binfo_vtbls, dfs_marked_real_bases_queue_p,
|
||||
BINFO_TYPE (binfo));
|
||||
dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
|
||||
*index = TREE_TYPE (secondary_vptrs);
|
||||
|
||||
/* The secondary vptrs come back in reverse order. After we reverse
|
||||
@ -6721,16 +6754,22 @@ build_vtt_inits (binfo, t, inits, index)
|
||||
}
|
||||
|
||||
/* Add the secondary VTTs for virtual bases. */
|
||||
for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
|
||||
{
|
||||
tree vbase;
|
||||
if (virtual_vtts_p)
|
||||
for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
|
||||
{
|
||||
tree vbase;
|
||||
|
||||
if (!TREE_VIA_VIRTUAL (b))
|
||||
continue;
|
||||
|
||||
vbase = binfo_for_vbase (BINFO_TYPE (b), t);
|
||||
inits = build_vtt_inits (vbase, t, /*virtual_vtts_p=*/0,
|
||||
inits, index);
|
||||
}
|
||||
|
||||
if (!TREE_VIA_VIRTUAL (b))
|
||||
continue;
|
||||
|
||||
vbase = binfo_for_vbase (BINFO_TYPE (b), t);
|
||||
inits = build_vtt_inits (vbase, t, inits, index);
|
||||
}
|
||||
dfs_walk (binfo, dfs_fixup_binfo_vtbls,
|
||||
dfs_unmarked_real_bases_queue_p,
|
||||
build_tree_list (t, binfo));
|
||||
|
||||
return inits;
|
||||
}
|
||||
@ -6738,7 +6777,7 @@ build_vtt_inits (binfo, t, inits, index)
|
||||
/* Called from build_vtt_inits via dfs_walk. */
|
||||
|
||||
static tree
|
||||
dfs_build_vtt_inits (binfo, data)
|
||||
dfs_build_secondary_vptr_vtt_inits (binfo, data)
|
||||
tree binfo;
|
||||
void *data;
|
||||
{
|
||||
@ -6748,7 +6787,7 @@ dfs_build_vtt_inits (binfo, data)
|
||||
tree index;
|
||||
|
||||
l = (tree) data;
|
||||
t = TREE_PURPOSE (l);
|
||||
t = TREE_CHAIN (l);
|
||||
|
||||
SET_BINFO_MARKED (binfo);
|
||||
|
||||
@ -6769,7 +6808,7 @@ dfs_build_vtt_inits (binfo, data)
|
||||
virtual path. The point is that given:
|
||||
|
||||
struct V { virtual void f(); int i; };
|
||||
struct C : public V { void f (); };
|
||||
struct C : public virtual V { void f (); };
|
||||
|
||||
when we constrct C we need a secondary vptr for V-in-C because we
|
||||
don't know what the vcall offset for `f' should be. If `V' ends
|
||||
@ -6777,7 +6816,7 @@ dfs_build_vtt_inits (binfo, data)
|
||||
different vcall offset than that present in the normal V-in-C
|
||||
vtable. */
|
||||
if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))
|
||||
&& !BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P (binfo))
|
||||
&& !BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P (get_matching_base (binfo, t)))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Record the index where this secondary vptr can be found. */
|
||||
@ -6789,7 +6828,7 @@ dfs_build_vtt_inits (binfo, data)
|
||||
/* Add the initializer for the secondary vptr itself. */
|
||||
init = BINFO_VTABLE (binfo);
|
||||
if (TREE_CODE (init) == TREE_LIST)
|
||||
init = TREE_PURPOSE (init);
|
||||
init = TREE_VALUE (init);
|
||||
TREE_VALUE (l) = tree_cons (NULL_TREE, init, TREE_VALUE (l));
|
||||
|
||||
return NULL_TREE;
|
||||
@ -6800,7 +6839,7 @@ dfs_build_vtt_inits (binfo, data)
|
||||
static tree
|
||||
dfs_fixup_binfo_vtbls (binfo, data)
|
||||
tree binfo;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
void *data;
|
||||
{
|
||||
CLEAR_BINFO_MARKED (binfo);
|
||||
|
||||
@ -6810,8 +6849,10 @@ dfs_fixup_binfo_vtbls (binfo, data)
|
||||
|
||||
/* If we scribbled the construction vtable vptr into BINFO, clear it
|
||||
out now. */
|
||||
if (TREE_CODE (BINFO_VTABLE (binfo)) == TREE_LIST)
|
||||
BINFO_VTABLE (binfo) = TREE_VALUE (BINFO_VTABLE (binfo));
|
||||
if (TREE_CODE (BINFO_VTABLE (binfo)) == TREE_LIST
|
||||
&& (TREE_PURPOSE (BINFO_VTABLE (binfo))
|
||||
== TREE_VALUE ((tree) data)))
|
||||
BINFO_VTABLE (binfo) = TREE_CHAIN (BINFO_VTABLE (binfo));
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
@ -6829,6 +6870,7 @@ build_ctor_vtbl_group (binfo, t)
|
||||
tree vtbl;
|
||||
tree inits;
|
||||
tree id;
|
||||
tree vbase;
|
||||
|
||||
/* See if we've already create this construction vtable group. */
|
||||
if (flag_new_abi)
|
||||
@ -6845,6 +6887,19 @@ build_ctor_vtbl_group (binfo, t)
|
||||
list = build_tree_list (vtbl, NULL_TREE);
|
||||
accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
|
||||
binfo, t, list);
|
||||
for (vbase = TYPE_BINFO (TREE_TYPE (binfo));
|
||||
vbase;
|
||||
vbase = TREE_CHAIN (vbase))
|
||||
{
|
||||
tree b;
|
||||
|
||||
if (!TREE_VIA_VIRTUAL (vbase))
|
||||
continue;
|
||||
|
||||
b = binfo_for_vbase (BINFO_TYPE (vbase), t);
|
||||
accumulate_vtbl_inits (b, vbase, binfo, t, list);
|
||||
}
|
||||
|
||||
inits = TREE_VALUE (list);
|
||||
|
||||
/* Figure out the type of the construction vtable. */
|
||||
@ -6886,7 +6941,9 @@ accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, inits)
|
||||
/* If we're building a construction vtable, we're not interested in
|
||||
subobjects that don't require construction vtables. */
|
||||
if (ctor_vtbl_p
|
||||
&& !TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
|
||||
&& !TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))
|
||||
&& !(BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P
|
||||
(get_matching_base (binfo, BINFO_TYPE (rtti_binfo)))))
|
||||
return;
|
||||
|
||||
/* Build the initializers for the BINFO-in-T vtable. */
|
||||
@ -6929,16 +6986,8 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
|
||||
tree l;
|
||||
{
|
||||
tree inits = NULL_TREE;
|
||||
int ctor_vtbl_p;
|
||||
|
||||
/* This is a construction vtable if the RTTI type is not the most
|
||||
derived type in the hierarchy. */
|
||||
ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
|
||||
|
||||
if (BINFO_NEW_VTABLE_MARKED (binfo, t)
|
||||
/* We need a new vtable, even for a primary base, when we're
|
||||
building a construction vtable. */
|
||||
|| (ctor_vtbl_p && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))))
|
||||
if (BINFO_NEW_VTABLE_MARKED (orig_binfo, t))
|
||||
{
|
||||
tree vtbl;
|
||||
tree index;
|
||||
@ -6963,14 +7012,14 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
|
||||
TREE_CONSTANT (vtbl) = 1;
|
||||
|
||||
/* For an ordinary vtable, set BINFO_VTABLE. */
|
||||
if (!ctor_vtbl_p)
|
||||
if (same_type_p (BINFO_TYPE (rtti_binfo), t))
|
||||
BINFO_VTABLE (binfo) = vtbl;
|
||||
/* For a construction vtable, we can't overwrite BINFO_VTABLE.
|
||||
So, we make a TREE_LIST. Later, dfs_fixup_binfo_vtbls will
|
||||
straighten this out. */
|
||||
else
|
||||
BINFO_VTABLE (binfo) = build_tree_list (vtbl,
|
||||
BINFO_VTABLE (binfo));
|
||||
BINFO_VTABLE (binfo) =
|
||||
tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo));
|
||||
}
|
||||
|
||||
return inits;
|
||||
|
@ -1781,8 +1781,6 @@ struct lang_type
|
||||
my_friendly_assert (!BINFO_PRIMARY_MARKED_P (B), 20000517), \
|
||||
my_friendly_assert (CLASSTYPE_VFIELDS (BINFO_TYPE (B)) != NULL_TREE, \
|
||||
20000517))
|
||||
#define CLEAR_BINFO_NEW_VTABLE_MARKED(B, C) \
|
||||
(BINFO_NEW_VTABLE_MARKED (B, C) = 0)
|
||||
|
||||
/* Nonzero means this class has done dfs_pushdecls. */
|
||||
#define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
|
||||
|
43
gcc/cp/pt.c
43
gcc/cp/pt.c
@ -6361,25 +6361,34 @@ tsubst (t, args, complain, in_decl)
|
||||
{
|
||||
case TEMPLATE_TYPE_PARM:
|
||||
case TEMPLATE_TEMPLATE_PARM:
|
||||
r = copy_node (t);
|
||||
TEMPLATE_TYPE_PARM_INDEX (r)
|
||||
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
|
||||
r, levels);
|
||||
TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
|
||||
TYPE_MAIN_VARIANT (r) = r;
|
||||
TYPE_POINTER_TO (r) = NULL_TREE;
|
||||
TYPE_REFERENCE_TO (r) = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
|
||||
&& TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
|
||||
if (CP_TYPE_QUALS (t))
|
||||
{
|
||||
tree argvec = tsubst (TYPE_TI_ARGS (t), args,
|
||||
complain, in_decl);
|
||||
if (argvec == error_mark_node)
|
||||
return error_mark_node;
|
||||
r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
|
||||
r = cp_build_qualified_type_real (r, CP_TYPE_QUALS (t),
|
||||
complain);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = copy_node (t);
|
||||
TEMPLATE_TYPE_PARM_INDEX (r)
|
||||
= reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t),
|
||||
r, levels);
|
||||
TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r);
|
||||
TYPE_MAIN_VARIANT (r) = r;
|
||||
TYPE_POINTER_TO (r) = NULL_TREE;
|
||||
TYPE_REFERENCE_TO (r) = NULL_TREE;
|
||||
|
||||
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
|
||||
= tree_cons (TYPE_TI_TEMPLATE (t), argvec, NULL_TREE);
|
||||
if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
|
||||
&& TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
|
||||
{
|
||||
tree argvec = tsubst (TYPE_TI_ARGS (t), args,
|
||||
complain, in_decl);
|
||||
if (argvec == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r)
|
||||
= tree_cons (TYPE_TI_TEMPLATE (t), argvec, NULL_TREE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user