class.c (VTT_TOP_LEVEL_P, [...]): Remove.
* class.c (VTT_TOP_LEVEL_P, VTT_MARKED_BINFO_P): Remove. (struct secondary_vptr_vtt_init_data_s): New. (build_vtt_inits): Adjust dfs_walkers. (dfs_build_secondary_vptr_vtt_inits): Caller data is a secondary_vptr_vtt_init_data_s structure. Adjust. (dfs_ctor_vtable_bases_queue_p): Remove. (dfs_fixup_binfo_vtbls): No need to clear BINFO_MARKED. Simplify. * pt.c (struct get_template_base_data_s): Remove. (get_template_base_r): Fold into get_template_base. (get_template_base): Walk base binfos directly in inheritance graph order. Remove duplicated changelog entries From-SVN: r88224
This commit is contained in:
parent
628f6a4e7c
commit
a3a0fc7f89
@ -1,3 +1,18 @@
|
||||
2004-09-28 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* class.c (VTT_TOP_LEVEL_P, VTT_MARKED_BINFO_P): Remove.
|
||||
(struct secondary_vptr_vtt_init_data_s): New.
|
||||
(build_vtt_inits): Adjust dfs_walkers.
|
||||
(dfs_build_secondary_vptr_vtt_inits): Caller data is a
|
||||
secondary_vptr_vtt_init_data_s structure. Adjust.
|
||||
(dfs_ctor_vtable_bases_queue_p): Remove.
|
||||
(dfs_fixup_binfo_vtbls): No need to clear BINFO_MARKED. Simplify.
|
||||
|
||||
* pt.c (struct get_template_base_data_s): Remove.
|
||||
(get_template_base_r): Fold into get_template_base.
|
||||
(get_template_base): Walk base binfos directly in inheritance
|
||||
graph order.
|
||||
|
||||
2004-09-27 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17642
|
||||
@ -29,7 +44,7 @@
|
||||
|
||||
2004-09-27 Matt Austern <austern@apple.com>
|
||||
|
||||
* cp/parser.c (struct cp_token): new one-bit field , implicit_extern_c
|
||||
* cp/parser.c (struct cp_token): New one-bit field , implicit_extern_c
|
||||
(cp_lexer_get_preprocessor_token): Set implicit_extern_c for
|
||||
tokens that come from headers that are implicitly extern "C".
|
||||
(struct cp_parser): new one-bit field, implicit_extern_c.
|
||||
@ -73,40 +88,6 @@
|
||||
return NULL on failure.
|
||||
(unify): Remove error_mark_node check from get_template_base result.
|
||||
|
||||
2004-09-27 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17585
|
||||
* cp-tree.h (shared_member_p): Declare.
|
||||
* search.c (shared_member_p): Give it external linkage.
|
||||
* semantics.c (finish_qualified_id_expr): Use it.
|
||||
(finish_id_expression): Likewise.
|
||||
|
||||
PR c++/17585
|
||||
* semantics.c (finish_id_expression): Do not add "this->" to
|
||||
static member functions.
|
||||
|
||||
2004-09-27 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/17681
|
||||
* error.c (dump_type): Change TREE_VEC case into TREE_BINFO.
|
||||
|
||||
* class.c (struct count_depth_data): Remove.
|
||||
(dfs_depth_post, dfs_depth_q): Remove.
|
||||
(find_final_overrider): Use number of vbase classes as depth
|
||||
bound.
|
||||
|
||||
* cp-tree.h (types_overlap_p): Remove.
|
||||
* search.c (struct overlap_info): Remove.
|
||||
(dfs_check_overlap, dfs_no_overlap_yet, types_overlap_p): Remove.
|
||||
|
||||
* pt.c (GTB_VIA_VIRTUAL, GTB_IGNORE_TYPE): Remove.
|
||||
(get_template_base_recursive): Remove. Replace with ...
|
||||
(get_template_base_r): ... this.
|
||||
(struct get_template_base_data_s): New.
|
||||
(get_template_base): Use get_template_base_r via dfs_walk. Always
|
||||
return NULL on failure.
|
||||
(unify): Remove error_mark_node check from get_template_base result.
|
||||
|
||||
2004-09-24 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* parser.c (cp_parser_expression_stack): Clarify why it is
|
||||
|
165
gcc/cp/class.c
165
gcc/cp/class.c
@ -188,7 +188,6 @@ static void build_vtt (tree);
|
||||
static tree binfo_ctor_vtable (tree);
|
||||
static tree *build_vtt_inits (tree, tree, tree *, tree *);
|
||||
static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
|
||||
static tree dfs_ctor_vtable_bases_queue_p (tree, int, void *data);
|
||||
static tree dfs_fixup_binfo_vtbls (tree, void *);
|
||||
static int record_subobject_offset (tree, tree, splay_tree);
|
||||
static int check_subobject_offset (tree, tree, splay_tree);
|
||||
@ -206,12 +205,6 @@ static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
|
||||
static tree end_of_base (tree);
|
||||
static tree get_vcall_index (tree, tree);
|
||||
|
||||
/* Macros for dfs walking during vtt construction. See
|
||||
dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits
|
||||
and dfs_fixup_binfo_vtbls. */
|
||||
#define VTT_TOP_LEVEL_P(NODE) (TREE_LIST_CHECK (NODE)->common.unsigned_flag)
|
||||
#define VTT_MARKED_BINFO_P(NODE) TREE_USED (NODE)
|
||||
|
||||
/* Variables shared between class.c and call.c. */
|
||||
|
||||
#ifdef GATHER_STATISTICS
|
||||
@ -6716,6 +6709,22 @@ binfo_ctor_vtable (tree binfo)
|
||||
return vt;
|
||||
}
|
||||
|
||||
/* Data for secondary VTT initialization. */
|
||||
typedef struct secondary_vptr_vtt_init_data_s
|
||||
{
|
||||
/* Is this the primary VTT? */
|
||||
bool top_level_p;
|
||||
|
||||
/* Current index into the VTT. */
|
||||
tree index;
|
||||
|
||||
/* TREE_LIST of initializers built up. */
|
||||
tree inits;
|
||||
|
||||
/* The type being constructed by this secondary VTT. */
|
||||
tree type_being_constructed;
|
||||
} secondary_vptr_vtt_init_data;
|
||||
|
||||
/* 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
|
||||
@ -6725,12 +6734,13 @@ binfo_ctor_vtable (tree binfo)
|
||||
vtables for the BINFO-in-T variant. */
|
||||
|
||||
static tree *
|
||||
build_vtt_inits (tree binfo, tree t, tree* inits, tree* index)
|
||||
build_vtt_inits (tree binfo, tree t, tree *inits, tree *index)
|
||||
{
|
||||
int i;
|
||||
tree b;
|
||||
tree init;
|
||||
tree secondary_vptrs;
|
||||
secondary_vptr_vtt_init_data data;
|
||||
int top_level_p = same_type_p (TREE_TYPE (binfo), t);
|
||||
|
||||
/* We only need VTTs for subobjects with virtual bases. */
|
||||
@ -6766,26 +6776,21 @@ build_vtt_inits (tree binfo, tree t, tree* inits, tree* index)
|
||||
/* Add secondary virtual pointers for all subobjects of BINFO with
|
||||
either virtual bases or reachable along a virtual path, except
|
||||
subobjects that are non-virtual primary bases. */
|
||||
secondary_vptrs = tree_cons (t, NULL_TREE, BINFO_TYPE (binfo));
|
||||
TREE_TYPE (secondary_vptrs) = *index;
|
||||
VTT_TOP_LEVEL_P (secondary_vptrs) = top_level_p;
|
||||
VTT_MARKED_BINFO_P (secondary_vptrs) = 0;
|
||||
data.top_level_p = top_level_p;
|
||||
data.index = *index;
|
||||
data.inits = NULL;
|
||||
data.type_being_constructed = BINFO_TYPE (binfo);
|
||||
|
||||
dfs_walk_real (binfo,
|
||||
dfs_build_secondary_vptr_vtt_inits,
|
||||
NULL,
|
||||
dfs_ctor_vtable_bases_queue_p,
|
||||
secondary_vptrs);
|
||||
VTT_MARKED_BINFO_P (secondary_vptrs) = 1;
|
||||
dfs_walk (binfo, dfs_unmark, dfs_ctor_vtable_bases_queue_p,
|
||||
secondary_vptrs);
|
||||
dfs_walk_real (binfo, dfs_build_secondary_vptr_vtt_inits,
|
||||
NULL, unmarkedp, &data);
|
||||
dfs_walk (binfo, dfs_unmark, markedp, 0);
|
||||
|
||||
*index = TREE_TYPE (secondary_vptrs);
|
||||
*index = data.index;
|
||||
|
||||
/* The secondary vptrs come back in reverse order. After we reverse
|
||||
them, and add the INITS, the last init will be the first element
|
||||
of the chain. */
|
||||
secondary_vptrs = TREE_VALUE (secondary_vptrs);
|
||||
secondary_vptrs = data.inits;
|
||||
if (secondary_vptrs)
|
||||
{
|
||||
*inits = nreverse (secondary_vptrs);
|
||||
@ -6793,8 +6798,9 @@ build_vtt_inits (tree binfo, tree t, tree* inits, tree* index)
|
||||
gcc_assert (*inits == NULL_TREE);
|
||||
}
|
||||
|
||||
/* Add the secondary VTTs for virtual bases. */
|
||||
if (top_level_p)
|
||||
/* Add the secondary VTTs for virtual bases in inheritance graph
|
||||
order. */
|
||||
for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
|
||||
{
|
||||
if (!BINFO_VIRTUAL_P (b))
|
||||
@ -6802,121 +6808,84 @@ build_vtt_inits (tree binfo, tree t, tree* inits, tree* index)
|
||||
|
||||
inits = build_vtt_inits (b, t, inits, index);
|
||||
}
|
||||
|
||||
if (!top_level_p)
|
||||
{
|
||||
tree data = tree_cons (t, binfo, NULL_TREE);
|
||||
VTT_TOP_LEVEL_P (data) = 0;
|
||||
VTT_MARKED_BINFO_P (data) = 0;
|
||||
|
||||
dfs_walk (binfo, dfs_fixup_binfo_vtbls,
|
||||
dfs_ctor_vtable_bases_queue_p,
|
||||
data);
|
||||
}
|
||||
else
|
||||
/* Remove the ctor vtables we created. */
|
||||
dfs_walk (binfo, dfs_fixup_binfo_vtbls, 0, binfo);
|
||||
|
||||
return inits;
|
||||
}
|
||||
|
||||
/* Called from build_vtt_inits via dfs_walk. BINFO is the binfo for the base
|
||||
in most derived. DATA is a TREE_LIST who's TREE_CHAIN is the type of the
|
||||
base being constructed whilst this secondary vptr is live. The
|
||||
TREE_TOP_LEVEL flag indicates that this is the primary VTT. */
|
||||
in most derived. DATA is a SECONDARY_VPTR_VTT_INIT_DATA structure. */
|
||||
|
||||
static tree
|
||||
dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data)
|
||||
dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_)
|
||||
{
|
||||
tree l;
|
||||
tree t;
|
||||
tree init;
|
||||
tree index;
|
||||
int top_level_p;
|
||||
secondary_vptr_vtt_init_data *data = (secondary_vptr_vtt_init_data *)data_;
|
||||
|
||||
l = (tree) data;
|
||||
t = TREE_CHAIN (l);
|
||||
top_level_p = VTT_TOP_LEVEL_P (l);
|
||||
|
||||
BINFO_MARKED (binfo) = 1;
|
||||
|
||||
/* We don't care about bases that don't have vtables. */
|
||||
if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
|
||||
return NULL_TREE;
|
||||
|
||||
/* We're only interested in proper subobjects of T. */
|
||||
if (same_type_p (BINFO_TYPE (binfo), t))
|
||||
/* We're only interested in proper subobjects of the type being
|
||||
constructed. */
|
||||
if (same_type_p (BINFO_TYPE (binfo), data->type_being_constructed))
|
||||
return NULL_TREE;
|
||||
|
||||
/* We're not interested in non-virtual primary bases. */
|
||||
if (!BINFO_VIRTUAL_P (binfo) && BINFO_PRIMARY_P (binfo))
|
||||
return NULL_TREE;
|
||||
|
||||
/* If BINFO has virtual bases or is reachable via a virtual path
|
||||
from T, it'll have a secondary vptr. */
|
||||
/* We're only interested in bases with virtual bases or reachable
|
||||
via a virtual path from the type being constructed. */
|
||||
if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
|
||||
&& !binfo_via_virtual (binfo, t))
|
||||
&& !binfo_via_virtual (binfo, data->type_being_constructed))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Record the index where this secondary vptr can be found. */
|
||||
index = TREE_TYPE (l);
|
||||
if (top_level_p)
|
||||
if (data->top_level_p)
|
||||
{
|
||||
gcc_assert (!BINFO_VPTR_INDEX (binfo));
|
||||
BINFO_VPTR_INDEX (binfo) = index;
|
||||
}
|
||||
TREE_TYPE (l) = size_binop (PLUS_EXPR, index,
|
||||
TYPE_SIZE_UNIT (ptr_type_node));
|
||||
BINFO_VPTR_INDEX (binfo) = data->index;
|
||||
|
||||
/* Add the initializer for the secondary vptr itself. */
|
||||
if (top_level_p && BINFO_VIRTUAL_P (binfo))
|
||||
{
|
||||
/* 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_P (binfo))
|
||||
binfo = BINFO_INHERITANCE_CHAIN (binfo);
|
||||
if (BINFO_VIRTUAL_P (binfo))
|
||||
{
|
||||
/* It's a primary virtual base, and this is not a
|
||||
construction vtable. Find the base this is primary of in
|
||||
the inheritance graph, and use that base's vtable
|
||||
now. */
|
||||
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));
|
||||
|
||||
/* Add the initializer for the secondary vptr itself. */
|
||||
data->inits = tree_cons (NULL_TREE, binfo_ctor_vtable (binfo), data->inits);
|
||||
|
||||
/* Advance the vtt index. */
|
||||
data->index = size_binop (PLUS_EXPR, data->index,
|
||||
TYPE_SIZE_UNIT (ptr_type_node));
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* dfs_walk_real predicate for building vtables. DATA is a TREE_LIST,
|
||||
VTT_MARKED_BINFO_P indicates whether marked or unmarked bases
|
||||
should be walked. TREE_PURPOSE is the TREE_TYPE that dominates the
|
||||
hierarchy. */
|
||||
|
||||
static tree
|
||||
dfs_ctor_vtable_bases_queue_p (tree derived, int ix,
|
||||
void* data)
|
||||
{
|
||||
tree binfo = BINFO_BASE_BINFO (derived, ix);
|
||||
|
||||
if (!BINFO_MARKED (binfo) == VTT_MARKED_BINFO_P ((tree) data))
|
||||
return NULL_TREE;
|
||||
return binfo;
|
||||
}
|
||||
|
||||
/* Called from build_vtt_inits via dfs_walk. After building constructor
|
||||
vtables and generating the sub-vtt from them, we need to restore the
|
||||
BINFO_VTABLES that were scribbled on. DATA is a TREE_LIST whose
|
||||
TREE_VALUE is the TREE_TYPE of the base whose sub vtt was generated. */
|
||||
/* Called from build_vtt_inits via dfs_walk. After building
|
||||
constructor vtables and generating the sub-vtt from them, we need
|
||||
to restore the BINFO_VTABLES that were scribbled on. DATA is the
|
||||
binfo of the base whose sub vtt was generated. */
|
||||
|
||||
static tree
|
||||
dfs_fixup_binfo_vtbls (tree binfo, void* data)
|
||||
{
|
||||
BINFO_MARKED (binfo) = 0;
|
||||
|
||||
/* We don't care about bases that don't have vtables. */
|
||||
if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
|
||||
return NULL_TREE;
|
||||
tree vtable = BINFO_VTABLE (binfo);
|
||||
|
||||
/* If we scribbled the construction vtable vptr into BINFO, clear it
|
||||
out now. */
|
||||
if (BINFO_VTABLE (binfo)
|
||||
&& TREE_CODE (BINFO_VTABLE (binfo)) == TREE_LIST
|
||||
&& (TREE_PURPOSE (BINFO_VTABLE (binfo))
|
||||
== TREE_VALUE ((tree) data)))
|
||||
BINFO_VTABLE (binfo) = TREE_CHAIN (BINFO_VTABLE (binfo));
|
||||
if (vtable && TREE_CODE (vtable) == TREE_LIST
|
||||
&& (TREE_PURPOSE (vtable) == (tree) data))
|
||||
BINFO_VTABLE (binfo) = TREE_CHAIN (vtable);
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
82
gcc/cp/pt.c
82
gcc/cp/pt.c
@ -148,7 +148,6 @@ static tree process_partial_specialization (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_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);
|
||||
@ -9475,30 +9474,31 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg)
|
||||
return arg;
|
||||
}
|
||||
|
||||
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. */
|
||||
/* Given a template type PARM and a class type ARG, find the unique
|
||||
base type in ARG that is an instance of PARM. We do not examine
|
||||
ARG itself; only its base-classes. If there is not exactly one
|
||||
appropriate base class, return NULL_TREE. PARM may be the type of
|
||||
a partial specialization, as well as a plain template type. Used
|
||||
by unify. */
|
||||
|
||||
static tree
|
||||
get_template_base_r (tree arg_binfo,
|
||||
void *data_)
|
||||
get_template_base (tree tparms, tree targs, tree parm, tree arg)
|
||||
{
|
||||
get_template_base_data *data = data_;
|
||||
tree rval = NULL_TREE;
|
||||
tree binfo;
|
||||
|
||||
/* Do not look at the most derived binfo -- that's not a proper
|
||||
base. */
|
||||
if (BINFO_INHERITANCE_CHAIN (arg_binfo))
|
||||
gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
|
||||
|
||||
binfo = TYPE_BINFO (complete_type (arg));
|
||||
if (!binfo)
|
||||
/* The type could not be completed. */
|
||||
return NULL_TREE;
|
||||
|
||||
/* Walk in inheritance graph order. The search order is not
|
||||
important, and this avoids multiple walks of virtual bases. */
|
||||
for (binfo = TREE_CHAIN (binfo); binfo; binfo = TREE_CHAIN (binfo))
|
||||
{
|
||||
tree r = try_class_unification (data->tparms, data->targs,
|
||||
data->parm, BINFO_TYPE (arg_binfo));
|
||||
tree r = try_class_unification (tparms, targs, parm, BINFO_TYPE (binfo));
|
||||
|
||||
if (r)
|
||||
{
|
||||
@ -9510,48 +9510,14 @@ get_template_base_r (tree arg_binfo,
|
||||
deduction fails.
|
||||
|
||||
applies. */
|
||||
if (data->rval && !same_type_p (r, data->rval))
|
||||
{
|
||||
data->rval = NULL_TREE;
|
||||
/* Terminate the walk with any non-NULL value. */
|
||||
return r;
|
||||
}
|
||||
if (rval && !same_type_p (r, rval))
|
||||
return NULL_TREE;
|
||||
|
||||
data->rval = r;
|
||||
rval = r;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Given a template type PARM and a class type ARG, find the unique
|
||||
base type in ARG that is an instance of PARM. We do not examine
|
||||
ARG itself; only its base-classes. If there is no appropriate base
|
||||
class, return NULL_TREE. If there is more than one, return
|
||||
error_mark_node. PARM may be the type of a partial specialization,
|
||||
as well as a plain template type. Used by unify. */
|
||||
|
||||
static tree
|
||||
get_template_base (tree tparms, tree targs, tree parm, tree arg)
|
||||
{
|
||||
get_template_base_data data;
|
||||
tree arg_binfo;
|
||||
|
||||
gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
|
||||
|
||||
arg_binfo = TYPE_BINFO (complete_type (arg));
|
||||
if (!arg_binfo)
|
||||
/* The type could not be completed. */
|
||||
return NULL_TREE;
|
||||
|
||||
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 data.rval;
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Returns the level of DECL, which declares a template parameter. */
|
||||
|
Loading…
Reference in New Issue
Block a user