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] Delay binfo creation


Mark,
this patch delays the creation of the binfo structure to the point at which
we also create the vector of base binfos (so that I can just create one
object).  The impact of this is that incomplete types now have a
null TYPE_BINFO, and we have to call xref_basetypes for all user-visible
record and union types.  Thus most of this patch is being more careful
about looking at TYPE_BINFO.

There will be a tiny memory improvement, in that all variants of a type
point at the same binfo (rather than each having their own binfo that
points to shared structure).

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

The next patch will do the merge of binfo with base binfo vector.

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

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

	* call.c (build_user_type_conversion_1, build_new_op,
	check_constructor_callable, build_temp,
	perform_direct_initialization_of_possible): Pass type directly to
	lookup_fnfields & build_special_member_call.
	(build_special_member_call): Accept a type, and complete it.
	* class.c (finish_stuct_bits): Copy the BINFOs here.
	* cvt.c (ocp_convert): Pass type directly to
	build_special_member_call.
	* decl.c (build_ptrmemfunc_type): Call xref_bastypes here.
	(xref_basetypes): Allocate the binfo here. Adjust.
	* init.c (build_init, build_new_1): Pass type directly to
	build_special_member_call.
	* lex.c (cxx_make_type): Do not allocate binfo here.
	* name-lookup.c (arg_assoc_class): Incomplete types have no binfo.
	* parser.c (cp_parser_class_head): Always call xref_basetypes.
	* pt.c (instantiate_class_template): Likewise. Inhibit access
	checking for template friends.
	* ptree.c (cxx_print_type): Adjust record printing.
	* search.c (lookup_base): When taking a type, complete it before
	looking for a binfo.
	(lookup_member): Delay completing a type.
	(push_class_decls): Don't walk an incomplete type.
	(lookup_conversions): Likewise.
	* semantics.c (finish_stmt_expr_expr): Pass type directly to
	build_special_member_call.
	* tree.c (copy_base_binfos): Adjust.
	(make_binfo): Likewise.
	* typeck.c (build_modify_expr): Pass type directly to
	build_special_member_call.
	* typeck2.c (process_init_constructor): Check a binfo exists.
	(build_m_component_ref): Allow accessing an incomplete type.
	(build_functional_cast): Pass type directly to
	build_special_member_call.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.492
diff -c -3 -p -r1.492 call.c
*** cp/call.c	7 Jul 2004 21:16:57 -0000	1.492
--- cp/call.c	9 Jul 2004 09:02:39 -0000
*************** build_user_type_conversion_1 (tree totyp
*** 2500,2508 ****
  		      || !DERIVED_FROM_P (totype, fromtype), 20011226);
  
    if (IS_AGGR_TYPE (totype))
!     ctors = lookup_fnfields (TYPE_BINFO (totype),
! 			     complete_ctor_identifier,
! 			     0);
  
    if (IS_AGGR_TYPE (fromtype))
      conv_fns = lookup_conversions (fromtype);
--- 2500,2506 ----
  		      || !DERIVED_FROM_P (totype, fromtype), 20011226);
  
    if (IS_AGGR_TYPE (totype))
!     ctors = lookup_fnfields (totype, complete_ctor_identifier, 0);
  
    if (IS_AGGR_TYPE (fromtype))
      conv_fns = lookup_conversions (fromtype);
*************** build_new_op (enum tree_code code, int f
*** 3644,3650 ****
      {
        tree fns;
  
!       fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1);
        if (fns == error_mark_node)
  	{
  	  result = error_mark_node;
--- 3642,3648 ----
      {
        tree fns;
  
!       fns = lookup_fnfields (TREE_TYPE (arg1), fnname, 1);
        if (fns == error_mark_node)
  	{
  	  result = error_mark_node;
*************** check_constructor_callable (tree type, t
*** 4086,4092 ****
    build_special_member_call (NULL_TREE,
  			     complete_ctor_identifier,
  			     build_tree_list (NULL_TREE, expr), 
! 			     TYPE_BINFO (type),
  			     LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
  			     | LOOKUP_CONSTRUCTOR_CALLABLE);
  }
--- 4084,4090 ----
    build_special_member_call (NULL_TREE,
  			     complete_ctor_identifier,
  			     build_tree_list (NULL_TREE, expr), 
! 			     type,
  			     LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
  			     | LOOKUP_CONSTRUCTOR_CALLABLE);
  }
*************** build_temp (tree expr, tree type, int fl
*** 4107,4114 ****
    expr = build_special_member_call (NULL_TREE,
  				    complete_ctor_identifier,
  				    build_tree_list (NULL_TREE, expr), 
! 				    TYPE_BINFO (type),
! 				    flags);
    if (warningcount > savew)
      *diagnostic_fn = warning;
    else if (errorcount > savee)
--- 4105,4111 ----
    expr = build_special_member_call (NULL_TREE,
  				    complete_ctor_identifier,
  				    build_tree_list (NULL_TREE, expr), 
! 				    type, flags);
    if (warningcount > savew)
      *diagnostic_fn = warning;
    else if (errorcount > savee)
*************** build_special_member_call (tree instance
*** 5008,5013 ****
--- 5005,5019 ----
  		      || name == deleting_dtor_identifier
  		      || name == ansi_assopname (NOP_EXPR),
  		      20020712);
+   if (TYPE_P (binfo))
+     {
+       /* Resolve the name.  */
+       if (!complete_type_or_else (binfo, NULL_TREE))
+ 	return error_mark_node;
+ 
+       binfo = TYPE_BINFO (binfo);
+     }
+   
    my_friendly_assert (binfo != NULL_TREE, 20020712);
  
    class_type = BINFO_TYPE (binfo);
*************** build_special_member_call (tree instance
*** 5047,5056 ****
    
    my_friendly_assert (instance != NULL_TREE, 20020712);
  
-   /* Resolve the name.  */
-   if (!complete_type_or_else (BINFO_TYPE (binfo), NULL_TREE))
-     return error_mark_node;
- 
    fns = lookup_fnfields (binfo, name, 1);
      
    /* When making a call to a constructor or destructor for a subobject
--- 5053,5058 ----
*************** perform_direct_initialization_if_possibl
*** 6296,6303 ****
      {
        expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
  					build_tree_list (NULL_TREE, expr),
! 					TYPE_BINFO (type),
! 					LOOKUP_NORMAL);
        return build_cplus_new (type, expr);
      }
  
--- 6298,6304 ----
      {
        expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
  					build_tree_list (NULL_TREE, expr),
! 					type, LOOKUP_NORMAL);
        return build_cplus_new (type, expr);
      }
  
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.626
diff -c -3 -p -r1.626 class.c
*** cp/class.c	8 Jul 2004 04:32:27 -0000	1.626
--- cp/class.c	9 Jul 2004 09:02:55 -0000
*************** finish_struct_bits (tree t)
*** 1501,1512 ****
--- 1501,1516 ----
  	= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t);
        TYPE_POLYMORPHIC_P (variants) = TYPE_POLYMORPHIC_P (t);
        TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t);
+       
+       TYPE_BINFO (variants) = TYPE_BINFO (t);
+ 
        /* Copy whatever these are holding today.  */
        TYPE_VFIELD (variants) = TYPE_VFIELD (t);
        TYPE_METHODS (variants) = TYPE_METHODS (t);
        TYPE_FIELDS (variants) = TYPE_FIELDS (t);
        TYPE_SIZE (variants) = TYPE_SIZE (t);
        TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
+       
        variants = TYPE_NEXT_VARIANT (variants);
      }
  
Index: cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.157
diff -c -3 -p -r1.157 cvt.c
*** cp/cvt.c	31 May 2004 21:24:29 -0000	1.157
--- cp/cvt.c	9 Jul 2004 09:02:58 -0000
*************** ocp_convert (tree type, tree expr, int c
*** 748,754 ****
  	ctor = build_special_member_call (NULL_TREE, 
  					  complete_ctor_identifier,
  					  build_tree_list (NULL_TREE, ctor),
! 					  TYPE_BINFO (type), flags);
        if (ctor)
  	return build_cplus_new (type, ctor);
      }
--- 748,754 ----
  	ctor = build_special_member_call (NULL_TREE, 
  					  complete_ctor_identifier,
  					  build_tree_list (NULL_TREE, ctor),
! 					  type, flags);
        if (ctor)
  	return build_cplus_new (type, ctor);
      }
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1240
diff -c -3 -p -r1.1240 decl.c
*** cp/decl.c	8 Jul 2004 04:32:27 -0000	1.1240
--- cp/decl.c	9 Jul 2004 09:03:20 -0000
*************** build_ptrmemfunc_type (tree type)
*** 5871,5876 ****
--- 5871,5878 ----
        = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
  
    t = make_aggr_type (RECORD_TYPE);
+   xref_basetypes (t, NULL_TREE);
+   
    /* Let the front-end know this is a pointer to member function...  */
    TYPE_PTRMEMFUNC_FLAG (t) = 1;
    /* ... and not really an aggregate.  */
*************** xref_basetypes (tree ref, tree base_list
*** 9051,9063 ****
    if (ref == error_mark_node)
      return;
  
!   if (TREE_CODE (ref) == UNION_TYPE)
!     {
!       error ("derived union `%T' invalid", ref);
!       return;
!     }
! 
!   tag_code = (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type);
  
    /* First, make sure that any templates in base-classes are
       instantiated.  This ensures that if we call ourselves recursively
--- 9053,9060 ----
    if (ref == error_mark_node)
      return;
  
!   tag_code = TREE_CODE (ref) == UNION_TYPE ? union_type
!     : (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type);
  
    /* First, make sure that any templates in base-classes are
       instantiated.  This ensures that if we call ourselves recursively
*************** xref_basetypes (tree ref, tree base_list
*** 9067,9072 ****
--- 9064,9070 ----
    while (*basep) 
      {
        tree basetype = TREE_VALUE (*basep);
+       
        if (!(processing_template_decl && uses_template_parms (basetype))
  	  && !complete_type_or_else (basetype, NULL))
  	/* An incomplete type.  Remove it from the list.  */
*************** xref_basetypes (tree ref, tree base_list
*** 9077,9082 ****
--- 9075,9085 ----
  
    SET_CLASSTYPE_MARKED (ref);
    i = list_length (base_list);
+   /* The binfo slot should be empty, unless this is an (ill-formed)
+      redefinition.  */
+   my_friendly_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref), 20040706);
+   TYPE_BINFO (ref) = make_binfo (size_zero_node, ref, NULL_TREE, NULL_TREE);
+   
    if (i)
      {
        tree binfo = TYPE_BINFO (ref);
*************** xref_basetypes (tree ref, tree base_list
*** 9129,9142 ****
  	  if (CLASS_TYPE_P (basetype))
  	    {
  	      base_binfo = TYPE_BINFO (basetype);
! 	      /* This flag will be in the binfo of the base type, we must
! 	     	 clear it after copying the base binfos.  */
! 	      BINFO_DEPENDENT_BASE_P (base_binfo)
! 		= dependent_type_p (basetype);
  	    }
  	  else
! 	    base_binfo = make_binfo (size_zero_node, basetype,
! 				     NULL_TREE, NULL_TREE);
  	  
  	  TREE_VEC_ELT (binfos, i) = base_binfo;
  	  TREE_VEC_ELT (accesses, i) = access;
--- 9132,9153 ----
  	  if (CLASS_TYPE_P (basetype))
  	    {
  	      base_binfo = TYPE_BINFO (basetype);
! 
! 	      if (dependent_type_p (basetype))
! 		{
! 		  base_binfo = make_binfo (size_zero_node, basetype,
! 					   NULL_TREE, NULL_TREE);
! 		  BINFO_DEPENDENT_BASE_P (base_binfo) = 1;
! 		}
! 	      else
! 		my_friendly_assert (base_binfo, 20040706);
  	    }
  	  else
! 	    {
! 	      base_binfo = make_binfo (size_zero_node, basetype,
! 				       NULL_TREE, NULL_TREE);
! 	      BINFO_DEPENDENT_BASE_P (base_binfo) = 1;
! 	    }
  	  
  	  TREE_VEC_ELT (binfos, i) = base_binfo;
  	  TREE_VEC_ELT (accesses, i) = access;
*************** xref_basetypes (tree ref, tree base_list
*** 9196,9201 ****
--- 9207,9218 ----
       inheritance order chain.  */
    copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE);
  
+   if (TREE_CODE (ref) == UNION_TYPE)
+     {
+       if (i)
+ 	error ("derived union `%T' invalid", ref);
+     }
+ 
    if (TYPE_FOR_JAVA (ref))
      {
        if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
*************** xref_basetypes (tree ref, tree base_list
*** 9207,9220 ****
    /* Unmark all the types.  */
    while (i--)
      {
!       tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (ref), i));
        
        CLEAR_CLASSTYPE_MARKED (basetype);
!       if (CLASS_TYPE_P (basetype))
! 	{
! 	  BINFO_VIRTUAL_P (TYPE_BINFO (basetype)) = 0;
! 	  BINFO_DEPENDENT_BASE_P (TYPE_BINFO (basetype)) = 0;
! 	}
      }
    CLEAR_CLASSTYPE_MARKED (ref);
  }
--- 9224,9235 ----
    /* Unmark all the types.  */
    while (i--)
      {
!       tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (ref), i);
!       tree basetype = BINFO_TYPE (binfo);
        
        CLEAR_CLASSTYPE_MARKED (basetype);
!       if (!BINFO_DEPENDENT_BASE_P (binfo))
! 	BINFO_VIRTUAL_P (TYPE_BINFO (basetype)) = 0;
      }
    CLEAR_CLASSTYPE_MARKED (ref);
  }
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.383
diff -c -3 -p -r1.383 init.c
*** cp/init.c	7 Jul 2004 10:20:33 -0000	1.383
--- cp/init.c	9 Jul 2004 09:03:27 -0000
*************** build_init (tree decl, tree init, int fl
*** 1145,1151 ****
    else if (CLASS_TYPE_P (TREE_TYPE (decl)))
      expr = build_special_member_call (decl, complete_ctor_identifier,
  				      build_tree_list (NULL_TREE, init),
! 				      TYPE_BINFO (TREE_TYPE (decl)),
  				      LOOKUP_NORMAL|flags);
    else
      expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
--- 1145,1151 ----
    else if (CLASS_TYPE_P (TREE_TYPE (decl)))
      expr = build_special_member_call (decl, complete_ctor_identifier,
  				      build_tree_list (NULL_TREE, init),
! 				      TREE_TYPE (decl),
  				      LOOKUP_NORMAL|flags);
    else
      expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
*************** build_new_1 (tree exp)
*** 2088,2094 ****
  	{
  	  init_expr = build_special_member_call (init_expr, 
  						 complete_ctor_identifier,
! 						 init, TYPE_BINFO (true_type),
  						 LOOKUP_NORMAL);
  	  stable = stabilize_init (init_expr, &init_preeval_expr);
  	}
--- 2088,2094 ----
  	{
  	  init_expr = build_special_member_call (init_expr, 
  						 complete_ctor_identifier,
! 						 init, true_type,
  						 LOOKUP_NORMAL);
  	  stable = stabilize_init (init_expr, &init_preeval_expr);
  	}
Index: cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.334
diff -c -3 -p -r1.334 lex.c
*** cp/lex.c	7 Jul 2004 21:26:31 -0000	1.334
--- cp/lex.c	9 Jul 2004 09:03:28 -0000
*************** cxx_make_type (enum tree_code code)
*** 782,789 ****
  	 presence of parse errors, the normal was of assuring this
  	 might not ever get executed, so we lay it out *immediately*.  */
        build_pointer_type (t);
- 
-       TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE);
      }
    else
      /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits.  But,
--- 782,787 ----
Index: cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.68
diff -c -3 -p -r1.68 name-lookup.c
*** cp/name-lookup.c	8 Jul 2004 09:39:17 -0000	1.68
--- cp/name-lookup.c	9 Jul 2004 09:03:38 -0000
*************** arg_assoc_class (struct arg_lookup *k, t
*** 4347,4358 ****
    context = decl_namespace (TYPE_MAIN_DECL (type));
    if (arg_assoc_namespace (k, context))
      return true;
!   
!   /* 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; 
--- 4347,4359 ----
    context = decl_namespace (TYPE_MAIN_DECL (type));
    if (arg_assoc_namespace (k, context))
      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; 
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.223
diff -c -3 -p -r1.223 parser.c
*** cp/parser.c	30 Jun 2004 18:23:34 -0000	1.223
--- cp/parser.c	9 Jul 2004 09:04:11 -0000
*************** cp_parser_class_head (cp_parser* parser,
*** 12481,12486 ****
--- 12481,12487 ----
    bool invalid_explicit_specialization_p = false;
    bool pop_p = false;
    unsigned num_templates;
+   tree bases;
  
    /* Assume no nested-name-specifier will be present.  */
    *nested_name_specifier_p = false;
*************** cp_parser_class_head (cp_parser* parser,
*** 12757,12773 ****
       is valid.  */
    if (nested_name_specifier)
      pop_p = push_scope (nested_name_specifier);
!   /* Now, look for the base-clause.  */
!   token = cp_lexer_peek_token (parser->lexer);
!   if (token->type == CPP_COLON)
!     {
!       tree bases;
  
-       /* Get the list of base-classes.  */
-       bases = cp_parser_base_clause (parser);
-       /* Process them.  */
-       xref_basetypes (type, bases);
-     }
    /* Leave the scope given by the nested-name-specifier.  We will
       enter the class scope itself while processing the members.  */
    if (pop_p)
--- 12758,12773 ----
       is valid.  */
    if (nested_name_specifier)
      pop_p = push_scope (nested_name_specifier);
!   
!   bases = NULL_TREE;
!   
!   /* Get the list of base-classes, if there is one.  */
!   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
!     bases = cp_parser_base_clause (parser);
!   
!   /* Process the base classes.  */
!   xref_basetypes (type, bases);
  
    /* Leave the scope given by the nested-name-specifier.  We will
       enter the class scope itself while processing the members.  */
    if (pop_p)
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.883
diff -c -3 -p -r1.883 pt.c
*** cp/pt.c	7 Jul 2004 10:20:38 -0000	1.883
--- cp/pt.c	9 Jul 2004 09:04:36 -0000
*************** instantiate_class_template (tree type)
*** 5286,5291 ****
--- 5286,5292 ----
    tree template, args, pattern, t, member;
    tree typedecl;
    tree pbinfo;
+   tree base_list;
    
    if (type == error_mark_node)
      return error_mark_node;
*************** instantiate_class_template (tree type)
*** 5419,5427 ****
      abort ();
  #endif
  
    if (BINFO_BASE_BINFOS (pbinfo))
      {
-       tree base_list = NULL_TREE;
        tree pbases = BINFO_BASE_BINFOS (pbinfo);
        tree paccesses = BINFO_BASE_ACCESSES (pbinfo);
        tree context = TYPE_CONTEXT (type);
--- 5420,5428 ----
      abort ();
  #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);
*************** instantiate_class_template (tree type)
*** 5457,5469 ****
        /* The list is now in reverse order; correct that.  */
        base_list = nreverse (base_list);
  
-       /* Now call xref_basetypes to set up all the base-class
- 	 information.  */
-       xref_basetypes (type, base_list);
- 
        if (pop_p)
  	pop_scope (context ? context : global_namespace);
      }
  
    /* Now that our base classes are set up, enter the scope of the
       class, so that name lookups into base classes, etc. will work
--- 5458,5470 ----
        /* The list is now in reverse order; correct that.  */
        base_list = nreverse (base_list);
  
        if (pop_p)
  	pop_scope (context ? context : global_namespace);
      }
+   /* Now call xref_basetypes to set up all the base-class
+      information.  */
+   xref_basetypes (type, base_list);
+ 
  
    /* Now that our base classes are set up, enter the scope of the
       class, so that name lookups into base classes, etc. will work
*************** instantiate_class_template (tree type)
*** 5647,5657 ****
  	      tree r;
  
  	      if (TREE_CODE (t) == TEMPLATE_DECL)
! 		++processing_template_decl;
  	      r = tsubst_friend_function (t, args);
- 	      if (TREE_CODE (t) == TEMPLATE_DECL)
- 		--processing_template_decl;
  	      add_friend (type, r, /*complain=*/false);
  	    }
  	}
      }
--- 5648,5665 ----
  	      tree r;
  
  	      if (TREE_CODE (t) == TEMPLATE_DECL)
! 		{
! 		  ++processing_template_decl;
! 		  push_deferring_access_checks (dk_no_check);
! 		}
! 	      
  	      r = tsubst_friend_function (t, args);
  	      add_friend (type, r, /*complain=*/false);
+ 	      if (TREE_CODE (t) == TEMPLATE_DECL)
+ 		{
+ 		  pop_deferring_access_checks ();
+ 		  --processing_template_decl;
+ 		}
  	    }
  	}
      }
Index: cp/ptree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ptree.c,v
retrieving revision 1.41
diff -c -3 -p -r1.41 ptree.c
*** cp/ptree.c	7 Jul 2004 10:20:41 -0000	1.41
--- cp/ptree.c	9 Jul 2004 09:04:36 -0000
*************** cxx_print_type (FILE *file, tree node, i
*** 128,134 ****
  
    if (TREE_CODE (node) == RECORD_TYPE)
      {
!       fprintf (file, " n_parents %d", BINFO_N_BASE_BINFOS (TYPE_BINFO (node)));
        fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node));
        if (CLASSTYPE_INTERFACE_ONLY (node))
  	fprintf (file, " interface-only");
--- 128,139 ----
  
    if (TREE_CODE (node) == RECORD_TYPE)
      {
!       if (TYPE_BINFO (node))
! 	fprintf (file, " n_parents=%d",
! 		 BINFO_N_BASE_BINFOS (TYPE_BINFO (node)));
!       else
! 	fprintf (file, " no-binfo");
!       
        fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node));
        if (CLASSTYPE_INTERFACE_ONLY (node))
  	fprintf (file, " interface-only");
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.186
diff -c -3 -p -r1.186 rtti.c
*** cp/rtti.c	7 Jul 2004 18:29:38 -0000	1.186
--- cp/rtti.c	9 Jul 2004 09:04:40 -0000
*************** along with GCC; see the file COPYING.  I
*** 20,26 ****
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
- 
  #include "config.h"
  #include "system.h"
  #include "coretypes.h"
--- 20,25 ----
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.296
diff -c -3 -p -r1.296 search.c
*** cp/search.c	7 Jul 2004 10:20:41 -0000	1.296
--- cp/search.c	9 Jul 2004 09:04:45 -0000
*************** accessible_base_p (tree t, tree base)
*** 271,278 ****
  tree
  lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
  {
!   tree binfo = NULL;		/* The binfo we've found so far.  */
!   tree t_binfo = NULL;
    base_kind bk;
    
    if (t == error_mark_node || base == error_mark_node)
--- 271,278 ----
  tree
  lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
  {
!   tree binfo = NULL_TREE;	/* The binfo we've found so far.  */
!   tree t_binfo = NULL_TREE;
    base_kind bk;
    
    if (t == error_mark_node || base == error_mark_node)
*************** lookup_base (tree t, tree base, base_acc
*** 288,301 ****
        t_binfo = t;
        t = BINFO_TYPE (t);
      }
!   else 
!     t_binfo = TYPE_BINFO (t);
! 
!   /* Ensure that the types are instantiated.  */
!   t = complete_type (TYPE_MAIN_VARIANT (t));
!   base = complete_type (TYPE_MAIN_VARIANT (base));
    
!   bk = lookup_base_r (t_binfo, base, access, 0, &binfo);
  
    /* Check that the base is unambiguous and accessible.  */
    if (access != ba_any)
--- 288,305 ----
        t_binfo = t;
        t = BINFO_TYPE (t);
      }
!   else  
!     {
!       t = complete_type (TYPE_MAIN_VARIANT (t));
!       t_binfo = TYPE_BINFO (t);
!     }
    
!   base = complete_type (TYPE_MAIN_VARIANT (base));
! 
!   if (t_binfo)
!     bk = lookup_base_r (t_binfo, base, access, 0, &binfo);
!   else
!     bk = bk_not_base;
  
    /* Check that the base is unambiguous and accessible.  */
    if (access != ba_any)
*************** lookup_member (tree xbasetype, tree name
*** 1257,1264 ****
      {
        my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)), 20030624);
        type = xbasetype;
!       basetype_path = TYPE_BINFO (type);
!       my_friendly_assert (!BINFO_INHERITANCE_CHAIN (basetype_path), 980827);
      }
  
    if (type == current_class_type && TYPE_BEING_DEFINED (type)
--- 1261,1267 ----
      {
        my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)), 20030624);
        type = xbasetype;
!       xbasetype = NULL_TREE;
      }
  
    if (type == current_class_type && TYPE_BEING_DEFINED (type)
*************** lookup_member (tree xbasetype, tree name
*** 1272,1278 ****
  	return field;
      }
  
!   complete_type (type);
  
  #ifdef GATHER_STATISTICS
    n_calls_lookup_field++;
--- 1275,1286 ----
  	return field;
      }
  
!   type = complete_type (type);
!   if (!basetype_path)
!     basetype_path = TYPE_BINFO (type);
! 
!   if (!basetype_path)
!     return NULL_TREE;
  
  #ifdef GATHER_STATISTICS
    n_calls_lookup_field++;
*************** push_class_decls (tree type)
*** 2240,2245 ****
--- 2248,2258 ----
  {
    search_stack = push_search_level (search_stack, &search_obstack);
  
+   if (!TYPE_BINFO (type))
+     /* This occurs when parsing an invalid declarator id where the
+        scope is incomplete.  */
+     return;
+   
    /* Enter type declarations and mark.  */
    dfs_walk (TYPE_BINFO (type), dfs_push_type_decls, unmarked_pushdecls_p, 0);
  
*************** lookup_conversions (tree type)
*** 2391,2397 ****
    tree conversions = NULL_TREE;
  
    complete_type (type);
!   bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions);
  
    for (t = conversions; t; t = TREE_CHAIN (t))
      IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (t)))) = 0;
--- 2404,2411 ----
    tree conversions = NULL_TREE;
  
    complete_type (type);
!   if (TYPE_BINFO (type))
!     bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions);
  
    for (t = conversions; t; t = TREE_CHAIN (t))
      IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (t)))) = 0;
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.415
diff -c -3 -p -r1.415 semantics.c
*** cp/semantics.c	6 Jul 2004 08:51:28 -0000	1.415
--- cp/semantics.c	9 Jul 2004 09:04:51 -0000
*************** finish_stmt_expr_expr (tree expr, tree s
*** 1490,1496 ****
  	      expr = build_special_member_call
  		(NULL_TREE, complete_ctor_identifier,
  		 build_tree_list (NULL_TREE, expr),
! 		 TYPE_BINFO (type), LOOKUP_NORMAL);
  	      expr = build_cplus_new (type, expr);
  	      my_friendly_assert (TREE_CODE (expr) == TARGET_EXPR, 20030729);
  	    }
--- 1490,1496 ----
  	      expr = build_special_member_call
  		(NULL_TREE, complete_ctor_identifier,
  		 build_tree_list (NULL_TREE, expr),
! 		 type, LOOKUP_NORMAL);
  	      expr = build_cplus_new (type, expr);
  	      my_friendly_assert (TREE_CODE (expr) == TARGET_EXPR, 20030729);
  	    }
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.389
diff -c -3 -p -r1.389 tree.c
*** cp/tree.c	7 Jul 2004 10:20:42 -0000	1.389
--- cp/tree.c	9 Jul 2004 09:04:55 -0000
*************** copy_base_binfos (tree binfo, tree t, tr
*** 602,608 ****
        tree base_binfo = TREE_VEC_ELT (binfos, ix);
        tree new_binfo = NULL_TREE;
  
!       if (!CLASS_TYPE_P (BINFO_TYPE (base_binfo)))
  	{
  	  my_friendly_assert (binfo == TYPE_BINFO (t), 20030204);
  	  
--- 602,608 ----
        tree base_binfo = TREE_VEC_ELT (binfos, ix);
        tree new_binfo = NULL_TREE;
  
!       if (BINFO_DEPENDENT_BASE_P (base_binfo))
  	{
  	  my_friendly_assert (binfo == TYPE_BINFO (t), 20030204);
  	  
*************** make_binfo (tree offset, tree binfo, tre
*** 777,789 ****
    if (TREE_CODE (binfo) == TREE_BINFO)
      {
        type = BINFO_TYPE (binfo);
!       BINFO_DEPENDENT_BASE_P (new_binfo) = BINFO_DEPENDENT_BASE_P (binfo);
      }
    else
      {
        type = binfo;
        binfo = NULL_TREE;
-       BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
      }
  
    TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
--- 777,788 ----
    if (TREE_CODE (binfo) == TREE_BINFO)
      {
        type = BINFO_TYPE (binfo);
!       my_friendly_assert (!BINFO_DEPENDENT_BASE_P (binfo), 20040706);
      }
    else
      {
        type = binfo;
        binfo = NULL_TREE;
      }
  
    TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
*************** make_binfo (tree offset, tree binfo, tre
*** 791,798 ****
    BINFO_VTABLE (new_binfo) = vtable;
    BINFO_VIRTUALS (new_binfo) = virtuals;
  
!   if (binfo && !BINFO_DEPENDENT_BASE_P (binfo)
!       && BINFO_BASE_BINFOS (binfo) != NULL_TREE)
      {
        BINFO_BASE_BINFOS (new_binfo) = copy_node (BINFO_BASE_BINFOS (binfo));
        /* We do not need to copy the accesses, as they are read only.  */
--- 790,796 ----
    BINFO_VTABLE (new_binfo) = vtable;
    BINFO_VIRTUALS (new_binfo) = virtuals;
  
!   if (binfo && BINFO_BASE_BINFOS (binfo))
      {
        BINFO_BASE_BINFOS (new_binfo) = copy_node (BINFO_BASE_BINFOS (binfo));
        /* We do not need to copy the accesses, as they are read only.  */
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.558
diff -c -3 -p -r1.558 typeck.c
*** cp/typeck.c	8 Jul 2004 10:03:54 -0000	1.558
--- cp/typeck.c	9 Jul 2004 09:05:09 -0000
*************** build_modify_expr (tree lhs, enum tree_c
*** 5070,5077 ****
  	{
  	  result = build_special_member_call (lhs, complete_ctor_identifier,
  					      build_tree_list (NULL_TREE, rhs),
! 					      TYPE_BINFO (lhstype), 
! 					      LOOKUP_NORMAL);
  	  if (result == NULL_TREE)
  	    return error_mark_node;
  	  return result;
--- 5070,5076 ----
  	{
  	  result = build_special_member_call (lhs, complete_ctor_identifier,
  					      build_tree_list (NULL_TREE, rhs),
! 					      lhstype, LOOKUP_NORMAL);
  	  if (result == NULL_TREE)
  	    return error_mark_node;
  	  return result;
Index: cp/typeck2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck2.c,v
retrieving revision 1.163
diff -c -3 -p -r1.163 typeck2.c
*** cp/typeck2.c	7 Jul 2004 10:20:46 -0000	1.163
--- cp/typeck2.c	9 Jul 2004 09:05:11 -0000
*************** process_init_constructor (tree type, tre
*** 804,810 ****
  	      return error_mark_node;
  	    }
  
! 	  if (BINFO_BASE_BINFOS (TYPE_BINFO (type)))
  	    {
  	      sorry ("initializer list for object of class with base classes");
  	      return error_mark_node;
--- 804,810 ----
  	      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;
*************** build_m_component_ref (tree datum, tree 
*** 1154,1159 ****
--- 1154,1160 ----
    tree objtype;
    tree type;
    tree binfo;
+   tree ctype;
  
    datum = decay_conversion (datum);
  
*************** build_m_component_ref (tree datum, tree 
*** 1177,1192 ****
      }
  
    type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
!   binfo = lookup_base (objtype, TYPE_PTRMEM_CLASS_TYPE (ptrmem_type),
! 		       ba_check, NULL);
!   if (!binfo)
      {
!       error ("member type `%T::' incompatible with object type `%T'",
! 	     type, objtype);
!       return error_mark_node;
      }
-   else if (binfo == error_mark_node)
-     return error_mark_node;
  
    if (TYPE_PTRMEM_P (ptrmem_type))
      {
--- 1178,1205 ----
      }
  
    type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
!   ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type));
! 
!   if (!COMPLETE_TYPE_P (ctype))
      {
!       if (!same_type_p (ctype, objtype))
! 	goto mismatch;
!       binfo = NULL;
!     }
!   else
!     {
!       binfo = lookup_base (objtype, ctype, ba_check, NULL);
!       
!       if (!binfo)
! 	{
! 	mismatch:
! 	  error ("pointer to member type `%T' incompatible with object type `%T'",
! 		 type, objtype);
! 	  return error_mark_node;
! 	}
!       else if (binfo == error_mark_node)
! 	return error_mark_node;
      }
  
    if (TYPE_PTRMEM_P (ptrmem_type))
      {
*************** build_m_component_ref (tree datum, tree 
*** 1197,1208 ****
        type = cp_build_qualified_type (type,
  				      (cp_type_quals (type)  
  				       | cp_type_quals (TREE_TYPE (datum))));
        /* Build an expression for "object + offset" where offset is the
  	 value stored in the pointer-to-data-member.  */
        datum = build (PLUS_EXPR, build_pointer_type (type),
! 		     build_base_path (PLUS_EXPR, build_address (datum), 
! 				      binfo, 1),
! 		     build_nop (ptrdiff_type_node, component));
        return build_indirect_ref (datum, 0);
      }
    else
--- 1210,1226 ----
        type = cp_build_qualified_type (type,
  				      (cp_type_quals (type)  
  				       | cp_type_quals (TREE_TYPE (datum))));
+ 
+       datum = build_address (datum);
+       
+       /* Convert object to the correct base.  */
+       if (binfo)
+ 	datum = build_base_path (PLUS_EXPR, datum, binfo, 1);
+       
        /* Build an expression for "object + offset" where offset is the
  	 value stored in the pointer-to-data-member.  */
        datum = build (PLUS_EXPR, build_pointer_type (type),
! 		     datum, build_nop (ptrdiff_type_node, component));
        return build_indirect_ref (datum, 0);
      }
    else
*************** build_functional_cast (tree exp, tree pa
*** 1270,1276 ****
      }
  
    exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
! 				   TYPE_BINFO (type), LOOKUP_NORMAL);
  
    if (exp == error_mark_node)
      return error_mark_node;
--- 1288,1294 ----
      }
  
    exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
! 				   type, LOOKUP_NORMAL);
  
    if (exp == error_mark_node)
      return error_mark_node;

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