Deleted Added
full compact
2c2
< Copyright (C) 1987, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
---
> Copyright (C) 1987, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
23c23
< /* High-level class interface. */
---
> /* High-level class interface. */
25a26
> #include "system.h"
27d27
< #include <stdio.h>
31a32
> #include "toplev.h"
40c41
< same. */
---
> same. */
75c76,78
< tree current_class_decl, C_C_D; /* PARM_DECL: the class instance variable */
---
> /* The current_class_ptr is the pointer to the current class.
> current_class_ref is the actual current class. */
> tree current_class_ptr, current_class_ref;
82a86,88
>
> struct base_info;
>
84c90,128
< tree the_null_vtable_entry;
---
> static void finish_struct_anon PROTO((tree));
> static tree build_vbase_pointer PROTO((tree, tree));
> static int complete_type_p PROTO((tree));
> static tree build_vtable_entry PROTO((tree, tree));
> static tree get_vtable_name PROTO((tree));
> static tree get_derived_offset PROTO((tree, tree));
> static tree get_basefndecls PROTO((tree, tree));
> static void set_rtti_entry PROTO((tree, tree, tree));
> static tree build_vtable PROTO((tree, tree));
> static void prepare_fresh_vtable PROTO((tree, tree));
> static void fixup_vtable_deltas1 PROTO((tree, tree));
> static void fixup_vtable_deltas PROTO((tree, int, tree));
> static void grow_method PROTO((tree, tree *));
> static void finish_vtbls PROTO((tree, int, tree));
> static void modify_vtable_entry PROTO((tree, tree, tree));
> static tree get_vtable_entry_n PROTO((tree, unsigned HOST_WIDE_INT));
> static void add_virtual_function PROTO((tree *, tree *, int *, tree, tree));
> static tree delete_duplicate_fields_1 PROTO((tree, tree));
> static void delete_duplicate_fields PROTO((tree));
> static void finish_struct_bits PROTO((tree, int));
> static int alter_access PROTO((tree, tree, tree, tree));
> static void handle_using_decl PROTO((tree, tree, tree, tree));
> static int overrides PROTO((tree, tree));
> static int strictly_overrides PROTO((tree, tree));
> static void merge_overrides PROTO((tree, tree, int, tree));
> static void override_one_vtable PROTO((tree, tree, tree));
> static void mark_overriders PROTO((tree, tree));
> static void check_for_override PROTO((tree, tree));
> static tree maybe_fixup_vptrs PROTO((tree, tree, tree));
> static tree get_class_offset_1 PROTO((tree, tree, tree, tree, tree));
> static tree get_class_offset PROTO((tree, tree, tree, tree));
> static void modify_one_vtable PROTO((tree, tree, tree, tree));
> static void modify_all_vtables PROTO((tree, tree, tree));
> static void modify_all_direct_vtables PROTO((tree, int, tree, tree,
> tree));
> static void modify_all_indirect_vtables PROTO((tree, int, int, tree,
> tree, tree));
> static void build_class_init_list PROTO((tree));
> static int finish_base_struct PROTO((tree, struct base_info *));
91c135
< tree lang_name_c, lang_name_cplusplus;
---
> tree lang_name_c, lang_name_cplusplus, lang_name_java;
94,95d137
< char *dont_allow_type_definitions;
<
100a143,152
> /* Constants used for access control. */
> tree access_default_node; /* 0 */
> tree access_public_node; /* 1 */
> tree access_protected_node; /* 2 */
> tree access_private_node; /* 3 */
> tree access_default_virtual_node; /* 4 */
> tree access_public_virtual_node; /* 5 */
> tree access_protected_virtual_node; /* 6 */
> tree access_private_virtual_node; /* 7 */
>
102a155
> #ifdef GATHER_STATISTICS
110a164
> #endif
113c167,168
< tree
---
>
> static tree
121c176
< return build_component_ref (exp, get_identifier (name), 0, 0);
---
> return build_component_ref (exp, get_identifier (name), NULL_TREE, 0);
125,126c180,182
< If we are going to be wrong, we must be conservative, and return 0. */
< int
---
> If we are going to be wrong, we must be conservative, and return 0. */
>
> static int
146c202
< /* fall through... */
---
> /* fall through... */
153c209
< /* fall through... */
---
> /* fall through... */
159c215
< /* fall through... */
---
> /* fall through... */
176a233
>
186c243
< int fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
---
> int fixed_type_p;
190a248,250
> if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE)
> return build1 (NOP_EXPR, type, expr);
>
193a254
> #if 0
197a259,260
> fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
> #else
199c262
< for a testcase. */
---
> for a testcase. */
200a264
> #endif
209a274
> push_expression_obstack ();
217a283
> pop_obstacks ();
233d298
< extern int flag_assume_nonnull_objects;
237c302
< find a path. */
---
> find a path. */
281c346,347
< TREE_TYPE (TREE_OPERAND (expr, 1)) = TREE_TYPE (nonnull_expr);
---
> TREE_TYPE (expr) = TREE_TYPE (TREE_OPERAND (expr, 1))
> = TREE_TYPE (nonnull_expr);
313c379,381
< offset = convert (type, offset);
---
> offset = cp_convert (type, offset);
> #if 0
> /* This shouldn't be necessary. (mrs) */
314a383
> #endif
352,357d420
< /* Virtual functions to be dealt with after laying out our base
< classes. We do all overrides after we layout virtual base classes.
< */
< static tree pending_hard_virtuals;
< static int doing_hard_virtuals;
<
363c426,427
< tree
---
>
> static tree
367d430
<
371,372c434
< extern tree make_thunk ();
< if (idelta)
---
> if (idelta && ! DECL_ABSTRACT_VIRTUAL_P (TREE_OPERAND (pfn, 0)))
387,389c449,451
< tree elems = tree_cons (NULL_TREE, delta,
< tree_cons (NULL_TREE, integer_zero_node,
< build_tree_list (NULL_TREE, pfn)));
---
> tree elems = expr_tree_cons (NULL_TREE, delta,
> expr_tree_cons (NULL_TREE, integer_zero_node,
> build_expr_list (NULL_TREE, pfn)));
392,395c454,456
< /* DELTA is constructed by `size_int', which means it may be an
< unsigned quantity on some platforms. Therefore, we cannot use
< `int_fits_type_p', because when DELTA is really negative,
< `force_fit_type' will make it look like a very large number. */
---
> /* DELTA used to be constructed by `size_int' and/or size_binop,
> which caused overflow problems when it was negative. That should
> be fixed now. */
397,405c458,465
< if ((TREE_INT_CST_LOW (TYPE_MAX_VALUE (delta_type_node))
< < TREE_INT_CST_LOW (delta))
< || (TREE_INT_CST_LOW (delta)
< < TREE_INT_CST_LOW (TYPE_MIN_VALUE (delta_type_node))))
< if (flag_huge_objects)
< sorry ("object size exceeds built-in limit for virtual function table implementation");
< else
< sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
<
---
> if (! int_fits_type_p (delta, delta_type_node))
> {
> if (flag_huge_objects)
> sorry ("object size exceeds built-in limit for virtual function table implementation");
> else
> sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
> }
>
419,421c479,482
< virtual function corresponding to INDEX. There are many special
< cases for INSTANCE which we take care of here, mainly to avoid
< creating extra tree nodes when we don't have to. */
---
> virtual function vtable element corresponding to INDEX. There are
> many special cases for INSTANCE which we take care of here, mainly
> to avoid creating extra tree nodes when we don't have to. */
>
423,425c484,485
< build_vfn_ref (ptr_to_instptr, instance, idx)
< tree *ptr_to_instptr, instance;
< tree idx;
---
> build_vtbl_ref (instance, idx)
> tree instance, idx;
427d486
< extern int building_cleanup;
434c493
< if (instance == C_C_D)
---
> if (instance == current_class_ref)
482,485c541,542
< /* Save the intermediate result in a SAVE_EXPR so we don't have to
< compute each component of the virtual function pointer twice. */
< if (!building_cleanup && TREE_CODE (aref) == INDIRECT_REF)
< TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
---
> return aref;
> }
486a544,557
> /* Given an object INSTANCE, return an expression which yields the
> virtual function corresponding to INDEX. There are many special
> cases for INSTANCE which we take care of here, mainly to avoid
> creating extra tree nodes when we don't have to. */
>
> tree
> build_vfn_ref (ptr_to_instptr, instance, idx)
> tree *ptr_to_instptr, instance;
> tree idx;
> {
> tree aref = build_vtbl_ref (instance, idx);
>
> /* When using thunks, there is no extra delta, and we get the pfn
> directly. */
489c560,561
< else
---
>
> if (ptr_to_instptr)
491,497c563,572
< if (ptr_to_instptr)
< *ptr_to_instptr
< = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
< *ptr_to_instptr,
< convert (ptrdiff_type_node,
< build_component_ref (aref, delta_identifier, 0, 0)));
< return build_component_ref (aref, pfn_identifier, 0, 0);
---
> /* Save the intermediate result in a SAVE_EXPR so we don't have to
> compute each component of the virtual function pointer twice. */
> if (TREE_CODE (aref) == INDIRECT_REF)
> TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
>
> *ptr_to_instptr
> = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
> *ptr_to_instptr,
> cp_convert (ptrdiff_type_node,
> build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
498a574,575
>
> return build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
502a580
>
508,509c586,587
< char *buf = (char *)alloca (strlen (VTABLE_NAME_FORMAT)
< + IDENTIFIER_LENGTH (type_id) + 2);
---
> char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
> + IDENTIFIER_LENGTH (type_id) + 2);
524a603,670
> /* Return the offset to the main vtable for a given base BINFO. */
>
> tree
> get_vfield_offset (binfo)
> tree binfo;
> {
> tree tmp
> = size_binop (FLOOR_DIV_EXPR,
> DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))),
> size_int (BITS_PER_UNIT));
> tmp = convert (sizetype, tmp);
> return size_binop (PLUS_EXPR, tmp, BINFO_OFFSET (binfo));
> }
>
> /* Get the offset to the start of the original binfo that we derived
> this binfo from. If we find TYPE first, return the offset only
> that far. The shortened search is useful because the this pointer
> on method calling is expected to point to a DECL_CONTEXT (fndecl)
> object, and not a baseclass of it. */
>
> static tree
> get_derived_offset (binfo, type)
> tree binfo, type;
> {
> tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
> tree offset2;
> int i;
> while (BINFO_BASETYPES (binfo)
> && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
> {
> tree binfos = BINFO_BASETYPES (binfo);
> if (BINFO_TYPE (binfo) == type)
> break;
> binfo = TREE_VEC_ELT (binfos, i);
> }
> offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
> return size_binop (MINUS_EXPR, offset1, offset2);
> }
>
> /* Update the rtti info for this class. */
>
> static void
> set_rtti_entry (virtuals, offset, type)
> tree virtuals, offset, type;
> {
> tree vfn;
>
> if (flag_rtti)
> vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type));
> else
> vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, size_zero_node);
> TREE_CONSTANT (vfn) = 1;
>
> if (! flag_vtable_thunks)
> TREE_VALUE (virtuals) = build_vtable_entry (offset, vfn);
> else
> {
> tree voff = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
> TREE_CONSTANT (voff) = 1;
>
> TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, voff);
>
> /* The second slot is for the tdesc pointer when thunks are used. */
> TREE_VALUE (TREE_CHAIN (virtuals))
> = build_vtable_entry (integer_zero_node, vfn);
> }
> }
>
528a675
>
537a685,686
> tree offset;
>
539a689,693
>
> /* Now do rtti stuff. */
> offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE);
> offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset);
> set_rtti_entry (virtuals, offset, type);
555c709,710
< IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl);
---
> decl = pushdecl_top_level (decl);
> SET_IDENTIFIER_GLOBAL_VALUE (name, decl);
560a716
> DECL_ARTIFICIAL (decl) = 1;
581,582c737
< /* Given a base type PARENT, and a derived type TYPE, build
< a name which distinguishes exactly the PARENT member of TYPE's type.
---
> extern tree signed_size_zero_node;
584,585c739,742
< FORMAT is a string which controls how sprintf formats the name
< we have generated.
---
> /* Give TYPE a new virtual function table which is initialized
> with a skeleton-copy of its original initialization. The only
> entry that changes is the `delta' entry, so we can really
> share a lot of structure.
587c744,745
< For example, given
---
> FOR_TYPE is the derived type which caused this table to
> be needed.
589c747
< class A; class B; class C : A, B;
---
> BINFO is the type association which provided TYPE for FOR_TYPE.
591c749,751
< it is possible to distinguish "A" from "C's A". And given
---
> The order in which vtables are built (by calling this function) for
> an object must remain the same, otherwise a binary incompatibility
> can result. */
593,606c753,755
< class L;
< class A : L; class B : L; class C : A, B;
<
< it is possible to distinguish "L" from "A's L", and also from
< "C's L from A".
<
< Make sure to use the DECL_ASSEMBLER_NAME of the TYPE_NAME of the
< type, as template have DECL_NAMEs like: X<int>, whereas the
< DECL_ASSEMBLER_NAME is set to be something the assembler can handle.
< */
< static tree
< build_type_pathname (format, parent, type)
< char *format;
< tree parent, type;
---
> static void
> prepare_fresh_vtable (binfo, for_type)
> tree binfo, for_type;
608,609c757,764
< extern struct obstack temporary_obstack;
< char *first, *base, *name;
---
> tree basetype;
> tree orig_decl = BINFO_VTABLE (binfo);
> tree name;
> tree new_decl;
> tree offset;
> tree path = binfo;
> char *buf, *buf2;
> char joiner = '_';
611d765
< tree id;
613,621d766
< parent = TYPE_MAIN_VARIANT (parent);
<
< /* Remember where to cut the obstack to. */
< first = obstack_base (&temporary_obstack);
<
< /* Put on TYPE+PARENT. */
< obstack_grow (&temporary_obstack,
< TYPE_ASSEMBLER_NAME_STRING (type),
< TYPE_ASSEMBLER_NAME_LENGTH (type));
623,625c768
< obstack_1grow (&temporary_obstack, JOINER);
< #else
< obstack_1grow (&temporary_obstack, '_');
---
> joiner = JOINER;
627,632d769
< obstack_grow0 (&temporary_obstack,
< TYPE_ASSEMBLER_NAME_STRING (parent),
< TYPE_ASSEMBLER_NAME_LENGTH (parent));
< i = obstack_object_size (&temporary_obstack);
< base = obstack_base (&temporary_obstack);
< obstack_finish (&temporary_obstack);
634,639c771
< /* Put on FORMAT+TYPE+PARENT. */
< obstack_blank (&temporary_obstack, strlen (format) + i + 1);
< name = obstack_base (&temporary_obstack);
< sprintf (name, format, base);
< id = get_identifier (name);
< obstack_free (&temporary_obstack, first);
---
> basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo));
641,642c773,774
< return id;
< }
---
> buf2 = TYPE_ASSEMBLER_NAME_STRING (basetype);
> i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1;
644,655c776,787
< /* Update the rtti info for this class. */
< static void
< set_rtti_entry (virtuals, offset, type)
< tree virtuals, offset, type;
< {
< if (! flag_vtable_thunks)
< TREE_VALUE (virtuals)
< = build_vtable_entry (offset,
< (flag_rtti
< ? build_t_desc (type, 0)
< : integer_zero_node));
< else
---
> /* We know that the vtable that we are going to create doesn't exist
> yet in the global namespace, and when we finish, it will be
> pushed into the global namespace. In complex MI hierarchies, we
> have to loop while the name we are thinking of adding is globally
> defined, adding more name components to the vtable name as we
> loop, until the name is unique. This is because in complex MI
> cases, we might have the same base more than once. This means
> that the order in which this function is called for vtables must
> remain the same, otherwise binary compatibility can be
> compromised. */
>
> while (1)
657,658c789,791
< tree vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
< TREE_CONSTANT (vfn) = 1;
---
> char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type)
> + 1 + i);
> char *new_buf2;
660,667c793,797
< TREE_VALUE (virtuals)
< = build_vtable_entry (integer_zero_node, vfn);
< /* The second slot is for the tdesc pointer when thunks are used. */
< vfn = flag_rtti
< ? build_t_desc (type, 0)
< : integer_zero_node;
< vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, vfn);
< TREE_CONSTANT (vfn) = 1;
---
> sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner,
> buf2);
> buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + strlen (buf1) + 1);
> sprintf (buf, VTABLE_NAME_FORMAT, buf1);
> name = get_identifier (buf);
669,672c799,800
< TREE_VALUE (TREE_CHAIN (virtuals))
< = build_vtable_entry (integer_zero_node, vfn);
< }
< }
---
> /* If this name doesn't clash, then we can use it, otherwise
> we add more to the name until it is unique. */
674,677c802,803
< /* Give TYPE a new virtual function table which is initialized
< with a skeleton-copy of its original initialization. The only
< entry that changes is the `delta' entry, so we can really
< share a lot of structure.
---
> if (! IDENTIFIER_GLOBAL_VALUE (name))
> break;
679,680c805
< FOR_TYPE is the derived type which caused this table to
< be needed.
---
> /* Set values for next loop through, if the name isn't unique. */
682,694c807
< BINFO is the type association which provided TYPE for FOR_TYPE. */
< static void
< prepare_fresh_vtable (binfo, for_type)
< tree binfo, for_type;
< {
< tree basetype = BINFO_TYPE (binfo);
< tree orig_decl = BINFO_VTABLE (binfo);
< /* This name is too simplistic. We can have multiple basetypes for
< for_type, and we really want different names. (mrs) */
< tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type);
< tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
< tree path, offset;
< int result;
---
> path = BINFO_INHERITANCE_CHAIN (path);
695a809,850
> /* We better not run out of stuff to make it unique. */
> my_friendly_assert (path != NULL_TREE, 368);
>
> basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path));
>
> if (for_type == basetype)
> {
> /* If we run out of basetypes in the path, we have already
> found created a vtable with that name before, we now
> resort to tacking on _%d to distinguish them. */
> int j = 2;
> i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i + 1 + 3;
> buf1 = (char *) alloca (i);
> do {
> sprintf (buf1, "%s%c%s%c%d",
> TYPE_ASSEMBLER_NAME_STRING (basetype), joiner,
> buf2, joiner, j);
> buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
> + strlen (buf1) + 1);
> sprintf (buf, VTABLE_NAME_FORMAT, buf1);
> name = get_identifier (buf);
>
> /* If this name doesn't clash, then we can use it,
> otherwise we add something different to the name until
> it is unique. */
> } while (++j <= 999 && IDENTIFIER_GLOBAL_VALUE (name));
>
> /* Hey, they really like MI don't they? Increase the 3
> above to 6, and the 999 to 999999. :-) */
> my_friendly_assert (j <= 999, 369);
>
> break;
> }
>
> i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i;
> new_buf2 = (char *) alloca (i);
> sprintf (new_buf2, "%s%c%s",
> TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, buf2);
> buf2 = new_buf2;
> }
>
> new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
698a854
> DECL_ARTIFICIAL (new_decl) = 1;
712,713c868,879
< offset = BINFO_OFFSET (binfo_member (BINFO_TYPE (binfo),
< CLASSTYPE_VBASECLASSES (for_type)));
---
> {
> tree binfo1 = binfo_member (BINFO_TYPE (binfo),
> CLASSTYPE_VBASECLASSES (for_type));
>
> /* XXX - This should never happen, if it does, the caller should
> ensure that the binfo is from for_type's binfos, not from any
> base type's. We can remove all this code after a while. */
> if (binfo1 != binfo)
> warning ("internal inconsistency: binfo offset error for rtti");
>
> offset = BINFO_OFFSET (binfo1);
> }
718c884
< size_binop (MINUS_EXPR, integer_zero_node, offset),
---
> ssize_binop (MINUS_EXPR, integer_zero_node, offset),
735a902
> #if 0
739a907
>
759a928
> #endif
779c948
< /* We can dispatch this, through any overridden base function. */
---
> /* We can dispatch this, through any overridden base function. */
787c956
< /* Access the virtual function table entry i. VIRTUALS is the virtual
---
> /* Access the virtual function table entry N. VIRTUALS is the virtual
788a958
>
809,811c979,982
< static tree
< add_virtual_function (pending_virtuals, has_virtual, fndecl, t)
< tree pending_virtuals;
---
>
> static void
> add_virtual_function (pv, phv, has_virtual, fndecl, t)
> tree *pv, *phv;
814c985
< tree t; /* Structure type. */
---
> tree t; /* Structure type. */
815a987,989
> tree pending_virtuals = *pv;
> tree pending_hard_virtuals = *phv;
>
838,842c1012,1013
< if (flag_rtti && *has_virtual == 0)
< {
< /* CLASSTYPE_RTTI is only used as a Boolean (NULL or not). */
< CLASSTYPE_RTTI (t) = integer_one_node;
< }
---
> /* We remember that this was the base sub-object for rtti. */
> CLASSTYPE_RTTI (t) = t;
854c1025
< tree index;
---
> tree idx;
860c1031
< index = build_int_2 (i, 0);
---
> idx = build_int_2 (i, 0);
862c1033
< index_table[i] = index;
---
> index_table[i] = idx;
865c1036
< index = index_table[i];
---
> idx = index_table[i];
867,868c1038,1039
< /* Now assign virtual dispatch information. */
< DECL_VINDEX (fndecl) = index;
---
> /* Now assign virtual dispatch information. */
> DECL_VINDEX (fndecl) = idx;
882c1053,1054
< return pending_virtuals;
---
> *pv = pending_virtuals;
> *phv = pending_hard_virtuals;
894a1067
>
899,902d1071
< /* We must make a copy of METHOD here, since we must be sure that
< we have exclusive title to this method's DECL_CHAIN. */
< tree decl;
<
904,913d1072
< {
< decl = copy_node (method);
< if (DECL_RTL (decl) == 0
< && (!processing_template_decl
< || !uses_template_parms (decl)))
< {
< make_function_rtl (decl);
< DECL_RTL (method) = DECL_RTL (decl);
< }
< }
916,920c1075
< {
< /* Take care not to hide destructor. */
< DECL_CHAIN (decl) = DECL_CHAIN (*fields);
< DECL_CHAIN (*fields) = decl;
< }
---
> *fields = build_overload (method, *fields);
924c1079
< if (TYPE_IDENTIFIER (type) == DECL_NAME (decl))
---
> if (TYPE_IDENTIFIER (type) == DECL_NAME (method))
926,927c1081,1090
< TREE_VEC_ELT (method_vec, 0) = decl;
< TREE_VEC_LENGTH (method_vec) = 1;
---
> /* ??? Is it possible for there to have been enough room in the
> current chunk for the tree_vec structure but not a tree_vec
> plus a tree*? Will this work in that case? */
> obstack_free (current_obstack, method_vec);
> obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *));
> if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)))
> TREE_VEC_ELT (method_vec, 1) = method;
> else
> TREE_VEC_ELT (method_vec, 0) = method;
> TREE_VEC_LENGTH (method_vec) = 2;
935,937c1098,1100
< obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *));
< TREE_VEC_ELT (method_vec, 1) = decl;
< TREE_VEC_LENGTH (method_vec) = 2;
---
> obstack_blank (current_obstack, sizeof (struct tree_vec) + 2*sizeof (tree *));
> TREE_VEC_ELT (method_vec, 2) = method;
> TREE_VEC_LENGTH (method_vec) = 3;
949c1112
< if (TYPE_IDENTIFIER (type) == DECL_NAME (decl))
---
> if (TYPE_IDENTIFIER (type) == DECL_NAME (method))
951,956c1114,1118
< /* TREE_VEC_ELT (method_vec, 0) = decl; */
< if (decl != TREE_VEC_ELT (method_vec, 0))
< {
< DECL_CHAIN (decl) = TREE_VEC_ELT (method_vec, 0);
< TREE_VEC_ELT (method_vec, 0) = decl;
< }
---
> int idx = !!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method));
> /* TREE_VEC_ELT (method_vec, idx) = method; */
> if (method != TREE_VEC_ELT (method_vec, idx))
> TREE_VEC_ELT (method_vec, idx) =
> build_overload (method, TREE_VEC_ELT (method_vec, idx));
995c1157
< TREE_VEC_ELT (method_vec, len) = decl;
---
> TREE_VEC_ELT (method_vec, len) = method;
1012,1013c1174,1175
< DECL_CONTEXT (decl) = type;
< DECL_CLASS_CONTEXT (decl) = type;
---
> DECL_CONTEXT (method) = type;
> DECL_CLASS_CONTEXT (method) = type;
1032a1195
>
1077,1083c1240,1258
< else if (TREE_CODE (field) == TYPE_DECL
< && TREE_CODE (x) == TYPE_DECL)
< cp_error_at ("duplicate nested type `%D'", x);
< else if (TREE_CODE (field) == TYPE_DECL
< || TREE_CODE (x) == TYPE_DECL)
< cp_error_at ("duplicate field `%D' (as type and non-type)",
< x);
---
> else if (DECL_DECLARES_TYPE_P (field)
> && DECL_DECLARES_TYPE_P (x))
> {
> if (comptypes (TREE_TYPE (field), TREE_TYPE (x), 1))
> continue;
> cp_error_at ("duplicate nested type `%D'", x);
> }
> else if (DECL_DECLARES_TYPE_P (field)
> || DECL_DECLARES_TYPE_P (x))
> {
> /* Hide tag decls. */
> if ((TREE_CODE (field) == TYPE_DECL
> && DECL_ARTIFICIAL (field))
> || (TREE_CODE (x) == TYPE_DECL
> && DECL_ARTIFICIAL (x)))
> continue;
> cp_error_at ("duplicate field `%D' (as type and non-type)",
> x);
> }
1106,1107c1281,1284
< /* Change the access of FDECL to ACCESS in T.
< Return 1 if change was legit, otherwise return 0. */
---
> /* Change the access of FDECL to ACCESS in T. The access to FDECL is
> along the path given by BINFO. Return 1 if change was legit,
> otherwise return 0. */
>
1109c1286
< alter_access (t, fdecl, access)
---
> alter_access (t, binfo, fdecl, access)
1110a1288
> tree binfo;
1112c1290
< enum access_type access;
---
> tree access;
1115c1293
< if (elem && TREE_VALUE (elem) != (tree)access)
---
> if (elem)
1117c1295
< if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
---
> if (TREE_VALUE (elem) != access)
1119c1297,1301
< cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl));
---
> if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
> cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl));
> else
> error ("conflicting access specifications for field `%s', ignored",
> IDENTIFIER_POINTER (DECL_NAME (fdecl)));
1122,1123c1304,1308
< error ("conflicting access specifications for field `%s', ignored",
< IDENTIFIER_POINTER (DECL_NAME (fdecl)));
---
> {
> /* They're changing the access to the same thing they changed
> it to before. That's OK. */
> ;
> }
1125c1310
< else if (TREE_PRIVATE (fdecl))
---
> else
1127,1145c1312,1314
< if (access != access_private)
< cp_error_at ("cannot make private `%D' non-private", fdecl);
< goto alter;
< }
< else if (TREE_PROTECTED (fdecl))
< {
< if (access != access_protected)
< cp_error_at ("cannot make protected `%D' non-protected", fdecl);
< goto alter;
< }
< /* ARM 11.3: an access declaration may not be used to restrict access
< to a member that is accessible in the base class. */
< else if (access != access_public)
< cp_error_at ("cannot reduce access of public member `%D'", fdecl);
< else if (elem == NULL_TREE)
< {
< alter:
< DECL_ACCESS (fdecl) = tree_cons (t, (tree)access,
< DECL_ACCESS (fdecl));
---
> enforce_access (binfo, fdecl);
>
> DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
1151,1161c1320,1322
< /* Return the offset to the main vtable for a given base BINFO. */
< tree
< get_vfield_offset (binfo)
< tree binfo;
< {
< return size_binop (PLUS_EXPR,
< size_binop (FLOOR_DIV_EXPR,
< DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))),
< size_int (BITS_PER_UNIT)),
< BINFO_OFFSET (binfo));
< }
---
> /* Process the USING_DECL, which is a member of T. The METHOD_VEC, if
> non-NULL, is the methods of T. The FIELDS are the fields of T.
> Returns 1 if the USING_DECL was valid, 0 otherwise. */
1163,1170c1324,1329
< /* Get the offset to the start of the original binfo that we derived
< this binfo from. If we find TYPE first, return the offset only
< that far. The shortened search is useful because the this pointer
< on method calling is expected to point to a DECL_CONTEXT (fndecl)
< object, and not a baseclass of it. */
< static tree
< get_derived_offset (binfo, type)
< tree binfo, type;
---
> void
> handle_using_decl (using_decl, t, method_vec, fields)
> tree using_decl;
> tree t;
> tree method_vec;
> tree fields;
1172,1173c1331,1339
< tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
< tree offset2;
---
> tree ctype = DECL_INITIAL (using_decl);
> tree name = DECL_NAME (using_decl);
> tree access
> = TREE_PRIVATE (using_decl) ? access_private_node
> : TREE_PROTECTED (using_decl) ? access_protected_node
> : access_public_node;
> tree fdecl, binfo;
> tree flist = NULL_TREE;
> tree tmp;
1175,1176c1341,1353
< while (BINFO_BASETYPES (binfo)
< && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
---
> int n_methods;
>
> binfo = binfo_or_else (ctype, t);
> if (! binfo)
> return;
>
> if (name == constructor_name (ctype)
> || name == constructor_name_full (ctype))
> cp_error_at ("using-declaration for constructor", using_decl);
>
> fdecl = lookup_member (binfo, name, 0, 0);
>
> if (!fdecl)
1178,1181c1355,1356
< tree binfos = BINFO_BASETYPES (binfo);
< if (BINFO_TYPE (binfo) == type)
< break;
< binfo = TREE_VEC_ELT (binfos, i);
---
> cp_error_at ("no members matching `%D' in `%#T'", using_decl, ctype);
> return;
1183,1184c1358,1409
< offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
< return size_binop (MINUS_EXPR, offset1, offset2);
---
>
> /* Functions are represented as TREE_LIST, with the purpose
> being the type and the value the functions. Other members
> come as themselves. */
> if (TREE_CODE (fdecl) == TREE_LIST)
> /* Ignore base type this came from. */
> fdecl = TREE_VALUE (fdecl);
>
> if (TREE_CODE (fdecl) == OVERLOAD)
> {
> /* We later iterate over all functions. */
> flist = fdecl;
> fdecl = OVL_FUNCTION (flist);
> }
>
> name = DECL_NAME (fdecl);
> n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
> for (i = 2; i < n_methods; i++)
> if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
> == name)
> {
> cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
> cp_error_at (" because of local method `%#D' with same name",
> OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
> return;
> }
>
> if (! DECL_LANG_SPECIFIC (fdecl))
> /* We don't currently handle DECL_ACCESS for TYPE_DECLs; just return. */
> return;
>
> for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))
> if (DECL_NAME (tmp) == name)
> {
> cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
> cp_error_at (" because of local field `%#D' with same name", tmp);
> return;
> }
>
> /* Make type T see field decl FDECL with access ACCESS.*/
> if (flist)
> {
> while (flist)
> {
> if (alter_access (t, binfo, OVL_FUNCTION (flist),
> access) == 0)
> return;
> flist = OVL_CHAIN (flist);
> }
> }
> else
> alter_access (t, binfo, fdecl, access);
1205c1430
< /* Punt until this is implemented. */
---
> /* Punt until this is implemented. */
1338,1341c1563,1569
< if (member_init_list)
< CLASSTYPE_BASE_INIT_LIST (type) = build_tree_list (base_init_list, member_init_list);
< else
< CLASSTYPE_BASE_INIT_LIST (type) = base_init_list;
---
> {
> if (member_init_list)
> CLASSTYPE_BASE_INIT_LIST (type) =
> build_tree_list (base_init_list, member_init_list);
> else
> CLASSTYPE_BASE_INIT_LIST (type) = base_init_list;
> }
1352a1581
> tree rtti;
1355,1356d1583
< char cant_synth_copy_ctor;
< char cant_synth_asn_ref;
1358d1584
< char needs_virtual_dtor;
1375c1601
< or -1 if no such base class.
---
> or -1 if no such base class. */
1377,1378d1602
< Note that at this point TYPE_BINFO (t) != t_binfo. */
<
1380c1604
< finish_base_struct (t, b, t_binfo)
---
> finish_base_struct (t, b)
1383d1606
< tree t_binfo;
1385c1608
< tree binfos = BINFO_BASETYPES (t_binfo);
---
> tree binfos = TYPE_BINFO_BASETYPES (t);
1394a1618,1624
> /* Effective C++ rule 14. We only need to check TYPE_VIRTUAL_P
> here because the case of virtual functions but non-virtual
> dtor is handled in finish_struct_1. */
> if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
> && TYPE_HAS_DESTRUCTOR (basetype))
> cp_warning ("base class `%#T' has a non-virtual destructor", basetype);
>
1412,1413c1642
< if (TYPE_HAS_INIT_REF (basetype)
< && !TYPE_HAS_CONST_INIT_REF (basetype))
---
> if (! TYPE_HAS_CONST_INIT_REF (basetype))
1415,1418d1643
< if (! TYPE_HAS_INIT_REF (basetype)
< || (TYPE_HAS_NONPUBLIC_CTOR (basetype) == 2
< && ! is_friend_type (t, basetype)))
< b->cant_synth_copy_ctor = 1;
1435,1439d1659
< if (! TYPE_HAS_ASSIGN_REF (basetype)
< || TYPE_HAS_ABSTRACT_ASSIGN_REF (basetype)
< || (TYPE_HAS_NONPUBLIC_ASSIGN_REF (basetype) == 2
< && ! is_friend_type (t, basetype)))
< b->cant_synth_asn_ref = 1;
1451,1488d1670
< if (! TREE_VIA_VIRTUAL (base_binfo)
< #if 0
< /* This cannot be done, as prepare_fresh_vtable wants to modify
< binfos associated with vfields anywhere in the hierarchy, not
< just immediate base classes. Due to unsharing, the compiler
< might consume 3% more memory on a real program.
< */
< && ! BINFO_OFFSET_ZEROP (base_binfo)
< #endif
< && BINFO_BASETYPES (base_binfo))
< {
< tree base_binfos = BINFO_BASETYPES (base_binfo);
< tree chain = NULL_TREE;
< int j;
<
< /* Now unshare the structure beneath BASE_BINFO. */
< for (j = TREE_VEC_LENGTH (base_binfos)-1;
< j >= 0; j--)
< {
< tree base_base_binfo = TREE_VEC_ELT (base_binfos, j);
< if (! TREE_VIA_VIRTUAL (base_base_binfo))
< TREE_VEC_ELT (base_binfos, j)
< = make_binfo (BINFO_OFFSET (base_base_binfo),
< base_base_binfo,
< BINFO_VTABLE (base_base_binfo),
< BINFO_VIRTUALS (base_base_binfo),
< chain);
< 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);
< BINFO_INHERITANCE_CHAIN (chain) = base_binfo;
< }
<
< /* Completely unshare potentially shared data, and
< update what is ours. */
< propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));
< }
<
1494,1496c1676,1679
< /* If there's going to be a destructor needed, make
< sure it will be virtual. */
< b->needs_virtual_dtor = 1;
---
> /* Ensure that this is set from at least a virtual base
> class. */
> if (b->rtti == NULL_TREE)
> b->rtti = CLASSTYPE_RTTI (basetype);
1510,1511c1693,1694
< BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);
< BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);
---
> TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);
> TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
1559,1560c1742,1743
< BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);
< BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);
---
> TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);
> TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
1586c1769,1771
< /* Must come after offsets are fixed for all bases. */
---
> /* 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... */
1592c1777
< if (get_base_distance (basetype, t_binfo, 0, (tree*)0) == -2)
---
> if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
1596,1597d1780
< b->cant_synth_asn_ref = 1;
< b->cant_synth_copy_ctor = 1;
1601c1784
< tree v = get_vbase_types (t_binfo);
---
> tree v = get_vbase_types (t);
1606c1789
< if (get_base_distance (basetype, t_binfo, 0, (tree*)0) == -2)
---
> if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
1611,1612d1793
< b->cant_synth_asn_ref = 1;
< b->cant_synth_copy_ctor = 1;
1632a1814,1818
>
> /* Update the rtti base if we have a non-virtual base class version
> of it. */
> b->rtti = CLASSTYPE_RTTI (BINFO_TYPE (TREE_VEC_ELT (binfos, first_vfn_base_index)));
>
1635,1644d1820
<
< static int
< typecode_p (type, code)
< tree type;
< enum tree_code code;
< {
< return (TREE_CODE (type) == code
< || (TREE_CODE (type) == REFERENCE_TYPE
< && TREE_CODE (TREE_TYPE (type)) == code));
< }
1647a1824
>
1654d1830
< tree method_vec = CLASSTYPE_METHOD_VEC (t);
1672a1849,1851
> TYPE_FIELDS (variants) = TYPE_FIELDS (t);
> TYPE_SIZE (variants) = TYPE_SIZE (t);
> TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
1691c1870
< an artificial abstract. */
---
> an artificial abstract. */
1709,1714c1888
< if (TYPE_HAS_CONVERSION (basetype))
< {
< TYPE_HAS_CONVERSION (t) = 1;
< TYPE_HAS_INT_CONVERSION (t) |= TYPE_HAS_INT_CONVERSION (basetype);
< TYPE_HAS_REAL_CONVERSION (t) |= TYPE_HAS_REAL_CONVERSION (basetype);
< }
---
> TYPE_HAS_CONVERSION (t) |= TYPE_HAS_CONVERSION (basetype);
1723,1724c1897,1904
< a register. */
< if (! TYPE_HAS_TRIVIAL_INIT_REF (t))
---
> a register.
>
> Also do this if the class has BLKmode but can still be returned in
> registers, since function_cannot_inline_p won't let us inline
> functions returning such a type. This affects the HP-PA. */
> if (! TYPE_HAS_TRIVIAL_INIT_REF (t)
> || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t)
> && CLASSTYPE_NON_AGGREGATE (t)))
1727,1728c1907
< if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
< DECL_MODE (TYPE_NAME (t)) = BLKmode;
---
> DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode;
1737,1738c1916,1919
< /* Add FN to the method_vec growing on the class_obstack. Used by
< finish_struct_methods. */
---
> /* Add FNDECL to the method_vec growing on the class_obstack. Used by
> finish_struct_methods. Note, FNDECL cannot be a constructor or
> destructor, those cases are handled by the caller. */
>
1740,1741c1921,1922
< grow_method (fn, method_vec_ptr)
< tree fn;
---
> grow_method (fndecl, method_vec_ptr)
> tree fndecl;
1745,1746c1926,1931
< tree *testp = &TREE_VEC_ELT (method_vec, 0);
< if (*testp == NULL_TREE)
---
>
> /* Start off past the constructors and destructor. */
> tree *testp = &TREE_VEC_ELT (method_vec, 2);
>
> while (testp < (tree *) obstack_next_free (&class_obstack)
> && (*testp == NULL_TREE || DECL_NAME (OVL_CURRENT (*testp)) != DECL_NAME (fndecl)))
1748,1755d1932
< while (((HOST_WIDE_INT) testp
< < (HOST_WIDE_INT) obstack_next_free (&class_obstack))
< && DECL_NAME (*testp) != DECL_NAME (fn))
< testp++;
< if ((HOST_WIDE_INT) testp
< < (HOST_WIDE_INT) obstack_next_free (&class_obstack))
< {
< tree x, prev_x;
1757,1784c1934,1935
< for (x = *testp; x; x = DECL_CHAIN (x))
< {
< if (DECL_NAME (fn) == ansi_opname[(int) DELETE_EXPR]
< || DECL_NAME (fn) == ansi_opname[(int) VEC_DELETE_EXPR])
< {
< /* ANSI C++ June 5 1992 WP 12.5.5.1 */
< cp_error_at ("`%D' overloaded", fn);
< cp_error_at ("previous declaration as `%D' here", x);
< }
< if (DECL_ASSEMBLER_NAME (fn)==DECL_ASSEMBLER_NAME (x))
< {
< /* We complain about multiple destructors on sight,
< so we do not repeat the warning here. Friend-friend
< ambiguities are warned about outside this loop. */
< if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn)))
< cp_error_at ("ambiguous method `%#D' in structure", fn);
< break;
< }
< prev_x = x;
< }
< if (x == 0)
< {
< if (*testp)
< DECL_CHAIN (prev_x) = fn;
< else
< *testp = fn;
< }
< }
---
> if (testp < (tree *) obstack_next_free (&class_obstack))
> *testp = build_overload (fndecl, *testp);
1787c1938
< obstack_ptr_grow (&class_obstack, fn);
---
> obstack_ptr_grow (&class_obstack, fndecl);
1815c1966
< static tree
---
> tree
1822,1824c1973,1974
< tree save_fn_fields = tree_cons (NULL_TREE, NULL_TREE, fn_fields);
< tree lastp;
< tree name = constructor_name (t);
---
> tree save_fn_fields = fn_fields;
> tree ctor_name = constructor_name (t);
1830,1831c1980
< method_vec = make_node (TREE_VEC);
< /* Room has been saved for constructors and destructors. */
---
> method_vec = make_tree_vec (2);
1832a1982
>
1835d1984
< obstack_blank (&class_obstack, sizeof (struct tree_vec));
1837,1838c1986,1987
< /* First fill in entry 0 with the constructors, and the next few with
< type conversion operators (if any). */
---
> /* Save room for constructors and destructors. */
> obstack_blank (&class_obstack, sizeof (struct tree_vec) + sizeof (struct tree *));
1840c1989,1992
< for (lastp = save_fn_fields; fn_fields; fn_fields = TREE_CHAIN (lastp))
---
> /* First fill in entry 0 with the constructors, entry 1 with destructors,
> and the next few with type conversion operators (if any). */
>
> for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
1843,1844d1994
< if (fn_name == NULL_TREE)
< fn_name = name;
1855c2005
< if (fn_name == name)
---
> if (fn_name == ctor_name)
1873,1875c2023,2034
< /* Constructors are handled easily in search routines. */
< DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 0);
< TREE_VEC_ELT (method_vec, 0) = fn_fields;
---
> if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields)))
> {
> /* Destructors go in slot 1. */
> TREE_VEC_ELT (method_vec, 1) =
> build_overload (fn_fields, TREE_VEC_ELT (method_vec, 1));
> }
> else
> {
> /* Constructors go in slot 0. */
> TREE_VEC_ELT (method_vec, 0) =
> build_overload (fn_fields, TREE_VEC_ELT (method_vec, 0));
> }
1878,1897c2037
< {
< tree return_type = TREE_TYPE (TREE_TYPE (fn_fields));
<
< if (typecode_p (return_type, INTEGER_TYPE)
< || typecode_p (return_type, BOOLEAN_TYPE)
< || typecode_p (return_type, ENUMERAL_TYPE))
< TYPE_HAS_INT_CONVERSION (t) = 1;
< else if (typecode_p (return_type, REAL_TYPE))
< TYPE_HAS_REAL_CONVERSION (t) = 1;
<
< grow_method (fn_fields, &method_vec);
< }
< else
< {
< lastp = fn_fields;
< continue;
< }
<
< TREE_CHAIN (lastp) = TREE_CHAIN (fn_fields);
< TREE_CHAIN (fn_fields) = NULL_TREE;
---
> grow_method (fn_fields, &method_vec);
1900,1901c2040,2041
< fn_fields = TREE_CHAIN (save_fn_fields);
< while (fn_fields)
---
> fn_fields = save_fn_fields;
> for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields))
1903d2042
< tree nextp;
1905,1906d2043
< if (fn_name == NULL_TREE)
< fn_name = name;
1908,1909c2045,2046
< nextp = TREE_CHAIN (fn_fields);
< TREE_CHAIN (fn_fields) = NULL_TREE;
---
> if (fn_name == ctor_name || IDENTIFIER_TYPENAME_P (fn_name))
> continue;
1925d2061
< fn_fields = nextp;
1935c2071
< && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE)
---
> && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE)
1945c2081,2082
< if (nonprivate_method == 0)
---
> if (nonprivate_method == 0
> && warn_ctor_dtor_privacy)
1949,1952c2086,2087
< /* If there are constructors (and destructors), they are at the
< front. Place destructors at very front. Also warn if all
< constructors and/or destructors are private (in which case this
< class is effectively unusable. */
---
> /* Warn if all destructors are private (in which case this class is
> effectively unusable. */
1955c2090
< tree dtor, prev;
---
> tree dtor = TREE_VEC_ELT (method_vec, 1);
1957,1972d2091
< for (dtor = TREE_VEC_ELT (method_vec, 0);
< dtor;
< prev = dtor, dtor = DECL_CHAIN (dtor))
< {
< if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (dtor)))
< {
< if (TREE_PRIVATE (dtor)
< && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
< && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE
< && warn_ctor_dtor_privacy)
< cp_warning ("`%#T' only defines a private destructor and has no friends",
< t);
< break;
< }
< }
<
1976,1981c2095,2100
< else if (dtor != TREE_VEC_ELT (method_vec, 0))
< {
< DECL_CHAIN (prev) = DECL_CHAIN (dtor);
< DECL_CHAIN (dtor) = TREE_VEC_ELT (method_vec, 0);
< TREE_VEC_ELT (method_vec, 0) = dtor;
< }
---
> else if (TREE_PRIVATE (dtor)
> && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
> && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE
> && warn_ctor_dtor_privacy)
> cp_warning ("`%#T' only defines a private destructor and has no friends",
> t);
1988c2107
< && TREE_VEC_LENGTH (method_vec) > 1)
---
> && TREE_VEC_LENGTH (method_vec) > 2)
1995c2114
< for (i = 1; i < len; i++)
---
> for (i = 2; i < len; i++)
1998c2117,2118
< = get_baselinks (baselink_binfo, t, DECL_NAME (TREE_VEC_ELT (method_vec, i)));
---
> = get_baselinks (baselink_binfo, t,
> DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))));
2008,2043d2127
< /* Now add the methods to the TYPE_METHODS of T, arranged in a chain. */
< {
< tree x, last_x = NULL_TREE;
< int limit = TREE_VEC_LENGTH (method_vec);
<
< for (i = 1; i < limit; i++)
< {
< for (x = TREE_VEC_ELT (method_vec, i); x; x = DECL_CHAIN (x))
< {
< if (last_x != NULL_TREE)
< TREE_CHAIN (last_x) = x;
< last_x = x;
< }
< }
<
< /* Put ctors and dtors at the front of the list. */
< x = TREE_VEC_ELT (method_vec, 0);
< if (x)
< {
< while (DECL_CHAIN (x))
< {
< /* Let's avoid being circular about this. */
< if (x == DECL_CHAIN (x))
< break;
< TREE_CHAIN (x) = DECL_CHAIN (x);
< x = DECL_CHAIN (x);
< }
< if (TREE_VEC_LENGTH (method_vec) > 1)
< TREE_CHAIN (x) = TREE_VEC_ELT (method_vec, 1);
< else
< TREE_CHAIN (x) = NULL_TREE;
< }
< }
<
< TYPE_METHODS (t) = method_vec;
<
2047c2131
< /* Emit error when a duplicate definition of a type is seen. Patch up. */
---
> /* Emit error when a duplicate definition of a type is seen. Patch up. */
2061,2067c2145,2150
< anymore, so we unravel them.
< */
< /*
< * This used to be in finish_struct, but it turns out that the
< * TREE_CHAIN is used by dbxout_type_methods and perhaps some other things...
< */
< if (CLASSTYPE_METHOD_VEC(t))
---
> anymore, so we unravel them. */
>
> /* This used to be in finish_struct, but it turns out that the
> TREE_CHAIN is used by dbxout_type_methods and perhaps some other
> things... */
> if (CLASSTYPE_METHOD_VEC (t))
2069,2070c2152,2153
< tree tv = CLASSTYPE_METHOD_VEC(t);
< int i, len = TREE_VEC_LENGTH (tv);
---
> tree method_vec = CLASSTYPE_METHOD_VEC (t);
> int i, len = TREE_VEC_LENGTH (method_vec);
2073c2156
< tree unchain = TREE_VEC_ELT (tv, i);
---
> tree unchain = TREE_VEC_ELT (method_vec, i);
2076,2077c2159,2160
< TREE_CHAIN (unchain) = NULL_TREE;
< unchain = DECL_CHAIN(unchain);
---
> TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE;
> unchain = OVL_NEXT (unchain);
2098d2180
< CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
2109c2191,2192
< /* finish up all new vtables. */
---
> /* finish up all new vtables. */
>
2112c2195
< tree binfo, t;
---
> tree binfo;
2113a2197
> tree t;
2141,2142c2225,2226
< int is_not_base_vtable =
< i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
---
> int is_not_base_vtable
> = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
2152a2237
>
2157,2159c2242,2244
< /* Destructors have special names. */
< if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl)) &&
< DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
---
> /* Destructors have special names. */
> if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
> && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
2161,2162c2246,2247
< if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl)) ||
< DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
---
> if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl))
> || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
2166c2251
< tree rettype, base_rettype, types, base_types;
---
> tree types, base_types;
2228a2314
>
2254c2340
< derived binfos. */
---
> derived binfos. */
2261a2348
>
2290d2376
< tree old_rtti;
2336c2422
< this_offset = size_binop (MINUS_EXPR, offset, base_offset);
---
> this_offset = ssize_binop (MINUS_EXPR, offset, base_offset);
2372c2458,2459
< /* These are the ones that are not through virtual base classes. */
---
> /* These are the ones that are not through virtual base classes. */
>
2375c2462
< tree binfo, t, fndecl, pfn;
---
> tree binfo;
2376a2464
> tree t, fndecl, pfn;
2390,2391c2478,2479
< int is_not_base_vtable =
< i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
---
> int is_not_base_vtable
> = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
2397a2486
>
2430c2519,2520
< get_derived_offset (binfo, DECL_CONTEXT (fndecl)),
---
> get_derived_offset (binfo,
> DECL_CONTEXT (fndecl)),
2432c2522
< this_offset = size_binop (MINUS_EXPR, offset, base_offset);
---
> this_offset = ssize_binop (MINUS_EXPR, offset, base_offset);
2471a2562
>
2474c2565
< tree binfo, t;
---
> tree binfo;
2475a2567
> tree t;
2483,2484c2575,2576
< int is_not_base_vtable =
< i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
---
> int is_not_base_vtable
> = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
2495c2587,2588
< /* These are the ones that are through virtual base classes. */
---
> /* These are the ones that are through virtual base classes. */
>
2498c2591
< tree binfo, t, fndecl, pfn;
---
> tree binfo;
2499a2593
> tree t, fndecl, pfn;
2513,2514c2607,2608
< int is_not_base_vtable =
< i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
---
> int is_not_base_vtable
> = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
2529c2623
< vtable, over a virtual classes vtable. */
---
> vtable, over a virtual classes vtable. */
2536a2631
>
2560a2656
>
2570c2666
< reuse another vtable. */
---
> reuse another vtable. */
2585c2681
< /* First check to see if they are the same. */
---
> /* First check to see if they are the same. */
2588c2684
< /* No need to do anything. */
---
> /* No need to do anything. */
2643c2739,2740
< /* Make sure we search for it later. */
---
> DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1;
> /* Make sure we search for it later. */
2650,2651c2747,2748
< /* We can use integer_zero_node, as we will will core dump
< if this is used anyway. */
---
> /* We can use integer_zero_node, as we will core dump
> if this is used anyway. */
2659c2756
< /* Let's reuse the old vtable. */
---
> /* Let's reuse the old vtable. */
2669a2767
>
2672c2770
< tree binfo, old, t;
---
> tree binfo, old;
2673a2772
> tree t;
2689,2690c2788,2789
< int is_not_base_vtable =
< i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
---
> int is_not_base_vtable
> = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
2695a2795,3033
> /* Get the base virtual function declarations in T that are either
> overridden or hidden by FNDECL as a list. We set TREE_PURPOSE with
> the overrider/hider. */
>
> static tree
> get_basefndecls (fndecl, t)
> tree fndecl, t;
> {
> tree methods = TYPE_METHODS (t);
> tree base_fndecls = NULL_TREE;
> tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
> int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
>
> while (methods)
> {
> if (TREE_CODE (methods) == FUNCTION_DECL
> && DECL_VINDEX (methods) != NULL_TREE
> && DECL_NAME (fndecl) == DECL_NAME (methods))
> base_fndecls = temp_tree_cons (fndecl, methods, base_fndecls);
>
> methods = TREE_CHAIN (methods);
> }
>
> if (base_fndecls)
> return base_fndecls;
>
> for (i = 0; i < n_baseclasses; i++)
> {
> tree base_binfo = TREE_VEC_ELT (binfos, i);
> tree basetype = BINFO_TYPE (base_binfo);
>
> base_fndecls = chainon (get_basefndecls (fndecl, basetype),
> base_fndecls);
> }
>
> return base_fndecls;
> }
>
> /* Mark the functions that have been hidden with their overriders.
> Since we start out with all functions already marked with a hider,
> no need to mark functions that are just hidden. */
>
> static void
> mark_overriders (fndecl, base_fndecls)
> tree fndecl, base_fndecls;
> {
> while (base_fndecls)
> {
> if (overrides (TREE_VALUE (base_fndecls), fndecl))
> TREE_PURPOSE (base_fndecls) = fndecl;
>
> base_fndecls = TREE_CHAIN (base_fndecls);
> }
> }
>
> /* If this declaration supersedes the declaration of
> a method declared virtual in the base class, then
> mark this field as being virtual as well. */
>
> static void
> check_for_override (decl, ctype)
> tree decl, ctype;
> {
> tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
> int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
> int virtualp = DECL_VIRTUAL_P (decl);
>
> for (i = 0; i < n_baselinks; i++)
> {
> tree base_binfo = TREE_VEC_ELT (binfos, i);
> if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))
> || flag_all_virtual == 1)
> {
> tree tmp = get_matching_virtual
> (base_binfo, decl,
> DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
> if (tmp)
> {
> /* If this function overrides some virtual in some base
> class, then the function itself is also necessarily
> virtual, even if the user didn't explicitly say so. */
> DECL_VIRTUAL_P (decl) = 1;
>
> /* The TMP we really want is the one from the deepest
> baseclass on this path, taking care not to
> duplicate if we have already found it (via another
> path to its virtual baseclass. */
> if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
> {
> cp_error_at ("method `%D' may not be declared static",
> decl);
> cp_error_at ("(since `%D' declared virtual in base class.)",
> tmp);
> break;
> }
> virtualp = 1;
>
> #if 0 /* The signature of an overriding function is not changed. */
> {
> /* The argument types may have changed... */
> tree type = TREE_TYPE (decl);
> tree argtypes = TYPE_ARG_TYPES (type);
> tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
> tree raises = TYPE_RAISES_EXCEPTIONS (type);
>
> argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
> TREE_CHAIN (argtypes));
> /* But the return type has not. */
> type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
> if (raises)
> type = build_exception_variant (type, raises);
> TREE_TYPE (decl) = type;
> }
> #endif
> DECL_VINDEX (decl)
> = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
> break;
> }
> }
> }
> if (virtualp)
> {
> if (DECL_VINDEX (decl) == NULL_TREE)
> DECL_VINDEX (decl) = error_mark_node;
> IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
> }
> }
>
> /* Warn about hidden virtual functions that are not overridden in t.
> We know that constructors and destructors don't apply. */
>
> void
> warn_hidden (t)
> tree t;
> {
> tree method_vec = CLASSTYPE_METHOD_VEC (t);
> int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
> int i;
>
> /* We go through each separately named virtual function. */
> for (i = 2; i < n_methods; ++i)
> {
> tree fns = TREE_VEC_ELT (method_vec, i);
> tree fndecl;
>
> tree base_fndecls = NULL_TREE;
> tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
> int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
>
> fndecl = OVL_CURRENT (fns);
> if (DECL_VINDEX (fndecl) == NULL_TREE)
> continue;
>
> /* First we get a list of all possible functions that might be
> hidden from each base class. */
> for (i = 0; i < n_baseclasses; i++)
> {
> tree base_binfo = TREE_VEC_ELT (binfos, i);
> tree basetype = BINFO_TYPE (base_binfo);
>
> base_fndecls = chainon (get_basefndecls (fndecl, basetype),
> base_fndecls);
> }
>
> fns = OVL_NEXT (fns);
> if (fns)
> fndecl = OVL_CURRENT (fns);
> else
> fndecl = NULL_TREE;
>
> /* ...then mark up all the base functions with overriders, preferring
> overriders to hiders. */
> if (base_fndecls)
> while (fndecl)
> {
> mark_overriders (fndecl, base_fndecls);
>
> fns = OVL_NEXT (fns);
> if (fns)
> fndecl = OVL_CURRENT (fns);
> else
> fndecl = NULL_TREE;
> }
>
> /* Now give a warning for all base functions without overriders,
> as they are hidden. */
> while (base_fndecls)
> {
> if (! overrides (TREE_VALUE (base_fndecls),
> TREE_PURPOSE (base_fndecls)))
> {
> /* Here we know it is a hider, and no overrider exists. */
> cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
> cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls));
> }
>
> base_fndecls = TREE_CHAIN (base_fndecls);
> }
> }
> }
>
> /* Check for things that are invalid. There are probably plenty of other
> things we should check for also. */
>
> static void
> finish_struct_anon (t)
> tree t;
> {
> tree field;
> for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
> {
> if (TREE_STATIC (field))
> continue;
> if (TREE_CODE (field) != FIELD_DECL)
> continue;
>
> if (DECL_NAME (field) == NULL_TREE
> && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
> {
> tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
> for (; *uelt; uelt = &TREE_CHAIN (*uelt))
> {
> if (TREE_CODE (*uelt) != FIELD_DECL)
> continue;
>
> if (TREE_PRIVATE (*uelt))
> cp_pedwarn_at ("private member `%#D' in anonymous union",
> *uelt);
> else if (TREE_PROTECTED (*uelt))
> cp_pedwarn_at ("protected member `%#D' in anonymous union",
> *uelt);
>
> TREE_PRIVATE (*uelt) = TREE_PRIVATE (field);
> TREE_PROTECTED (*uelt) = TREE_PROTECTED (field);
> }
> }
> }
> }
>
2726a3065,3066
> ATTRIBUTES is the set of decl attributes to be applied, if any.
>
2763,2764d3102
< int round_up_size = 1;
<
2768c3106
< tree fn_fields = CLASSTYPE_METHODS (t);
---
> tree fn_fields = TYPE_METHODS (t);
2770d3107
< int needs_virtual_dtor;
2774a3112
> tree pending_hard_virtuals = NULL_TREE;
2780,2781d3117
< int cant_synth_copy_ctor;
< int cant_synth_asn_ref;
2793d3128
< tree t_binfo = TYPE_BINFO (t);
2795a3131,3132
> int empty = 1;
> int has_pointers = 0;
2810,2815d3146
< if (dont_allow_type_definitions)
< {
< pedwarn ("types cannot be defined %s",
< dont_allow_type_definitions);
< }
<
2834,2840d3164
< #if 0
< if (flag_rtti)
< build_t_desc (t, 0);
< #endif
<
< TYPE_BINFO (t) = NULL_TREE;
<
2850,2851c3174,3175
< if (t_binfo && BINFO_BASETYPES (t_binfo))
< n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
---
> if (TYPE_BINFO_BASETYPES (t))
> n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t));
2859,2866c3183,3184
< /* If using multiple inheritance, this may cause variants of our
< basetypes to be used (instead of their canonical forms). */
< tree vf = layout_basetypes (t, BINFO_BASETYPES (t_binfo));
< last_x = tree_last (vf);
< fields = chainon (vf, fields);
<
< first_vfn_base_index = finish_base_struct (t, &base_info, t_binfo);
< /* Remember where we got our vfield from */
---
> first_vfn_base_index = finish_base_struct (t, &base_info);
> /* Remember where we got our vfield from. */
2872a3191
> CLASSTYPE_RTTI (t) = base_info.rtti;
2875,2876d3193
< cant_synth_copy_ctor = base_info.cant_synth_copy_ctor;
< cant_synth_asn_ref = base_info.cant_synth_asn_ref;
2878,2879d3194
< needs_virtual_dtor = base_info.needs_virtual_dtor;
< n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
2889c3204
< last_x = NULL_TREE;
---
> CLASSTYPE_RTTI (t) = NULL_TREE;
2892,2893d3206
< cant_synth_copy_ctor = 0;
< cant_synth_asn_ref = 0;
2895d3207
< needs_virtual_dtor = 0;
2911,2912d3222
< TREE_CHAIN (t_binfo) = TYPE_BINFO (t);
< TYPE_BINFO (t) = t_binfo;
2918c3228
< else if (flag_all_virtual == 1 && TYPE_OVERLOADS_METHOD_CALL_EXPR (t))
---
> else if (flag_all_virtual == 1)
2923c3233
< for (x = CLASSTYPE_METHODS (t); x; x = TREE_CHAIN (x))
---
> for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
2941a3252,3255
> check_for_override (x, t);
> if (DECL_ABSTRACT_VIRTUAL_P (x) && ! DECL_VINDEX (x))
> cp_error_at ("initializer specified for non-virtual method `%D'", x);
>
2947,2948c3261,3262
< pending_virtuals = add_virtual_function (pending_virtuals,
< &has_virtual, x, t);
---
> add_virtual_function (&pending_virtuals, &pending_hard_virtuals,
> &has_virtual, x, t);
2950a3265,3266
> #if 0
> /* XXX Why did I comment this out? (jason) */
2952a3269
> #endif
2956c3273,3277
< for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x))
---
> if (n_baseclasses)
> fields = chainon (build_vbase_pointer_fields (t), fields);
>
> last_x = NULL_TREE;
> for (x = fields; x; x = TREE_CHAIN (x))
2960,2961c3281
< /* Handle access declarations. */
< if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
---
> if (TREE_CODE (x) == FIELD_DECL)
2963,2966c3283,3285
< tree fdecl = TREE_OPERAND (DECL_NAME (x), 1);
< enum access_type access
< = TREE_PRIVATE (x) ? access_private :
< TREE_PROTECTED (x) ? access_protected : access_public;
---
> DECL_PACKED (x) |= TYPE_PACKED (t);
> empty = 0;
> }
2967a3287,3289
> if (TREE_CODE (x) == USING_DECL)
> {
> /* Save access declarations for later. */
2972,2973c3294,3295
<
< access_decls = tree_cons ((tree) access, fdecl, access_decls);
---
>
> access_decls = scratch_tree_cons (NULL_TREE, x, access_decls);
2979c3301,3302
< if (TREE_CODE (x) == TYPE_DECL)
---
> if (TREE_CODE (x) == TYPE_DECL
> || TREE_CODE (x) == TEMPLATE_DECL)
2983c3306
< or an enumerator. */
---
> or an enumerator. */
3012c3335
< cant_have_default_ctor = cant_synth_copy_ctor = 1;
---
> cant_have_default_ctor = 1;
3052d3374
< cant_synth_asn_ref = 1;
3053a3376
> TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
3063a3387,3389
> if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
> has_pointers = 1;
>
3075d3400
< cant_synth_asn_ref = 1;
3076a3402
> TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
3121c3447,3448
< register int width = TREE_INT_CST_LOW (DECL_INITIAL (x));
---
> tree w = DECL_INITIAL (x);
> register int width = 0;
3123c3450,3459
< if (width < 0)
---
> /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */
> STRIP_NOPS (w);
>
> /* detect invalid field size. */
> if (TREE_CODE (w) == CONST_DECL)
> w = DECL_INITIAL (w);
> else if (TREE_READONLY_DECL_P (w))
> w = decl_constant_value (w);
>
> if (TREE_CODE (w) != INTEGER_CST)
3124a3461,3467
> cp_error_at ("bit-field `%D' width not an integer constant",
> x);
> DECL_INITIAL (x) = NULL_TREE;
> }
> else if (width = TREE_INT_CST_LOW (w),
> width < 0)
> {
3144c3487,3488
< && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
---
> && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE
> && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE)
3157d3500
< }
3159,3164c3502,3504
< /* Process valid field width. */
< if (DECL_INITIAL (x))
< {
< register int width = TREE_INT_CST_LOW (DECL_INITIAL (x));
<
< if (width == 0)
---
> if (DECL_INITIAL (x) == NULL_TREE)
> ;
> else if (width == 0)
3167,3173c3507
< /* field size 0 => mark following field as "aligned" */
< if (TREE_CHAIN (x))
< DECL_ALIGN (TREE_CHAIN (x))
< = MAX (DECL_ALIGN (TREE_CHAIN (x)), EMPTY_FIELD_BOUNDARY);
< /* field of size 0 at the end => round up the size. */
< else
< round_up_size = EMPTY_FIELD_BOUNDARY;
---
> DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
3185,3189d3518
< /* Traditionally a bit field is unsigned
< even if declared signed. */
< if (flag_traditional
< && TREE_CODE (TREE_TYPE (x)) == INTEGER_TYPE)
< TREE_TYPE (x) = unsigned_type_node;
3200c3529
< if (TREE_CODE (type) == ARRAY_TYPE)
---
> while (TREE_CODE (type) == ARRAY_TYPE)
3222,3223c3551,3552
< else if (TYPE_HAS_REAL_ASSIGNMENT (type))
< fie = "assignment operator";
---
> else if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))
> fie = "copy assignment operator";
3236,3240c3565
< if (! TYPE_HAS_INIT_REF (type)
< || (TYPE_HAS_NONPUBLIC_CTOR (type)
< && ! is_friend (t, type)))
< cant_synth_copy_ctor = 1;
< else if (!TYPE_HAS_CONST_INIT_REF (type))
---
> if (!TYPE_HAS_CONST_INIT_REF (type))
3243,3247c3568
< if (! TYPE_HAS_ASSIGN_REF (type)
< || (TYPE_HAS_NONPUBLIC_ASSIGN_REF (type)
< && ! is_friend (t, type)))
< cant_synth_asn_ref = 1;
< else if (!TYPE_HAS_CONST_ASSIGN_REF (type))
---
> if (!TYPE_HAS_CONST_ASSIGN_REF (type))
3297c3618,3619
< tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0);
---
> tree dtor = cons_up_default_function (t, name, 0);
> check_for_override (dtor, t);
3304c3626
< /* Link dtor onto end of fn_fields. */
---
> /* Link dtor onto end of fn_fields. */
3309,3313d3630
< if (DECL_VINDEX (dtor) == NULL_TREE
< && (needs_virtual_dtor
< || pending_virtuals != NULL_TREE
< || pending_hard_virtuals != NULL_TREE))
< DECL_VINDEX (dtor) = error_mark_node;
3315,3316c3632,3633
< pending_virtuals = add_virtual_function (pending_virtuals,
< &has_virtual, dtor, t);
---
> add_virtual_function (&pending_virtuals, &pending_hard_virtuals,
> &has_virtual, dtor, t);
3320a3638,3653
> /* Effective C++ rule 11. */
> if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t)
> && ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
> {
> cp_warning ("`%#T' has pointer data members", t);
>
> if (! TYPE_HAS_INIT_REF (t))
> {
> cp_warning (" but does not override `%T(const %T&)'", t, t);
> if (! TYPE_HAS_ASSIGN_REF (t))
> cp_warning (" or `operator=(const %T&)'", t);
> }
> else if (! TYPE_HAS_ASSIGN_REF (t))
> cp_warning (" but does not override `operator=(const %T&)'", t);
> }
>
3322,3324d3654
< if (flag_rtti && (max_has_virtual > 0 || needs_virtual_dtor) &&
< has_virtual == 0)
< has_virtual = 1;
3328c3658
< || any_default_members);
---
> || has_virtual || any_default_members);
3331c3661
< || has_virtual || any_default_members || first_vfn_base_index >= 0);
---
> || has_virtual || any_default_members);
3349,3350c3679
< if (! TYPE_HAS_INIT_REF (t) && ! cant_synth_copy_ctor
< && ! IS_SIGNATURE (t))
---
> if (! TYPE_HAS_INIT_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t))
3365,3366c3694
< if (! TYPE_HAS_ASSIGN_REF (t) && ! cant_synth_asn_ref
< && ! IS_SIGNATURE (t))
---
> if (! TYPE_HAS_ASSIGN_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t))
3375a3704
> TYPE_METHODS (t) = fn_fields;
3380c3709
< && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE)
---
> && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE)
3387,3388c3716,3717
< ctor = DECL_CHAIN (ctor))
< if (! TREE_PRIVATE (ctor))
---
> ctor = OVL_NEXT (ctor))
> if (! TREE_PRIVATE (OVL_CURRENT (ctor)))
3409,3420c3738,3740
< {
< int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
<
< for (access_decls = nreverse (access_decls); access_decls;
< access_decls = TREE_CHAIN (access_decls))
< {
< tree fdecl = TREE_VALUE (access_decls);
< tree flist = NULL_TREE;
< tree name;
< enum access_type access = (enum access_type)TREE_PURPOSE(access_decls);
< int i = TREE_VEC_ELT (method_vec, 0) ? 0 : 1;
< tree tmp;
---
> for (access_decls = nreverse (access_decls); access_decls;
> access_decls = TREE_CHAIN (access_decls))
> handle_using_decl (TREE_VALUE (access_decls), t, method_vec, fields);
3422,3471d3741
< if (TREE_CODE (fdecl) == TREE_LIST)
< {
< flist = fdecl;
< fdecl = TREE_VALUE (flist);
< }
<
< name = DECL_NAME (fdecl);
<
< for (; i < n_methods; i++)
< if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
< {
< cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
< cp_error_at (" because of local method `%#D' with same name",
< TREE_VEC_ELT (method_vec, i));
< fdecl = NULL_TREE;
< break;
< }
<
< if (! fdecl)
< continue;
<
< for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))
< if (DECL_NAME (tmp) == name)
< {
< cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
< cp_error_at (" because of local field `%#D' with same name", tmp);
< fdecl = NULL_TREE;
< break;
< }
<
< if (!fdecl)
< continue;
<
< /* Make type T see field decl FDECL with access ACCESS.*/
< if (flist)
< {
< fdecl = TREE_VALUE (flist);
< while (fdecl)
< {
< if (alter_access (t, fdecl, access) == 0)
< break;
< fdecl = DECL_CHAIN (fdecl);
< }
< }
< else
< alter_access (t, fdecl, access);
< }
<
< }
<
3480c3750
< them too. */
---
> them too. */
3483a3754
> DECL_ARTIFICIAL (vfield) = 1;
3490c3761,3769
< if (CLASSTYPE_RTTI (t))
---
> #if 0
> /* This is more efficient, but breaks binary compatibility, turn
> it on sometime when we don't care. If we turn it on, we also
> have to enable the code in dfs_init_vbase_pointers. */
> /* vfield is always first entry in structure. */
> TREE_CHAIN (vfield) = fields;
> fields = vfield;
> #else
> if (last_x)
3492,3497d3770
< /* vfield is always first entry in structure. */
< TREE_CHAIN (vfield) = fields;
< fields = vfield;
< }
< else if (last_x)
< {
3503a3777,3778
> #endif
> empty = 0;
3537c3812,3816
< int i = /*TREE_VEC_ELT (method_vec, 0) ? 0 : */ 1;
---
> int i = 2;
>
> if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
> continue;
>
3539c3818,3819
< if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
---
> if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
> == name)
3543c3823
< TREE_VEC_ELT (method_vec, i));
---
> OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
3554,3558d3833
< /* If there's a :0 field at the end, round the size to the
< EMPTY_FIELD_BOUNDARY. */
< TYPE_ALIGN (t) = round_up_size;
<
< /* Pass layout information about base classes to layout_type, if any. */
3561c3836
< tree pseudo_basetype = TREE_TYPE (base_layout_decl);
---
> last_x = build_base_fields (t);
3563,3571c3838,3841
< TREE_CHAIN (base_layout_decl) = TYPE_FIELDS (t);
< TYPE_FIELDS (t) = base_layout_decl;
<
< TYPE_SIZE (pseudo_basetype) = CLASSTYPE_SIZE (t);
< TYPE_MODE (pseudo_basetype) = TYPE_MODE (t);
< TYPE_ALIGN (pseudo_basetype) = CLASSTYPE_ALIGN (t);
< DECL_ALIGN (base_layout_decl) = TYPE_ALIGN (pseudo_basetype);
< /* Don't re-use old size. */
< DECL_SIZE (base_layout_decl) = NULL_TREE;
---
> /* If all our bases are empty, we can be empty too. */
> for (x = last_x; empty && x; x = TREE_CHAIN (x))
> if (DECL_SIZE (x) != integer_zero_node)
> empty = 0;
3572a3843,3852
> if (empty)
> {
> /* C++: do not let empty structures exist. */
> tree decl = build_lang_field_decl
> (FIELD_DECL, NULL_TREE, char_type_node);
> TREE_CHAIN (decl) = fields;
> TYPE_FIELDS (t) = decl;
> }
> if (n_baseclasses)
> TYPE_FIELDS (t) = chainon (last_x, TYPE_FIELDS (t));
3576,3583c3856,3865
< {
< tree field;
< for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
< {
< if (TREE_STATIC (field))
< continue;
< if (TREE_CODE (field) != FIELD_DECL)
< continue;
---
> /* Remember the size and alignment of the class before adding
> the virtual bases. */
> if (empty && flag_new_abi)
> CLASSTYPE_SIZE (t) = integer_zero_node;
> else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t)
> && TYPE_HAS_COMPLEX_ASSIGN_REF (t))
> CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
> else
> CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
> CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
3585,3586c3867
< /* If this field is an anonymous union,
< give each union-member the same position as the union has.
---
> finish_struct_anon (t);
3588,3629d3868
< ??? This is a real kludge because it makes the structure
< of the types look strange. This feature is only used by
< C++, which should have build_component_ref build two
< COMPONENT_REF operations, one for the union and one for
< the inner field. We set the offset of this field to zero
< so that either the old or the correct method will work.
< Setting DECL_FIELD_CONTEXT is wrong unless the inner fields are
< moved into the type of this field, but nothing seems to break
< by doing this. */
<
< if (DECL_NAME (field) == NULL_TREE
< && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
< {
< tree uelt = TYPE_FIELDS (TREE_TYPE (field));
< for (; uelt; uelt = TREE_CHAIN (uelt))
< {
< if (TREE_CODE (uelt) != FIELD_DECL)
< continue;
<
< if (TREE_PRIVATE (uelt))
< cp_pedwarn_at ("private member `%#D' in anonymous union",
< uelt);
< else if (TREE_PROTECTED (uelt))
< cp_pedwarn_at ("protected member `%#D' in anonymous union",
< uelt);
<
< DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);
< DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);
< }
<
< DECL_FIELD_BITPOS (field) = integer_zero_node;
< }
< }
< }
<
< if (n_baseclasses)
< TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t));
<
< /* C++: do not let empty structures exist. */
< if (integer_zerop (TYPE_SIZE (t)))
< TYPE_SIZE (t) = TYPE_SIZE (char_type_node);
<
3634,3635c3873
< if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
< layout_decl (TYPE_NAME (t), 0);
---
> layout_decl (TYPE_MAIN_DECL (t), 0);
3640d3877
< doing_hard_virtuals = 1;
3642a3880,3885
> if (n_baseclasses)
> /* layout_basetypes will remove the base subobject fields. */
> max_has_virtual = layout_basetypes (t, max_has_virtual);
> else if (empty)
> TYPE_FIELDS (t) = fields;
>
3647d3889
< max_has_virtual = layout_vbasetypes (t, max_has_virtual);
3651,3661d3892
< /* The rtti code should do this. (mrs) */
< #if 0
< while (vbases)
< {
< /* Update rtti info with offsets for virtual baseclasses. */
< if (flag_rtti && ! BINFO_NEW_VTABLE_MARKED (vbases))
< prepare_fresh_vtable (vbases, t);
< vbases = TREE_CHAIN (vbases);
< }
< #endif
<
3684,3696d3914
<
< /* Now fixup any virtual function entries from virtual bases
< that have different deltas. */
< vbases = CLASSTYPE_VBASECLASSES (t);
< while (vbases)
< {
< /* We might be able to shorten the amount of work we do by
< only doing this for vtables that come from virtual bases
< that have differing offsets, but don't want to miss any
< entries. */
< fixup_vtable_deltas (vbases, 1, t);
< vbases = TREE_CHAIN (vbases);
< }
3739c3957,3976
< doing_hard_virtuals = 0;
---
>
> if (TYPE_USES_VIRTUAL_BASECLASSES (t))
> {
> tree vbases;
> /* Now fixup any virtual function entries from virtual bases
> that have different deltas. This has to come after we do the
> pending hard virtuals, as we might have a function that comes
> from multiple virtual base instances that is only overridden
> by a hard virtual above. */
> vbases = CLASSTYPE_VBASECLASSES (t);
> while (vbases)
> {
> /* We might be able to shorten the amount of work we do by
> only doing this for vtables that come from virtual bases
> that have differing offsets, but don't want to miss any
> entries. */
> fixup_vtable_deltas (vbases, 1, t);
> vbases = TREE_CHAIN (vbases);
> }
> }
3743c3980
< if (pending_virtuals || (flag_rtti && TYPE_VIRTUAL_P (t)))
---
> if (pending_virtuals)
3749,3751d3985
< /* The first slot is for the rtti offset. */
< pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
<
3756c3990,3994
< set_rtti_entry (pending_virtuals, integer_zero_node, t);
---
> /* The first slot is for the rtti offset. */
> pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals);
>
> set_rtti_entry (pending_virtuals,
> convert (ssizetype, integer_zero_node), t);
3761d3998
< tree offset;
3767,3770d4003
<
< offset = get_derived_offset (TYPE_BINFO (t), NULL_TREE);
< offset = size_binop (MINUS_EXPR, integer_zero_node, offset);
< set_rtti_entry (TYPE_BINFO_VIRTUALS (t), offset, t);
3880,3915d4112
< /* Now add the tags, if any, to the list of TYPE_DECLs
< defined for this type. */
< if (CLASSTYPE_TAGS (t))
< {
< x = CLASSTYPE_TAGS (t);
< last_x = tree_last (TYPE_FIELDS (t));
< while (x)
< {
< tree tag = TYPE_NAME (TREE_VALUE (x));
<
< /* Check to see if it is already there. This will be the case if
< was do enum { red; } color; */
< if (chain_member (tag, TYPE_FIELDS (t)))
< {
< x = TREE_CHAIN (x);
< continue;
< }
<
< #ifdef DWARF_DEBUGGING_INFO
< if (write_symbols == DWARF_DEBUG)
< {
< /* Notify dwarfout.c that this TYPE_DECL node represent a
< gratuitous typedef. */
< DECL_IGNORED_P (tag) = 1;
< }
< #endif /* DWARF_DEBUGGING_INFO */
<
< TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
< x = TREE_CHAIN (x);
< last_x = chainon (last_x, tag);
< }
< if (TYPE_FIELDS (t) == NULL_TREE)
< TYPE_FIELDS (t) = last_x;
< CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
< }
<
3935,3937d4131
< if (! IS_SIGNATURE (t))
< embrace_waiting_friends (t);
<
3945c4139
< /* This is now done above. */
---
> /* This is now done above. */
3964c4158
< /* In addition to this one, all the other vfields should be listed. */
---
> /* In addition to this one, all the other vfields should be listed. */
3970c4164
< && DECL_VINDEX (TREE_VEC_ELT (method_vec, 0)) == NULL_TREE)
---
> && DECL_VINDEX (TREE_VEC_ELT (method_vec, 1)) == NULL_TREE)
3978d4171
< TYPE_BEING_DEFINED (t) = 0;
3985,3988d4177
< if (current_class_type)
< popclass (0);
< else
< error ("trying to finish struct, but kicked out due to previous parse errors.");
3992,3993c4181,4182
< if (flag_cadillac)
< cadillac_finish_struct (t);
---
> if (warn_overloaded_virtual)
> warn_hidden (t);
4002,4004c4191,4192
< if (DECL_CONTEXT (TYPE_NAME (t))
< && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (TYPE_NAME (t)))) == 't')
< DECL_IGNORED_P (TYPE_NAME (t)) = TREE_ASM_WRITTEN (TYPE_NAME (t));
---
> if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (t)))
> DECL_IGNORED_P (TYPE_MAIN_DECL (t)) = TREE_ASM_WRITTEN (TYPE_MAIN_DECL (t));
4008c4196
< if (write_symbols != DWARF_DEBUG)
---
> if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG)
4016c4204,4207
< that member function's debug info is written out. */
---
> that member function's debug info is written out.
>
> We can't do this with DWARF, which does not support name
> references between translation units. */
4024c4215
< TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t))
---
> TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t))
4027c4218,4220
< TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
---
> TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
> #if 0
> /* XXX do something about this. */
4030c4223,4224
< TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
---
> TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
> #endif
4033c4227
< TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
---
> TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
4043,4045c4237,4238
< finish_struct (t, list_of_fieldlists, warn_anon)
< tree t;
< tree list_of_fieldlists;
---
> finish_struct (t, list_of_fieldlists, attributes, warn_anon)
> tree t, list_of_fieldlists, attributes;
4048,4049c4241,4244
< tree fields = NULL_TREE, fn_fields, *tail;
< tree *tail_user_methods = &CLASSTYPE_METHODS (t);
---
> tree fields = NULL_TREE;
> tree *tail = &TYPE_METHODS (t);
> tree specializations = NULL_TREE;
> tree *specialization_tail = &specializations;
4052c4247,4249
< enum access_type access;
---
> tree access;
> tree dummy = NULL_TREE;
> tree next_x = NULL_TREE;
4074,4080c4271,4275
< tail = &fn_fields;
< if (last_x && list_of_fieldlists)
< TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
<
< /* For signatures, we made all methods `public' in the parser and
< reported an error if a access specifier was used. */
< if (CLASSTYPE_DECLARED_CLASS (t) == 0)
---
> /* Move our self-reference declaration to the end of the field list so
> any real field with the same name takes precedence. */
> if (list_of_fieldlists
> && TREE_VALUE (list_of_fieldlists)
> && DECL_ARTIFICIAL (TREE_VALUE (list_of_fieldlists)))
4082,4084c4277,4278
< if (list_of_fieldlists
< && TREE_PURPOSE (list_of_fieldlists) == (tree)access_default)
< TREE_PURPOSE (list_of_fieldlists) = (tree)access_public;
---
> dummy = TREE_VALUE (list_of_fieldlists);
> list_of_fieldlists = TREE_CHAIN (list_of_fieldlists);
4086,4088d4279
< else if (list_of_fieldlists
< && TREE_PURPOSE (list_of_fieldlists) == (tree)access_default)
< TREE_PURPOSE (list_of_fieldlists) = (tree)access_private;
4089a4281,4283
> if (last_x && list_of_fieldlists)
> TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
>
4092c4286
< access = (enum access_type)TREE_PURPOSE (list_of_fieldlists);
---
> access = TREE_PURPOSE (list_of_fieldlists);
4094c4288,4290
< for (x = TREE_VALUE (list_of_fieldlists); x; x = TREE_CHAIN (x))
---
> /* For signatures, we made all methods `public' in the parser and
> reported an error if a access specifier was used. */
> if (access == access_default_node)
4096,4097c4292,4296
< TREE_PRIVATE (x) = access == access_private;
< TREE_PROTECTED (x) = access == access_protected;
---
> if (CLASSTYPE_DECLARED_CLASS (t) == 0)
> access = access_public_node;
> else
> access = access_private_node;
> }
4099c4298,4313
< /* Check for inconsistent use of this name in the class body.
---
> for (x = TREE_VALUE (list_of_fieldlists); x; x = next_x)
> {
> next_x = TREE_CHAIN (x);
>
> TREE_PRIVATE (x) = access == access_private_node;
> TREE_PROTECTED (x) = access == access_protected_node;
>
> if (TREE_CODE (x) == TEMPLATE_DECL)
> {
> TREE_PRIVATE (DECL_RESULT (x)) = TREE_PRIVATE (x);
> TREE_PROTECTED (DECL_RESULT (x)) = TREE_PROTECTED (x);
> }
>
> /* A name N used in a class S shall refer to the same declaration
> in its context and when re-evaluated in the completed scope of S.
>
4101c4315,4317
< if (TREE_CODE (x) != TYPE_DECL
---
> if (TREE_CODE (x) != TYPE_DECL && TREE_CODE (x) != USING_DECL
> && ! (TREE_CODE (x) == TEMPLATE_DECL
> && TREE_CODE (DECL_RESULT (x)) == TYPE_DECL)
4113a4330
> && flag_optional_diags
4122,4125c4339,4342
< cp_error_at ("declaration of identifier `%D' as `%+#D'",
< name, x);
< cp_error_at ("conflicts with other use in class as `%#D'",
< icv);
---
> cp_pedwarn_at ("declaration of identifier `%D' as `%+#D'",
> name, x);
> cp_pedwarn_at ("conflicts with other use in class as `%#D'",
> icv);
4129c4346,4347
< if (TREE_CODE (x) == FUNCTION_DECL)
---
> if (TREE_CODE (x) == FUNCTION_DECL
> || DECL_FUNCTION_TEMPLATE_P (x))
4130a4349,4350
> DECL_CLASS_CONTEXT (x) = t;
>
4132,4133c4352,4367
< TREE_CHAIN (last_x) = TREE_CHAIN (x);
< /* Link x onto end of fn_fields and CLASSTYPE_METHODS. */
---
> TREE_CHAIN (last_x) = next_x;
>
> if (DECL_TEMPLATE_SPECIALIZATION (x))
> /* We don't enter the specialization into the class
> method vector since specializations don't affect
> overloading. Instead we keep track of the
> specializations, and process them after the method
> vector is complete. */
> {
> *specialization_tail = x;
> specialization_tail = &TREE_CHAIN (x);
> TREE_CHAIN (x) = NULL_TREE;
> continue;
> }
>
> /* Link x onto end of TYPE_METHODS. */
4136,4137d4369
< *tail_user_methods = x;
< tail_user_methods = &DECL_NEXT_METHOD (x);
4141,4150c4373,4374
< #if 0
< /* Handle access declarations. */
< if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
< {
< tree n = DECL_NAME (x);
< x = build_decl
< (USING_DECL, DECL_NAME (TREE_OPERAND (n, 1)), TREE_TYPE (x));
< DECL_RESULT (x) = n;
< }
< #endif
---
> if (TREE_CODE (x) != TYPE_DECL)
> DECL_FIELD_CONTEXT (x) = t;
4168a4393,4420
> /* Now add the tags, if any, to the list of TYPE_DECLs
> defined for this type. */
> if (CLASSTYPE_TAGS (t) || dummy)
> {
> /* The list of tags was built up in pushtag in reverse order; we need
> to fix that so that enumerators will be processed in forward order
> in template instantiation. */
> CLASSTYPE_TAGS (t) = x = nreverse (CLASSTYPE_TAGS (t));
> while (x)
> {
> tree tag_type = TREE_VALUE (x);
> tree tag = TYPE_MAIN_DECL (TREE_VALUE (x));
>
> if (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type))
> && CLASSTYPE_IS_TEMPLATE (tag_type))
> tag = CLASSTYPE_TI_TEMPLATE (tag_type);
>
> TREE_NONLOCAL_FLAG (tag_type) = 0;
> x = TREE_CHAIN (x);
> last_x = chainon (last_x, tag);
> }
> if (dummy)
> last_x = chainon (last_x, dummy);
> if (fields == NULL_TREE)
> fields = last_x;
> CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
> }
>
4170d4421
< *tail_user_methods = NULL_TREE;
4173c4424,4426
< if (0 && processing_template_defn)
---
> cplus_decl_attributes (t, attributes, NULL_TREE);
>
> if (processing_template_decl)
4175,4176c4428,4500
< CLASSTYPE_METHOD_VEC (t) = finish_struct_methods (t, fn_fields, 1);
< return t;
---
> tree d = getdecls ();
> for (; d; d = TREE_CHAIN (d))
> {
> /* If this is the decl for the class or one of the template
> parms, we've seen all the injected decls. */
> if ((TREE_CODE (d) == TYPE_DECL
> && (TREE_TYPE (d) == t
> || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM
> || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM))
> || TREE_CODE (d) == CONST_DECL)
> break;
> /* Don't inject cache decls. */
> else if (IDENTIFIER_TEMPLATE (DECL_NAME (d)))
> continue;
> DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))
> = tree_cons (NULL_TREE, d,
> DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)));
> }
> CLASSTYPE_METHOD_VEC (t)
> = finish_struct_methods (t, TYPE_METHODS (t), 1);
> TYPE_SIZE (t) = integer_zero_node;
> }
> else
> t = finish_struct_1 (t, warn_anon);
>
> TYPE_BEING_DEFINED (t) = 0;
>
> /* Now, figure out which member templates we're specializing. */
> for (x = specializations; x != NULL_TREE; x = TREE_CHAIN (x))
> {
> tree spec_args;
> tree fn;
> int pending_specialization;
>
> if (uses_template_parms (t))
> /* If t is a template class, and x is a specialization, then x
> is itself really a template. Due to the vagaries of the
> parser, however, we will have a handle to a function
> declaration, rather than the template declaration, at this
> point. */
> {
> my_friendly_assert (DECL_TEMPLATE_INFO (x) != NULL_TREE, 0);
> my_friendly_assert (DECL_TI_TEMPLATE (x) != NULL_TREE, 0);
> fn = DECL_TI_TEMPLATE (x);
> }
> else
> fn = x;
>
> /* We want the specialization arguments, which will be the
> innermost ones. */
> if (DECL_TI_ARGS (fn) && TREE_CODE (DECL_TI_ARGS (fn)) == TREE_VEC)
> spec_args
> = TREE_VEC_ELT (DECL_TI_ARGS (fn), 0);
> else
> spec_args = DECL_TI_ARGS (fn);
>
> pending_specialization
> = TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (fn));
> check_explicit_specialization
> (lookup_template_function (DECL_NAME (fn), spec_args),
> fn, 0, 1 | (8 * pending_specialization));
> TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (fn)) = 0;
>
> /* Now, the assembler name will be correct for fn, so we
> make its RTL. */
> DECL_RTL (fn) = 0;
> make_decl_rtl (fn, NULL_PTR, 1);
>
> if (x != fn)
> {
> DECL_RTL (x) = 0;
> make_decl_rtl (x, NULL_PTR, 1);
> }
4177a4502,4504
>
> if (current_class_type)
> popclass (0);
4179c4506,4508
< return finish_struct_1 (t, warn_anon);
---
> error ("trying to finish struct, but kicked out due to previous parse errors.");
>
> return t;
4187a4517
>
4222,4228d4551
< /* This is a call to `new', hence it's never zero. */
< if (TREE_CALLS_NEW (instance))
< {
< if (nonnull)
< *nonnull = 1;
< return 1;
< }
4252,4255d4574
< case WITH_CLEANUP_EXPR:
< if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
< return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
< /* fall through... */
4265c4584
< /* fall through... */
---
> /* fall through... */
4276c4595
< if (instance == current_class_decl
---
> if (instance == current_class_ptr
4307a4627,4635
> access_default_node = build_int_2 (0, 0);
> access_public_node = build_int_2 (1, 0);
> access_protected_node = build_int_2 (2, 0);
> access_private_node = build_int_2 (3, 0);
> access_default_virtual_node = build_int_2 (4, 0);
> access_public_virtual_node = build_int_2 (5, 0);
> access_protected_virtual_node = build_int_2 (6, 0);
> access_private_virtual_node = build_int_2 (7, 0);
>
4309d4636
< the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node);
4354a4682
> type = TYPE_MAIN_VARIANT (type);
4362,4364c4690,4692
< current_class_base =
< (tree *)xrealloc (current_class_base,
< sizeof (tree) * (current_class_stacksize + 10));
---
> current_class_base
> = (tree *)xrealloc (current_class_base,
> sizeof (tree) * (current_class_stacksize + 10));
4384a4713,4717
> #if 0
> if (CLASSTYPE_TEMPLATE_INFO (type))
> overload_template_name (type);
> #endif
>
4397,4399c4730
< if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
< declare_uninstantiated_type_level ();
< else if (type != previous_class_type || current_class_depth > 1)
---
> if (type != previous_class_type || current_class_depth > 1)
4400a4732
> #ifdef MI_MATRIX
4404,4405c4736,4738
< if (current_class_depth == 1)
< previous_class_type = type;
---
> #else
> push_class_decls (type);
> #endif
4426,4428d4758
< if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (type)))
< overload_template_name (current_class_name, 0);
<
4431c4761,4763
< TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1;
---
> tree tag_type = TREE_VALUE (tags);
>
> TREE_NONLOCAL_FLAG (tag_type) = 1;
4434c4766,4770
< pushtag (TREE_PURPOSE (tags), TREE_VALUE (tags), 0);
---
> if (! (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type))
> && CLASSTYPE_IS_TEMPLATE (tag_type)))
> pushtag (TREE_PURPOSE (tags), tag_type, 0);
> else
> pushdecl_class_level (CLASSTYPE_TI_TEMPLATE (tag_type));
4439,4441d4774
<
< if (flag_cadillac)
< cadillac_push_class (type);
4447a4781
>
4452,4454d4785
< if (flag_cadillac)
< cadillac_pop_class ();
<
4485,4486d4815
< if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)))
< undo_template_name_overload (current_class_name, 0);
4497c4826
< pop_class_decls (current_class_type);
---
> pop_class_decls ();
4508a4838,4852
> /* Returns 1 if current_class_type is either T or a nested type of T. */
>
> int
> currently_open_class (t)
> tree t;
> {
> int i;
> if (t == current_class_type)
> return 1;
> for (i = 0; i < current_class_depth; ++i)
> if (current_class_stack [-i*2 - 1] == t)
> return 1;
> return 0;
> }
>
4523c4867,4871
< if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type))
---
> my_friendly_assert (!type || TREE_CODE (type) != NAMESPACE_DECL, 980711);
>
> if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type)
> || TREE_CODE (type) == TEMPLATE_TYPE_PARM
> || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
4526c4874
< context = DECL_CONTEXT (TYPE_NAME (type));
---
> context = DECL_CONTEXT (TYPE_MAIN_DECL (type));
4539c4887
< tree context = DECL_CONTEXT (TYPE_NAME (current_class_type));
---
> tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
4556,4558c4904,4906
< current_lang_base =
< (tree *)xrealloc (current_lang_base,
< sizeof (tree) * (current_lang_stacksize + 10));
---
> current_lang_base
> = (tree *)xrealloc (current_lang_base,
> sizeof (tree) * (current_lang_stacksize + 10));
4563c4911
< if (name == lang_name_cplusplus)
---
> if (name == lang_name_cplusplus || name == lang_name_java)
4575,4577d4922
<
< if (flag_cadillac)
< cadillac_push_lang (name);
4580a4926
>
4584,4586d4929
< if (flag_cadillac)
< cadillac_pop_lang ();
<
4588c4931,4932
< if (current_lang_name == lang_name_cplusplus)
---
> if (current_lang_name == lang_name_cplusplus
> || current_lang_name == lang_name_java)
4592a4937,4938
>
> /* Type instantiation routines. */
4594,4595c4940,4943
< int
< root_lang_context_p ()
---
> static tree
> validate_lhs (lhstype, complain)
> tree lhstype;
> int complain;
4597c4945,4960
< return current_lang_stack == current_lang_base;
---
> if (TYPE_PTRMEMFUNC_P (lhstype))
> lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
>
> if (TREE_CODE (lhstype) == POINTER_TYPE)
> {
> if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
> || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
> lhstype = TREE_TYPE (lhstype);
> else
> {
> if (complain)
> error ("invalid type combination for overload");
> return error_mark_node;
> }
> }
> return lhstype;
4599,4600d4961
<
< /* Type instantiation routines. */
4602,4604c4963,4968
< /* This function will instantiate the type of the expression given
< in RHS to match the type of LHSTYPE. If LHSTYPE is NULL_TREE,
< or other errors exist, the TREE_TYPE of RHS will be ERROR_MARK_NODE.
---
> /* This function will instantiate the type of the expression given in
> RHS to match the type of LHSTYPE. If errors exist, then return
> error_mark_node. If only complain is COMPLAIN is set. If we are
> not complaining, never modify rhs, as overload resolution wants to
> try many possible instantiations, in hopes that at least one will
> work.
4607a4972
>
4612a4978,4980
> tree explicit_targs = NULL_TREE;
> int template_only = 0;
>
4621c4989,4996
< return rhs;
---
> {
> if (comptypes (lhstype, TREE_TYPE (rhs), 1))
> return rhs;
> if (complain)
> cp_error ("argument of type `%T' does not match `%T'",
> TREE_TYPE (rhs), lhstype);
> return error_mark_node;
> }
4622a4998,5002
> /* We don't overwrite rhs if it is an overloaded function.
> Copying it would destroy the tree link. */
> if (TREE_CODE (rhs) != OVERLOAD)
> rhs = copy_node (rhs);
>
4640,4645c5020,5021
< TREE_TYPE (rhs) = lhstype;
< lhstype = build_pointer_type (lhstype);
< TREE_OPERAND (rhs, 0)
< = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
< if (TREE_OPERAND (rhs, 0) == error_mark_node)
< return error_mark_node;
---
> {
> tree new_rhs;
4647c5023,5026
< return rhs;
---
> new_rhs = instantiate_type (build_pointer_type (lhstype),
> TREE_OPERAND (rhs, 0), complain);
> if (new_rhs == error_mark_node)
> return error_mark_node;
4648a5028,5032
> TREE_TYPE (rhs) = lhstype;
> TREE_OPERAND (rhs, 0) = new_rhs;
> return rhs;
> }
>
4673a5058
> mark_used (function);
4676a5062,5064
> /* I could not trigger this code. MvL */
> my_friendly_abort (980326);
> #if 0
4689a5078
> mark_used (field);
4715a5105
> #endif
4719c5109,5117
< case TREE_LIST:
---
> case OFFSET_REF:
> /* This can happen if we are forming a pointer-to-member for a
> member template. */
> rhs = TREE_OPERAND (rhs, 1);
> my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0);
>
> /* Fall through. */
>
> case TEMPLATE_ID_EXPR:
4721,4722c5119,5124
< tree elem, baselink, name;
< int globals = overloaded_globals_p (rhs);
---
> explicit_targs = TREE_OPERAND (rhs, 1);
> template_only = 1;
> rhs = TREE_OPERAND (rhs, 0);
> }
> /* fall through */
> my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);
4724,4728c5126,5128
< #if 0 /* obsolete */
< /* If there's only one function we know about, return that. */
< if (globals > 0 && TREE_CHAIN (rhs) == NULL_TREE)
< return TREE_VALUE (rhs);
< #endif
---
> case OVERLOAD:
> {
> tree elem, elems;
4730,4732c5130,5133
< /* First look for an exact match. Search either overloaded
< functions or member functions. May have to undo what
< `default_conversion' might do to lhstype. */
---
> /* Check that the LHSTYPE and the RHS are reasonable. */
> lhstype = validate_lhs (lhstype, complain);
> if (lhstype == error_mark_node)
> return lhstype;
4734,4748c5135,5136
< if (TYPE_PTRMEMFUNC_P (lhstype))
< lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
<
< if (TREE_CODE (lhstype) == POINTER_TYPE)
< if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
< || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
< lhstype = TREE_TYPE (lhstype);
< else
< {
< if (complain)
< error ("invalid type combination for overload");
< return error_mark_node;
< }
<
< if (TREE_CODE (lhstype) != FUNCTION_TYPE && globals > 0)
---
> if (TREE_CODE (lhstype) != FUNCTION_TYPE
> && TREE_CODE (lhstype) != METHOD_TYPE)
4751,4752c5139,5141
< cp_error ("cannot resolve overloaded function `%D' based on non-function type",
< TREE_PURPOSE (rhs));
---
> cp_error("cannot resolve overloaded function `%D' "
> "based on non-function type",
> DECL_NAME (OVL_FUNCTION (rhs)));
4755,4756c5144,5152
<
< if (globals > 0)
---
>
> /* Look for an exact match, by searching through the
> overloaded functions. */
> if (template_only)
> /* If we're processing a template-id, only a template
> function can match, so we don't look through the
> overloaded functions. */
> ;
> else for (elems = rhs; elems; elems = OVL_CHAIN (elems))
4758,4762c5154,5157
< elem = get_first_fn (rhs);
< while (elem)
< if (! comptypes (lhstype, TREE_TYPE (elem), 1))
< elem = DECL_CHAIN (elem);
< else
---
> elem = OVL_FUNCTION (elems);
> if (comptypes (lhstype, TREE_TYPE (elem), 1))
> {
> mark_used (elem);
4763a5159,5160
> }
> }
4765,4769c5162,5179
< /* No exact match found, look for a compatible template. */
< {
< tree save_elem = 0;
< for (elem = get_first_fn (rhs); elem; elem = DECL_CHAIN (elem))
< if (TREE_CODE (elem) == TEMPLATE_DECL)
---
> /* No overloaded function was an exact match. See if we can
> instantiate some template to match. */
> {
> tree save_elem = 0;
> elems = rhs;
> if (TREE_CODE (elems) == TREE_LIST)
> elems = TREE_VALUE (rhs);
> for (; elems; elems = OVL_NEXT (elems))
> if (TREE_CODE (elem = OVL_CURRENT (elems)) == TEMPLATE_DECL)
> {
> int n = DECL_NTPARMS (elem);
> tree t = make_scratch_vec (n);
> int i;
> i = type_unification
> (DECL_INNERMOST_TEMPLATE_PARMS (elem), t,
> TYPE_ARG_TYPES (TREE_TYPE (elem)),
> TYPE_ARG_TYPES (lhstype), explicit_targs, DEDUCE_EXACT, 1);
> if (i == 0)
4771,4777c5181
< int n = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (elem));
< tree *t = (tree *) alloca (sizeof (tree) * n);
< int i, d = 0;
< i = type_unification (DECL_TEMPLATE_PARMS (elem), t,
< TYPE_ARG_TYPES (TREE_TYPE (elem)),
< TYPE_ARG_TYPES (lhstype), &d, 0);
< if (i == 0)
---
> if (save_elem)
4779,4788c5183,5184
< if (save_elem)
< {
< cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
< return error_mark_node;
< }
< save_elem = instantiate_template (elem, t);
< /* Check the return type. */
< if (! comptypes (TREE_TYPE (lhstype),
< TREE_TYPE (TREE_TYPE (save_elem)), 1))
< save_elem = 0;
---
> cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
> return error_mark_node;
4789a5186,5190
> save_elem = instantiate_template (elem, t);
> /* Check the return type. */
> if (! comptypes (TREE_TYPE (lhstype),
> TREE_TYPE (TREE_TYPE (save_elem)), 1))
> save_elem = 0;
4791,4792c5192,5196
< if (save_elem)
< return save_elem;
---
> }
> if (save_elem)
> {
> mark_used (save_elem);
> return save_elem;
4793a5198
> }
4795,4800c5200,5207
< /* No match found, look for a compatible function. */
< elem = get_first_fn (rhs);
< while (elem && comp_target_types (lhstype,
< TREE_TYPE (elem), 1) <= 0)
< elem = DECL_CHAIN (elem);
< if (elem)
---
> /* There's no exact match, and no templates can be
> instantiated to match. The last thing we try is to see if
> some ordinary overloaded function is close enough. If
> we're only looking for template functions, we don't do
> this. */
> if (!template_only)
> {
> for (elems = rhs; elems; elems = OVL_NEXT (elems))
4801a5209,5214
> elem = OVL_CURRENT (elems);
> if (comp_target_types (lhstype, TREE_TYPE (elem), 1) > 0)
> break;
> }
> if (elems)
> {
4803,4807c5216,5217
< elem = DECL_CHAIN (elem);
< while (elem && comp_target_types (lhstype,
< TREE_TYPE (elem), 0) <= 0)
< elem = DECL_CHAIN (elem);
< if (elem)
---
> for (elems = OVL_CHAIN (elems); elems;
> elems = OVL_CHAIN (elems))
4808a5219,5224
> elem = OVL_FUNCTION (elems);
> if (comp_target_types (lhstype, TREE_TYPE (elem), 0) > 0)
> break;
> }
> if (elems)
> {
4811,4813c5227,5230
< cp_error ("cannot resolve overload to target type `%#T'",
< lhstype);
< cp_error_at (" ambiguity between `%#D'", save_elem);
---
> cp_error
> ("cannot resolve overload to target type `%#T'",
> lhstype);
> cp_error_at (" ambiguity between `%#D'", save_elem);
4817a5235
> mark_used (save_elem);
4820,4827d5237
< if (complain)
< {
< cp_error ("cannot resolve overload to target type `%#T'",
< lhstype);
< cp_error (" because no suitable overload of function `%D' exists",
< TREE_PURPOSE (rhs));
< }
< return error_mark_node;
4830c5240,5241
< if (TREE_NONLOCAL_FLAG (rhs))
---
> /* We failed to find a match. */
> if (complain)
4832,4834c5243,5246
< /* Got to get it as a baselink. */
< rhs = lookup_fnfields (TYPE_BINFO (current_class_type),
< TREE_PURPOSE (rhs), 0);
---
> cp_error ("cannot resolve overload to target type `%#T'", lhstype);
> cp_error
> (" because no suitable overload of function `%D' exists",
> DECL_NAME (OVL_FUNCTION (rhs)));
4836c5248,5255
< else
---
> return error_mark_node;
> }
>
> case TREE_LIST:
> {
> tree elem, baselink, name = NULL_TREE;
>
> if (TREE_PURPOSE (rhs) == error_mark_node)
4838,4842c5257,5262
< my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181);
< if (TREE_CODE (TREE_VALUE (rhs)) == TREE_LIST)
< rhs = TREE_VALUE (rhs);
< my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL,
< 182);
---
> /* Make sure we don't drop the non-local flag, as the old code
> would rely on it. */
> int nl = TREE_NONLOCAL_FLAG (rhs);
> /* We don't need the type of this node. */
> rhs = TREE_VALUE (rhs);
> my_friendly_assert (TREE_NONLOCAL_FLAG (rhs) == nl, 980331);
4844a5265,5280
> /* Now we should have a baselink. */
> my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC,
> 980331);
> /* First look for an exact match. Search member functions.
> May have to undo what `default_conversion' might do to
> lhstype. */
>
> lhstype = validate_lhs (lhstype, complain);
> if (lhstype == error_mark_node)
> return lhstype;
>
> my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181);
> my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL
> || TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD,
> 182);
>
4850,4851c5286,5290
< if (comptypes (lhstype, TREE_TYPE (elem), 1))
< return elem;
---
> if (comptypes (lhstype, TREE_TYPE (OVL_CURRENT (elem)), 1))
> {
> mark_used (OVL_CURRENT (elem));
> return OVL_CURRENT (elem);
> }
4853c5292
< elem = DECL_CHAIN (elem);
---
> elem = OVL_NEXT (elem);
4861,4863c5300,5303
< while (elem && comp_target_types (lhstype,
< TREE_TYPE (elem), 1) <= 0)
< elem = DECL_CHAIN (elem);
---
> for (; elem; elem = OVL_NEXT (elem))
> if (comp_target_types (lhstype,
> TREE_TYPE (OVL_CURRENT (elem)), 1) > 0)
> break;
4866,4870c5306,5310
< tree save_elem = elem;
< elem = DECL_CHAIN (elem);
< while (elem && comp_target_types (lhstype,
< TREE_TYPE (elem), 0) <= 0)
< elem = DECL_CHAIN (elem);
---
> tree save_elem = OVL_CURRENT (elem);
> for (elem = OVL_NEXT (elem); elem; elem = OVL_NEXT (elem))
> if (comp_target_types (lhstype,
> TREE_TYPE (OVL_CURRENT (elem)), 0) > 0)
> break;
4876a5317
> mark_used (save_elem);
4879c5320,5323
< name = DECL_NAME (TREE_VALUE (rhs));
---
> name = rhs;
> while (TREE_CODE (name) == TREE_LIST)
> name = TREE_VALUE (name);
> name = DECL_NAME (OVL_CURRENT (name));
5009,5010d5452
< TREE_TYPE (rhs) = lhstype;
< lhstype = TREE_TYPE (lhstype);
5012c5454
< tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
---
> tree fn = instantiate_type (TREE_TYPE (lhstype), TREE_OPERAND (rhs, 0), complain);
5015a5458
> TREE_TYPE (rhs) = lhstype;
5017a5461,5466
> if (TREE_CODE (lhstype) == POINTER_TYPE
> && TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
> {
> build_ptrmemfunc_type (lhstype);
> rhs = build_ptrmemfunc (lhstype, rhs, 0);
> }
5038a5488
>
5052,5053c5502,5503
< buf = (char *)alloca (sizeof (VFIELD_NAME_FORMAT)
< + TYPE_NAME_LENGTH (type) + 2);
---
> buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
> + TYPE_NAME_LENGTH (type) + 2);
5079a5530
>
5086a5538,5583
>
> /* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
> according to [class]:
> The class-name is also inserted
> into the scope of the class itself. For purposes of access checking,
> the inserted class name is treated as if it were a public member name. */
>
> tree
> build_self_reference ()
> {
> tree name = constructor_name (current_class_type);
> tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
> DECL_NONLOCAL (value) = 1;
> DECL_CONTEXT (value) = current_class_type;
> DECL_CLASS_CONTEXT (value) = current_class_type;
> CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
> DECL_ARTIFICIAL (value) = 1;
>
> pushdecl_class_level (value);
> return value;
> }
>
> /* Returns 1 if TYPE contains only padding bytes. */
>
> int
> is_empty_class (type)
> tree type;
> {
> tree t;
>
> if (type == error_mark_node)
> return 0;
>
> if (! IS_AGGR_TYPE (type))
> return 0;
>
> if (flag_new_abi)
> return CLASSTYPE_SIZE (type) == integer_zero_node;
>
> if (TYPE_BINFO_BASETYPES (type))
> return 0;
> t = TYPE_FIELDS (type);
> while (t && TREE_CODE (t) != FIELD_DECL)
> t = TREE_CHAIN (t);
> return (t == NULL_TREE);
> }