* class.c (build_vbase_path): Use reverse_path.
(finish_base_struct): Move warnings for inaccessible bases to
layout_basetypes.
(modify_one_vtable): Remove check of TREE_USED (binfo).
(fixup_vtable_deltas1): Likewise.
* cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here.
(xref_tag): Remove binfos parameter.
(make_binfo): Remove chain parameter.
(reverse_path): Add copy parameter.
* decl.c (init_decl_processing): Change calls to xref_tag.
(xref_tag): Remove binfos parameter.
(xref_basetypes): Change calls to make_binfo.
* decl2.c (grok_x_components): Change calls to xref_tag.
(handle_class_head): Likewise.
* friend.c (do_friend): Likewise.
* lex.c (make_lang_type): Change calls to make_binfo.
* parse.y (structsp): Change calls to xref_tag.
(named_complex_class_head_sans_basetype): Likewise.
(named_class_head): Likewise.
* rtti.c (init_rtti_processing): Likewise.
* search.c (compute_access): Change calls to reverse_path.
(dfs_get_vbase_types): Change calls to make_binfo.
(get_vbase_types): Remove dead code.
* tree.c (unshare_base_binfos): Change calls to make_binfo.
(layout_basetypes): Warn here about inaccessible bases.
(make_binfo): Remove chain parameter.
(reverse_path): Add copy parameter.
From-SVN: r22021
+1998-08-27 Mark Mitchell <mark@markmitchell.com>
+
+ * class.c (build_vbase_path): Use reverse_path.
+ (finish_base_struct): Move warnings for inaccessible bases to
+ layout_basetypes.
+ (modify_one_vtable): Remove check of TREE_USED (binfo).
+ (fixup_vtable_deltas1): Likewise.
+ * cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here.
+ (xref_tag): Remove binfos parameter.
+ (make_binfo): Remove chain parameter.
+ (reverse_path): Add copy parameter.
+ * decl.c (init_decl_processing): Change calls to xref_tag.
+ (xref_tag): Remove binfos parameter.
+ (xref_basetypes): Change calls to make_binfo.
+ * decl2.c (grok_x_components): Change calls to xref_tag.
+ (handle_class_head): Likewise.
+ * friend.c (do_friend): Likewise.
+ * lex.c (make_lang_type): Change calls to make_binfo.
+ * parse.y (structsp): Change calls to xref_tag.
+ (named_complex_class_head_sans_basetype): Likewise.
+ (named_class_head): Likewise.
+ * rtti.c (init_rtti_processing): Likewise.
+ * search.c (compute_access): Change calls to reverse_path.
+ (dfs_get_vbase_types): Change calls to make_binfo.
+ (get_vbase_types): Remove dead code.
+ * tree.c (unshare_base_binfos): Change calls to make_binfo.
+ (layout_basetypes): Warn here about inaccessible bases.
+ (make_binfo): Remove chain parameter.
+ (reverse_path): Add copy parameter.
+
1998-08-27 Jason Merrill <jason@yorick.cygnus.com>
* class.c: #if 0 complete_type_p.
if (BINFO_INHERITANCE_CHAIN (path))
{
- tree reverse_path = NULL_TREE;
-
push_expression_obstack ();
- while (path)
- {
- tree r = copy_node (path);
- BINFO_INHERITANCE_CHAIN (r) = reverse_path;
- reverse_path = r;
- path = BINFO_INHERITANCE_CHAIN (path);
- }
- path = reverse_path;
+ path = reverse_path (path, /*copy=*/1);
pop_obstacks ();
}
}
}
- /* This comment said "Must come after offsets are fixed for all bases."
- Well, now this happens before the offsets are fixed, but it seems to
- work fine. Guess we'll see... */
- for (i = 0; i < n_baseclasses; i++)
- {
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- tree basetype = BINFO_TYPE (base_binfo);
-
- if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
- {
- cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
- basetype, t);
- }
- }
- {
- tree v = get_vbase_types (t);
-
- for (; v; v = TREE_CHAIN (v))
- {
- tree basetype = BINFO_TYPE (v);
- if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
- {
- if (extra_warnings)
- cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
- basetype, t);
- }
- }
- }
-
{
tree vfields;
/* Find the base class with the largest number of virtual functions. */
BINFO_OFFSET (binfo));
this_offset = ssize_binop (MINUS_EXPR, offset, base_offset);
- /* Make sure we can modify the derived association with immunity. */
- if (TREE_USED (binfo))
- my_friendly_assert (0, 999);
-
if (binfo == TYPE_BINFO (t))
{
/* In this case, it is *type*'s vtable we are modifying.
if (! tree_int_cst_equal (this_offset, delta))
{
/* Make sure we can modify the derived association with immunity. */
- if (TREE_USED (binfo))
- my_friendly_assert (0, 999);
-
if (binfo == TYPE_BINFO (t))
{
/* In this case, it is *type*'s vtable we are modifying.
\f
/* Additional macros for inheritance information. */
+/* The BINFO_INHERITANCE_CHAIN is used opposite to the description in
+ gcc/tree.h. In particular if D is derived from B then the BINFO
+ for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to
+ D. In tree.h, this pointer is described as pointing in other
+ direction.
+
+ After a call to get_vbase_types, the vbases are chained together in
+ depth-first order via TREE_CHAIN. Other than that, TREE_CHAIN is
+ unused. */
+
#ifdef MI_MATRIX
/* When building a matrix to determine by a single lookup
whether one class is derived from another or not,
extern int copy_args_p PROTO((tree));
extern int grok_ctor_properties PROTO((tree, tree));
extern void grok_op_properties PROTO((tree, int, int));
-extern tree xref_tag PROTO((tree, tree, tree, int));
+extern tree xref_tag PROTO((tree, tree, int));
extern tree xref_tag_from_type PROTO((tree, tree, int));
extern void xref_basetypes PROTO((tree, tree, tree, tree));
extern tree start_enum PROTO((tree));
extern tree hash_tree_chain PROTO((tree, tree));
extern tree hash_chainon PROTO((tree, tree));
extern tree get_decl_list PROTO((tree));
-extern tree make_binfo PROTO((tree, tree, tree, tree, tree));
+extern tree make_binfo PROTO((tree, tree, tree, tree));
extern tree binfo_value PROTO((tree, tree));
-extern tree reverse_path PROTO((tree));
+extern tree reverse_path PROTO((tree, int));
extern int count_functions PROTO((tree));
extern int is_overloaded_fn PROTO((tree));
extern tree get_first_fn PROTO((tree));
if (flag_honor_std)
push_namespace (get_identifier ("std"));
bad_alloc_type_node = xref_tag
- (class_type_node, get_identifier ("bad_alloc"), NULL_TREE, 1);
+ (class_type_node, get_identifier ("bad_alloc"), 1);
if (flag_honor_std)
pop_namespace ();
newtype = build_exception_variant
scope.) */
tree
-xref_tag (code_type_node, name, binfo, globalize)
+xref_tag (code_type_node, name, globalize)
tree code_type_node;
- tree name, binfo;
+ tree name;
int globalize;
{
enum tag_types tag_code;
redeclare_class_template (ref, current_template_parms);
}
- if (binfo)
- xref_basetypes (code_type_node, name, ref, binfo);
-
/* Until the type is defined, tentatively accept whatever
structure tag the user hands us. */
if (TYPE_SIZE (ref) == NULL_TREE
if (id == NULL_TREE)
id = TYPE_IDENTIFIER (old);
- return xref_tag (code_type_node, id, NULL_TREE, globalize);
+ return xref_tag (code_type_node, id, globalize);
}
void
base_binfo = make_binfo (integer_zero_node, basetype,
TYPE_BINFO_VTABLE (basetype),
- TYPE_BINFO_VIRTUALS (basetype), NULL_TREE);
+ TYPE_BINFO_VIRTUALS (basetype));
TREE_VEC_ELT (binfos, i) = base_binfo;
TREE_VIA_PUBLIC (base_binfo) = via_public;
x = DECL_NAME (CLASSTYPE_TI_TEMPLATE (t));
else
x = TYPE_IDENTIFIER (t);
- t = xref_tag (tcode, x, NULL_TREE, 0);
+ t = xref_tag (tcode, x, 0);
}
if (ANON_UNION_TYPE_P (t))
case ENUMERAL_TYPE:
tcode = enum_type_node;
- t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0);
+ t = xref_tag (tcode, TYPE_IDENTIFIER (t), 0);
x = grok_enum_decls (NULL_TREE);
return x;
break;
cp_error ("no file-scope type named `%D'", id);
id = xref_tag
- (aggr, make_anon_name (), NULL_TREE, 1);
+ (aggr, make_anon_name (), 1);
return TYPE_MAIN_DECL (id);
}
if (decl == NULL_TREE)
{
cp_warning ("implicitly declaring `%T' as struct", declarator);
- decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
+ decl = xref_tag (record_type_node, declarator, 1);
decl = TYPE_MAIN_DECL (decl);
}
CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
- TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE,
- NULL_TREE);
+ TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
/* Make sure this is laid out, for ease of use later.
77, 78, 79, 80, 81, 82, 83, 84
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 3 "/usr/lib/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
#endif
#endif
\f
-#line 196 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 196 "/usr/lib/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
break;}
case 471:
#line 2086 "parse.y"
-{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, NULL_TREE, 1);
+{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, 1);
yyval.ftype.new_type_flag = 0; ;
break;}
case 472:
#line 2089 "parse.y"
-{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, NULL_TREE, 1);
+{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, 1);
yyval.ftype.new_type_flag = 0; ;
break;}
case 473:
break;}
case 497:
#line 2196 "parse.y"
-{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, NULL_TREE, 0); ;
+{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, 0); ;
break;}
case 498:
#line 2201 "parse.y"
-{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, NULL_TREE, 1); ;
+{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, 1); ;
break;}
case 499:
#line 2204 "parse.y"
break;}
case 501:
#line 2228 "parse.y"
-{ yyval.ttype = xref_tag (yyval.ttype, make_anon_name (), NULL_TREE, 0);
+{ yyval.ttype = xref_tag (yyval.ttype, make_anon_name (), 0);
yyungetc ('{', 1); ;
break;}
case 504:
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 498 "/usr/lib/bison.simple"
\f
yyvsp -= yylen;
yyssp -= yylen;
$$.new_type_flag = 1;
check_for_missing_semicolon ($$.t); }
| ENUM identifier
- { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1);
+ { $$.t = xref_tag (enum_type_node, $2, 1);
$$.new_type_flag = 0; }
| ENUM complex_type_name
- { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1);
+ { $$.t = xref_tag (enum_type_node, $2, 1);
$$.new_type_flag = 0; }
| TYPENAME_KEYWORD typename_sub
{ $$.t = $2;
do_xref_defn:
/* empty */ %prec EMPTY
- { $<ttype>$ = xref_tag (current_aggr, $<ttype>0, NULL_TREE, 0); }
+ { $<ttype>$ = xref_tag (current_aggr, $<ttype>0, 0); }
;
named_class_head:
named_class_head_sans_basetype %prec EMPTY
- { $$ = xref_tag (current_aggr, $1, NULL_TREE, 1); }
+ { $$ = xref_tag (current_aggr, $1, 1); }
| named_class_head_sans_basetype_defn do_xref_defn
maybe_base_class_list %prec EMPTY
{
unnamed_class_head:
aggr '{'
- { $$ = xref_tag ($$, make_anon_name (), NULL_TREE, 0);
+ { $$ = xref_tag ($$, make_anon_name (), 0);
yyungetc ('{', 1); }
;
if (flag_honor_std)
push_namespace (get_identifier ("std"));
type_info_type_node = xref_tag
- (class_type_node, get_identifier ("type_info"), NULL_TREE, 1);
+ (class_type_node, get_identifier ("type_info"), 1);
if (flag_honor_std)
pop_namespace ();
tinfo_fn_id = get_identifier ("__tf");
}
/* must reverse more than one element */
- basetype_path = reverse_path (basetype_path);
+ basetype_path = reverse_path (basetype_path, /*copy=*/0);
types = basetype_path;
via_protected = 0;
access = access_default_node;
else
break;
}
- reverse_path (basetype_path);
+ reverse_path (basetype_path, /*copy=*/0);
/* No special visibilities apply. Use normal rules. */
{
if (TREE_VIA_VIRTUAL (binfo) && ! BINFO_VBASE_MARKED (binfo))
{
- vbase_types = make_binfo (integer_zero_node, binfo,
- BINFO_VTABLE (binfo),
- BINFO_VIRTUALS (binfo), vbase_types);
- TREE_VIA_VIRTUAL (vbase_types) = 1;
+ tree new_vbase = make_binfo (integer_zero_node, binfo,
+ BINFO_VTABLE (binfo),
+ BINFO_VIRTUALS (binfo));
+ TREE_CHAIN (new_vbase) = vbase_types;
+ TREE_VIA_VIRTUAL (new_vbase) = 1;
+ vbase_types = new_vbase;
SET_BINFO_VBASE_MARKED (binfo);
}
SET_BINFO_MARKED (binfo);
tree vbases;
tree binfo;
- if (TREE_CODE (type) == TREE_VEC)
- binfo = type;
- else
- binfo = TYPE_BINFO (type);
-
+ binfo = TYPE_BINFO (type);
vbase_types = NULL_TREE;
dfs_walk (binfo, dfs_get_vbase_types, unmarkedp);
dfs_walk (binfo, dfs_unmark, markedp);
dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap, dfs_no_overlap_yet);
return found_overlap;
}
+
= make_binfo (BINFO_OFFSET (base_base_binfo),
base_base_binfo,
BINFO_VTABLE (base_base_binfo),
- BINFO_VIRTUALS (base_base_binfo),
- chain);
+ BINFO_VIRTUALS (base_base_binfo));
chain = TREE_VEC_ELT (base_binfos, j);
TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
tree binfos = TYPE_BINFO_BASETYPES (rec);
int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
- /* Get all the virtual base types that this type uses.
- The TREE_VALUE slot holds the virtual baseclass type. */
- tree vbase_types = get_vbase_types (rec);
+ tree vbase_types;
unsigned int record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));
unsigned int desired_align;
record_align = MAX (record_align, STRUCTURE_SIZE_BOUNDARY);
#endif
- CLASSTYPE_VBASECLASSES (rec) = vbase_types;
+ /* Get all the virtual base types that this type uses. The
+ TREE_VALUE slot holds the virtual baseclass type. Note that
+ get_vbase_types makes copies of the virtual base BINFOs, so that
+ the vbase_types are unshared. */
+ CLASSTYPE_VBASECLASSES (rec) = vbase_types = get_vbase_types (rec);
my_friendly_assert (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST, 19970302);
const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec));
else
{
my_friendly_assert (TREE_TYPE (field) == basetype, 23897);
+
+ if (get_base_distance (basetype, rec, 0, (tree*)0) == -2)
+ cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
+ basetype, rec);
+
BINFO_OFFSET (base_binfo)
= size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)),
BITS_PER_UNIT));
{
BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec);
unshare_base_binfos (vbase_types);
+
+ if (extra_warnings)
+ {
+ tree basetype = BINFO_TYPE (vbase_types);
+ if (get_base_distance (basetype, rec, 0, (tree*)0) == -2)
+ cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
+ basetype, rec);
+ }
}
return max;
VTABLE is the virtual function table with which to initialize
sub-objects of type TYPE.
- VIRTUALS are the virtual functions sitting in VTABLE.
-
- CHAIN are more associations we must retain. */
+ VIRTUALS are the virtual functions sitting in VTABLE. */
tree
-make_binfo (offset, binfo, vtable, virtuals, chain)
+make_binfo (offset, binfo, vtable, virtuals)
tree offset, binfo;
tree vtable, virtuals;
- tree chain;
{
tree new_binfo = make_tree_vec (7);
tree type;
binfo = TYPE_BINFO (binfo);
}
- TREE_CHAIN (new_binfo) = chain;
- if (chain)
- TREE_USED (new_binfo) = TREE_USED (chain);
-
TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
BINFO_OFFSET (new_binfo) = offset;
BINFO_VTABLE (new_binfo) = vtable;
return get_binfo (elem, type, 0);
}
+/* Reverse the BINFO-chain given by PATH. (If the
+ BINFO_INHERITANCE_CHAIN points from base classes to derived
+ classes, it will instead point from derived classes to base
+ classes.) Returns the first node in the reversed chain. If COPY
+ is non-zero, the nodes are copied as the chain is traversed. */
+
tree
-reverse_path (path)
+reverse_path (path, copy)
tree path;
+ int copy;
{
register tree prev = 0, tmp, next;
for (tmp = path; tmp; tmp = next)
{
+ if (copy)
+ tmp = copy_node (tmp);
next = BINFO_INHERITANCE_CHAIN (tmp);
BINFO_INHERITANCE_CHAIN (tmp) = prev;
prev = tmp;
--- /dev/null
+// Build don't link:
+
+struct B {
+ int i;
+};
+
+struct D: virtual public B {
+ int i;
+};
+
+struct D2 : public D {
+ void f() { i = 3; }
+};
--- /dev/null
+// Build don't link:
+
+struct B {
+ int i;
+};
+
+struct D: public B {
+ int i;
+};
+
+template <class T>
+struct D2 : public D {
+ void f() { i = 3; }
+};