(C++) patch for conversion function overloading

Jason Merrill jason@cygnus.com
Wed Oct 28 04:03:00 GMT 1998


Applied.  Fixes g++.robertl/eb70.C.

! 	  /* [over.match.funcs] For conversion functions, the function is
! 	     considered to be a member of the class of the implicit object
! 	     argument for the purpose of defining the type of the implicit
! 	     object parameter.

1998-10-28  Jason Merrill  <jason@yorick.cygnus.com>

	* call.c (add_function_candidate): Treat conversion functions
	as coming from the argument's class.
	* cp-tree.h (DECL_CONV_FN_P): New fn.
	(DECL_DESTRUCTOR_P): Also check DECL_LANGUAGE.
	* class.c (add_method): Use DECL_CONV_FN_P.
	* decl2.c (check_classfn): Likewise.
	* error.c (dump_function_name): Likewise.
	(dump_function_decl): Likewise.
	* pt.c (fn_type_unification): Likewise.
	* search.c (add_conversions): Likewise.

Index: call.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/call.c,v
retrieving revision 1.116
diff -c -p -r1.116 call.c
*** call.c	1998/10/27 22:33:29	1.116
--- call.c	1998/10/28 09:52:03
*************** add_function_candidate (candidates, fn, 
*** 1150,1157 ****
  
        if (parmnode == void_list_node)
  	break;
!       else if (parmnode)
! 	t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags);
        else
  	{
  	  t = build1 (IDENTITY_CONV, argtype, arg);
--- 1150,1177 ----
  
        if (parmnode == void_list_node)
  	break;
! 
!       if (parmnode)
! 	{
! 	  tree parmtype = TREE_VALUE (parmnode);
! 
! 	  /* [over.match.funcs] For conversion functions, the function is
! 	     considered to be a member of the class of the implicit object
! 	     argument for the purpose of defining the type of the implicit
! 	     object parameter.
! 
! 	     Since build_over_call ignores the ICS for the `this' parameter,
! 	     we can just change the parm type.  */
! 	  if (DECL_CONV_FN_P (fn) && i == 0)
! 	    {
! 	      parmtype
! 		= build_qualified_type (TREE_TYPE (argtype),
! 					TYPE_QUALS (TREE_TYPE (parmtype)));
! 	      parmtype = build_pointer_type (parmtype);
! 	    }
! 
! 	  t = implicit_conversion (parmtype, argtype, arg, flags);
! 	}
        else
  	{
  	  t = build1 (IDENTITY_CONV, argtype, arg);
Index: class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.100
diff -c -p -r1.100 class.c
*** class.c	1998/10/27 22:33:31	1.100
--- class.c	1998/10/28 09:52:03
*************** add_method (type, fields, method)
*** 1229,1235 ****
  		}
  	    }
  
! 	  if (IDENTIFIER_TYPENAME_P (DECL_NAME (method)))
  	    {
  	      /* Type conversion operators have to come before
  		 ordinary methods; add_conversions depends on this to
--- 1229,1235 ----
  		}
  	    }
  
! 	  if (DECL_CONV_FN_P (method))
  	    {
  	      /* Type conversion operators have to come before
  		 ordinary methods; add_conversions depends on this to
*************** add_method (type, fields, method)
*** 1240,1254 ****
  	      for (i = 2; i < len; ++i)
  		{
  		  tree fn = TREE_VEC_ELT (method_vec, i);
- 		  tree name;
  
  		  if (!fn)
  		    /* There are no more entries in the vector, so we
  		       can insert the new conversion operator here.  */
  		    break;
  		  
! 		  name = DECL_NAME (OVL_CURRENT (fn));
! 		  if (!IDENTIFIER_TYPENAME_P (name))
  		    /* We can insert the new function right at the Ith
  		       position.  */
  		    break;
--- 1240,1252 ----
  	      for (i = 2; i < len; ++i)
  		{
  		  tree fn = TREE_VEC_ELT (method_vec, i);
  
  		  if (!fn)
  		    /* There are no more entries in the vector, so we
  		       can insert the new conversion operator here.  */
  		    break;
  		  
! 		  if (! DECL_CONV_FN_P (OVL_CURRENT (fn)))
  		    /* We can insert the new function right at the Ith
  		       position.  */
  		    break;
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.162
diff -c -p -r1.162 cp-tree.h
*** cp-tree.h	1998/10/27 22:33:32	1.162
--- cp-tree.h	1998/10/28 09:52:03
*************** struct lang_decl
*** 1128,1134 ****
  
  /* For FUNCTION_DECLs: nonzero means that this function is a constructor.  */
  #define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr)
! #define DECL_DESTRUCTOR_P(NODE) (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME(NODE)))
  
  /* For FUNCTION_DECLs: nonzero means that this function is a constructor
     for an object with virtual baseclasses.  */
--- 1128,1142 ----
  
  /* For FUNCTION_DECLs: nonzero means that this function is a constructor.  */
  #define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr)
! 
! /* There ought to be a better way to find out whether or not something is
!    a destructor.  */
! #define DECL_DESTRUCTOR_P(NODE)				\
!   (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (NODE))	\
!    && DECL_LANGUAGE (NODE) == lang_cplusplus)
! 
! #define DECL_CONV_FN_P(NODE)						     \
!   (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)) && TREE_TYPE (DECL_NAME (NODE)))
  
  /* For FUNCTION_DECLs: nonzero means that this function is a constructor
     for an object with virtual baseclasses.  */
Index: decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.149
diff -c -p -r1.149 decl2.c
*** decl2.c	1998/10/23 14:53:01	1.149
--- decl2.c	1998/10/28 09:52:03
*************** check_classfn (ctype, function)
*** 1426,1433 ****
  	      break;		/* loser */
  	    }
  	  else if (TREE_CODE (fndecl) == TEMPLATE_DECL 
! 		   && IDENTIFIER_TYPENAME_P (DECL_NAME (fndecl))
! 		   && IDENTIFIER_TYPENAME_P (fn_name))
  	    /* The method in the class is a member template
  	       conversion operator.  We are declaring another
  	       conversion operator.  It is possible that even though
--- 1426,1433 ----
  	      break;		/* loser */
  	    }
  	  else if (TREE_CODE (fndecl) == TEMPLATE_DECL 
! 		   && DECL_CONV_FN_P (fndecl)
! 		   && DECL_CONV_FN_P (function))
  	    /* The method in the class is a member template
  	       conversion operator.  We are declaring another
  	       conversion operator.  It is possible that even though
Index: error.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/error.c,v
retrieving revision 1.59
diff -c -p -r1.59 error.c
*** error.c	1998/10/26 23:48:50	1.59
--- error.c	1998/10/28 09:52:03
*************** dump_function_decl (t, v)
*** 978,986 ****
        if (DECL_STATIC_FUNCTION_P (t))
  	OB_PUTS ("static ");
      
!       if (! IDENTIFIER_TYPENAME_P (name)
  	  && ! DECL_CONSTRUCTOR_P (t)
! 	  && ! DESTRUCTOR_NAME_P (name))
  	{
  	  dump_type_prefix (TREE_TYPE (fntype), 1, 0);
  	  OB_PUTC (' ');
--- 978,986 ----
        if (DECL_STATIC_FUNCTION_P (t))
  	OB_PUTS ("static ");
      
!       if (! DECL_CONV_FN_P (t)
  	  && ! DECL_CONSTRUCTOR_P (t)
! 	  && ! DECL_DESTRUCTOR_P (t))
  	{
  	  dump_type_prefix (TREE_TYPE (fntype), 1, 0);
  	  OB_PUTC (' ');
*************** dump_function_decl (t, v)
*** 1012,1018 ****
  
    OB_PUTC (')');
  
!   if (v && ! IDENTIFIER_TYPENAME_P (name))
      dump_type_suffix (TREE_TYPE (fntype), 1, 0);
  
    if (TREE_CODE (fntype) == METHOD_TYPE)
--- 1012,1018 ----
  
    OB_PUTC (')');
  
!   if (v && ! DECL_CONV_FN_P (t))
      dump_type_suffix (TREE_TYPE (fntype), 1, 0);
  
    if (TREE_CODE (fntype) == METHOD_TYPE)
*************** dump_function_name (t)
*** 1036,1050 ****
  {
    tree name = DECL_NAME (t);
  
!   /* There ought to be a better way to find out whether or not something is
!      a destructor.  */
!   if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t))
!       && DECL_LANGUAGE (t) == lang_cplusplus)
      {
        OB_PUTC ('~');
        dump_decl (name, 0);
      }
!   else if (IDENTIFIER_TYPENAME_P (name))
      {
        /* This cannot use the hack that the operator's return
  	 type is stashed off of its name because it may be
--- 1036,1047 ----
  {
    tree name = DECL_NAME (t);
  
!   if (DECL_DESTRUCTOR_P (t))
      {
        OB_PUTC ('~');
        dump_decl (name, 0);
      }
!   else if (DECL_CONV_FN_P (t))
      {
        /* This cannot use the hack that the operator's return
  	 type is stashed off of its name because it may be
Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.221
diff -c -p -r1.221 pt.c
*** pt.c	1998/10/27 22:33:37	1.221
--- pt.c	1998/10/28 09:52:04
*************** fn_type_unification (fn, explicit_targs,
*** 6565,6571 ****
  
    parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
  
!   if (IDENTIFIER_TYPENAME_P (DECL_NAME (fn))) 
      {
        /* This is a template conversion operator.  Use the return types
           as well as the argument types.  */
--- 6565,6571 ----
  
    parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
  
!   if (DECL_CONV_FN_P (fn))
      {
        /* This is a template conversion operator.  Use the return types
           as well as the argument types.  */
Index: search.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/search.c,v
retrieving revision 1.62
diff -c -p -r1.62 search.c
*** search.c	1998/10/26 23:48:56	1.62
--- search.c	1998/10/28 09:52:04
*************** add_conversions (binfo)
*** 3295,3302 ****
      {
        tree tmp = TREE_VEC_ELT (method_vec, i);
  
!       if (!tmp
! 	  || !IDENTIFIER_TYPENAME_P (DECL_NAME (OVL_CURRENT (tmp))))
  	break;
        conversions = scratch_tree_cons (binfo, tmp, conversions);
      }
--- 3295,3301 ----
      {
        tree tmp = TREE_VEC_ELT (method_vec, i);
  
!       if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp)))
  	break;
        conversions = scratch_tree_cons (binfo, tmp, conversions);
      }



More information about the Gcc-patches mailing list