This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binfo] Inline base binfo vector


Hi,
this patch places a binfo's vector of base binfos as an inline trailing
array, thus reducing memory fragmentation and indirection.

To do this, I had to hoist the three c++ specific fields to the common
code, thus making binfos themselves bigger for Java.  However, overall it
is still a win. Two weeks ago I removed on word from the binfo (by
stopping it be a TREE_VEC), this patch removes the VEC overhead of the
base binfo vector (4 words), but adds 2 words for the new vector.  Thus
saving 3 words overall (which I use up with the new c++ fields).  The java
saving is thus in removing indirection, I hope this is satisfactory.

The PRIMARY_BASE_OF field could probably be removed with a bit of
surgery, if it is really desired.

booted & tested on i686-pc-linux-gnu, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2004-07-19  Nathan Sidwell  <nathan@codesourcery.com>

	* tree.h: Include vec.h
	(DEF_VEC_P(tree)): New type.
	(BINFO_BASE_BINFOS, BINFO_N_BASE_BINFOS, BINFO_BASE_BINFO): Adjust.
	(BINFO_BASE_APPEND, BINFO_BASE_ITERATE): New.
	(BINFO_LANG_SLOT): Remove.
	(BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX, BINFO_PRIMARY_BASE_OF): New.
	(struct tree_binfo): Turn base_binfos into a trailing
	VEC(tree). Add vtt_subvtt, vtt_vptr, primary fields.
	(binfo_lang_slots): Remove.
	* tree.c (binfo_lang_slots): Remove.
	(make_tree_binfo_stat): Take a base binfo count, not a
	lang slot count.  Adjust.
	* Makefile.in (TREE_H): Add vec.h
	* alias.c (record_component_aliases): Adjust BINFO access.
	* dbxout.c (dbxout_type): Likewise.
	* dwarf2out.c (gen_member_die): Likewise.
	* sdbout.c (sdbout_one_type): Likewise.
	* tree-dump.c (deque_and_dump): Likewise.
	* config/i386/i386.c (classify_argument,
	contains_128bit_aligned_vector_p): Likewise.
	* config/sh/symbian.c (symbian_export_vtable_and_rtti_p): Likewise.
	* doc/c-tree.texi (Classes): Update BINFO documentation.

2004-07-19  Nathan Sidwell  <nathan@codesourcery.com>

	* cp-tree.h (DEF_VEC_P(tree)): Remove here.
	(BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX, BINFO_PRIMARY_BASE_OF):
	Moved to common.
	(BINFO_LANG_SLOTS): Remove.
	* tree.c (copy_binfo): Adjust BINFO creation and accessors.
	* decl.c (xref_basetypes): Adjust BINFO creation and accessors.
	* class.c (check_bases): Adjust BINFO accessors.
	(determine_primary_base, finish_struct_bits,
	maybe_warn_about_overly_private_class, warn_hidden,
	walk_subobject_offsets, propagate_binfo_offsets, end_of_class,
	warn_about_ambiguous_bases, get_vfield_name,
	dump_class_hierarchy_r, build_vtt_inits, accumulate_vtbl_inits,
	add_vcall_offset_vtbl_entries_r): Likewise.
	* dump.c (cp_dump_tree): Likewise.
	* init.c (sort_mem_initializers, expand_member_init, build_delete,
	push_base_cleanups): Likewise.
	* method.c (do_build_copy_constructor, do_build_assign_ref,
	synthesize_exception_spec): Likewise.
	name-lookup.c (arg_assoc_class): Likewise.
	* pt.c (instantiate_class_template,
	get_template_base_recursive): Likewise.
	* rtti.c (get_pseudo_ti_init, get_pseudo_ti_desc): Likewise.
	* typeck2.c (process_init_constructor): Likewise.
	* search.c (lookup_base_r, dynamic_cast_base_recurse,
	dfs_access_in_type, dfs_walk_real, look_for_overrides,
	types_overlap_p, copied_binfo, original_binfo): Likewise.
	(binfo_for_vtable): Remove

2004-07-19  Nathan Sidwell  <nathan@codesourcery.com>

	* class.c (add_interface_do): Remove.
	(set_super_info, interface_of_p, maybe_add_interface,
	add_interface, make_class_data, layout_class,
	add_miranda_methods): Adjust BINFO accessors and addition.
	* expr.c (can_widen_reference_to, lookup_field): Adjust BINFO
	accessors.
	* jcf-write.c (generate_classfile): Likewise.
	* parse.y (patch_anonymous_class, check_inner_circular_reference,
	check_circular_reference, java_complete_class,
	check_abstract_method_definitions,
	java_check_abstract_method_definitions,
	check_interface_throws_clauses, java_check_abstract_methods,
	lookup_java_interface_method2,
	find_applicable_accessible_methods_list): Adjust BINFO accessors
	and addition.
	* typeck.c (find_method_in_interfaces): Adjust BINFO accessors.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1329
diff -c -3 -p -r1.1329 Makefile.in
*** Makefile.in	18 Jul 2004 15:29:08 -0000	1.1329
--- Makefile.in	19 Jul 2004 17:18:23 -0000
*************** RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H)
*** 686,692 ****
  RTL_H = $(RTL_BASE_H) genrtl.h input.h statistics.h
  PARAMS_H = params.h params.def
  TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h builtins.def \
!           input.h statistics.h
  BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
            hard-reg-set.h cfghooks.h
  COVERAGE_H = coverage.h gcov-io.h gcov-iov.h
--- 686,692 ----
  RTL_H = $(RTL_BASE_H) genrtl.h input.h statistics.h
  PARAMS_H = params.h params.def
  TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h builtins.def \
!           input.h statistics.h vec.h
  BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
            hard-reg-set.h cfghooks.h
  COVERAGE_H = coverage.h gcov-io.h gcov-iov.h
Index: alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alias.c,v
retrieving revision 1.235
diff -c -3 -p -r1.235 alias.c
*** alias.c	9 Jul 2004 03:29:25 -0000	1.235
--- alias.c	19 Jul 2004 17:18:43 -0000
*************** record_component_aliases (tree type)
*** 718,732 ****
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
        /* Recursively record aliases for the base classes, if there are any.  */
!       if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type)))
  	{
  	  int i;
! 	  for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++)
! 	    {
! 	      tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
! 	      record_alias_subset (superset,
! 				   get_alias_set (BINFO_TYPE (binfo)));
! 	    }
  	}
        for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
  	if (TREE_CODE (field) == FIELD_DECL && ! DECL_NONADDRESSABLE_P (field))
--- 718,732 ----
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
        /* Recursively record aliases for the base classes, if there are any.  */
!       if (TYPE_BINFO (type))
  	{
  	  int i;
! 	  tree binfo, base_binfo;
! 	  
! 	  for (binfo = TYPE_BINFO (type), i = 0;
! 	       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
! 	    record_alias_subset (superset,
! 				 get_alias_set (BINFO_TYPE (base_binfo)));
  	}
        for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
  	if (TREE_CODE (field) == FIELD_DECL && ! DECL_NONADDRESSABLE_P (field))
Index: dbxout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dbxout.c,v
retrieving revision 1.190
diff -c -3 -p -r1.190 dbxout.c
*** dbxout.c	7 Jul 2004 10:19:12 -0000	1.190
--- dbxout.c	19 Jul 2004 17:19:00 -0000
*************** dbxout_type (tree type, int full)
*** 1633,1642 ****
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
        {
! 	int i, n_baseclasses = 0;
! 
! 	if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type)))
! 	  n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (type));
  
  	/* Output a structure type.  We must use the same test here as we
  	   use in the DBX_NO_XREFS case above.  */
--- 1633,1639 ----
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
        {
! 	tree binfo = TYPE_BINFO (type);
  
  	/* Output a structure type.  We must use the same test here as we
  	   use in the DBX_NO_XREFS case above.  */
*************** dbxout_type (tree type, int full)
*** 1683,1747 ****
  	CHARS (1);
  	print_wide_int (int_size_in_bytes (type));
  
! 	if (use_gnu_debug_info_extensions)
! 	  {
! 	    if (n_baseclasses)
! 	      {
! 		have_used_extensions = 1;
! 		fprintf (asmfile, "!%d,", n_baseclasses);
! 		CHARS (8);
! 	      }
! 	  }
! 	for (i = 0; i < n_baseclasses; i++)
  	  {
! 	    tree binfo = TYPE_BINFO (type);
! 	    tree child = BINFO_BASE_BINFO (binfo, i);
! 	    tree access = (BINFO_BASE_ACCESSES (binfo)
! 			   ? BINFO_BASE_ACCESS (binfo, i) : access_public_node);
! 
  	    if (use_gnu_debug_info_extensions)
  	      {
! 		have_used_extensions = 1;
!                 putc (BINFO_VIRTUAL_P (child) ? '1' : '0', asmfile);
!                 putc (access == access_public_node ? '2' :
!                       (access == access_protected_node ? '1' :'0'),
!                       asmfile);
! 		CHARS (2);
! 		if (BINFO_VIRTUAL_P (child)
! 		    && strcmp (lang_hooks.name, "GNU C++") == 0)
! 		  /* For a virtual base, print the (negative) offset within
! 		     the vtable where we must look to find the necessary
! 		     adjustment.  */
! 		  print_wide_int (tree_low_cst (BINFO_VPTR_FIELD (child), 0)
! 				  * BITS_PER_UNIT);
! 		else
! 		  print_wide_int (tree_low_cst (BINFO_OFFSET (child), 0)
! 				  * BITS_PER_UNIT);
! 		putc (',', asmfile);
! 		CHARS (1);
! 		dbxout_type (BINFO_TYPE (child), 0);
! 		putc (';', asmfile);
! 		CHARS (1);
  	      }
! 	    else
  	      {
! 		/* Print out the base class information with fields
! 		   which have the same names at the types they hold.  */
! 		dbxout_type_name (BINFO_TYPE (child));
! 		putc (':', asmfile);
! 		CHARS (1);
! 		dbxout_type (BINFO_TYPE (child), full);
! 		putc (',', asmfile);
! 		CHARS (1);
! 		print_wide_int (tree_low_cst (BINFO_OFFSET (child), 0)
! 				* BITS_PER_UNIT);
! 		putc (',', asmfile);
! 		CHARS (1);
! 		print_wide_int (tree_low_cst (TYPE_SIZE (BINFO_TYPE (child)),
! 					      0)
! 				* BITS_PER_UNIT);
! 		putc (';', asmfile);
! 		CHARS (1);
  	      }
  	  }
        }
--- 1680,1751 ----
  	CHARS (1);
  	print_wide_int (int_size_in_bytes (type));
  
! 	if (binfo)
  	  {
! 	    int i;
! 	    tree child;
! 	    
  	    if (use_gnu_debug_info_extensions)
  	      {
! 		if (BINFO_N_BASE_BINFOS (binfo))
! 		  {
! 		    have_used_extensions = 1;
! 		    fprintf (asmfile, "!%d,", BINFO_N_BASE_BINFOS (binfo));
! 		    CHARS (8);
! 		  }
  	      }
! 	    for (i = 0; BINFO_BASE_ITERATE (binfo, i, child); i++)
  	      {
! 		tree access = (BINFO_BASE_ACCESSES (binfo)
! 			       ? BINFO_BASE_ACCESS (binfo, i)
! 			       : access_public_node);
! 
! 		if (use_gnu_debug_info_extensions)
! 		  {
! 		    have_used_extensions = 1;
! 		    putc (BINFO_VIRTUAL_P (child) ? '1' : '0', asmfile);
! 		    putc (access == access_public_node ? '2' :
! 			  (access == access_protected_node ? '1' :'0'),
! 			  asmfile);
! 		    CHARS (2);
! 		    if (BINFO_VIRTUAL_P (child)
! 			&& strcmp (lang_hooks.name, "GNU C++") == 0)
! 		      /* For a virtual base, print the (negative)
! 		     	 offset within the vtable where we must look
! 		     	 to find the necessary adjustment.  */
! 		      print_wide_int
! 			(tree_low_cst (BINFO_VPTR_FIELD (child), 0)
! 			 * BITS_PER_UNIT);
! 		    else
! 		      print_wide_int (tree_low_cst (BINFO_OFFSET (child), 0)
! 				      * BITS_PER_UNIT);
! 		    putc (',', asmfile);
! 		    CHARS (1);
! 		    dbxout_type (BINFO_TYPE (child), 0);
! 		    putc (';', asmfile);
! 		    CHARS (1);
! 		  }
! 		else
! 		  {
! 		    /* Print out the base class information with
! 		       fields which have the same names at the types
! 		       they hold.  */
! 		    dbxout_type_name (BINFO_TYPE (child));
! 		    putc (':', asmfile);
! 		    CHARS (1);
! 		    dbxout_type (BINFO_TYPE (child), full);
! 		    putc (',', asmfile);
! 		    CHARS (1);
! 		    print_wide_int (tree_low_cst (BINFO_OFFSET (child), 0)
! 				    * BITS_PER_UNIT);
! 		    putc (',', asmfile);
! 		    CHARS (1);
! 		    print_wide_int
! 		      (tree_low_cst (TYPE_SIZE (BINFO_TYPE (child)), 0)
! 		       * BITS_PER_UNIT);
! 		    putc (';', asmfile);
! 		    CHARS (1);
! 		  }
  	      }
  	  }
        }
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.534
diff -c -3 -p -r1.534 dwarf2out.c
*** dwarf2out.c	15 Jul 2004 01:07:48 -0000	1.534
--- dwarf2out.c	19 Jul 2004 17:20:10 -0000
*************** gen_member_die (tree type, dw_die_ref co
*** 11891,11905 ****
       the TREE node representing the appropriate (containing) type.  */
  
    /* First output info about the base classes.  */
!   if (binfo && BINFO_BASE_BINFOS (binfo))
      {
-       tree bases = BINFO_BASE_BINFOS (binfo);
        tree accesses = BINFO_BASE_ACCESSES (binfo);
-       int n_bases = TREE_VEC_LENGTH (bases);
        int i;
  
!       for (i = 0; i < n_bases; i++)
! 	gen_inheritance_die (TREE_VEC_ELT (bases, i),
  			     (accesses ? TREE_VEC_ELT (accesses, i)
  			      : access_public_node), context_die);
      }
--- 11891,11904 ----
       the TREE node representing the appropriate (containing) type.  */
  
    /* First output info about the base classes.  */
!   if (binfo)
      {
        tree accesses = BINFO_BASE_ACCESSES (binfo);
        int i;
+       tree base;
  
!       for (i = 0; BINFO_BASE_ITERATE (binfo, i, base); i++)
! 	gen_inheritance_die (base,
  			     (accesses ? TREE_VEC_ELT (accesses, i)
  			      : access_public_node), context_die);
      }
Index: sdbout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sdbout.c,v
retrieving revision 1.93
diff -c -3 -p -r1.93 sdbout.c
*** sdbout.c	7 Jul 2004 10:19:18 -0000	1.93
--- sdbout.c	19 Jul 2004 17:20:19 -0000
*************** sdbout_one_type (tree type)
*** 1109,1115 ****
  	int size = int_size_in_bytes (type);
  	int member_scl = 0;
  	tree tem;
- 	int i, n_baseclasses = 0;
  
  	/* Record the type tag, but not in its permanent place just yet.  */
  	sdbout_record_type_name (type);
--- 1109,1114 ----
*************** sdbout_one_type (tree type)
*** 1149,1164 ****
  	/* This is only relevant to aggregate types.  TYPE_BINFO is used
  	   for other purposes in an ENUMERAL_TYPE, so we must exclude that
  	   case.  */
! 	if (TREE_CODE (type) != ENUMERAL_TYPE)
  	  {
! 	    if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type)))
! 	      n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (type));
! 	    
! 	    for (i = 0; i < n_baseclasses; i++)
  	      {
- 		tree child = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
  		tree child_type = BINFO_TYPE (child);
  		tree child_type_name;
  		if (TYPE_NAME (child_type) == 0)
  		  continue;
  		if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
--- 1148,1164 ----
  	/* This is only relevant to aggregate types.  TYPE_BINFO is used
  	   for other purposes in an ENUMERAL_TYPE, so we must exclude that
  	   case.  */
! 	if (TREE_CODE (type) != ENUMERAL_TYPE && TYPE_BINFO (type))
  	  {
! 	    int i;
! 	    tree binfo, child;
! 
! 	    for (binfo = TYPE_BINFO (type), i = 0;
! 		 BINFO_BASE_ITERATE (binfo, i, child); i++)
  	      {
  		tree child_type = BINFO_TYPE (child);
  		tree child_type_name;
+ 		
  		if (TYPE_NAME (child_type) == 0)
  		  continue;
  		if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
Index: tree-dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-dump.c,v
retrieving revision 1.27
diff -c -3 -p -r1.27 tree-dump.c
*** tree-dump.c	7 Jul 2004 10:19:18 -0000	1.27
--- tree-dump.c	19 Jul 2004 17:20:23 -0000
*************** dequeue_and_dump (dump_info_p di)
*** 251,258 ****
    if (dni->binfo_p)
      {
        unsigned ix;
!       tree bases = BINFO_BASE_BINFOS (t);
!       unsigned n_bases = bases ? TREE_VEC_LENGTH (bases): 0;
        tree accesses = BINFO_BASE_ACCESSES (t);
  
        dump_child ("type", BINFO_TYPE (t));
--- 251,257 ----
    if (dni->binfo_p)
      {
        unsigned ix;
!       tree base;
        tree accesses = BINFO_BASE_ACCESSES (t);
  
        dump_child ("type", BINFO_TYPE (t));
*************** dequeue_and_dump (dump_info_p di)
*** 260,269 ****
        if (BINFO_VIRTUAL_P (t))
  	dump_string (di, "virt");
  
!       dump_int (di, "bases", n_bases);
!       for (ix = 0; ix != n_bases; ix++)
  	{
- 	  tree base = TREE_VEC_ELT (bases, ix);
  	  tree access = (accesses ? TREE_VEC_ELT (accesses, ix)
  			 : access_public_node);
  	  const char *string = NULL;
--- 259,267 ----
        if (BINFO_VIRTUAL_P (t))
  	dump_string (di, "virt");
  
!       dump_int (di, "bases", BINFO_N_BASE_BINFOS (t));
!       for (ix = 0; BINFO_BASE_ITERATE (t, ix, base); ix++)
  	{
  	  tree access = (accesses ? TREE_VEC_ELT (accesses, ix)
  			 : access_public_node);
  	  const char *string = NULL;
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.397
diff -c -3 -p -r1.397 tree.c
*** tree.c	15 Jul 2004 00:02:29 -0000	1.397
--- tree.c	19 Jul 2004 17:20:49 -0000
*************** struct type_hash GTY(())
*** 94,102 ****
    tree type;
  };
  
- /* Additional language-dependent binfo slots.  */
- unsigned binfo_lang_slots;
- 
  /* Initial size of the hash table (rounded to next prime).  */
  #define TYPE_HASH_INITIAL_SIZE 1000
  
--- 94,99 ----
*************** build_complex (tree type, tree real, tre
*** 582,601 ****
  /* Build a BINFO with LEN language slots.  */
  
  tree
! make_tree_binfo_stat (unsigned lang_slots MEM_STAT_DECL)
  {
    tree t;
!   static unsigned length;
!   
!   if (!length)
!     {
!       length = (offsetof (struct tree_binfo, lang_slots)
! 		+ (sizeof (((struct tree_binfo *)0)->lang_slots[0])
! 		   * lang_slots));
!       binfo_lang_slots = lang_slots;
!     }
!   else if (binfo_lang_slots != lang_slots)
!     abort ();
    
  #ifdef GATHER_STATISTICS
    tree_node_counts[(int) binfo_kind]++;
--- 579,589 ----
  /* Build a BINFO with LEN language slots.  */
  
  tree
! make_tree_binfo_stat (unsigned base_binfos MEM_STAT_DECL)
  {
    tree t;
!   size_t length = (offsetof (struct tree_binfo, base_binfos)
! 		   + VEC_embedded_size (tree, base_binfos));
    
  #ifdef GATHER_STATISTICS
    tree_node_counts[(int) binfo_kind]++;
*************** make_tree_binfo_stat (unsigned lang_slot
*** 604,612 ****
  
    t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT);
  
!   memset (t, 0, length);
  
    TREE_SET_CODE (t, TREE_BINFO);
  
    return t;
  }
--- 592,602 ----
  
    t = ggc_alloc_zone_stat (length, tree_zone PASS_MEM_STAT);
  
!   memset (t, 0, offsetof (struct tree_binfo, base_binfos));
  
    TREE_SET_CODE (t, TREE_BINFO);
+   
+   VEC_embedded_init (tree, BINFO_BASE_BINFOS (t), base_binfos);
  
    return t;
  }
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.562
diff -c -3 -p -r1.562 tree.h
*** tree.h	18 Jul 2004 05:44:11 -0000	1.562
--- tree.h	19 Jul 2004 17:21:17 -0000
*************** Software Foundation, 59 Temple Place - S
*** 25,30 ****
--- 25,31 ----
  #include "machmode.h"
  #include "input.h"
  #include "statistics.h"
+ #include "vec.h"
  
  /* Codes of tree nodes */
  
*************** extern const unsigned char tree_code_len
*** 74,79 ****
--- 75,84 ----
  /* Names of tree components.  */
  
  extern const char *const tree_code_name[];
+ 
+ /* A vector of trees.  */
+ DEF_VEC_P(tree);
+ 
  
  /* Classify which part of the compiler has defined a given builtin function.
     Note that we assume below that this is no more than two bits.  */
*************** struct tree_type GTY(())
*** 1641,1660 ****
  
     If this basetype describes type D as inherited in C, and if the
     basetypes of D are E and F, then this vector contains binfos for
!    inheritance of E and F by C.
! 
!    ??? This could probably be done by just allocating the
!    base types at the end of this TREE_VEC (instead of using
!    another TREE_VEC).  This would simplify the calculation
!    of how many basetypes a given type had.  */
! #define BINFO_BASE_BINFOS(NODE) (TREE_BINFO_CHECK(NODE)->binfo.base_binfos)
  
  /* The number of basetypes for NODE.  */
! #define BINFO_N_BASE_BINFOS(NODE) \
!   (BINFO_BASE_BINFOS (NODE) ? TREE_VEC_LENGTH (BINFO_BASE_BINFOS (NODE)) : 0)
  
  /* Accessor macro to get to the Nth base binfo of this binfo.  */
! #define BINFO_BASE_BINFO(NODE,N) TREE_VEC_ELT (BINFO_BASE_BINFOS (NODE), (N))
  
  /* For a BINFO record describing a virtual base class, i.e., one where
     TREE_VIA_VIRTUAL is set, this field assists in locating the virtual
--- 1646,1664 ----
  
     If this basetype describes type D as inherited in C, and if the
     basetypes of D are E and F, then this vector contains binfos for
!    inheritance of E and F by C.  */
! #define BINFO_BASE_BINFOS(NODE) (&TREE_BINFO_CHECK(NODE)->binfo.base_binfos)
  
  /* The number of basetypes for NODE.  */
! #define BINFO_N_BASE_BINFOS(NODE) (VEC_length (tree, BINFO_BASE_BINFOS (NODE)))
  
  /* Accessor macro to get to the Nth base binfo of this binfo.  */
! #define BINFO_BASE_BINFO(NODE,N) \
!  (VEC_index (tree, BINFO_BASE_BINFOS (NODE), (N)))
! #define BINFO_BASE_ITERATE(NODE,N,B) \
!  (VEC_iterate (tree, BINFO_BASE_BINFOS (NODE), (N), (B)))
! #define BINFO_BASE_APPEND(NODE,T) \
!  (VEC_quick_push (tree, BINFO_BASE_BINFOS (NODE), (T)))
  
  /* For a BINFO record describing a virtual base class, i.e., one where
     TREE_VIA_VIRTUAL is set, this field assists in locating the virtual
*************** struct tree_type GTY(())
*** 1669,1678 ****
  #define BINFO_BASE_ACCESSES(NODE) (TREE_BINFO_CHECK(NODE)->binfo.base_accesses)
  #define BINFO_BASE_ACCESS(NODE,N) TREE_VEC_ELT (BINFO_BASE_ACCESSES(NODE), (N))
  
! /* Number of language independent elements in a binfo.  Languages may
!    add additional trailing elements.  */
! 
! #define BINFO_LANG_SLOT(NODE,N) (TREE_BINFO_CHECK(NODE)->binfo.lang_slots[N])
  
  /* The BINFO_INHERITANCE_CHAIN points at the binfo for the base
     inheriting this base for non-virtual bases. For virtual bases it
--- 1673,1691 ----
  #define BINFO_BASE_ACCESSES(NODE) (TREE_BINFO_CHECK(NODE)->binfo.base_accesses)
  #define BINFO_BASE_ACCESS(NODE,N) TREE_VEC_ELT (BINFO_BASE_ACCESSES(NODE), (N))
  
! /* The index in the VTT where this subobject's sub-VTT can be found.
!    NULL_TREE if there is no sub-VTT.  */
! #define BINFO_SUBVTT_INDEX(NODE) (TREE_BINFO_CHECK(NODE)->binfo.vtt_subvtt)
! 
! /* The index in the VTT where the vptr for this subobject can be
!    found.  NULL_TREE if there is no secondary vptr in the VTT.  */
! #define BINFO_VPTR_INDEX(NODE) (TREE_BINFO_CHECK(NODE)->binfo.vtt_vptr)
! 
! /* The binfo of which NODE is a primary base.  (This is different from
!    BINFO_INHERITANCE_CHAIN for virtual base because a virtual base is
!    sometimes a primary base for a class for which it is not an
!    immediate base.)  */
! #define BINFO_PRIMARY_BASE_OF(NODE) (TREE_BINFO_CHECK(NODE)->binfo.primary)
  
  /* The BINFO_INHERITANCE_CHAIN points at the binfo for the base
     inheriting this base for non-virtual bases. For virtual bases it
*************** struct tree_binfo GTY (())
*** 1687,1700 ****
    tree offset;
    tree vtable;
    tree virtuals;
-   tree base_binfos;
    tree vptr_field;
    tree base_accesses;
    tree inheritance;
  
!   tree GTY ((length ("binfo_lang_slots"))) lang_slots[1];
  };
- extern GTY (()) unsigned binfo_lang_slots;
  
  
  /* Define fields and accessors for nodes representing declared names.  */
--- 1700,1715 ----
    tree offset;
    tree vtable;
    tree virtuals;
    tree vptr_field;
    tree base_accesses;
    tree inheritance;
  
!   tree vtt_subvtt;
!   tree vtt_vptr;
!   tree primary;
! 
!   VEC(tree) base_binfos;
  };
  
  
  /* Define fields and accessors for nodes representing declared names.  */
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.694
diff -c -3 -p -r1.694 i386.c
*** config/i386/i386.c	17 Jul 2004 21:09:11 -0000	1.694
--- config/i386/i386.c	19 Jul 2004 17:22:47 -0000
*************** classify_argument (enum machine_mode mod
*** 2105,2122 ****
        if (TREE_CODE (type) == RECORD_TYPE)
  	{
  	  /* For classes first merge in the field of the subclasses.  */
! 	  if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type)))
  	    {
! 	      tree bases = BINFO_BASE_BINFOS (TYPE_BINFO (type));
! 	      int n_bases = BINFO_N_BASE_BINFOS (TYPE_BINFO (type));
  	      int i;
  
! 	      for (i = 0; i < n_bases; ++i)
  		{
- 		   tree binfo = TREE_VEC_ELT (bases, i);
  		   int num;
! 		   int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
! 		   tree type = BINFO_TYPE (binfo);
  
  		   num = classify_argument (TYPE_MODE (type),
  					    type, subclasses,
--- 2105,2121 ----
        if (TREE_CODE (type) == RECORD_TYPE)
  	{
  	  /* For classes first merge in the field of the subclasses.  */
! 	  if (TYPE_BINFO (type))
  	    {
! 	      tree binfo, base_binfo;
  	      int i;
  
! 	      for (binfo = TYPE_BINFO (type), i = 0;
! 		   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
  		{
  		   int num;
! 		   int offset = tree_low_cst (BINFO_OFFSET (base_binfo), 0) * 8;
! 		   tree type = BINFO_TYPE (base_binfo);
  
  		   num = classify_argument (TYPE_MODE (type),
  					    type, subclasses,
*************** classify_argument (enum machine_mode mod
*** 2193,2210 ****
  	       || TREE_CODE (type) == QUAL_UNION_TYPE)
  	{
  	  /* For classes first merge in the field of the subclasses.  */
! 	  if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type)))
  	    {
! 	      tree bases = BINFO_BASE_BINFOS (TYPE_BINFO (type));
! 	      int n_bases = BINFO_N_BASE_BINFOS (TYPE_BINFO (type));
  	      int i;
  
! 	      for (i = 0; i < n_bases; ++i)
  		{
- 		   tree binfo = TREE_VEC_ELT (bases, i);
  		   int num;
! 		   int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
! 		   tree type = BINFO_TYPE (binfo);
  
  		   num = classify_argument (TYPE_MODE (type),
  					    type, subclasses,
--- 2192,2208 ----
  	       || TREE_CODE (type) == QUAL_UNION_TYPE)
  	{
  	  /* For classes first merge in the field of the subclasses.  */
! 	  if (TYPE_BINFO (type))
  	    {
! 	      tree binfo, base_binfo;
  	      int i;
  
! 	      for (binfo = TYPE_BINFO (type), i = 0;
! 		   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
  		{
  		   int num;
! 		   int offset = tree_low_cst (BINFO_OFFSET (base_binfo), 0) * 8;
! 		   tree type = BINFO_TYPE (base_binfo);
  
  		   num = classify_argument (TYPE_MODE (type),
  					    type, subclasses,
*************** contains_128bit_aligned_vector_p (tree t
*** 2818,2837 ****
  	{
  	  tree field;
  
! 	  if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type)))
  	    {
! 	      tree bases = BINFO_BASE_BINFOS (TYPE_BINFO (type));
! 	      int n_bases = BINFO_N_BASE_BINFOS (TYPE_BINFO (type));
  	      int i;
  
! 	      for (i = 0; i < n_bases; ++i)
! 		{
! 		  tree binfo = TREE_VEC_ELT (bases, i);
! 		  tree type = BINFO_TYPE (binfo);
! 
! 		  if (contains_128bit_aligned_vector_p (type))
! 		    return true;
! 		}
  	    }
  	  /* And now merge the fields of structure.  */
  	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
--- 2816,2830 ----
  	{
  	  tree field;
  
! 	  if (TYPE_BINFO (type))
  	    {
! 	      tree binfo, base_binfo;
  	      int i;
  
! 	      for (binfo = TYPE_BINFO (type), i = 0;
! 		   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
! 		if (contains_128bit_aligned_vector_p (BINFO_TYPE (base_binfo)))
! 		  return true;
  	    }
  	  /* And now merge the fields of structure.  */
  	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
Index: config/sh/symbian.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/symbian.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 symbian.c
*** config/sh/symbian.c	12 Jul 2004 08:45:00 -0000	1.1
--- config/sh/symbian.c	19 Jul 2004 17:22:53 -0000
*************** symbian_export_vtable_and_rtti_p (tree c
*** 618,626 ****
    bool inline_ctor_dtor;
    bool dllimport_ctor_dtor;
    bool dllimport_member;
!   tree binfos;
    tree methods;
    tree key;
    int len;
  
    /* Make sure that we are examining a class...  */
--- 618,627 ----
    bool inline_ctor_dtor;
    bool dllimport_ctor_dtor;
    bool dllimport_member;
!   tree binfo, base_binfo;
    tree methods;
    tree key;
+   int i;
    int len;
  
    /* Make sure that we are examining a class...  */
*************** symbian_export_vtable_and_rtti_p (tree c
*** 729,748 ****
  #endif
  
    /* Now we must check and possibly export the base classes.  */
!   binfos = BINFO_BASE_BINFOS (TYPE_BINFO (ctype));
!   len = BINFO_N_BASE_BINFOS (TYPE_BINFO (ctype));
! 
!   for (; len --;)
!     {
!       tree base_binfo;
!       tree basetype;
! 
!       /* Figure out which base we're looking at.  */
!       base_binfo = TREE_VEC_ELT (binfos, len);
!       basetype = TREE_TYPE (base_binfo);
! 
!       symbian_possibly_export_base_class (basetype);
!     }
  
    return true;
  }
--- 730,738 ----
  #endif
  
    /* Now we must check and possibly export the base classes.  */
!   for (i = 0, binfo = TYPE_BINFO (ctype);
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
!     symbian_possibly_export_base_class (BINFO_TYPE (base_binfo));
  
    return true;
  }
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.638
diff -c -3 -p -r1.638 class.c
*** cp/class.c	19 Jul 2004 15:45:48 -0000	1.638
--- cp/class.c	19 Jul 2004 17:23:54 -0000
*************** check_bases (tree t,
*** 1130,1152 ****
               int* cant_have_const_ctor_p,
               int* no_const_asn_ref_p)
  {
-   int n_baseclasses;
    int i;
    int seen_non_virtual_nearly_empty_base_p;
!   tree binfos;
  
-   binfos = BINFO_BASE_BINFOS (TYPE_BINFO (t));
-   n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
    seen_non_virtual_nearly_empty_base_p = 0;
  
!   for (i = 0; i < n_baseclasses; ++i) 
      {
!       tree base_binfo;
!       tree basetype;
! 
!       /* Figure out what base we're looking at.  */
!       base_binfo = TREE_VEC_ELT (binfos, i);
!       basetype = TREE_TYPE (base_binfo);
  
        my_friendly_assert (COMPLETE_TYPE_P (basetype), 20040714);
        
--- 1130,1146 ----
               int* cant_have_const_ctor_p,
               int* no_const_asn_ref_p)
  {
    int i;
    int seen_non_virtual_nearly_empty_base_p;
!   tree base_binfo;
!   tree binfo;
  
    seen_non_virtual_nearly_empty_base_p = 0;
  
!   for (binfo = TYPE_BINFO (t), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
      {
!       tree basetype = TREE_TYPE (base_binfo);
  
        my_friendly_assert (COMPLETE_TYPE_P (basetype), 20040714);
        
*************** determine_primary_base (tree t)
*** 1269,1285 ****
    unsigned i, n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
    tree type_binfo = TYPE_BINFO (t);
    tree vbase_binfo;
    VEC(tree) *vbases;
  
    /* If there are no baseclasses, there is certainly no primary base.  */
    if (n_baseclasses == 0)
      return;
  
!   type_binfo = TYPE_BINFO (t);
! 
!   for (i = 0; i < n_baseclasses; i++)
      {
-       tree base_binfo = BINFO_BASE_BINFO (type_binfo, i);
        tree basetype = BINFO_TYPE (base_binfo);
  
        if (TYPE_CONTAINS_VPTR_P (basetype))
--- 1263,1277 ----
    unsigned i, n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
    tree type_binfo = TYPE_BINFO (t);
    tree vbase_binfo;
+   tree base_binfo;
    VEC(tree) *vbases;
  
    /* If there are no baseclasses, there is certainly no primary base.  */
    if (n_baseclasses == 0)
      return;
  
!   for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, base_binfo); i++)
      {
        tree basetype = BINFO_TYPE (base_binfo);
  
        if (TYPE_CONTAINS_VPTR_P (basetype))
*************** determine_primary_base (tree t)
*** 1325,1336 ****
        /* See if this virtual base is an indirect primary base.  To be
           so, it must be a primary base within the hierarchy of one of
           our direct bases.  */
!       for (j = 0; j != n_baseclasses; ++j) 
  	{
  	  unsigned k;
  	  VEC (tree) *base_vbases;
  	  tree base_vbase_binfo;
! 	  tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), j));
  	  
  	  for (base_vbases = CLASSTYPE_VBASECLASSES (basetype), k = 0;
  	       VEC_iterate (tree, base_vbases, k, base_vbase_binfo); k++)
--- 1317,1328 ----
        /* See if this virtual base is an indirect primary base.  To be
           so, it must be a primary base within the hierarchy of one of
           our direct bases.  */
!       for (j = 0; BINFO_BASE_ITERATE (type_binfo, j, base_binfo); j++)
  	{
  	  unsigned k;
  	  VEC (tree) *base_vbases;
  	  tree base_vbase_binfo;
! 	  tree basetype = BINFO_TYPE (base_binfo);
  	  
  	  for (base_vbases = CLASSTYPE_VBASECLASSES (basetype), k = 0;
  	       VEC_iterate (tree, base_vbases, k, base_vbase_binfo); k++)
*************** determine_primary_base (tree t)
*** 1407,1413 ****
  static void
  finish_struct_bits (tree t)
  {
-   int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
    tree variants;
    
    /* Fix up variants (if any).  */
--- 1399,1404 ----
*************** finish_struct_bits (tree t)
*** 1439,1445 ****
        TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
      }
  
!   if (n_baseclasses && TYPE_POLYMORPHIC_P (t))
      /* For a class w/o baseclasses, `finish_struct' has set
         CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition).
         Similarly for a class whose base classes do not have vtables.
--- 1430,1436 ----
        TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
      }
  
!   if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
      /* For a class w/o baseclasses, `finish_struct' has set
         CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition).
         Similarly for a class whose base classes do not have vtables.
*************** maybe_warn_about_overly_private_class (t
*** 1537,1546 ****
  	 constructors/destructors we want to use the code below that
  	 issues error messages specifically referring to
  	 constructors/destructors.)  */
!       int i;
        tree binfo = TYPE_BINFO (t);
        
!       for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++)
  	if (BINFO_BASE_ACCESS (binfo, i) != access_private_node)
  	  {
  	    has_nonprivate_method = 1;
--- 1528,1537 ----
  	 constructors/destructors we want to use the code below that
  	 issues error messages specifically referring to
  	 constructors/destructors.)  */
!       unsigned i;
        tree binfo = TYPE_BINFO (t);
        
!       for (i = 0; i != BINFO_N_BASE_BINFOS (binfo); i++)
  	if (BINFO_BASE_ACCESS (binfo, i) != access_private_node)
  	  {
  	    has_nonprivate_method = 1;
*************** warn_hidden (tree t)
*** 2370,2375 ****
--- 2361,2368 ----
        tree name;
        tree fndecl;
        tree base_fndecls;
+       tree base_binfo;
+       tree binfo;
        int j;
  
        /* All functions in this slot in the CLASSTYPE_METHOD_VEC will
*************** warn_hidden (tree t)
*** 2379,2387 ****
        base_fndecls = NULL_TREE;
        /* Iterate through all of the base classes looking for possibly
  	 hidden functions.  */
!       for (j = 0; j < BINFO_N_BASE_BINFOS (TYPE_BINFO (t)); j++)
  	{
! 	  tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), j));
  	  base_fndecls = chainon (get_basefndecls (name, basetype),
  				  base_fndecls);
  	}
--- 2372,2381 ----
        base_fndecls = NULL_TREE;
        /* Iterate through all of the base classes looking for possibly
  	 hidden functions.  */
!       for (binfo = TYPE_BINFO (t), j = 0;
! 	   BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
  	{
! 	  tree basetype = BINFO_TYPE (base_binfo);
  	  base_fndecls = chainon (get_basefndecls (name, basetype),
  				  base_fndecls);
  	}
*************** walk_subobject_offsets (tree type, 
*** 3178,3189 ****
        /* Iterate through the direct base classes of TYPE.  */
        if (!type_binfo)
  	type_binfo = TYPE_BINFO (type);
!       for (i = 0; i < BINFO_N_BASE_BINFOS (type_binfo); ++i)
  	{
  	  tree binfo_offset;
  
- 	  binfo = BINFO_BASE_BINFO (type_binfo, i);
- 
  	  if (abi_version_at_least (2) 
  	      && BINFO_VIRTUAL_P (binfo))
  	    continue;
--- 3172,3181 ----
        /* Iterate through the direct base classes of TYPE.  */
        if (!type_binfo)
  	type_binfo = TYPE_BINFO (type);
!       for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, binfo); i++)
  	{
  	  tree binfo_offset;
  
  	  if (abi_version_at_least (2) 
  	      && BINFO_VIRTUAL_P (binfo))
  	    continue;
*************** propagate_binfo_offsets (tree binfo, tre
*** 4263,4268 ****
--- 4255,4261 ----
  {
    int i;
    tree primary_binfo;
+   tree base_binfo;
  
    /* Update BINFO's offset.  */
    BINFO_OFFSET (binfo)
*************** propagate_binfo_offsets (tree binfo, tre
*** 4279,4288 ****
    
    /* Scan all of the bases, pushing the BINFO_OFFSET adjust
       downwards.  */
!   for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); ++i)
      {
-       tree base_binfo = BINFO_BASE_BINFO (binfo, i);
-       
        /* Don't do the primary base twice.  */
        if (base_binfo == primary_binfo)
  	continue;
--- 4272,4279 ----
    
    /* Scan all of the bases, pushing the BINFO_OFFSET adjust
       downwards.  */
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
      {
        /* Don't do the primary base twice.  */
        if (base_binfo == primary_binfo)
  	continue;
*************** end_of_class (tree t, int include_virtua
*** 4403,4418 ****
    tree offset;
    int i;
  
!   for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (t)); ++i)
      {
-       binfo = BINFO_BASE_BINFO (TYPE_BINFO (t), i);
- 
        if (!include_virtuals_p
! 	  && BINFO_VIRTUAL_P (binfo) 
! 	  && BINFO_PRIMARY_BASE_OF (binfo) != TYPE_BINFO (t))
  	continue;
  
!       offset = end_of_base (binfo);
        if (INT_CST_LT_UNSIGNED (result, offset))
  	result = offset;
      }
--- 4394,4408 ----
    tree offset;
    int i;
  
!   for (binfo = TYPE_BINFO (t), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
      {
        if (!include_virtuals_p
! 	  && BINFO_VIRTUAL_P (base_binfo) 
! 	  && BINFO_PRIMARY_BASE_OF (base_binfo) != TYPE_BINFO (t))
  	continue;
  
!       offset = end_of_base (base_binfo);
        if (INT_CST_LT_UNSIGNED (result, offset))
  	result = offset;
      }
*************** warn_about_ambiguous_bases (tree t)
*** 4447,4458 ****
    VEC (tree) *vbases;
    tree basetype;
    tree binfo;
  
    /* Check direct bases.  */
!   for (i = 0;
!        i < BINFO_N_BASE_BINFOS (TYPE_BINFO (t)); ++i)
      {
!       basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), i));
  
        if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
  	warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
--- 4437,4449 ----
    VEC (tree) *vbases;
    tree basetype;
    tree binfo;
+   tree base_binfo;
  
    /* Check direct bases.  */
!   for (binfo = TYPE_BINFO (t), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
      {
!       basetype = BINFO_TYPE (base_binfo);
  
        if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
  	warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
*************** get_vfield_name (tree type)
*** 6142,6148 ****
    char *buf;
  
    for (binfo = TYPE_BINFO (type);
!        BINFO_BASE_BINFOS (binfo);
         binfo = base_binfo)
      {
        base_binfo = BINFO_BASE_BINFO (binfo, 0);
--- 6133,6139 ----
    char *buf;
  
    for (binfo = TYPE_BINFO (type);
!        BINFO_N_BASE_BINFOS (binfo);
         binfo = base_binfo)
      {
        base_binfo = BINFO_BASE_BINFO (binfo, 0);
*************** contains_empty_class_p (tree type)
*** 6231,6241 ****
    if (CLASS_TYPE_P (type))
      {
        tree field;
        int i;
  
!       for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); ++i)
! 	if (contains_empty_class_p
! 	    (BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type), i))))
  	  return true;
        for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  	if (TREE_CODE (field) == FIELD_DECL
--- 6222,6234 ----
    if (CLASS_TYPE_P (type))
      {
        tree field;
+       tree binfo;
+       tree base_binfo;
        int i;
  
!       for (binfo = TYPE_BINFO (type), i = 0;
! 	   BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
! 	if (contains_empty_class_p (BINFO_TYPE (base_binfo)))
  	  return true;
        for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
  	if (TREE_CODE (field) == FIELD_DECL
*************** dump_class_hierarchy_r (FILE *stream,
*** 6401,6407 ****
                          int indent)
  {
    int indented = 0;
!   tree base_binfos;
    
    indented = maybe_indent_hierarchy (stream, indent, 0);
    fprintf (stream, "%s (0x%lx) ",
--- 6394,6401 ----
                          int indent)
  {
    int indented = 0;
!   tree base_binfo;
!   int i;
    
    indented = maybe_indent_hierarchy (stream, indent, 0);
    fprintf (stream, "%s (0x%lx) ",
*************** dump_class_hierarchy_r (FILE *stream,
*** 6477,6497 ****
        if (indented)
  	fprintf (stream, "\n");
      }
-   
-   base_binfos = BINFO_BASE_BINFOS (binfo);
-   if (base_binfos)
-     {
-       int ix, n;
- 
-       n = TREE_VEC_LENGTH (base_binfos);
-       for (ix = 0; ix != n; ix++)
- 	{
- 	  tree base_binfo = TREE_VEC_ELT (base_binfos, ix);
  
! 	  igo = dump_class_hierarchy_r (stream, flags, base_binfo,
! 					igo, indent + 2);
! 	}
!     }
    
    return igo;
  }
--- 6471,6479 ----
        if (indented)
  	fprintf (stream, "\n");
      }
  
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
!     igo = dump_class_hierarchy_r (stream, flags, base_binfo, igo, indent + 2);
    
    return igo;
  }
*************** build_vtt_inits (tree binfo, tree t, tre
*** 6820,6832 ****
    *index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));
  		       
    /* Recursively add the secondary VTTs for non-virtual bases.  */
!   for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); ++i)
!     {
!       b = BINFO_BASE_BINFO (binfo, i);
!       if (!BINFO_VIRTUAL_P (b))
! 	inits = build_vtt_inits (BINFO_BASE_BINFO (binfo, i), t, 
! 				 inits, index);
!     }
        
    /* Add secondary virtual pointers for all subobjects of BINFO with
       either virtual bases or reachable along a virtual path, except
--- 6802,6810 ----
    *index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));
  		       
    /* Recursively add the secondary VTTs for non-virtual bases.  */
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
!     if (!BINFO_VIRTUAL_P (b))
!       inits = build_vtt_inits (BINFO_BASE_BINFO (binfo, i), t, inits, index);
        
    /* Add secondary virtual pointers for all subobjects of BINFO with
       either virtual bases or reachable along a virtual path, except
*************** accumulate_vtbl_inits (tree binfo,
*** 7058,7063 ****
--- 7036,7042 ----
                         tree inits)
  {
    int i;
+   tree base_binfo;
    int ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
  
    my_friendly_assert (same_type_p (BINFO_TYPE (binfo),
*************** accumulate_vtbl_inits (tree binfo,
*** 7086,7095 ****
       secondary vtable lies from the primary vtable.  We can't use
       dfs_walk here because we need to iterate through bases of BINFO
       and RTTI_BINFO simultaneously.  */
!   for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); ++i)
      {
-       tree base_binfo = BINFO_BASE_BINFO (binfo, i);
-       
        /* Skip virtual bases.  */
        if (BINFO_VIRTUAL_P (base_binfo))
  	continue;
--- 7065,7072 ----
       secondary vtable lies from the primary vtable.  We can't use
       dfs_walk here because we need to iterate through bases of BINFO
       and RTTI_BINFO simultaneously.  */
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
      {
        /* Skip virtual bases.  */
        if (BINFO_VIRTUAL_P (base_binfo))
  	continue;
*************** add_vcall_offset_vtbl_entries_r (tree bi
*** 7562,7567 ****
--- 7539,7545 ----
  {
    int i;
    tree primary_binfo;
+   tree base_binfo;
  
    /* Don't walk into virtual bases -- except, of course, for the
       virtual base for which we are building vcall offsets.  Any
*************** add_vcall_offset_vtbl_entries_r (tree bi
*** 7579,7592 ****
    add_vcall_offset_vtbl_entries_1 (binfo, vid);
  
    /* Scan the non-primary bases of BINFO.  */
!   for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); ++i) 
!     {
!       tree base_binfo;
!       
!       base_binfo = BINFO_BASE_BINFO (binfo, i);
!       if (base_binfo != primary_binfo)
! 	add_vcall_offset_vtbl_entries_r (base_binfo, vid);
!     }
  }
  
  /* Called from build_vcall_offset_vtbl_entries_r.  */
--- 7557,7565 ----
    add_vcall_offset_vtbl_entries_1 (binfo, vid);
  
    /* Scan the non-primary bases of BINFO.  */
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
!     if (base_binfo != primary_binfo)
!       add_vcall_offset_vtbl_entries_r (base_binfo, vid);
  }
  
  /* Called from build_vcall_offset_vtbl_entries_r.  */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1013
diff -c -3 -p -r1.1013 cp-tree.h
*** cp/cp-tree.h	18 Jul 2004 23:57:30 -0000	1.1013
--- cp/cp-tree.h	19 Jul 2004 17:24:34 -0000
*************** struct lang_type_header GTY(())
*** 937,944 ****
    BOOL_BITFIELD has_const_assign_ref : 1;
  };
  
- DEF_VEC_P (tree);
- 
  /* This structure provides additional information above and beyond
     what is provide in the ordinary tree_type.  In the past, we used it
     for the types of class types, template parameters types, typename
--- 937,942 ----
*************** struct lang_type GTY(())
*** 1397,1420 ****
  #define BINFO_PRIMARY_P(NODE) \
    (BINFO_PRIMARY_BASE_OF (NODE) != NULL_TREE)
  
- /* The index in the VTT where this subobject's sub-VTT can be found.
-    NULL_TREE if there is no sub-VTT.  */
- #define BINFO_SUBVTT_INDEX(NODE) BINFO_LANG_SLOT(NODE, 0)
- 
- /* The index in the VTT where the vptr for this subobject can be
-    found.  NULL_TREE if there is no secondary vptr in the VTT.  */
- #define BINFO_VPTR_INDEX(NODE) BINFO_LANG_SLOT(NODE, 1)
- 
- /* The binfo of which NODE is a primary base.  (This is different from
-    BINFO_INHERITANCE_CHAIN for virtual base because a virtual base is
-    sometimes a primary base for a class for which it is not an
-    immediate base.)  */
- #define BINFO_PRIMARY_BASE_OF(NODE) BINFO_LANG_SLOT(NODE, 2)
- 
- /* C++ binfos have 3 additional entries.  */
- 
- #define BINFO_LANG_SLOTS (3)
- 
  /* Nonzero if this binfo is for a dependent base - one that should not
     be searched.  */
  #define BINFO_DEPENDENT_BASE_P(NODE) BINFO_FLAG_3 (NODE)
--- 1395,1400 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1255
diff -c -3 -p -r1.1255 decl.c
*** cp/decl.c	18 Jul 2004 05:44:18 -0000	1.1255
--- cp/decl.c	19 Jul 2004 17:25:46 -0000
*************** void
*** 9031,9037 ****
  xref_basetypes (tree ref, tree base_list)
  {
    tree *basep;
!   tree binfo;
    unsigned max_vbases = 0; /* Maxium direct & indirect virtual bases. */
    unsigned max_bases = 0;  /* Maxium direct bases.  */
    int i;
--- 9031,9037 ----
  xref_basetypes (tree ref, tree base_list)
  {
    tree *basep;
!   tree binfo, base_binfo;
    unsigned max_vbases = 0; /* Maxium direct & indirect virtual bases. */
    unsigned max_bases = 0;  /* Maxium direct bases.  */
    int i;
*************** xref_basetypes (tree ref, tree base_list
*** 9078,9091 ****
    my_friendly_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref), 20040706);
    my_friendly_assert (TYPE_MAIN_VARIANT (ref) == ref, 20040712);
    
!   binfo = make_tree_binfo (BINFO_LANG_SLOTS);
    TYPE_BINFO (ref) = binfo;
    BINFO_OFFSET (binfo) = size_zero_node;
    BINFO_TYPE (binfo) = ref;
    
    if (max_bases)
      {
-       BINFO_BASE_BINFOS (binfo) = make_tree_vec (max_bases);
        BINFO_BASE_ACCESSES (binfo) = make_tree_vec (max_bases);
        /* An aggregate cannot have baseclasses.  */
        CLASSTYPE_NON_AGGREGATE (ref) = 1;
--- 9078,9090 ----
    my_friendly_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref), 20040706);
    my_friendly_assert (TYPE_MAIN_VARIANT (ref) == ref, 20040712);
    
!   binfo = make_tree_binfo (max_bases);
    TYPE_BINFO (ref) = binfo;
    BINFO_OFFSET (binfo) = size_zero_node;
    BINFO_TYPE (binfo) = ref;
    
    if (max_bases)
      {
        BINFO_BASE_ACCESSES (binfo) = make_tree_vec (max_bases);
        /* An aggregate cannot have baseclasses.  */
        CLASSTYPE_NON_AGGREGATE (ref) = 1;
*************** xref_basetypes (tree ref, tree base_list
*** 9117,9129 ****
  	error ("Java class '%T' cannot have virtual bases", ref);
      }
  
-   i = 0;
    for (igo_prev = binfo; base_list; base_list = TREE_CHAIN (base_list))
      {
        tree access = TREE_PURPOSE (base_list);
        int via_virtual = TREE_TYPE (base_list) != NULL_TREE;
        tree basetype = TREE_VALUE (base_list);
-       tree base_binfo = NULL_TREE;
        
        if (access == access_default_node)
  	access = default_access;
--- 9116,9126 ----
*************** xref_basetypes (tree ref, tree base_list
*** 9153,9158 ****
--- 9150,9156 ----
        if (TYPE_FOR_JAVA (basetype) && (current_lang_depth () == 0))
  	TYPE_FOR_JAVA (ref) = 1;
  
+       base_binfo = NULL_TREE;
        if (CLASS_TYPE_P (basetype) && !dependent_type_p (basetype))
  	{
  	  base_binfo = TYPE_BINFO (basetype);
*************** xref_basetypes (tree ref, tree base_list
*** 9177,9198 ****
        if (!BINFO_INHERITANCE_CHAIN (base_binfo))
  	BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
  
!       TREE_VEC_ELT (BINFO_BASE_ACCESSES (binfo), i) = access;
!       BINFO_BASE_BINFO (binfo, i) = base_binfo;
!       i++;
      }
  
    if (max_bases)
!     {
!       /* If any bases were invalid, we will have allocated too many
! 	 slots.  */
!       TREE_VEC_LENGTH (BINFO_BASE_ACCESSES (binfo)) = i;
!       TREE_VEC_LENGTH (BINFO_BASE_BINFOS (binfo)) = i;
!     }
    
    /* Unmark all the types.  */
!   for (i = 0; i != BINFO_N_BASE_BINFOS (binfo); i++)
!     CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (BINFO_BASE_BINFO (binfo, i)));
    CLEAR_CLASSTYPE_MARKED (ref);
  }
  
--- 9175,9194 ----
        if (!BINFO_INHERITANCE_CHAIN (base_binfo))
  	BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
  
!       TREE_VEC_ELT (BINFO_BASE_ACCESSES (binfo),
! 		    BINFO_N_BASE_BINFOS (binfo)) = access;
!       BINFO_BASE_APPEND (binfo, base_binfo);
      }
  
    if (max_bases)
!     /* If any bases were invalid, we will have allocated too many
!        slots.  */
!     TREE_VEC_LENGTH (BINFO_BASE_ACCESSES (binfo))
!       = BINFO_N_BASE_BINFOS (binfo);
    
    /* Unmark all the types.  */
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
!     CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (base_binfo));
    CLEAR_CLASSTYPE_MARKED (ref);
  }
  
Index: cp/dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/dump.c,v
retrieving revision 1.79
diff -c -3 -p -r1.79 dump.c
*** cp/dump.c	16 Jul 2004 08:22:11 -0000	1.79
--- cp/dump.c	19 Jul 2004 17:25:47 -0000
*************** cp_dump_tree (void* dump_info, tree t)
*** 267,276 ****
        if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t))
  	{
  	  int i;
  	  
! 	  for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (t)); ++i)
  	    {
- 	      tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (t), i);
  	      dump_child ("base", BINFO_TYPE (base_binfo));
  	      if (BINFO_VIRTUAL_P (base_binfo)) 
  		dump_string (di, "virtual");
--- 267,278 ----
        if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t))
  	{
  	  int i;
+ 	  tree binfo;
+ 	  tree base_binfo;
  	  
! 	  for (binfo = TYPE_BINFO (t), i = 0;
! 	       BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
  	    {
  	      dump_child ("base", BINFO_TYPE (base_binfo));
  	      if (BINFO_VIRTUAL_P (base_binfo)) 
  		dump_string (di, "virtual");
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.387
diff -c -3 -p -r1.387 init.c
*** cp/init.c	19 Jul 2004 15:45:49 -0000	1.387
--- cp/init.c	19 Jul 2004 17:25:59 -0000
*************** static tree
*** 457,463 ****
  sort_mem_initializers (tree t, tree mem_inits)
  {
    tree init;
!   tree base;
    tree sorted_inits;
    tree next_subobject;
    VEC (tree) *vbases;
--- 457,463 ----
  sort_mem_initializers (tree t, tree mem_inits)
  {
    tree init;
!   tree base, binfo, base_binfo;
    tree sorted_inits;
    tree next_subobject;
    VEC (tree) *vbases;
*************** sort_mem_initializers (tree t, tree mem_
*** 476,487 ****
      sorted_inits = tree_cons (base, NULL_TREE, sorted_inits);
    
    /* Process the direct bases.  */
!   for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (t)); ++i)
!     {
!       base = BINFO_BASE_BINFO (TYPE_BINFO (t), i);
!       if (!BINFO_VIRTUAL_P (base))
! 	sorted_inits = tree_cons (base, NULL_TREE, sorted_inits);
!     }
    /* Process the non-static data members.  */
    sorted_inits = build_field_list (t, sorted_inits, &uses_unions_p);
    /* Reverse the entire list of initializations, so that they are in
--- 476,486 ----
      sorted_inits = tree_cons (base, NULL_TREE, sorted_inits);
    
    /* Process the direct bases.  */
!   for (binfo = TYPE_BINFO (t), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
!     if (!BINFO_VIRTUAL_P (base_binfo))
!       sorted_inits = tree_cons (base_binfo, NULL_TREE, sorted_inits);
! 
    /* Process the non-static data members.  */
    sorted_inits = build_field_list (t, sorted_inits, &uses_unions_p);
    /* Reverse the entire list of initializations, so that they are in
*************** expand_member_init (tree name)
*** 983,996 ****
        virtual_binfo = NULL_TREE;
  
        /* Look for a direct base.  */
!       for (i = 0; i < BINFO_N_BASE_BINFOS (class_binfo); ++i)
! 	if (same_type_p
! 	    (basetype, BINFO_TYPE
! 	     (BINFO_BASE_BINFO (TYPE_BINFO (current_class_type), i))))
! 	  {
! 	    direct_binfo = BINFO_BASE_BINFO (class_binfo, i);
! 	    break;
! 	  }
        /* Look for a virtual base -- unless the direct base is itself
  	 virtual.  */
        if (!direct_binfo || !BINFO_VIRTUAL_P (direct_binfo))
--- 982,991 ----
        virtual_binfo = NULL_TREE;
  
        /* Look for a direct base.  */
!       for (i = 0; BINFO_BASE_ITERATE (class_binfo, i, direct_binfo); ++i)
! 	if (same_type_p (basetype, BINFO_TYPE (direct_binfo)))
! 	  break;
! 
        /* Look for a virtual base -- unless the direct base is itself
  	 virtual.  */
        if (!direct_binfo || !BINFO_VIRTUAL_P (direct_binfo))
*************** build_delete (tree type, tree addr, spec
*** 2858,2865 ****
  void
  push_base_cleanups (void)
  {
!   tree binfos, base_binfo;
!   int i, n_baseclasses;
    tree member;
    tree expr;
    VEC (tree) *vbases;
--- 2853,2860 ----
  void
  push_base_cleanups (void)
  {
!   tree binfo, base_binfo;
!   int i;
    tree member;
    tree expr;
    VEC (tree) *vbases;
*************** push_base_cleanups (void)
*** 2892,2904 ****
  	}
      }
  
-   binfos = BINFO_BASE_BINFOS (TYPE_BINFO (current_class_type));
-   n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (current_class_type));
- 
    /* Take care of the remaining baseclasses.  */
!   for (i = 0; i < n_baseclasses; i++)
      {
-       tree base_binfo = TREE_VEC_ELT (binfos, i);
        if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))
  	  || BINFO_VIRTUAL_P (base_binfo))
  	continue;
--- 2887,2896 ----
  	}
      }
  
    /* Take care of the remaining baseclasses.  */
!   for (binfo = TYPE_BINFO (current_class_type), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
      {
        if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))
  	  || BINFO_VIRTUAL_P (base_binfo))
  	continue;
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.299
diff -c -3 -p -r1.299 method.c
*** cp/method.c	19 Jul 2004 15:45:49 -0000	1.299
--- cp/method.c	19 Jul 2004 17:26:04 -0000
*************** do_build_copy_constructor (tree fndecl)
*** 515,526 ****
    else
      {
        tree fields = TYPE_FIELDS (current_class_type);
-       int n_bases = BINFO_N_BASE_BINFOS (TYPE_BINFO (current_class_type));
-       tree binfos = BINFO_BASE_BINFOS (TYPE_BINFO (current_class_type));
        tree member_init_list = NULL_TREE;
        int cvquals = cp_type_quals (TREE_TYPE (parm));
        int i;
!       tree binfo;
        VEC (tree) *vbases;
  
        /* Initialize all the base-classes with the parameter converted
--- 515,524 ----
    else
      {
        tree fields = TYPE_FIELDS (current_class_type);
        tree member_init_list = NULL_TREE;
        int cvquals = cp_type_quals (TREE_TYPE (parm));
        int i;
!       tree binfo, base_binfo;
        VEC (tree) *vbases;
  
        /* Initialize all the base-classes with the parameter converted
*************** do_build_copy_constructor (tree fndecl)
*** 539,555 ****
  			 member_init_list);
  	}
  
!       for (i = 0; i < n_bases; ++i)
  	{
! 	  tree binfo = TREE_VEC_ELT (binfos, i);
! 	  if (BINFO_VIRTUAL_P (binfo))
  	    continue; 
  
  	  member_init_list 
! 	    = tree_cons (binfo,
  			 build_tree_list (NULL_TREE,
  					  build_base_path (PLUS_EXPR, parm,
! 							   binfo, 1)),
  			 member_init_list);
  	}
  
--- 537,553 ----
  			 member_init_list);
  	}
  
!       for (binfo = TYPE_BINFO (current_class_type), i = 0;
! 	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
  	{
! 	  if (BINFO_VIRTUAL_P (base_binfo))
  	    continue; 
  
  	  member_init_list 
! 	    = tree_cons (base_binfo,
  			 build_tree_list (NULL_TREE,
  					  build_base_path (PLUS_EXPR, parm,
! 							   base_binfo, 1)),
  			 member_init_list);
  	}
  
*************** do_build_assign_ref (tree fndecl)
*** 617,642 ****
        tree fields;
        int cvquals = cp_type_quals (TREE_TYPE (parm));
        int i;
  
        /* Assign to each of the direct base classes.  */
!       for (i = 0;
! 	   i < BINFO_N_BASE_BINFOS (TYPE_BINFO (current_class_type));
! 	   ++i)
  	{
- 	  tree binfo;
  	  tree converted_parm;
  
- 	  binfo = BINFO_BASE_BINFO (TYPE_BINFO (current_class_type), i);
  	  /* We must convert PARM directly to the base class
  	     explicitly since the base class may be ambiguous.  */
! 	  converted_parm = build_base_path (PLUS_EXPR, parm, binfo, 1);
  	  /* Call the base class assignment operator.  */
  	  finish_expr_stmt 
  	    (build_special_member_call (current_class_ref, 
  					ansi_assopname (NOP_EXPR),
  					build_tree_list (NULL_TREE, 
  							 converted_parm),
! 					binfo,
  					LOOKUP_NORMAL | LOOKUP_NONVIRTUAL));
  	}
  
--- 615,638 ----
        tree fields;
        int cvquals = cp_type_quals (TREE_TYPE (parm));
        int i;
+       tree binfo, base_binfo;
  
        /* Assign to each of the direct base classes.  */
!       for (binfo = TYPE_BINFO (current_class_type), i = 0;
! 	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
  	{
  	  tree converted_parm;
  
  	  /* We must convert PARM directly to the base class
  	     explicitly since the base class may be ambiguous.  */
! 	  converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
  	  /* Call the base class assignment operator.  */
  	  finish_expr_stmt 
  	    (build_special_member_call (current_class_ref, 
  					ansi_assopname (NOP_EXPR),
  					build_tree_list (NULL_TREE, 
  							 converted_parm),
! 					base_binfo,
  					LOOKUP_NORMAL | LOOKUP_NONVIRTUAL));
  	}
  
*************** synthesize_exception_spec (tree type, tr
*** 783,795 ****
  {
    tree raises = empty_except_spec;
    tree fields = TYPE_FIELDS (type);
!   int i, n_bases = BINFO_N_BASE_BINFOS (TYPE_BINFO (type));
!   tree binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
  
!   for (i = 0; i != n_bases; i++)
      {
!       tree base = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
!       tree fn = (*extractor) (base, client);
        if (fn)
          {
            tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
--- 779,791 ----
  {
    tree raises = empty_except_spec;
    tree fields = TYPE_FIELDS (type);
!   tree binfo, base_binfo;
!   int i;
  
!   for (binfo = TYPE_BINFO (type), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
      {
!       tree fn = (*extractor) (BINFO_TYPE (base_binfo), client);
        if (fn)
          {
            tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
Index: cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.77
diff -c -3 -p -r1.77 name-lookup.c
*** cp/name-lookup.c	19 Jul 2004 15:45:50 -0000	1.77
--- cp/name-lookup.c	19 Jul 2004 17:26:25 -0000
*************** arg_assoc_class (struct arg_lookup *k, t
*** 4400,4410 ****
      return true;
  
    if (TYPE_BINFO (type))
!     /* Process baseclasses.  */
!     for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++)
!       if (arg_assoc_class
! 	  (k, BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (type), i))))
! 	return true;
    
    /* Process friends.  */
    for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; 
--- 4400,4414 ----
      return true;
  
    if (TYPE_BINFO (type))
!     {
!       /* Process baseclasses.  */
!       tree binfo, base_binfo;
!       
!       for (binfo = TYPE_BINFO (type), i = 0;
! 	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
! 	if (arg_assoc_class (k, BINFO_TYPE (base_binfo)))
! 	  return true;
!     }
    
    /* Process friends.  */
    for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; 
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.890
diff -c -3 -p -r1.890 pt.c
*** cp/pt.c	19 Jul 2004 15:45:50 -0000	1.890
--- cp/pt.c	19 Jul 2004 17:27:36 -0000
*************** instantiate_class_template (tree type)
*** 5416,5425 ****
  #endif
  
    base_list = NULL_TREE;
!   if (BINFO_BASE_BINFOS (pbinfo))
      {
!       tree pbases = BINFO_BASE_BINFOS (pbinfo);
!       tree paccesses = BINFO_BASE_ACCESSES (pbinfo);
        tree context = TYPE_CONTEXT (type);
        bool pop_p;
        int i;
--- 5416,5424 ----
  #endif
  
    base_list = NULL_TREE;
!   if (BINFO_N_BASE_BINFOS (pbinfo))
      {
!       tree pbase_binfo;
        tree context = TYPE_CONTEXT (type);
        bool pop_p;
        int i;
*************** instantiate_class_template (tree type)
*** 5431,5452 ****
    
        /* Substitute into each of the bases to determine the actual
  	 basetypes.  */
!       for (i = 0; i < TREE_VEC_LENGTH (pbases); ++i)
  	{
  	  tree base;
! 	  tree access;
! 	  tree pbase;
! 
! 	  pbase = TREE_VEC_ELT (pbases, i);
! 	  access = TREE_VEC_ELT (paccesses, i);
  
  	  /* Substitute to figure out the base class.  */
! 	  base = tsubst (BINFO_TYPE (pbase), args, tf_error, NULL_TREE);
  	  if (base == error_mark_node)
  	    continue;
  	  
  	  base_list = tree_cons (access, base, base_list);
! 	  if (BINFO_VIRTUAL_P (pbase))
  	    TREE_TYPE (base_list) = integer_type_node;
  	}
  
--- 5430,5447 ----
    
        /* Substitute into each of the bases to determine the actual
  	 basetypes.  */
!       for (i = 0; BINFO_BASE_ITERATE (pbinfo, i, pbase_binfo); i++)
  	{
  	  tree base;
! 	  tree access = BINFO_BASE_ACCESS (pbinfo, i);
  
  	  /* Substitute to figure out the base class.  */
! 	  base = tsubst (BINFO_TYPE (pbase_binfo), args, tf_error, NULL_TREE);
  	  if (base == error_mark_node)
  	    continue;
  	  
  	  base_list = tree_cons (access, base, base_list);
! 	  if (BINFO_VIRTUAL_P (pbase_binfo))
  	    TREE_TYPE (base_list) = integer_type_node;
  	}
  
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 7421,7426 ****
--- 7416,7422 ----
  	  if (ctx != DECL_CONTEXT (t))
  	    return lookup_field (ctx, DECL_NAME (t), 0, false);
  	}
+       
        return t;
  
      case VAR_DECL:
*************** get_template_base_recursive (tree tparms
*** 9366,9373 ****
                               tree rval, 
                               int flags)
  {
!   tree binfos;
!   int i, n_baselinks;
    tree arg = BINFO_TYPE (arg_binfo);
  
    if (!(flags & GTB_IGNORE_TYPE))
--- 9362,9369 ----
                               tree rval, 
                               int flags)
  {
!   tree base_binfo;
!   int i;
    tree arg = BINFO_TYPE (arg_binfo);
  
    if (!(flags & GTB_IGNORE_TYPE))
*************** get_template_base_recursive (tree tparms
*** 9389,9401 ****
  	rval = r;
      }
  
-   binfos = BINFO_BASE_BINFOS (arg_binfo);
-   n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
- 
    /* Process base types.  */
!   for (i = 0; i < n_baselinks; i++)
      {
-       tree base_binfo = TREE_VEC_ELT (binfos, i);
        int this_virtual;
  
        /* Skip this base, if we've already seen it.  */
--- 9385,9393 ----
  	rval = r;
      }
  
    /* Process base types.  */
!   for (i = 0; BINFO_BASE_ITERATE (arg_binfo, i, base_binfo); i++)
      {
        int this_virtual;
  
        /* Skip this base, if we've already seen it.  */
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.189
diff -c -3 -p -r1.189 rtti.c
*** cp/rtti.c	16 Jul 2004 01:15:42 -0000	1.189
--- cp/rtti.c	19 Jul 2004 17:27:45 -0000
*************** get_pseudo_ti_init (tree type, tree var_
*** 1032,1039 ****
          }
        else if (var_desc == si_class_desc_type_node)
  	{
!           tree base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
! 	  tree base_binfo = TREE_VEC_ELT (base_binfos, 0);
  	  tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
  	  tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
  	  
--- 1032,1038 ----
          }
        else if (var_desc == si_class_desc_type_node)
  	{
!           tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), 0);
  	  tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
  	  tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
  	  
*************** get_pseudo_ti_init (tree type, tree var_
*** 1044,1050 ****
  	  int hint = class_hint_flags (type);
  	  tree binfo = TYPE_BINFO (type);
            int nbases = BINFO_N_BASE_BINFOS (binfo);
-           tree base_binfos = BINFO_BASE_BINFOS (binfo);
  	  tree base_accesses = BINFO_BASE_ACCESSES (binfo);
            tree base_inits = NULL_TREE;
            int ix;
--- 1043,1048 ----
*************** get_pseudo_ti_init (tree type, tree var_
*** 1052,1058 ****
            /* Generate the base information initializer.  */
            for (ix = nbases; ix--;)
              {
!               tree base_binfo = TREE_VEC_ELT (base_binfos, ix);
                tree base_init = NULL_TREE;
                int flags = 0;
                tree tinfo;
--- 1050,1056 ----
            /* Generate the base information initializer.  */
            for (ix = nbases; ix--;)
              {
!               tree base_binfo = BINFO_BASE_BINFO (binfo, ix);
                tree base_init = NULL_TREE;
                int flags = 0;
                tree tinfo;
*************** get_pseudo_ti_desc (tree type)
*** 1192,1201 ****
        else
  	{
  	  tree binfo = TYPE_BINFO (type);
- 	  tree base_binfos = BINFO_BASE_BINFOS (binfo);
  	  tree base_accesses = BINFO_BASE_ACCESSES (binfo);
! 	  tree base_binfo = TREE_VEC_ELT (base_binfos, 0);
! 	  int num_bases = TREE_VEC_LENGTH (base_binfos);
  	  
  	  if (num_bases == 1
  	      && TREE_VEC_ELT (base_accesses, 0) == access_public_node
--- 1190,1198 ----
        else
  	{
  	  tree binfo = TYPE_BINFO (type);
  	  tree base_accesses = BINFO_BASE_ACCESSES (binfo);
! 	  tree base_binfo = BINFO_BASE_BINFO (binfo, 0);
! 	  int num_bases = BINFO_N_BASE_BINFOS (binfo);
  	  
  	  if (num_bases == 1
  	      && TREE_VEC_ELT (base_accesses, 0) == access_public_node
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.303
diff -c -3 -p -r1.303 search.c
*** cp/search.c	19 Jul 2004 15:45:53 -0000	1.303
--- cp/search.c	19 Jul 2004 17:27:58 -0000
*************** lookup_base_r (tree binfo, tree base, ba
*** 97,103 ****
  	       tree *binfo_ptr)
  {
    int i;
!   tree bases, accesses;
    base_kind found = bk_not_base;
    
    if (same_type_p (BINFO_TYPE (binfo), base))
--- 97,103 ----
  	       tree *binfo_ptr)
  {
    int i;
!   tree base_binfo;
    base_kind found = bk_not_base;
    
    if (same_type_p (BINFO_TYPE (binfo), base))
*************** lookup_base_r (tree binfo, tree base, ba
*** 123,136 ****
        return found;
      }
    
!   bases = BINFO_BASE_BINFOS (binfo);
!   accesses = BINFO_BASE_ACCESSES (binfo);
!   if (!bases)
!     return bk_not_base;
!   
!   for (i = TREE_VEC_LENGTH (bases); i--;)
      {
-       tree base_binfo = TREE_VEC_ELT (bases, i);
        base_kind bk;
  
        bk = lookup_base_r (base_binfo, base,
--- 123,130 ----
        return found;
      }
    
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
      {
        base_kind bk;
  
        bk = lookup_base_r (base_binfo, base,
*************** static int
*** 290,297 ****
  dynamic_cast_base_recurse (tree subtype, tree binfo, bool is_via_virtual,
  			   tree *offset_ptr)
  {
!   tree binfos, accesses;
!   int i, n_baselinks;
    int worst = -2;
    
    if (BINFO_TYPE (binfo) == subtype)
--- 284,292 ----
  dynamic_cast_base_recurse (tree subtype, tree binfo, bool is_via_virtual,
  			   tree *offset_ptr)
  {
!   tree accesses;
!   tree base_binfo;
!   int i;
    int worst = -2;
    
    if (BINFO_TYPE (binfo) == subtype)
*************** dynamic_cast_base_recurse (tree subtype,
*** 305,316 ****
          }
      }
    
-   binfos = BINFO_BASE_BINFOS (binfo);
    accesses = BINFO_BASE_ACCESSES (binfo);
!   n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
!   for (i = 0; i < n_baselinks; i++)
      {
-       tree base_binfo = TREE_VEC_ELT (binfos, i);
        tree base_access = TREE_VEC_ELT (accesses, i);
        int rval;
        
--- 300,308 ----
          }
      }
    
    accesses = BINFO_BASE_ACCESSES (binfo);
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
      {
        tree base_access = TREE_VEC_ELT (accesses, i);
        int rval;
        
*************** dfs_access_in_type (tree binfo, void *da
*** 630,646 ****
        if (!access)
  	{
  	  int i;
! 	  int n_baselinks;
! 	  tree binfos, accesses;
  	  
  	  /* Otherwise, scan our baseclasses, and pick the most favorable
  	     access.  */
- 	  binfos = BINFO_BASE_BINFOS (binfo);
  	  accesses = BINFO_BASE_ACCESSES (binfo);
! 	  n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
! 	  for (i = 0; i < n_baselinks; ++i)
  	    {
- 	      tree base_binfo = TREE_VEC_ELT (binfos, i);
  	      tree base_access = TREE_VEC_ELT (accesses, i);
  	      access_kind base_access_now = BINFO_ACCESS (base_binfo);
  
--- 622,634 ----
        if (!access)
  	{
  	  int i;
! 	  tree base_binfo, accesses;
  	  
  	  /* Otherwise, scan our baseclasses, and pick the most favorable
  	     access.  */
  	  accesses = BINFO_BASE_ACCESSES (binfo);
! 	  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
  	    {
  	      tree base_access = TREE_VEC_ELT (accesses, i);
  	      access_kind base_access_now = BINFO_ACCESS (base_binfo);
  
*************** dfs_walk_real (tree binfo,
*** 1601,1606 ****
--- 1589,1596 ----
  	       tree (*qfn) (tree, int, void *),
  	       void *data)
  {
+   int i;
+   tree base_binfo;
    tree rval = NULL_TREE;
  
    /* Call the pre-order walking function.  */
*************** dfs_walk_real (tree binfo,
*** 1612,1636 ****
      }
  
    /* Process the basetypes.  */
!   if (BINFO_BASE_BINFOS (binfo))
      {
!       int i, n = TREE_VEC_LENGTH (BINFO_BASE_BINFOS (binfo));
!       for (i = 0; i != n; i++)
  	{
! 	  tree base_binfo;
!       
! 	  if (qfn)
! 	    base_binfo = (*qfn) (binfo, i, data);
! 	  else
! 	    base_binfo = BINFO_BASE_BINFO (binfo, i);
! 	  
! 	  if (base_binfo)
! 	    {
! 	      rval = dfs_walk_real (base_binfo, prefn, postfn, qfn, data);
! 	      if (rval)
! 		return rval;
! 	    }
  	}
      }
  
    /* Call the post-order walking function.  */
--- 1602,1618 ----
      }
  
    /* Process the basetypes.  */
!   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
      {
!       if (qfn)
  	{
! 	  base_binfo = (*qfn) (binfo, i, data);
! 	  if (!base_binfo)
! 	    continue;
  	}
+       rval = dfs_walk_real (base_binfo, prefn, postfn, qfn, data);
+       if (rval)
+ 	return rval;
      }
  
    /* Call the post-order walking function.  */
*************** int
*** 1761,1774 ****
  look_for_overrides (tree type, tree fndecl)
  {
    tree binfo = TYPE_BINFO (type);
!   tree basebinfos = BINFO_BASE_BINFOS (binfo);
!   int nbasebinfos = basebinfos ? TREE_VEC_LENGTH (basebinfos) : 0;
    int ix;
    int found = 0;
  
!   for (ix = 0; ix != nbasebinfos; ix++)
      {
!       tree basetype = BINFO_TYPE (TREE_VEC_ELT (basebinfos, ix));
        
        if (TYPE_POLYMORPHIC_P (basetype))
          found += look_for_overrides_r (basetype, fndecl);
--- 1743,1755 ----
  look_for_overrides (tree type, tree fndecl)
  {
    tree binfo = TYPE_BINFO (type);
!   tree base_binfo;
    int ix;
    int found = 0;
  
!   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
      {
!       tree basetype = BINFO_TYPE (base_binfo);
        
        if (TYPE_POLYMORPHIC_P (basetype))
          found += look_for_overrides_r (basetype, fndecl);
*************** dfs_check_overlap (tree empty_binfo, voi
*** 2161,2167 ****
  	  oi->found_overlap = 1;
  	  break;
  	}
!       else if (BINFO_BASE_BINFOS (binfo) == NULL_TREE)
  	break;
      }
  
--- 2142,2148 ----
  	  oi->found_overlap = 1;
  	  break;
  	}
!       else if (!BINFO_N_BASE_BINFOS (binfo))
  	break;
      }
  
*************** types_overlap_p (tree empty_type, tree n
*** 2196,2229 ****
    return oi.found_overlap;
  }
  
- /* Given a vtable VAR, determine which of the inherited classes the vtable
-    inherits (in a loose sense) functions from.
- 
-    FIXME: This does not work with the new ABI.  */
- 
- tree
- binfo_for_vtable (tree var)
- {
-   tree main_binfo = TYPE_BINFO (DECL_CONTEXT (var));
-   tree binfos = BINFO_BASE_BINFOS (TYPE_BINFO (BINFO_TYPE (main_binfo)));
-   int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (BINFO_TYPE (main_binfo)));
-   int i;
- 
-   for (i = 0; i < n_baseclasses; i++)
-     {
-       tree base_binfo = TREE_VEC_ELT (binfos, i);
-       if (base_binfo != NULL_TREE && BINFO_VTABLE (base_binfo) == var)
- 	return base_binfo;
-     }
- 
-   /* If no secondary base classes matched, return the primary base, if
-      there is one.  */
-   if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (main_binfo)))
-     return get_primary_binfo (main_binfo);
- 
-   return main_binfo;
- }
- 
  /* Returns the binfo of the first direct or indirect virtual base derived
     from BINFO, or NULL if binfo is not via virtual.  */
  
--- 2177,2182 ----
*************** copied_binfo (tree binfo, tree here)
*** 2275,2296 ****
      }
    else if (BINFO_INHERITANCE_CHAIN (binfo))
      {
!       tree base_binfos;
!       int ix, n;
        
!       base_binfos = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
!       base_binfos = BINFO_BASE_BINFOS (base_binfos);
!       n = TREE_VEC_LENGTH (base_binfos);
!       for (ix = 0; ix != n; ix++)
! 	{
! 	  tree base = TREE_VEC_ELT (base_binfos, ix);
! 	  
! 	  if (BINFO_TYPE (base) == BINFO_TYPE (binfo))
! 	    {
! 	      result = base;
! 	      break;
! 	    }
! 	}
      }
    else
      {
--- 2228,2244 ----
      }
    else if (BINFO_INHERITANCE_CHAIN (binfo))
      {
!       tree cbinfo;
!       tree base_binfo;
!       int ix;
        
!       cbinfo = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
!       for (ix = 0; BINFO_BASE_ITERATE (cbinfo, ix, base_binfo); ix++)
! 	if (BINFO_TYPE (base_binfo) == BINFO_TYPE (binfo))
! 	  {
! 	    result = base_binfo;
! 	    break;
! 	  }
      }
    else
      {
*************** original_binfo (tree binfo, tree here)
*** 2339,2358 ****
        base_binfos = original_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
        if (base_binfos)
  	{
! 	  int ix, n;
  	  
! 	  base_binfos = BINFO_BASE_BINFOS (base_binfos);
! 	  n = TREE_VEC_LENGTH (base_binfos);
! 	  for (ix = 0; ix != n; ix++)
! 	    {
! 	      tree base = TREE_VEC_ELT (base_binfos, ix);
! 	      
! 	      if (BINFO_TYPE (base) == BINFO_TYPE (binfo))
! 		{
! 		  result = base;
! 		  break;
! 		}
! 	    }
  	}
      }
    
--- 2287,2301 ----
        base_binfos = original_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
        if (base_binfos)
  	{
! 	  int ix;
! 	  tree base_binfo;
  	  
! 	  for (ix = 0; (base_binfo = BINFO_BASE_BINFO (base_binfos, ix)); ix++)
! 	    if (BINFO_TYPE (base_binfo) == BINFO_TYPE (binfo))
! 	      {
! 		result = base_binfo;
! 		break;
! 	      }
  	}
      }
    
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.394
diff -c -3 -p -r1.394 tree.c
*** cp/tree.c	19 Jul 2004 04:02:45 -0000	1.394
--- cp/tree.c	19 Jul 2004 17:28:08 -0000
*************** copy_binfo (tree binfo, tree type, tree 
*** 597,603 ****
  	return new_binfo;
      }
    
!   new_binfo = make_tree_binfo (BINFO_LANG_SLOTS);
    BINFO_TYPE (new_binfo) = type;
  
    /* Chain it into the inheritance graph.  */
--- 597,603 ----
  	return new_binfo;
      }
    
!   new_binfo = make_tree_binfo (binfo ? BINFO_N_BASE_BINFOS (binfo) : 0);
    BINFO_TYPE (new_binfo) = type;
  
    /* Chain it into the inheritance graph.  */
*************** copy_binfo (tree binfo, tree type, tree 
*** 606,612 ****
    
    if (binfo)
      {
!       int ix, n = BINFO_N_BASE_BINFOS (binfo);
        
        my_friendly_assert (!BINFO_DEPENDENT_BASE_P (binfo), 20040712);
        my_friendly_assert (type == BINFO_TYPE (binfo), 20040714);
--- 606,613 ----
    
    if (binfo)
      {
!       int ix;
!       tree base_binfo;
        
        my_friendly_assert (!BINFO_DEPENDENT_BASE_P (binfo), 20040712);
        my_friendly_assert (type == BINFO_TYPE (binfo), 20040714);
*************** copy_binfo (tree binfo, tree type, tree 
*** 614,631 ****
        BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
        BINFO_VIRTUALS (new_binfo) = BINFO_VIRTUALS (binfo);
        
!       /* Create a new base binfo vector.  */
!       if (n)
! 	{
! 	  BINFO_BASE_BINFOS (new_binfo) = make_tree_vec (n);
!           /* We do not need to copy the accesses, as they are read only.  */
! 	  BINFO_BASE_ACCESSES (new_binfo) = BINFO_BASE_ACCESSES (binfo);
! 	}
        
        /* Recursively copy base binfos of BINFO.  */
!       for (ix = 0; ix != n; ix++)
  	{
- 	  tree base_binfo = BINFO_BASE_BINFO (binfo, ix);
  	  tree new_base_binfo;
  	  
  	  my_friendly_assert (!BINFO_DEPENDENT_BASE_P (base_binfo), 20040713);
--- 615,626 ----
        BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
        BINFO_VIRTUALS (new_binfo) = BINFO_VIRTUALS (binfo);
        
!       /* We do not need to copy the accesses, as they are read only.  */
!       BINFO_BASE_ACCESSES (new_binfo) = BINFO_BASE_ACCESSES (binfo);
        
        /* Recursively copy base binfos of BINFO.  */
!       for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
  	{
  	  tree new_base_binfo;
  	  
  	  my_friendly_assert (!BINFO_DEPENDENT_BASE_P (base_binfo), 20040713);
*************** copy_binfo (tree binfo, tree type, tree 
*** 635,641 ****
  	  
  	  if (!BINFO_INHERITANCE_CHAIN (new_base_binfo))
  	    BINFO_INHERITANCE_CHAIN (new_base_binfo) = new_binfo;
! 	  BINFO_BASE_BINFO (new_binfo, ix) = new_base_binfo;
  	}
      }
    else
--- 630,636 ----
  	  
  	  if (!BINFO_INHERITANCE_CHAIN (new_base_binfo))
  	    BINFO_INHERITANCE_CHAIN (new_base_binfo) = new_binfo;
! 	  BINFO_BASE_APPEND (new_binfo, new_base_binfo);
  	}
      }
    else
Index: cp/typeck2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck2.c,v
retrieving revision 1.165
diff -c -3 -p -r1.165 typeck2.c
*** cp/typeck2.c	12 Jul 2004 16:06:40 -0000	1.165
--- cp/typeck2.c	19 Jul 2004 17:28:13 -0000
*************** process_init_constructor (tree type, tre
*** 954,960 ****
  	      return error_mark_node;
  	    }
  
! 	  if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type)))
  	    {
  	      sorry ("initializer list for object of class with base classes");
  	      return error_mark_node;
--- 954,960 ----
  	      return error_mark_node;
  	    }
  
! 	  if (TYPE_BINFO (type) && BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
  	    {
  	      sorry ("initializer list for object of class with base classes");
  	      return error_mark_node;
Index: doc/c-tree.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/c-tree.texi,v
retrieving revision 1.60
diff -c -3 -p -r1.60 c-tree.texi
*** doc/c-tree.texi	6 Jul 2004 08:51:32 -0000	1.60
--- doc/c-tree.texi	19 Jul 2004 17:28:28 -0000
*************** list.  Implicitly declared functions (in
*** 747,778 ****
  copy constructors, assignment operators, and destructors) will appear on
  this list as well.
  
- @c under reconstruction 2004-07-01, FIXME:Nathan Sidwell
- [Binfos are being redesigned, this information is in a state of flux.]
  Every class has an associated @dfn{binfo}, which can be obtained with
  @code{TYPE_BINFO}.  Binfos are used to represent base-classes.  The
  binfo given by @code{TYPE_BINFO} is the degenerate case, whereby every
! class is considered to be its own base-class.  The base classes for a
! particular binfo can be obtained with @code{BINFO_BASETYPES}.  These
! base-classes are themselves binfos.  The class type associated with a
! binfo is given by @code{BINFO_TYPE}.  It is always the case that
! @code{BINFO_TYPE (TYPE_BINFO (x))} is the same type as @code{x}, up to
! qualifiers.  However, it is not always the case that @code{TYPE_BINFO
! (BINFO_TYPE (y))} is always the same binfo as @code{y}.  The reason is
! that if @code{y} is a binfo representing a base-class @code{B} of a
! derived class @code{D}, then @code{BINFO_TYPE (y)} will be @code{B},
! and @code{TYPE_BINFO (BINFO_TYPE (y))} will be @code{B} as its own
! base-class, rather than as a base-class of @code{D}.
! 
! The @code{BINFO_BASETYPES} is a @code{TREE_VEC} (@pxref{Containers}).
! Base types appear in left-to-right order in this vector.  You can tell
! whether or @code{public}, @code{protected}, or @code{private}
! inheritance was used by using the @code{TREE_VIA_PUBLIC},
! @code{TREE_VIA_PROTECTED}, and @code{TREE_VIA_PRIVATE} macros.  Each of
! these macros takes a @code{BINFO} and is true if and only if the
! indicated kind of inheritance was used.  If @code{TREE_VIA_VIRTUAL}
! holds of a binfo, then its @code{BINFO_TYPE} was inherited from
! virtually.
  
  The following macros can be used on a tree node representing a class-type.
  
--- 747,779 ----
  copy constructors, assignment operators, and destructors) will appear on
  this list as well.
  
  Every class has an associated @dfn{binfo}, which can be obtained with
  @code{TYPE_BINFO}.  Binfos are used to represent base-classes.  The
  binfo given by @code{TYPE_BINFO} is the degenerate case, whereby every
! class is considered to be its own base-class.  The base binfos for a
! particular binfo are held in a vector, whose length is obtained with
! @code{BINFO_N_BASE_BINFOS}.  The base binfos themselves are obtained
! with @code{BINFO_BASE_BINFO} and @code{BINFO_BASE_ITERATE}.  To add a
! new binfo, use @code{BINFO_BASE_APPEND}.  The vector of base binfos can
! be obtained with @code{BINFO_BASE_BINFOS}, but normally you do not need
! to use that.  The class type associated with a binfo is given by
! @code{BINFO_TYPE}.  It is not always the case that @code{BINFO_TYPE
! (TYPE_BINFO (x))}, because of typedefs and qualified types.  Neither is
! it the case that @code{TYPE_BINFO (BINFO_TYPE (y))} is the same binfo as
! @code{y}.  The reason is that if @code{y} is a binfo representing a
! base-class @code{B} of a derived class @code{D}, then @code{BINFO_TYPE
! (y)} will be @code{B}, and @code{TYPE_BINFO (BINFO_TYPE (y))} will be
! @code{B} as its own base-class, rather than as a base-class of @code{D}.
! 
! The access to a base type can be found with @code{BINFO_BASE_ACCESS}.
! This will produce @code{access_public_node}, @code{access_private_node}
! or @code{access_protected_node}.  If bases are always public,
! @code{BINFO_BASE_ACCESSES} may be @code{NULL}.
! 
! @code{BINFO_VIRTUAL_P} is used to specify whether the binfo is inherited
! virtually or not.  The other flags, @code{BINFO_MARKED_P} and
! @code{BINFO_FLAG_1} to @code{BINFO_FLAG_6} can be used for language
! specific use.
  
  The following macros can be used on a tree node representing a class-type.
  
Index: java/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.199
diff -c -3 -p -r1.199 class.c
*** java/class.c	18 Jul 2004 13:17:02 -0000	1.199
--- java/class.c	19 Jul 2004 17:30:08 -0000
*************** static tree make_field_value (tree);
*** 57,63 ****
  static tree get_dispatch_vector (tree);
  static tree get_dispatch_table (tree, tree);
  static int supers_all_compiled (tree type);
- static void add_interface_do (tree, tree, int);
  static tree maybe_layout_super_class (tree, tree);
  static void add_miranda_methods (tree, tree);
  static int assume_compiled (const char *);
--- 57,62 ----
*************** set_super_info (int access_flags, tree t
*** 476,491 ****
    if (super_class)
      total_supers++;
  
!   TYPE_BINFO (this_class) = make_tree_binfo (0);
    TYPE_VFIELD (this_class) = TYPE_VFIELD (object_type_node);
-   BINFO_BASE_BINFOS (TYPE_BINFO (this_class)) = make_tree_vec (total_supers);
    if (super_class)
      {
        tree super_binfo = make_tree_binfo (0);
        BINFO_TYPE (super_binfo) = super_class;
        BINFO_OFFSET (super_binfo) = integer_zero_node;
!       TREE_VEC_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (this_class)), 0)
! 	= super_binfo;
        CLASS_HAS_SUPER_FLAG (TYPE_BINFO (this_class)) = 1;
      }
  
--- 475,488 ----
    if (super_class)
      total_supers++;
  
!   TYPE_BINFO (this_class) = make_tree_binfo (total_supers);
    TYPE_VFIELD (this_class) = TYPE_VFIELD (object_type_node);
    if (super_class)
      {
        tree super_binfo = make_tree_binfo (0);
        BINFO_TYPE (super_binfo) = super_class;
        BINFO_OFFSET (super_binfo) = integer_zero_node;
!       BINFO_BASE_APPEND (TYPE_BINFO (this_class), super_binfo);
        CLASS_HAS_SUPER_FLAG (TYPE_BINFO (this_class)) = 1;
      }
  
*************** class_depth (tree clas)
*** 530,555 ****
  int
  interface_of_p (tree type1, tree type2)
  {
!   int n, i;
!   tree basetype_vec;
  
    if (! TYPE_BINFO (type2))
      return 0;
!   basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (type2));
!   n = TREE_VEC_LENGTH (basetype_vec);
!   for (i = 0; i < n; i++)
!     {
!       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
!       if (vec_elt && BINFO_TYPE (vec_elt) == type1)
! 	return 1;
!     }
!   for (i = 0; i < n; i++)
!     {
!       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
!       if (vec_elt && BINFO_TYPE (vec_elt) 
! 	  && interface_of_p (type1, BINFO_TYPE (vec_elt)))
! 	return 1;
!     }
    return 0;
  }
  
--- 527,549 ----
  int
  interface_of_p (tree type1, tree type2)
  {
!   int i;
!   tree binfo, base_binfo;
  
    if (! TYPE_BINFO (type2))
      return 0;
! 
!   for (binfo = TYPE_BINFO (type2), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
!     if (BINFO_TYPE (base_binfo) == type1)
!       return 1;
!   
!   for (binfo = TYPE_BINFO (type2), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) /*  */
!     if (BINFO_TYPE (base_binfo)
! 	&& interface_of_p (type1, BINFO_TYPE (base_binfo)))
!       return 1;
!   
    return 0;
  }
  
*************** common_enclosing_instance_p (tree type1,
*** 636,652 ****
    return 0;
  }
  
- static void
- add_interface_do (tree basetype_vec, tree interface_class, int i)
- {
-   tree interface_binfo = make_tree_binfo (0);
-   BINFO_TYPE (interface_binfo) = interface_class;
-   BINFO_OFFSET (interface_binfo) = integer_zero_node;
-   BINFO_VPTR_FIELD (interface_binfo) = integer_zero_node;
-   BINFO_VIRTUAL_P (interface_binfo) = 1;
-   TREE_VEC_ELT (basetype_vec, i) = interface_binfo;
- }
- 
  /* Add INTERFACE_CLASS to THIS_CLASS iff INTERFACE_CLASS can't be
     found in THIS_CLASS. Returns NULL_TREE upon success, INTERFACE_CLASS
     if attempt is made to add it twice. */
--- 630,635 ----
*************** add_interface_do (tree basetype_vec, tre
*** 654,675 ****
  tree
  maybe_add_interface (tree this_class, tree interface_class)
  {
!   tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (this_class));
    int i;
!   int n = TREE_VEC_LENGTH (basetype_vec);
!   for (i = 0; ; i++)
!     {
!       if (i >= n)
! 	{
! 	  error ("internal error - too many interface type");
! 	  return NULL_TREE;
! 	}
!       else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
! 	break;
!       else if (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)) == interface_class)
! 	return interface_class;
!     } 
!   add_interface_do (basetype_vec, interface_class, i);
    return NULL_TREE;
  }
  
--- 637,650 ----
  tree
  maybe_add_interface (tree this_class, tree interface_class)
  {
!   tree binfo, base_binfo;
    int i;
! 
!   for (binfo = TYPE_BINFO (this_class), i = 0;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
!     if (BINFO_TYPE (base_binfo) == interface_class)
!       return interface_class;
!   add_interface (this_class, interface_class);
    return NULL_TREE;
  }
  
*************** maybe_add_interface (tree this_class, tr
*** 678,697 ****
  void
  add_interface (tree this_class, tree interface_class)
  {
!   tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (this_class));
!   int i;
!   int n = TREE_VEC_LENGTH (basetype_vec);
!   for (i = 0; ; i++)
!     {
!       if (i >= n)
! 	{
! 	  error ("internal error - too many interface type");
! 	  return;
! 	}
!       else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
! 	break;
!     }
!   add_interface_do (basetype_vec, interface_class, i);
  }
  
  #if 0
--- 653,666 ----
  void
  add_interface (tree this_class, tree interface_class)
  {
!   tree interface_binfo = make_tree_binfo (0);
!   
!   BINFO_TYPE (interface_binfo) = interface_class;
!   BINFO_OFFSET (interface_binfo) = integer_zero_node;
!   BINFO_VPTR_FIELD (interface_binfo) = integer_zero_node;
!   BINFO_VIRTUAL_P (interface_binfo) = 1;
!   
!   BINFO_BASE_APPEND (TYPE_BINFO (this_class), interface_binfo);
  }
  
  #if 0
*************** make_class_data (tree type)
*** 1666,1674 ****
  	= build_prim_array_type (class_ptr_type, interface_len);
        idecl = build_decl (VAR_DECL, mangled_classname ("_IF_", type),
  			  interface_array_type);
        for (i = interface_len;  i > 0; i--)
  	{
! 	  tree child = TREE_VEC_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i);
  	  tree iclass = BINFO_TYPE (child);
  	  tree index;
  	  if (! flag_indirect_dispatch
--- 1635,1644 ----
  	= build_prim_array_type (class_ptr_type, interface_len);
        idecl = build_decl (VAR_DECL, mangled_classname ("_IF_", type),
  			  interface_array_type);
+       
        for (i = interface_len;  i > 0; i--)
  	{
! 	  tree child = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
  	  tree iclass = BINFO_TYPE (child);
  	  tree index;
  	  if (! flag_indirect_dispatch
*************** layout_class (tree this_class)
*** 2063,2089 ****
       of this itself.  */
    if (!CLASS_FROM_SOURCE_P (this_class))
      {
!       tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (this_class));
! 
!       if (basetype_vec)
  	{
! 	  int n = TREE_VEC_LENGTH (basetype_vec) - 1;
! 	  int i;
! 	  for (i = n; i > 0; i--)
  	    {
! 	      tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
! 	      tree super_interface = BINFO_TYPE (vec_elt);
! 
! 	      tree maybe_super_interface 
! 		= maybe_layout_super_class (super_interface, NULL_TREE);
! 	      if (maybe_super_interface == NULL
! 		  || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK)
! 		{
! 		  TYPE_SIZE (this_class) = error_mark_node;
! 		  CLASS_BEING_LAIDOUT (this_class) = 0;
! 		  class_list = TREE_CHAIN (class_list);
! 		  return;
! 		}
  	    }
  	}
      }
--- 2033,2053 ----
       of this itself.  */
    if (!CLASS_FROM_SOURCE_P (this_class))
      {
!       int i;
!       
!       for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--)
  	{
! 	  tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (this_class), i);
! 	  tree super_interface = BINFO_TYPE (binfo);
! 	  tree maybe_super_interface 
! 	    = maybe_layout_super_class (super_interface, NULL_TREE);
! 	  if (maybe_super_interface == NULL
! 	      || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK)
  	    {
! 	      TYPE_SIZE (this_class) = error_mark_node;
! 	      CLASS_BEING_LAIDOUT (this_class) = 0;
! 	      class_list = TREE_CHAIN (class_list);
! 	      return;
  	    }
  	}
      }
*************** layout_class (tree this_class)
*** 2099,2113 ****
  static void
  add_miranda_methods (tree base_class, tree search_class)
  {
!   tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (search_class));
!   int i, n = TREE_VEC_LENGTH (basetype_vec);
!   for (i = 1; i < n; ++i)
      {
        tree method_decl;
!       tree elt = TREE_VEC_ELT (basetype_vec, i);
!       if (elt == NULL_TREE)
! 	break;
!       elt = BINFO_TYPE (elt);
  
        /* Ensure that interface methods are seen in declared order.  */
        layout_class_methods (elt);
--- 2063,2076 ----
  static void
  add_miranda_methods (tree base_class, tree search_class)
  {
!   tree binfo, base_binfo;
!   int i;
!   
!   for (binfo = TYPE_BINFO (search_class), i = 1;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
      {
        tree method_decl;
!       tree elt = BINFO_TYPE (base_binfo);
  
        /* Ensure that interface methods are seen in declared order.  */
        layout_class_methods (elt);
Index: java/expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.198
diff -c -3 -p -r1.198 expr.c
*** java/expr.c	12 Jul 2004 01:05:28 -0000	1.198
--- java/expr.c	19 Jul 2004 17:30:20 -0000
*************** can_widen_reference_to (tree source_type
*** 426,440 ****
  	    {
  	      /* target_type is OK if source_type or source_type ancestors
  		 implement target_type. We handle multiple sub-interfaces  */
  
! 	      tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (source_type));
! 	      int n = TREE_VEC_LENGTH (basetype_vec), i;
! 	      for (i=0 ; i < n; i++)
! 	        if (can_widen_reference_to 
! 		    (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
! 		     target_type))
  		  return 1;
! 	      if (n == 0)
  		return 0;
  	    }
  
--- 426,441 ----
  	    {
  	      /* target_type is OK if source_type or source_type ancestors
  		 implement target_type. We handle multiple sub-interfaces  */
+ 	      tree binfo, base_binfo;
+ 	      int i;
  
! 	      for (binfo = TYPE_BINFO (source_type), i = 0;
! 		   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
! 	        if (can_widen_reference_to
! 		    (BINFO_TYPE (base_binfo), target_type))
  		  return 1;
! 	      
! 	      if (!i)
  		return 0;
  	    }
  
*************** lookup_field (tree *typep, tree name)
*** 1459,1479 ****
      }
    do
      {
!       tree field, basetype_vec;
        tree save_field;
!       int n, i;
  
        for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
  	if (DECL_NAME (field) == name)
  	  return field;
  
        /* Process implemented interfaces. */
-       basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (*typep));
-       n = TREE_VEC_LENGTH (basetype_vec);
        save_field = NULL_TREE;
!       for (i = 0; i < n; i++)
  	{
! 	  tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
  	  if ((field = lookup_field (&t, name)))
  	    {
  	      if (save_field == field)
--- 1460,1479 ----
      }
    do
      {
!       tree field, binfo, base_binfo;
        tree save_field;
!       int i;
  
        for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
  	if (DECL_NAME (field) == name)
  	  return field;
  
        /* Process implemented interfaces. */
        save_field = NULL_TREE;
!       for (binfo = TYPE_BINFO (*typep), i = 0;
! 	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
  	{
! 	  tree t = BINFO_TYPE (base_binfo);
  	  if ((field = lookup_field (&t, name)))
  	    {
  	      if (save_field == field)
Index: java/jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.152
diff -c -3 -p -r1.152 jcf-write.c
*** java/jcf-write.c	18 Jul 2004 13:17:03 -0000	1.152
--- java/jcf-write.c	19 Jul 2004 17:30:33 -0000
*************** generate_classfile (tree clas, struct jc
*** 2963,2977 ****
      }
    else
      {
!       tree basetypes = BINFO_BASE_BINFOS (TYPE_BINFO (clas));
!       tree base = BINFO_TYPE (TREE_VEC_ELT (basetypes, 0));
!       int j = find_class_constant (&state->cpool, base);
        PUT2 (j);  /* super_class */
        PUT2 (total_supers - 1);  /* interfaces_count */
!       for (i = 1;  i < total_supers;  i++)
  	{
! 	  base = BINFO_TYPE (TREE_VEC_ELT (basetypes, i));
! 	  j = find_class_constant (&state->cpool, base);
  	  PUT2 (j);
  	}
      }
--- 2963,2977 ----
      }
    else
      {
!       tree binfo = TYPE_BINFO (clas);
!       tree base_binfo = BINFO_BASE_BINFO (binfo, 0);
!       int j = find_class_constant (&state->cpool, BINFO_TYPE (base_binfo));
!       
        PUT2 (j);  /* super_class */
        PUT2 (total_supers - 1);  /* interfaces_count */
!       for (i = 1; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
  	{
! 	  j = find_class_constant (&state->cpool, BINFO_TYPE (base_binfo));
  	  PUT2 (j);
  	}
      }
Index: java/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.493
diff -c -3 -p -r1.493 parse.y
*** java/parse.y	17 Jul 2004 00:31:15 -0000	1.493
--- java/parse.y	19 Jul 2004 17:32:33 -0000
*************** patch_anonymous_class (tree type_decl, t
*** 3879,3894 ****
    /* If it's an interface, implement it */
    if (CLASS_INTERFACE (type_decl))
      {
-       tree s_binfo;
-       int length;
- 
        if (parser_check_super_interface (type_decl, class_decl, wfl))
  	return;
  
!       s_binfo = TREE_VEC_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (class)), 0);
!       length = TREE_VEC_LENGTH (BINFO_BASE_BINFOS (TYPE_BINFO (class)))+1;
!       BINFO_BASE_BINFOS (TYPE_BINFO (class)) = make_tree_vec (length);
!       TREE_VEC_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (class)), 0) = s_binfo;
        /* And add the interface */
        parser_add_interface (class_decl, type_decl, wfl);
      }
--- 3879,3902 ----
    /* If it's an interface, implement it */
    if (CLASS_INTERFACE (type_decl))
      {
        if (parser_check_super_interface (type_decl, class_decl, wfl))
  	return;
  
!       if (VEC_space (tree, BINFO_BASE_BINFOS (binfo), 1))
! 	{
! 	   /* Extend the binfo - by reallocating and copying it. */
! 	  tree new_binfo;
! 	  tree base_binfo;
! 	  int i;
! 	  
! 	  new_binfo = make_tree_binfo ((BINFO_N_BASE_BINFOS (binfo) + 1) * 2);
! 	  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
! 	    BINFO_BASE_APPEND (new_binfo, base_binfo);
! 	  CLASS_HAS_SUPER_FLAG (new_binfo) = CLASS_HAS_SUPER_FLAG (binfo);
! 	  BINFO_VTABLE (new_binfo) = BINFO_VTABLE (binfo);
! 	  TYPE_BINFO (class) = new_binfo;
! 	}
!       
        /* And add the interface */
        parser_add_interface (class_decl, type_decl, wfl);
      }
*************** patch_anonymous_class (tree type_decl, t
*** 3897,3903 ****
      {
        if (parser_check_super (type_decl, class_decl, wfl))
  	return;
!       BINFO_TYPE (TREE_VEC_ELT (BINFO_BASE_BINFOS (binfo), 0)) = type;
      }
  }
  
--- 3905,3911 ----
      {
        if (parser_check_super (type_decl, class_decl, wfl))
  	return;
!       BINFO_TYPE (BINFO_BASE_BINFO (binfo, 0)) = type;
      }
  }
  
*************** register_incomplete_type (int kind, tree
*** 5213,5235 ****
  static tree
  check_inner_circular_reference (tree source, tree target)
  {
!   tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (source));
    tree ctx, cl;
    int i;
  
!   if (!basetype_vec)
!     return NULL_TREE;
! 
!   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
      {
        tree su;
  
        /* We can end up with a NULL_TREE or an incomplete type here if
  	 we encountered previous type resolution errors. It's safe to
  	 simply ignore these cases.  */
!       if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
! 	continue;
!       su = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
        if (INCOMPLETE_TYPE_P (su))
  	continue;
  
--- 5221,5238 ----
  static tree
  check_inner_circular_reference (tree source, tree target)
  {
!   tree base_binfo;
    tree ctx, cl;
    int i;
  
!   for (i = 0; BINFO_BASE_ITERATE (TYPE_BINFO (source), i, base_binfo); i++)
      {
        tree su;
  
        /* We can end up with a NULL_TREE or an incomplete type here if
  	 we encountered previous type resolution errors. It's safe to
  	 simply ignore these cases.  */
!       su = BINFO_TYPE (base_binfo);
        if (INCOMPLETE_TYPE_P (su))
  	continue;
  
*************** check_inner_circular_reference (tree sou
*** 5259,5268 ****
  static tree
  check_circular_reference (tree type)
  {
!   tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (type));
    int i;
  
!   if (!basetype_vec)
      return NULL_TREE;
  
    if (! CLASS_INTERFACE (TYPE_NAME (type)))
--- 5262,5271 ----
  static tree
  check_circular_reference (tree type)
  {
!   tree base_binfo;
    int i;
  
!   if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
      return NULL_TREE;
  
    if (! CLASS_INTERFACE (TYPE_NAME (type)))
*************** check_circular_reference (tree type)
*** 5272,5283 ****
        return NULL_TREE;
      }
  
!   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
      {
!       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
!       if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node
! 	  && interface_of_p (type, BINFO_TYPE (vec_elt)))
! 	return lookup_cl (TYPE_NAME (BINFO_TYPE (vec_elt)));
      }
    return NULL_TREE;
  }
--- 5275,5285 ----
        return NULL_TREE;
      }
  
!   for (i = 0; BINFO_BASE_ITERATE (TYPE_BINFO (type), i, base_binfo); i++)
      {
!       if (BINFO_TYPE (base_binfo) != object_type_node
! 	  && interface_of_p (type, BINFO_TYPE (base_binfo)))
! 	return lookup_cl (TYPE_NAME (BINFO_TYPE (base_binfo)));
      }
    return NULL_TREE;
  }
*************** java_complete_class (void)
*** 5569,5576 ****
  	      /* Simply patch super */
  	      if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
  		continue;
! 	      BINFO_TYPE (TREE_VEC_ELT (BINFO_BASE_BINFOS (TYPE_BINFO
! 	        (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
  	      break;
  
  	    case JDEP_FIELD:
--- 5571,5579 ----
  	      /* Simply patch super */
  	      if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
  		continue;
! 	      BINFO_TYPE (BINFO_BASE_BINFO
! 			  (TYPE_BINFO (TREE_TYPE (JDEP_DECL (dep))), 0))
! 		= TREE_TYPE (decl);
  	      break;
  
  	    case JDEP_FIELD:
*************** check_abstract_method_definitions (int d
*** 6198,6209 ****
      {
        /* Check for implemented interfaces. */
        int i;
!       tree vector = BINFO_BASE_BINFOS (TYPE_BINFO (type));
!       for (i = 1; ok && vector && i < TREE_VEC_LENGTH (vector); i++)
! 	{
! 	  tree super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
! 	  ok = check_abstract_method_definitions (1, class_decl, super);
! 	}
      }
  
    return ok;
--- 6201,6213 ----
      {
        /* Check for implemented interfaces. */
        int i;
!       tree base_binfo;
!       
!       for (i = 1;
! 	   ok && BINFO_BASE_ITERATE (TYPE_BINFO (type), i, base_binfo);
! 	   i++)
! 	ok = check_abstract_method_definitions (1, class_decl,
! 						BINFO_TYPE (base_binfo));
      }
  
    return ok;
*************** static void
*** 6216,6222 ****
  java_check_abstract_method_definitions (tree class_decl)
  {
    tree class = TREE_TYPE (class_decl);
!   tree super, vector;
    int i;
  
    if (CLASS_ABSTRACT (class_decl))
--- 6220,6226 ----
  java_check_abstract_method_definitions (tree class_decl)
  {
    tree class = TREE_TYPE (class_decl);
!   tree super, base_binfo;
    int i;
  
    if (CLASS_ABSTRACT (class_decl))
*************** java_check_abstract_method_definitions (
*** 6230,6241 ****
    } while (super != object_type_node);
  
    /* Check for implemented interfaces. */
!   vector = BINFO_BASE_BINFOS (TYPE_BINFO (class));
!   for (i = 1; i < TREE_VEC_LENGTH (vector); i++)
!     {
!       super = BINFO_TYPE (TREE_VEC_ELT (vector, i));
!       check_abstract_method_definitions (1, class_decl, super);
!     }
  }
  
  /* Check all the types method DECL uses and return 1 if all of them
--- 6234,6241 ----
    } while (super != object_type_node);
  
    /* Check for implemented interfaces. */
!   for (i = 1; BINFO_BASE_ITERATE (TYPE_BINFO (class), i, base_binfo); i++)
!     check_abstract_method_definitions (1, class_decl, BINFO_TYPE (base_binfo));
  }
  
  /* Check all the types method DECL uses and return 1 if all of them
*************** check_interface_throws_clauses (tree che
*** 6493,6500 ****
  {
    for (; class_decl != NULL_TREE; class_decl = CLASSTYPE_SUPER (class_decl))
      {
-       tree bases;
-       int iface_len;
        int i;
  
        if (! CLASS_LOADED_P (class_decl))
--- 6493,6498 ----
*************** check_interface_throws_clauses (tree che
*** 6505,6515 ****
  	    load_class (class_decl, 1);
  	}
  
!       bases = BINFO_BASE_BINFOS (TYPE_BINFO (class_decl));
!       iface_len = TREE_VEC_LENGTH (bases) - 1;
!       for (i = iface_len; i > 0; --i)
  	{
! 	  tree interface = BINFO_TYPE (TREE_VEC_ELT (bases, i));
  	  tree iface_method;
  
  	  for (iface_method = TYPE_METHODS (interface);
--- 6503,6512 ----
  	    load_class (class_decl, 1);
  	}
  
!       for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (class_decl)) - 1; i > 0; --i)
  	{
! 	  tree interface
! 	    = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (class_decl), i));
  	  tree iface_method;
  
  	  for (iface_method = TYPE_METHODS (interface);
*************** check_throws_clauses (tree method, tree 
*** 6609,6617 ****
  static void
  java_check_abstract_methods (tree interface_decl)
  {
!   int i, n;
!   tree method, basetype_vec, found;
    tree interface = TREE_TYPE (interface_decl);
  
    for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
      {
--- 6606,6615 ----
  static void
  java_check_abstract_methods (tree interface_decl)
  {
!   int i;
!   tree method, found;
    tree interface = TREE_TYPE (interface_decl);
+   tree base_binfo;
  
    for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
      {
*************** java_check_abstract_methods (tree interf
*** 6637,6652 ****
      }
  
    /* 4- Inherited methods can't differ by their returned types */
!   if (!(basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (interface))))
!     return;
!   n = TREE_VEC_LENGTH (basetype_vec);
!   for (i = 0; i < n; i++)
      {
        tree sub_interface_method, sub_interface;
!       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
!       if (!vec_elt)
! 	continue;
!       sub_interface = BINFO_TYPE (vec_elt);
        for (sub_interface_method = TYPE_METHODS (sub_interface);
  	   sub_interface_method;
  	   sub_interface_method = TREE_CHAIN (sub_interface_method))
--- 6635,6645 ----
      }
  
    /* 4- Inherited methods can't differ by their returned types */
!   for (i = 0; BINFO_BASE_ITERATE (TYPE_BINFO (interface), i, base_binfo); i++)
      {
        tree sub_interface_method, sub_interface;
! 
!       sub_interface = BINFO_TYPE (base_binfo);
        for (sub_interface_method = TYPE_METHODS (sub_interface);
  	   sub_interface_method;
  	   sub_interface_method = TREE_CHAIN (sub_interface_method))
*************** java_check_abstract_methods (tree interf
*** 6676,6701 ****
  static tree
  lookup_java_interface_method2 (tree class, tree method_decl)
  {
!   int i, n;
!   tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (class));
    tree to_return;
  
!   if (!basetype_vec)
!     return NULL_TREE;
! 
!   n = TREE_VEC_LENGTH (basetype_vec);
!   for (i = 0; i < n; i++)
      {
!       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
!       if ((BINFO_TYPE (vec_elt) != object_type_node)
  	  && (to_return =
! 	      lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
  	return to_return;
      }
!   for (i = 0; i < n; i++)
      {
        to_return = lookup_java_interface_method2
! 	(BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
        if (to_return)
  	return to_return;
      }
--- 6669,6689 ----
  static tree
  lookup_java_interface_method2 (tree class, tree method_decl)
  {
!   int i;
!   tree base_binfo;
    tree to_return;
  
!   for (i = 0; BINFO_BASE_ITERATE (TYPE_BINFO (class), i, base_binfo); i++)
      {
!       if ((BINFO_TYPE (base_binfo) != object_type_node)
  	  && (to_return =
! 	      lookup_java_method2 (BINFO_TYPE (base_binfo), method_decl, 1)))
  	return to_return;
      }
!   for (i = 0; BINFO_BASE_ITERATE (TYPE_BINFO (class), i, base_binfo); i++)
      {
        to_return = lookup_java_interface_method2
! 	(BINFO_TYPE (base_binfo), method_decl);
        if (to_return)
  	return to_return;
      }
*************** find_applicable_accessible_methods_list 
*** 10984,10989 ****
--- 10972,10979 ----
    static htab_t searched_classes;
    static int search_not_done = 0;
    tree list = NULL_TREE, all_list = NULL_TREE;
+   tree base_binfo;
+   int i;
  
    /* Check the hash table to determine if this class has been searched
       already. */
*************** find_applicable_accessible_methods_list 
*** 11011,11026 ****
    if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL
        && CLASS_INTERFACE (TYPE_NAME (class)))
      {
-       int i, n;
-       tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (class));
        search_applicable_methods_list (lc, TYPE_METHODS (class),
  				      name, arglist, &list, &all_list);
!       n = TREE_VEC_LENGTH (basetype_vec);
!       for (i = 1; i < n; i++)
  	{
! 	  tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
  	  tree rlist;
! 
  	  rlist = find_applicable_accessible_methods_list (lc,  t, name,
  							   arglist);
  	  list = chainon (rlist, list);
--- 11001,11013 ----
    if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL
        && CLASS_INTERFACE (TYPE_NAME (class)))
      {
        search_applicable_methods_list (lc, TYPE_METHODS (class),
  				      name, arglist, &list, &all_list);
!       for (i = 1; BINFO_BASE_ITERATE (TYPE_BINFO (class), i, base_binfo); i++)
  	{
! 	  tree t = BINFO_TYPE (base_binfo);
  	  tree rlist;
! 	  
  	  rlist = find_applicable_accessible_methods_list (lc,  t, name,
  							   arglist);
  	  list = chainon (rlist, list);
*************** find_applicable_accessible_methods_list 
*** 11044,11064 ****
  
        /* We must search all interfaces of this class */
        if (!lc)
!       {
! 	tree basetype_vec = BINFO_BASE_BINFOS (TYPE_BINFO (class));
! 	int n = TREE_VEC_LENGTH (basetype_vec), i;
! 	for (i = 1; i < n; i++)
! 	  {
! 	    tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
! 	    if (t != object_type_node)
! 	      {
! 		tree rlist
! 		  = find_applicable_accessible_methods_list (lc, t,
! 							     name, arglist);
! 		list = chainon (rlist, list);
! 	      }
! 	  }
!       }
  
        /* Search superclass */
        if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
--- 11031,11050 ----
  
        /* We must search all interfaces of this class */
        if (!lc)
! 	{
! 	  for (i = 1;
! 	       BINFO_BASE_ITERATE (TYPE_BINFO (class), i, base_binfo); i++)
! 	    {
! 	      tree t = BINFO_TYPE (base_binfo);
! 	      if (t != object_type_node)
! 		{
! 		  tree rlist
! 		    = find_applicable_accessible_methods_list (lc, t,
! 							       name, arglist);
! 		  list = chainon (rlist, list);
! 		}
! 	    }
! 	}
  
        /* Search superclass */
        if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
Index: java/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/typeck.c,v
retrieving revision 1.66
diff -c -3 -p -r1.66 typeck.c
*** java/typeck.c	18 Jul 2004 13:17:03 -0000	1.66
--- java/typeck.c	19 Jul 2004 17:32:40 -0000
*************** find_method_in_interfaces (tree searched
*** 796,808 ****
                             tree signature, tree (*signature_builder) (tree))
  {
    int i;
!   int interface_len = 
!     TREE_VEC_LENGTH (BINFO_BASE_BINFOS (TYPE_BINFO (searched_class))) - 1;
  
!   for (i = interface_len; i > 0; i--)
      {
!       tree child = BINFO_BASE_BINFO (TYPE_BINFO (searched_class), i);
!       tree iclass = BINFO_TYPE (child);
        tree method;
  	  
        /* If the superinterface hasn't been loaded yet, do so now.  */
--- 796,807 ----
                             tree signature, tree (*signature_builder) (tree))
  {
    int i;
!   tree binfo, base_binfo;
  
!   for (binfo = TYPE_BINFO (searched_class), i = 1;
!        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
      {
!       tree iclass = BINFO_TYPE (base_binfo);
        tree method;
  	  
        /* If the superinterface hasn't been loaded yet, do so now.  */
*************** find_method_in_interfaces (tree searched
*** 814,820 ****
        /* First, we look in ICLASS.  If that doesn't work we'll
  	 recursively look through all its superinterfaces.  */
        method = shallow_find_method (iclass, flags, method_name, 
! 					 signature, signature_builder);      
        if (method != NULL_TREE)
  	return method;
    
--- 813,819 ----
        /* First, we look in ICLASS.  If that doesn't work we'll
  	 recursively look through all its superinterfaces.  */
        method = shallow_find_method (iclass, flags, method_name, 
! 				    signature, signature_builder);      
        if (method != NULL_TREE)
  	return method;
    

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]