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]

C++ PATCH to add VTT parm to DECL_ARGUMENTS


This is a rather large patch for what it does: add the VTT parm to
the DECL_ARGUMENTS and TYPE_ARG_TYPES lists for functions.  Unfortunately,
lots of places make assumptions about the contents of those lists, which is
probably why this wasn't done to begin with.  This patch is in preparation
for yet another patch to improve debugging of cloned [cd]tors.

Applied to trunk and branch.

2001-02-18  Jason Merrill  <jason@redhat.com>

	Do put the VTT parameter in DECL_ARGUMENTS.
	* cp-tree.h (struct cp_language_function): Add x_vtt_parm.
	(current_vtt_parm): New macro.
	(struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
	(DECL_HAS_VTT_PARM_P): New macro.
	(DECL_VTT_PARM): Remove.
	(FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
	* decl.c (duplicate_decls): Only copy the operator code if
	appropriate.
	(start_function): Set current_vtt_parm.
	(lang_mark_tree): Don't mark vtt_parm.
	* decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to 
	DECL_ARGUMENTS.  Set DECL_HAS_VTT_PARM_P.
	* class.c (build_clone): Maybe remove the VTT parm.
	* optimize.c (maybe_clone_body): Set up the VTT parm.
	* pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
	* call.c (build_over_call): Just allow the VTT arg.
	* method.c (make_thunk): Don't set DECL_VTT_PARM.
	(do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
	(synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
	* decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
	* error.c (dump_function_decl): Likewise.
	* call.c (build_user_type_conversion_1,	convert_like_real): Abort
	if we try to call a constructor with in-charge or VTT parms.
	* method.c (skip_artificial_parms_for): New fn.
	* call.c (add_function_candidate, build_over_call): Call it.
	* call.c (build_new_method_call): Use current_vtt_parm.
	* init.c (expand_virtual_init): Likewise.
	* class.c (same_signature_p): No longer static.
	* cp-tree.h: Declare it.
	* search.c (look_for_overrides_r): Use it.

Index: call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.260
diff -c -p -r1.260 call.c
*** call.c	2001/02/17 23:54:42	1.260
--- call.c	2001/02/18 14:40:06
*************** add_function_candidate (candidates, fn, 
*** 1305,1321 ****
    tree parmnode, argnode;
    int viable = 1;
  
!   /* The `this' and `in_chrg' arguments to constructors are not considered
!      in overload resolution.  */
    if (DECL_CONSTRUCTOR_P (fn))
      {
!       parmlist = TREE_CHAIN (parmlist);
!       arglist = TREE_CHAIN (arglist);
!       if (DECL_HAS_IN_CHARGE_PARM_P (fn))
! 	{
! 	  parmlist = TREE_CHAIN (parmlist);
! 	  arglist = TREE_CHAIN (arglist);
! 	}
      }
  
    len = list_length (arglist);
--- 1305,1316 ----
    tree parmnode, argnode;
    int viable = 1;
  
!   /* The `this', `in_chrg' and VTT arguments to constructors are not
!      considered in overload resolution.  */
    if (DECL_CONSTRUCTOR_P (fn))
      {
!       parmlist = skip_artificial_parms_for (fn, parmlist);
!       arglist = skip_artificial_parms_for (fn, arglist);
      }
  
    len = list_length (arglist);
*************** build_user_type_conversion_1 (totype, ex
*** 2382,2391 ****
        t = build_int_2 (0, 0);
        TREE_TYPE (t) = build_pointer_type (totype);
        args = build_tree_list (NULL_TREE, expr);
!       if (DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors)))
! 	args = tree_cons (NULL_TREE, 
! 			  in_charge_arg_for_name (complete_ctor_identifier), 
! 			  args);
        args = tree_cons (NULL_TREE, t, args);
      }
    for (; ctors; ctors = OVL_NEXT (ctors))
--- 2377,2387 ----
        t = build_int_2 (0, 0);
        TREE_TYPE (t) = build_pointer_type (totype);
        args = build_tree_list (NULL_TREE, expr);
!       if (DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
! 	  || DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)))
! 	/* We should never try to call the abstract or base constructor
! 	   from here.  */
! 	abort ();
        args = tree_cons (NULL_TREE, t, args);
      }
    for (; ctors; ctors = OVL_NEXT (ctors))
*************** convert_like_real (convs, expr, fn, argn
*** 3735,3742 ****
  	    TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (convfn));
  
  	    args = build_tree_list (NULL_TREE, expr);
! 	    if (DECL_HAS_IN_CHARGE_PARM_P (convfn))
! 	      args = tree_cons (NULL_TREE, integer_one_node, args);
  	    args = tree_cons (NULL_TREE, t, args);
  	  }
  	else
--- 3731,3741 ----
  	    TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (convfn));
  
  	    args = build_tree_list (NULL_TREE, expr);
! 	    if (DECL_HAS_IN_CHARGE_PARM_P (convfn)
! 		|| DECL_HAS_VTT_PARM_P (convfn))
! 	      /* We should never try to call the abstract or base constructor
! 		 from here.  */
! 	      abort ();
  	    args = tree_cons (NULL_TREE, t, args);
  	  }
  	else
*************** build_over_call (cand, args, flags)
*** 4065,4070 ****
--- 4064,4072 ----
        arg = TREE_CHAIN (arg);
        parm = TREE_CHAIN (parm);
        if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+ 	/* We should never try to call the abstract constructor.  */
+ 	abort ();
+       if (DECL_HAS_VTT_PARM_P (fn))
  	{
  	  converted_args = tree_cons
  	    (NULL_TREE, TREE_VALUE (arg), converted_args);
*************** build_over_call (cand, args, flags)
*** 4169,4177 ****
  	   && DECL_COPY_CONSTRUCTOR_P (fn))
      {
        tree targ;
!       arg = TREE_CHAIN (converted_args);
!       if (DECL_HAS_IN_CHARGE_PARM_P (fn))
! 	arg = TREE_CHAIN (arg);
        arg = TREE_VALUE (arg);
  
        /* Pull out the real argument, disregarding const-correctness.  */
--- 4171,4177 ----
  	   && DECL_COPY_CONSTRUCTOR_P (fn))
      {
        tree targ;
!       arg = skip_artificial_parms_for (fn, converted_args);
        arg = TREE_VALUE (arg);
  
        /* Pull out the real argument, disregarding const-correctness.  */
*************** build_new_method_call (instance, name, a
*** 4439,4445 ****
  	  vtt = build (COND_EXPR, TREE_TYPE (vtt),
  		       build (EQ_EXPR, boolean_type_node,
  			      current_in_charge_parm, integer_zero_node),
! 		       DECL_VTT_PARM (current_function_decl),
  		       vtt);
  	  if (TREE_VIA_VIRTUAL (basebinfo))
  	    basebinfo = binfo_for_vbase (basetype, current_class_type);
--- 4439,4445 ----
  	  vtt = build (COND_EXPR, TREE_TYPE (vtt),
  		       build (EQ_EXPR, boolean_type_node,
  			      current_in_charge_parm, integer_zero_node),
! 		       current_vtt_parm,
  		       vtt);
  	  if (TREE_VIA_VIRTUAL (basebinfo))
  	    basebinfo = binfo_for_vbase (basetype, current_class_type);
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.360
diff -c -p -r1.360 class.c
*** class.c	2001/02/14 10:49:26	1.360
--- class.c	2001/02/18 14:40:11
*************** static void delete_duplicate_fields PARA
*** 119,125 ****
  static void finish_struct_bits PARAMS ((tree));
  static int alter_access PARAMS ((tree, tree, tree));
  static void handle_using_decl PARAMS ((tree, tree));
- static int same_signature_p PARAMS ((tree, tree));
  static int strictly_overrides PARAMS ((tree, tree));
  static void mark_overriders PARAMS ((tree, tree));
  static void check_for_override PARAMS ((tree, tree));
--- 119,124 ----
*************** layout_vtable_decl (binfo, n)
*** 2460,2466 ****
  /* True iff FNDECL and BASE_FNDECL (both non-static member functions)
     have the same signature.  */
  
! static int
  same_signature_p (fndecl, base_fndecl)
       tree fndecl, base_fndecl;
  {
--- 2459,2465 ----
  /* True iff FNDECL and BASE_FNDECL (both non-static member functions)
     have the same signature.  */
  
! int
  same_signature_p (fndecl, base_fndecl)
       tree fndecl, base_fndecl;
  {
*************** build_clone (fn, name)
*** 4188,4195 ****
    DECL_PENDING_INLINE_P (clone) = 0;
    /* And it hasn't yet been deferred.  */
    DECL_DEFERRED_FN (clone) = 0;
-   /* There's no magic VTT parameter in the clone.  */
-   DECL_VTT_PARM (clone) = NULL_TREE;
  
    /* The base-class destructor is not virtual.  */
    if (name == base_dtor_identifier)
--- 4187,4192 ----
*************** build_clone (fn, name)
*** 4214,4223 ****
        parmtypes = TREE_CHAIN (parmtypes);
        /* Skip the in-charge parameter.  */
        parmtypes = TREE_CHAIN (parmtypes);
         /* If this is subobject constructor or destructor, add the vtt
  	 parameter.  */
-       if (DECL_NEEDS_VTT_PARM_P (clone))
- 	parmtypes = hash_tree_chain (vtt_parm_type, parmtypes);
        TREE_TYPE (clone) 
  	= build_cplus_method_type (basetype,
  				   TREE_TYPE (TREE_TYPE (clone)),
--- 4211,4222 ----
        parmtypes = TREE_CHAIN (parmtypes);
        /* Skip the in-charge parameter.  */
        parmtypes = TREE_CHAIN (parmtypes);
+       /* And the VTT parm, in a complete [cd]tor.  */
+       if (DECL_HAS_VTT_PARM_P (fn)
+ 	  && ! DECL_NEEDS_VTT_PARM_P (clone))
+ 	parmtypes = TREE_CHAIN (parmtypes);
         /* If this is subobject constructor or destructor, add the vtt
  	 parameter.  */
        TREE_TYPE (clone) 
  	= build_cplus_method_type (basetype,
  				   TREE_TYPE (TREE_TYPE (clone)),
*************** build_clone (fn, name)
*** 4227,4234 ****
  						     exceptions);
      }
  
!   /* Copy the function parameters.  But, DECL_ARGUMENTS aren't
!      function parameters; instead, those are the template parameters.  */
    if (TREE_CODE (clone) != TEMPLATE_DECL)
      {
        DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
--- 4226,4233 ----
  						     exceptions);
      }
  
!   /* Copy the function parameters.  But, DECL_ARGUMENTS on a TEMPLATE_DECL
!      aren't function parameters; those are the template parameters.  */
    if (TREE_CODE (clone) != TEMPLATE_DECL)
      {
        DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
*************** build_clone (fn, name)
*** 4239,4254 ****
  	    = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
  	  DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
  	}
! 
!       /* Add the VTT parameter.  */
!       if (DECL_NEEDS_VTT_PARM_P (clone))
  	{
! 	  tree parm;
! 
! 	  parm = build_artificial_parm (vtt_parm_identifier,
! 					vtt_parm_type);
! 	  TREE_CHAIN (parm) = TREE_CHAIN (DECL_ARGUMENTS (clone));
! 	  TREE_CHAIN (DECL_ARGUMENTS (clone)) = parm;
  	}
  
        for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
--- 4238,4254 ----
  	    = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
  	  DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
  	}
!       /* And the VTT parm, in a complete [cd]tor.  */
!       if (DECL_HAS_VTT_PARM_P (fn))
  	{
! 	  if (DECL_NEEDS_VTT_PARM_P (clone))
! 	    DECL_HAS_VTT_PARM_P (clone) = 1;
! 	  else
! 	    {
! 	      TREE_CHAIN (DECL_ARGUMENTS (clone))
! 		= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
! 	      DECL_HAS_VTT_PARM_P (clone) = 0;
! 	    }
  	}
  
        for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.577
diff -c -p -r1.577 cp-tree.h
*** cp-tree.h	2001/02/17 00:12:43	1.577
--- cp-tree.h	2001/02/18 14:40:14
*************** struct cp_language_function
*** 881,886 ****
--- 881,887 ----
    tree x_current_class_ref;
    tree x_eh_spec_try_block;
    tree x_in_charge_parm;
+   tree x_vtt_parm;
  
    tree *x_vcalls_possible_p;
  
*************** struct cp_language_function
*** 927,936 ****
  #define current_eh_spec_try_block cp_function_chain->x_eh_spec_try_block
  
  /* The `__in_chrg' parameter for the current function.  Only used for
!    destructors.  */
  
  #define current_in_charge_parm cp_function_chain->x_in_charge_parm
  
  /* In destructors, this is a pointer to a condition in an
     if-statement.  If the pointed-to value is boolean_true_node, then
     there may be virtual function calls in this destructor.  */
--- 928,942 ----
  #define current_eh_spec_try_block cp_function_chain->x_eh_spec_try_block
  
  /* The `__in_chrg' parameter for the current function.  Only used for
!    constructors and destructors.  */
  
  #define current_in_charge_parm cp_function_chain->x_in_charge_parm
  
+ /* The `__vtt_parm' parameter for the current function.  Only used for
+    constructors and destructors.  */
+ 
+ #define current_vtt_parm cp_function_chain->x_vtt_parm
+ 
  /* In destructors, this is a pointer to a condition in an
     if-statement.  If the pointed-to value is boolean_true_node, then
     there may be virtual function calls in this destructor.  */
*************** enum languages { lang_c, lang_cplusplus,
*** 1248,1255 ****
     : !DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0))				\
     ? (ENTRY)								\
     : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)))
  
- #define FUNCTION_ARG_CHAIN(NODE) (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
  #define PROMOTES_TO_AGGR_TYPE(NODE,CODE)	\
    (((CODE) == TREE_CODE (NODE)			\
         && IS_AGGR_TYPE (TREE_TYPE (NODE)))	\
--- 1254,1272 ----
     : !DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0))				\
     ? (ENTRY)								\
     : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)))
+ 
+ #define FUNCTION_ARG_CHAIN(NODE) \
+   (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
+ 
+ /* Given a FUNCTION_DECL, returns the first TREE_LIST out of TYPE_ARG_TYPES
+    which refers to a user-written parameter.  */
+ #define FUNCTION_FIRST_USER_PARMTYPE(NODE) \
+   (skip_artificial_parms_for (NODE, TYPE_ARG_TYPES (TREE_TYPE (NODE))))
+ 
+ /* Similarly, but for DECL_ARGUMENTS.  */
+ #define FUNCTION_FIRST_USER_PARM(NODE) \
+   (skip_artificial_parms_for (NODE, DECL_ARGUMENTS (NODE)))
  
  #define PROMOTES_TO_AGGR_TYPE(NODE,CODE)	\
    (((CODE) == TREE_CODE (NODE)			\
         && IS_AGGR_TYPE (TREE_TYPE (NODE)))	\
*************** struct lang_decl_flags
*** 1825,1831 ****
    unsigned assignment_operator_p : 1;
    unsigned anticipated_p : 1;
    unsigned generate_with_vtable_p : 1;
!   unsigned dummy : 1;
  
    union {
      /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
--- 1842,1848 ----
    unsigned assignment_operator_p : 1;
    unsigned anticipated_p : 1;
    unsigned generate_with_vtable_p : 1;
!   unsigned has_vtt_parm_p : 1;
  
    union {
      /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
*************** struct lang_decl
*** 1876,1884 ****
      /* In an overloaded operator, this is the value of
         DECL_OVERLOADED_OPERATOR_P.  */
      enum tree_code operator_code;
-     /* In a maybe-in-charge constructor or destructor, this is
-        DECL_VTT_PARM.  */
-     tree vtt_parm;
    } u2;
  };
  
--- 1893,1898 ----
*************** struct lang_decl
*** 1978,1987 ****
  #define DECL_CLONED_FUNCTION(NODE) \
    (DECL_LANG_SPECIFIC (NODE)->cloned_function)
  
! /* In a maybe-in-charge constructor or destructor, this is the VTT
!    parameter.  It's not actually on the DECL_ARGUMENTS list.  */
! #define DECL_VTT_PARM(NODE) \
!   (DECL_LANG_SPECIFIC (NODE)->u2.vtt_parm)
  
  /* Non-zero if NODE is a FUNCTION_DECL for which a VTT parameter is
     required.  */
--- 1992,2000 ----
  #define DECL_CLONED_FUNCTION(NODE) \
    (DECL_LANG_SPECIFIC (NODE)->cloned_function)
  
! /* Non-zero if the VTT parm has been added to NODE.  */
! #define DECL_HAS_VTT_PARM_P(NODE) \
!   (DECL_LANG_SPECIFIC (NODE)->decl_flags.has_vtt_parm_p)
  
  /* Non-zero if NODE is a FUNCTION_DECL for which a VTT parameter is
     required.  */
*************** extern void pop_lang_context			PARAMS ((
*** 3723,3728 ****
--- 3736,3742 ----
  extern tree instantiate_type			PARAMS ((tree, tree, enum instantiate_type_flags));
  extern void print_class_statistics		PARAMS ((void));
  extern void build_self_reference		PARAMS ((void));
+ extern int same_signature_p			PARAMS ((tree, tree));
  extern void warn_hidden				PARAMS ((tree));
  extern tree get_enclosing_class			PARAMS ((tree));
  int is_base_of_enclosing_class			PARAMS ((tree, tree));
*************** extern tree make_thunk				PARAMS ((tree,
*** 4085,4090 ****
--- 4099,4105 ----
  extern void use_thunk				PARAMS ((tree, int));
  extern void synthesize_method			PARAMS ((tree));
  extern tree implicitly_declare_fn               PARAMS ((special_function_kind, tree, int));
+ extern tree skip_artificial_parms_for		PARAMS ((tree, tree));
  
  /* In optimize.c */
  extern void optimize_function                   PARAMS ((tree));
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.750
diff -c -p -r1.750 decl.c
*** decl.c	2001/02/18 00:00:26	1.750
--- decl.c	2001/02/18 14:40:22
*************** duplicate_decls (newdecl, olddecl)
*** 3399,3405 ****
        DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
        DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
        DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
!       DECL_LANG_SPECIFIC (newdecl)->u2 = DECL_LANG_SPECIFIC (olddecl)->u2;
        new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
  
        /* Optionally warn about more than one declaration for the same
--- 3399,3407 ----
        DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
        DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
        DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
!       if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
! 	SET_OVERLOADED_OPERATOR_CODE
! 	  (newdecl, DECL_OVERLOADED_OPERATOR_P (olddecl));
        new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
  
        /* Optionally warn about more than one declaration for the same
*************** friend declaration requires class-key, i
*** 11300,11314 ****
  		/* The constructor can be called with exactly one
  		   parameter if there is at least one parameter, and
  		   any subsequent parameters have default arguments.
! 		   We don't look at the first parameter, which is
! 		   really just the `this' parameter for the new
! 		   object.  */
! 		tree arg_types =
! 		  TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
! 
! 		/* Skip the `in_chrg' argument too, if present.  */
! 		if (DECL_HAS_IN_CHARGE_PARM_P (decl))
! 		  arg_types = TREE_CHAIN (arg_types);
  
  		if (arg_types == void_list_node
  		    || (arg_types
--- 11302,11309 ----
  		/* The constructor can be called with exactly one
  		   parameter if there is at least one parameter, and
  		   any subsequent parameters have default arguments.
! 		   Ignore any compiler-added parms.  */
! 		tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl);
  
  		if (arg_types == void_list_node
  		    || (arg_types
*************** copy_args_p (d)
*** 11923,11931 ****
    if (!DECL_FUNCTION_MEMBER_P (d))
      return 0;
  
!   t = FUNCTION_ARG_CHAIN (d);
!   if (DECL_CONSTRUCTOR_P (d) && DECL_HAS_IN_CHARGE_PARM_P (d))
!     t = TREE_CHAIN (t);
    if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
        && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
  	  == DECL_CONTEXT (d))
--- 11918,11924 ----
    if (!DECL_FUNCTION_MEMBER_P (d))
      return 0;
  
!   t = FUNCTION_FIRST_USER_PARMTYPE (d);
    if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
        && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
  	  == DECL_CONTEXT (d))
*************** int
*** 11948,11969 ****
  grok_ctor_properties (ctype, decl)
       tree ctype, decl;
  {
!   tree parmtypes = FUNCTION_ARG_CHAIN (decl);
    tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
  
-   /* When a type has virtual baseclasses, a magical first int argument is
-      added to any ctor so we can tell if the class has been initialized
-      yet.  This could screw things up in this function, so we deliberately
-      ignore the leading int if we're in that situation.  */
-   if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-     {
-       my_friendly_assert (parmtypes
- 			  && TREE_VALUE (parmtypes) == integer_type_node,
- 			  980529);
-       parmtypes = TREE_CHAIN (parmtypes);
-       parmtype = TREE_VALUE (parmtypes);
-     }
- 
    /* [class.copy]
  
       A non-template constructor for class X is a copy constructor if
--- 11941,11949 ----
  grok_ctor_properties (ctype, decl)
       tree ctype, decl;
  {
!   tree parmtypes = FUNCTION_FIRST_USER_PARMTYPE (decl);
    tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
  
    /* [class.copy]
  
       A non-template constructor for class X is a copy constructor if
*************** start_function (declspecs, declarator, a
*** 13473,13480 ****
  
        /* Constructors and destructors need to know whether they're "in
  	 charge" of initializing virtual base classes.  */
        if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
! 	current_in_charge_parm = TREE_CHAIN (t);
      }
  
    if (DECL_INTERFACE_KNOWN (decl1))
--- 13453,13470 ----
  
        /* Constructors and destructors need to know whether they're "in
  	 charge" of initializing virtual base classes.  */
+       t = TREE_CHAIN (t);
        if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
! 	{
! 	  current_in_charge_parm = t;
! 	  t = TREE_CHAIN (t);
! 	}
!       if (DECL_HAS_VTT_PARM_P (decl1))
! 	{
! 	  if (DECL_NAME (t) != vtt_parm_identifier)
! 	    abort ();
! 	  current_vtt_parm = t;
! 	}
      }
  
    if (DECL_INTERFACE_KNOWN (decl1))
*************** lang_mark_tree (t)
*** 14425,14432 ****
  	      ggc_mark_tree (ld->befriending_classes);
  	      ggc_mark_tree (ld->context);
  	      ggc_mark_tree (ld->cloned_function);
- 	      if (!DECL_OVERLOADED_OPERATOR_P (t))
- 		ggc_mark_tree (ld->u2.vtt_parm);
  	      if (TREE_CODE (t) == TYPE_DECL)
  		ggc_mark_tree (ld->u.sorted_fields);
  	      else if (TREE_CODE (t) == FUNCTION_DECL
--- 14415,14420 ----
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.440
diff -c -p -r1.440 decl2.c
*** decl2.c	2001/02/18 00:00:27	1.440
--- decl2.c	2001/02/18 14:40:26
*************** build_artificial_parm (name, type)
*** 932,939 ****
  
     This function adds the "in-charge" flag to member function FN if
     appropriate.  It is called from grokclassfn and tsubst.
!    FN must be either a constructor or destructor.  */
  
  void
  maybe_retrofit_in_chrg (fn)
       tree fn;
--- 932,942 ----
  
     This function adds the "in-charge" flag to member function FN if
     appropriate.  It is called from grokclassfn and tsubst.
!    FN must be either a constructor or destructor.
  
+    The in-charge flag follows the 'this' parameter, and is followed by the
+    VTT parm (if any), then the user-written parms.  */
+ 
  void
  maybe_retrofit_in_chrg (fn)
       tree fn;
*************** maybe_retrofit_in_chrg (fn)
*** 955,971 ****
        && !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
      return;
  
-   /* First add it to DECL_ARGUMENTS...  */
-   parm = build_artificial_parm (in_charge_identifier, integer_type_node);
-   TREE_READONLY (parm) = 1;
-   parms = DECL_ARGUMENTS (fn);
-   TREE_CHAIN (parm) = TREE_CHAIN (parms);
-   TREE_CHAIN (parms) = parm;
- 
-   /* ...and then to TYPE_ARG_TYPES.  */
    arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
    basetype = TREE_TYPE (TREE_VALUE (arg_types));
!   arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types));
    fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),
  				    arg_types);
    if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
--- 958,995 ----
        && !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
      return;
  
    arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
    basetype = TREE_TYPE (TREE_VALUE (arg_types));
!   arg_types = TREE_CHAIN (arg_types);
! 
!   parms = TREE_CHAIN (DECL_ARGUMENTS (fn));
! 
!   /* If this is a subobject constructor or destructor, our caller will
!      pass us a pointer to our VTT.  */
!   if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
!     {
!       parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type);
! 
!       /* First add it to DECL_ARGUMENTS between 'this' and the real args...  */
!       TREE_CHAIN (parm) = parms;
!       parms = parm;
! 
!       /* ...and then to TYPE_ARG_TYPES.  */
!       arg_types = hash_tree_chain (vtt_parm_type, arg_types);
! 
!       DECL_HAS_VTT_PARM_P (fn) = 1;
!     }
! 
!   /* Then add the in-charge parm (before the VTT parm).  */
!   parm = build_artificial_parm (in_charge_identifier, integer_type_node);
!   TREE_CHAIN (parm) = parms;
!   parms = parm;
!   arg_types = hash_tree_chain (integer_type_node, arg_types);
! 
!   /* Insert our new parameter(s) into the list.  */
!   TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms;
! 
!   /* And rebuild the function type.  */
    fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),
  				    arg_types);
    if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
*************** maybe_retrofit_in_chrg (fn)
*** 975,989 ****
  
    /* Now we've got the in-charge parameter.  */
    DECL_HAS_IN_CHARGE_PARM_P (fn) = 1;
- 
-   /* If this is a subobject constructor or destructor, our caller will
-      pass us a pointer to our VTT.  */
-   if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
-     {
-       DECL_VTT_PARM (fn) = build_artificial_parm (vtt_parm_identifier, 
- 						  vtt_parm_type);
-       DECL_CONTEXT (DECL_VTT_PARM (fn)) = fn;
-     }
  }
  
  /* Classes overload their constituent function names automatically.
--- 999,1004 ----
Index: error.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/error.c,v
retrieving revision 1.149
diff -c -p -r1.149 error.c
*** error.c	2001/02/12 09:58:18	1.149
--- error.c	2001/02/18 14:40:27
*************** dump_function_decl (t, flags)
*** 1203,1209 ****
      }
  
    fntype = TREE_TYPE (t);
!   parmtypes = TYPE_ARG_TYPES (fntype);
  
    if (DECL_CLASS_SCOPE_P (t))
      cname = DECL_CONTEXT (t);
--- 1203,1209 ----
      }
  
    fntype = TREE_TYPE (t);
!   parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
  
    if (DECL_CLASS_SCOPE_P (t))
      cname = DECL_CONTEXT (t);
*************** dump_function_decl (t, flags)
*** 1241,1254 ****
  
    if (flags & TFF_DECL_SPECIFIERS) 
      {
-       if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
- 	/* Skip "this" parameter.  */
- 	parmtypes = TREE_CHAIN (parmtypes);
- 
-       /* Skip past the "in_charge" parameter.  */
-       if (DECL_HAS_IN_CHARGE_PARM_P (t))
- 	parmtypes = TREE_CHAIN (parmtypes);
- 
        dump_parameters (parmtypes, flags);
  
        if (show_return)
--- 1241,1246 ----
Index: init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.236
diff -c -p -r1.236 init.c
*** init.c	2001/02/18 00:00:27	1.236
--- init.c	2001/02/18 14:40:29
*************** expand_virtual_init (binfo, decl)
*** 860,866 ****
        tree vtt_parm;
  
        /* Compute the value to use, when there's a VTT.  */
!       vtt_parm = DECL_VTT_PARM (current_function_decl);
        vtbl2 = build (PLUS_EXPR, 
  		     TREE_TYPE (vtt_parm), 
  		     vtt_parm,
--- 860,866 ----
        tree vtt_parm;
  
        /* Compute the value to use, when there's a VTT.  */
!       vtt_parm = current_vtt_parm;
        vtbl2 = build (PLUS_EXPR, 
  		     TREE_TYPE (vtt_parm), 
  		     vtt_parm,
Index: method.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/method.c,v
retrieving revision 1.191
diff -c -p -r1.191 method.c
*** method.c	2001/02/14 10:57:59	1.191
--- method.c	2001/02/18 14:40:30
*************** make_thunk (function, delta, vcall_index
*** 364,370 ****
        DECL_CONSTRUCTOR_P (thunk) = 0;
        DECL_EXTERNAL (thunk) = 1;
        DECL_ARTIFICIAL (thunk) = 1;
-       DECL_VTT_PARM (thunk) = NULL_TREE;
        /* Even if this thunk is a member of a local class, we don't
  	 need a static chain.  */
        DECL_NO_STATIC_CHAIN (thunk) = 1;
--- 364,369 ----
*************** static void
*** 536,546 ****
  do_build_copy_constructor (fndecl)
       tree fndecl;
  {
!   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
    tree t;
  
-   if (DECL_HAS_IN_CHARGE_PARM_P (fndecl))
-     parm = TREE_CHAIN (parm);
    parm = convert_from_reference (parm);
  
    if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)
--- 535,543 ----
  do_build_copy_constructor (fndecl)
       tree fndecl;
  {
!   tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
    tree t;
  
    parm = convert_from_reference (parm);
  
    if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)
*************** synthesize_method (fndecl)
*** 760,768 ****
      setup_vtbl_ptr (NULL_TREE, NULL_TREE);
    else
      {
!       tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);
!       if (DECL_HAS_IN_CHARGE_PARM_P (fndecl))
! 	arg_chain = TREE_CHAIN (arg_chain);
        if (arg_chain != void_list_node)
  	do_build_copy_constructor (fndecl);
        else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
--- 757,763 ----
      setup_vtbl_ptr (NULL_TREE, NULL_TREE);
    else
      {
!       tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
        if (arg_chain != void_list_node)
  	do_build_copy_constructor (fndecl);
        else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
*************** implicitly_declare_fn (kind, type, const
*** 1040,1043 ****
--- 1035,1057 ----
    defer_fn (fn);
    
    return fn;
+ }
+ 
+ /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
+    as there are artificial parms in FN.  */
+ 
+ tree
+ skip_artificial_parms_for (fn, list)
+      tree fn, list;
+ {
+   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+     list = TREE_CHAIN (list);
+   else
+     return list;
+ 
+   if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+     list = TREE_CHAIN (list);
+   if (DECL_HAS_VTT_PARM_P (fn))
+     list = TREE_CHAIN (list);
+   return list;
  }
Index: optimize.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/optimize.c,v
retrieving revision 1.53
diff -c -p -r1.53 optimize.c
*** optimize.c	2001/02/17 00:12:44	1.53
--- optimize.c	2001/02/18 14:40:30
*************** maybe_clone_body (fn)
*** 981,1002 ****
  	      splay_tree_insert (id.decl_map,
  				 (splay_tree_key) parm,
  				 (splay_tree_value) in_charge);
! 
  	      /* For a subobject constructor or destructor, the next
  		 argument is the VTT parameter.  Remap the VTT_PARM
  		 from the CLONE to this parameter.  */
! 	      if (DECL_NEEDS_VTT_PARM_P (clone))
  		{
  		  splay_tree_insert (id.decl_map,
! 				     (splay_tree_key) DECL_VTT_PARM (fn),
  				     (splay_tree_value) clone_parm);
  		  clone_parm = TREE_CHAIN (clone_parm);
  		}
  	      /* Otherwise, map the VTT parameter to `NULL'.  */
! 	      else if (DECL_VTT_PARM (fn))
  		{
  		  splay_tree_insert (id.decl_map,
! 				     (splay_tree_key) DECL_VTT_PARM (fn),
  				     (splay_tree_value) null_pointer_node);
  		}
  	    }
--- 981,1005 ----
  	      splay_tree_insert (id.decl_map,
  				 (splay_tree_key) parm,
  				 (splay_tree_value) in_charge);
! 	    }
! 	  else if (DECL_ARTIFICIAL (parm)
! 		   && DECL_NAME (parm) == vtt_parm_identifier)
! 	    {
  	      /* For a subobject constructor or destructor, the next
  		 argument is the VTT parameter.  Remap the VTT_PARM
  		 from the CLONE to this parameter.  */
! 	      if (DECL_HAS_VTT_PARM_P (clone))
  		{
  		  splay_tree_insert (id.decl_map,
! 				     (splay_tree_key) parm,
  				     (splay_tree_value) clone_parm);
  		  clone_parm = TREE_CHAIN (clone_parm);
  		}
  	      /* Otherwise, map the VTT parameter to `NULL'.  */
! 	      else
  		{
  		  splay_tree_insert (id.decl_map,
! 				     (splay_tree_key) parm,
  				     (splay_tree_value) null_pointer_node);
  		}
  	    }
Index: pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.519
diff -c -p -r1.519 pt.c
*** pt.c	2001/02/16 07:57:50	1.519
--- pt.c	2001/02/18 14:40:36
*************** copy_default_args_to_explicit_spec (decl
*** 1208,1213 ****
--- 1208,1214 ----
    tree t;
    tree object_type = NULL_TREE;
    tree in_charge = NULL_TREE;
+   tree vtt = NULL_TREE;
  
    /* See if there's anything we need to do.  */
    tmpl = DECL_TI_TEMPLATE (decl);
*************** copy_default_args_to_explicit_spec (decl
*** 1236,1241 ****
--- 1237,1247 ----
            in_charge = spec_types;
  	  spec_types = TREE_CHAIN (spec_types);
  	}
+       if (DECL_HAS_VTT_PARM_P (decl))
+ 	{
+ 	  vtt = spec_types;
+ 	  spec_types = TREE_CHAIN (spec_types);
+ 	}
      }
  
    /* Compute the merged default arguments.  */
*************** copy_default_args_to_explicit_spec (decl
*** 1245,1250 ****
--- 1251,1261 ----
    /* Compute the new FUNCTION_TYPE.  */
    if (object_type)
      {
+       if (vtt)
+         new_spec_types = hash_tree_cons (TREE_PURPOSE (vtt),
+ 			  	         TREE_VALUE (vtt),
+ 				         new_spec_types);
+ 
        if (in_charge)
          /* Put the in-charge parameter back.  */
          new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
Index: search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.203
diff -c -p -r1.203 search.c
*** search.c	2001/02/14 10:49:27	1.203
--- search.c	2001/02/18 14:40:38
*************** look_for_overrides_r (type, fndecl)
*** 2046,2067 ****
                    return 1;
                  }
              }
!           else
              {
!               if (/* The first parameter is the `this' parameter,
! 	             which has POINTER_TYPE, and we can therefore
! 	             safely use TYPE_QUALS, rather than
! 		     CP_TYPE_QUALS.  */
! 	          (TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
! 	           == TYPE_QUALS (thistype))
! 	          && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
!                 {
!                   /* It's definitely virtual, even if not explicitly set.  */
!                   DECL_VIRTUAL_P (fndecl) = 1;
! 	          check_final_overrider (fndecl, fn);
! 	      
! 	          return 1;
! 	        }
  	    }
  	}
      }
--- 2046,2058 ----
                    return 1;
                  }
              }
!           else if (same_signature_p (fndecl, fn))
              {
! 	      /* It's definitely virtual, even if not explicitly set.  */
! 	      DECL_VIRTUAL_P (fndecl) = 1;
! 	      check_final_overrider (fndecl, fn);
! 
! 	      return 1;
  	    }
  	}
      }

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