+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
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.
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
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);
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
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
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. */
/* 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);
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))
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));
-
- return NULL_TREE;
-}
+
+ /* Add the initializer for the secondary vptr itself. */
+ data->inits = tree_cons (NULL_TREE, binfo_ctor_vtable (binfo), data->inits);
-/* 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. */
+ /* Advance the vtt index. */
+ data->index = size_binop (PLUS_EXPR, data->index,
+ TYPE_SIZE_UNIT (ptr_type_node));
-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;
+ return NULL_TREE;
}
-/* 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;
}
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);
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)
{
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. */