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]

C++ PATCH: Minor cleanups


We've committed to fixing the internal pointer-to-data-member
representation for a customer.  The problem here is that we use a
POINTER_TYPE around an OFFSET_TYPE, and the back end thinks that's
really a POINTER_TYPE, which causes problems on HP-UX.

Here's a first step towards fixing the problem -- using the macros we
have to avoid being quite so representation-dependent in a few places.
While in this code, I got rid of a couple of uses of cp_convert; that
function -- and much of the rest of cvt.c -- really needs to die.

Tested on i686-pc-linux-gnu, applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-07-03  Mark Mitchell  <mark@codesourcery.com>

	* call.c (build_scoped_method_call): Use convert_to_void.
	(build_method_call): Likewise.
	* class.c (check_field_decls): Remove dead code.
	* cvt.c (convert_from_reference): Remove OFFSET_TYPE handling.
	* decl2.c (grok_array_decl): Remove dead code.
	(arg_assoc_type): Avoid relying on POINTER_TYPE over OFFSET_TYPE
	as pointer-to-member representation.
	* init.c (build_offset_ref): Tidy.
	(build_vec_delete_1): Use convert_to_void.
	* mangle.c (write_type): Avoid relying on POINTER_TYPE over OFFSET_TYPE
	as pointer-to-member representation.

Index: call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.397
diff -c -5 -p -r1.397 call.c
*** call.c	2 Jul 2003 00:12:09 -0000	1.397
--- call.c	3 Jul 2003 17:13:26 -0000
*************** build_scoped_method_call (tree exp, tree
*** 261,271 ****
  	{
  	  if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype))
  	    error ("type of `%E' does not match destructor type `%T' (type was `%T')",
  		      exp, basetype, type);
  
! 	  return cp_convert (void_type_node, exp);
  	}
      }
  
    if (TREE_CODE (basetype) == NAMESPACE_DECL)
      {
--- 261,271 ----
  	{
  	  if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype))
  	    error ("type of `%E' does not match destructor type `%T' (type was `%T')",
  		      exp, basetype, type);
  
! 	  return convert_to_void (exp, /*implicit=*/NULL);
  	}
      }
  
    if (TREE_CODE (basetype) == NAMESPACE_DECL)
      {
*************** build_scoped_method_call (tree exp, tree
*** 288,298 ****
      {
        /* Call to a destructor.  */
        if (TREE_CODE (name) == BIT_NOT_EXPR)
  	{
  	  if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
! 	    return cp_convert (void_type_node, exp);
  	  
  	  return build_delete (TREE_TYPE (decl), decl, 
  			       sfk_complete_destructor,
  			       LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
  			       0);
--- 288,298 ----
      {
        /* Call to a destructor.  */
        if (TREE_CODE (name) == BIT_NOT_EXPR)
  	{
  	  if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
! 	    return convert_to_void (exp, /*implicit=*/NULL);
  	  
  	  return build_delete (TREE_TYPE (decl), decl, 
  			       sfk_complete_destructor,
  			       LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
  			       0);
*************** build_method_call (tree instance, tree n
*** 494,504 ****
  	error
  	  ("destructor name `~%T' does not match type `%T' of expression",
  	   TREE_OPERAND (name, 0), object_type);
  
        if (! TYPE_HAS_DESTRUCTOR (complete_type (object_type)))
! 	return cp_convert (void_type_node, instance);
        instance = default_conversion (instance);
        instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
        return build_delete (build_pointer_type (object_type),
  			   instance_ptr, sfk_complete_destructor,
  			   LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
--- 494,504 ----
  	error
  	  ("destructor name `~%T' does not match type `%T' of expression",
  	   TREE_OPERAND (name, 0), object_type);
  
        if (! TYPE_HAS_DESTRUCTOR (complete_type (object_type)))
! 	return convert_to_void (instance, /*implicit=*/NULL);
        instance = default_conversion (instance);
        instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
        return build_delete (build_pointer_type (object_type),
  			   instance_ptr, sfk_complete_destructor,
  			   LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
Index: class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.545
diff -c -5 -p -r1.545 class.c
*** class.c	24 Jun 2003 15:40:01 -0000	1.545
--- class.c	3 Jul 2003 17:13:27 -0000
*************** check_field_decls (tree t, tree *access_
*** 3089,3104 ****
  	{
  	  cp_error_at ("field `%D' invalidly declared method type", x);
  	  type = build_pointer_type (type);
  	  TREE_TYPE (x) = type;
  	}
-       else if (TREE_CODE (type) == OFFSET_TYPE)
- 	{
- 	  cp_error_at ("field `%D' invalidly declared offset type", x);
- 	  type = build_pointer_type (type);
- 	  TREE_TYPE (x) = type;
- 	}
  
        if (type == error_mark_node)
  	continue;
  	  
        /* When this goes into scope, it will be a non-local reference.  */
--- 3089,3098 ----
Index: cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.137
diff -c -5 -p -r1.137 cvt.c
*** cvt.c	18 Jun 2003 15:22:18 -0000	1.137
--- cvt.c	3 Jul 2003 17:13:28 -0000
*************** convert_to_reference (tree reftype, tree
*** 550,564 ****
     way down to its lowest form.  */
  
  tree
  convert_from_reference (tree val)
  {
!   tree type = TREE_TYPE (val);
! 
!   if (TREE_CODE (type) == OFFSET_TYPE)
!     type = TREE_TYPE (type);
!   if (TREE_CODE (type) == REFERENCE_TYPE)
      return build_indirect_ref (val, NULL);
    return val;
  }
  
  /* Implicitly convert the lvalue EXPR to another lvalue of type TOTYPE,
--- 550,560 ----
     way down to its lowest form.  */
  
  tree
  convert_from_reference (tree val)
  {
!   if (TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
      return build_indirect_ref (val, NULL);
    return val;
  }
  
  /* Implicitly convert the lvalue EXPR to another lvalue of type TOTYPE,
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.636
diff -c -5 -p -r1.636 decl2.c
*** decl2.c	2 Jul 2003 09:36:17 -0000	1.636
--- decl2.c	3 Jul 2003 17:13:30 -0000
*************** grok_array_decl (tree array_expr, tree i
*** 405,424 ****
      return error_mark_node;
    if (processing_template_decl)
      return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
  		      array_expr, index_exp);
  
!   if (type == NULL_TREE)
!     {
!       /* Something has gone very wrong.  Assume we are mistakenly reducing
! 	 an expression instead of a declaration.  */
!       error ("parser may be lost: is there a '{' missing somewhere?");
!       return NULL_TREE;
!     }
  
!   if (TREE_CODE (type) == OFFSET_TYPE
!       || TREE_CODE (type) == REFERENCE_TYPE)
      type = TREE_TYPE (type);
  
    /* If they have an `operator[]', use that.  */
    if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
      return build_new_op (ARRAY_REF, LOOKUP_NORMAL,
--- 405,417 ----
      return error_mark_node;
    if (processing_template_decl)
      return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
  		      array_expr, index_exp);
  
!   my_friendly_assert (type, 20030626);
  
!   if (TREE_CODE (type) == REFERENCE_TYPE)
      type = TREE_TYPE (type);
  
    /* If they have an `operator[]', use that.  */
    if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
      return build_new_op (ARRAY_REF, LOOKUP_NORMAL,
*************** arg_assoc_type (struct arg_lookup *k, tr
*** 4059,4070 ****
  {
    /* As we do not get the type of non-type dependent expressions
       right, we can end up with such things without a type.  */
    if (!type)
      return false;
!   
!   switch (TREE_CODE (type))
      {
      case ERROR_MARK:
        return false;
      case VOID_TYPE:
      case INTEGER_TYPE:
--- 4052,4070 ----
  {
    /* As we do not get the type of non-type dependent expressions
       right, we can end up with such things without a type.  */
    if (!type)
      return false;
! 
!   if (TYPE_PTRMEM_P (type))
!     {
!       /* Pointer to member: associate class type and value type.  */
!       if (arg_assoc_type (k, TYPE_PTRMEM_CLASS_TYPE (type)))
! 	return true;
!       return arg_assoc_type (k, TYPE_PTRMEM_POINTED_TO_TYPE (type));
!     }
!   else switch (TREE_CODE (type))
      {
      case ERROR_MARK:
        return false;
      case VOID_TYPE:
      case INTEGER_TYPE:
*************** arg_assoc_type (struct arg_lookup *k, tr
*** 4083,4097 ****
      case ARRAY_TYPE:
        return arg_assoc_type (k, TREE_TYPE (type));
      case UNION_TYPE:
      case ENUMERAL_TYPE:
        return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type)));
-     case OFFSET_TYPE:
-       /* Pointer to member: associate class type and value type.  */
-       if (arg_assoc_type (k, TYPE_OFFSET_BASETYPE (type)))
- 	return true;
-       return arg_assoc_type (k, TREE_TYPE (type));
      case METHOD_TYPE:
        /* The basetype is referenced in the first arg type, so just
  	 fall through.  */
      case FUNCTION_TYPE:
        /* Associate the parameter types.  */
--- 4083,4092 ----
Index: init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.324
diff -c -5 -p -r1.324 init.c
*** init.c	20 Jun 2003 00:33:55 -0000	1.324
--- init.c	3 Jul 2003 17:13:32 -0000
*************** build_member_call (tree type, tree name,
*** 1499,1509 ****
     @@ This function should be rewritten and placed in search.c.  */
  
  tree
  build_offset_ref (tree type, tree name)
  {
!   tree decl, t = error_mark_node;
    tree member;
    tree basebinfo = NULL_TREE;
    tree orig_name = name;
  
    /* class templates can come in as TEMPLATE_DECLs here.  */
--- 1499,1509 ----
     @@ This function should be rewritten and placed in search.c.  */
  
  tree
  build_offset_ref (tree type, tree name)
  {
!   tree decl;
    tree member;
    tree basebinfo = NULL_TREE;
    tree orig_name = name;
  
    /* class templates can come in as TEMPLATE_DECLs here.  */
*************** build_offset_ref (tree type, tree name)
*** 1544,1554 ****
      return error_mark_node;
    
    /* Handle namespace names fully here.  */
    if (TREE_CODE (type) == NAMESPACE_DECL)
      {
!       t = lookup_namespace_name (type, name);
        if (t == error_mark_node)
          return t;
        if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
          /* Reconstruct the TEMPLATE_ID_EXPR.  */
          t = build (TEMPLATE_ID_EXPR, TREE_TYPE (t),
--- 1544,1554 ----
      return error_mark_node;
    
    /* Handle namespace names fully here.  */
    if (TREE_CODE (type) == NAMESPACE_DECL)
      {
!       tree t = lookup_namespace_name (type, name);
        if (t == error_mark_node)
          return t;
        if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
          /* Reconstruct the TEMPLATE_ID_EXPR.  */
          t = build (TEMPLATE_ID_EXPR, TREE_TYPE (t),
*************** build_offset_ref (tree type, tree name)
*** 1595,1605 ****
    /* A lot of this logic is now handled in lookup_member.  */
    if (member && BASELINK_P (member))
      {
        /* Go from the TREE_BASELINK to the member function info.  */
        tree fnfields = member;
!       t = BASELINK_FUNCTIONS (fnfields);
  
        if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
  	{
  	  /* The FNFIELDS are going to contain functions that aren't
  	     necessarily templates, and templates that don't
--- 1595,1605 ----
    /* A lot of this logic is now handled in lookup_member.  */
    if (member && BASELINK_P (member))
      {
        /* Go from the TREE_BASELINK to the member function info.  */
        tree fnfields = member;
!       tree t = BASELINK_FUNCTIONS (fnfields);
  
        if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
  	{
  	  /* The FNFIELDS are going to contain functions that aren't
  	     necessarily templates, and templates that don't
*************** build_offset_ref (tree type, tree name)
*** 1642,1689 ****
        t = build (OFFSET_REF, unknown_type_node, decl, fnfields);
        PTRMEM_OK_P (t) = 1;
        return t;
      }
  
!   t = member;
! 
!   if (t == NULL_TREE)
      {
        error ("`%D' is not a member of type `%T'", name, type);
        return error_mark_node;
      }
  
!   if (TREE_CODE (t) == TYPE_DECL)
      {
!       TREE_USED (t) = 1;
!       return t;
      }
    /* static class members and class-specific enum
       values can be returned without further ado.  */
!   if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)
      {
!       mark_used (t);
!       return convert_from_reference (t);
      }
  
!   if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t))
      {
!       error ("invalid pointer to bit-field `%D'", t);
        return error_mark_node;
      }
  
    /* static class functions too.  */
!   if (TREE_CODE (t) == FUNCTION_DECL
!       && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
      abort ();
  
    /* In member functions, the form `type::name' is no longer
       equivalent to `this->type::name', at least not until
       resolve_offset_ref.  */
!   t = build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);
!   PTRMEM_OK_P (t) = 1;
!   return t;
  }
  
  /* If a OFFSET_REF made it through to here, then it did
     not have its address taken.  */
  
--- 1642,1688 ----
        t = build (OFFSET_REF, unknown_type_node, decl, fnfields);
        PTRMEM_OK_P (t) = 1;
        return t;
      }
  
!   if (member == NULL_TREE)
      {
        error ("`%D' is not a member of type `%T'", name, type);
        return error_mark_node;
      }
  
!   if (TREE_CODE (member) == TYPE_DECL)
      {
!       TREE_USED (member) = 1;
!       return member;
      }
    /* static class members and class-specific enum
       values can be returned without further ado.  */
!   if (TREE_CODE (member) == VAR_DECL || TREE_CODE (member) == CONST_DECL)
      {
!       mark_used (member);
!       return convert_from_reference (member);
      }
  
!   if (TREE_CODE (member) == FIELD_DECL && DECL_C_BIT_FIELD (member))
      {
!       error ("invalid pointer to bit-field `%D'", member);
        return error_mark_node;
      }
  
    /* static class functions too.  */
!   if (TREE_CODE (member) == FUNCTION_DECL
!       && TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE)
      abort ();
  
    /* In member functions, the form `type::name' is no longer
       equivalent to `this->type::name', at least not until
       resolve_offset_ref.  */
!   member = build (OFFSET_REF, build_offset_type (type, TREE_TYPE (member)), 
! 		  decl, member);
!   PTRMEM_OK_P (member) = 1;
!   return member;
  }
  
  /* If a OFFSET_REF made it through to here, then it did
     not have its address taken.  */
  
*************** build_vec_delete_1 (tree base, tree maxi
*** 2623,2633 ****
  
    if (TREE_CODE (base) == SAVE_EXPR)
      /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR.  */
      body = build (COMPOUND_EXPR, void_type_node, base, body);
  
!   return cp_convert (void_type_node, body);
  }
  
  /* Create an unnamed variable of the indicated TYPE.  */ 
  
  tree
--- 2622,2632 ----
  
    if (TREE_CODE (base) == SAVE_EXPR)
      /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR.  */
      body = build (COMPOUND_EXPR, void_type_node, base, body);
  
!   return convert_to_void (body, /*implicit=*/NULL);
  }
  
  /* Create an unnamed variable of the indicated TYPE.  */ 
  
  tree
Index: mangle.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/mangle.c,v
retrieving revision 1.79
diff -c -5 -p -r1.79 mangle.c
*** mangle.c	30 Jun 2003 19:02:04 -0000	1.79
--- mangle.c	3 Jul 2003 17:13:33 -0000
*************** write_type (tree type)
*** 1439,1449 ****
    else
      {
        /* See through any typedefs.  */
        type = TYPE_MAIN_VARIANT (type);
  
!       switch (TREE_CODE (type))
  	{
  	case VOID_TYPE:
  	case BOOLEAN_TYPE:
  	case INTEGER_TYPE:  /* Includes wchar_t.  */
  	case REAL_TYPE:
--- 1439,1451 ----
    else
      {
        /* See through any typedefs.  */
        type = TYPE_MAIN_VARIANT (type);
  
!       if (TYPE_PTRMEM_P (type))
! 	write_pointer_to_member_type (type);
!       else switch (TREE_CODE (type))
  	{
  	case VOID_TYPE:
  	case BOOLEAN_TYPE:
  	case INTEGER_TYPE:  /* Includes wchar_t.  */
  	case REAL_TYPE:
*************** write_type (tree type)
*** 1481,1499 ****
  	     ordinary nested names.  */
  	  write_nested_name (TYPE_STUB_DECL (type));
  	  break;
  
  	case POINTER_TYPE:
! 	  /* A pointer-to-member variable is represented by a POINTER_TYPE
! 	     to an OFFSET_TYPE, so check for this first.  */
! 	  if (TYPE_PTRMEM_P (type))
! 	    write_pointer_to_member_type (type);
! 	  else
! 	    {
! 	      write_char ('P');
! 	      write_type (TREE_TYPE (type));
! 	    }
  	  break;
  
  	case REFERENCE_TYPE:
  	  write_char ('R');
  	  write_type (TREE_TYPE (type));
--- 1483,1494 ----
  	     ordinary nested names.  */
  	  write_nested_name (TYPE_STUB_DECL (type));
  	  break;
  
  	case POINTER_TYPE:
! 	  write_char ('P');
! 	  write_type (TREE_TYPE (type));
  	  break;
  
  	case REFERENCE_TYPE:
  	  write_char ('R');
  	  write_type (TREE_TYPE (type));
*************** write_type (tree type)
*** 1510,1523 ****
  
  	case BOUND_TEMPLATE_TEMPLATE_PARM:
  	  write_template_template_param (type);
  	  write_template_args 
  	    (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
- 	  break;
- 
- 	case OFFSET_TYPE:
- 	  write_pointer_to_member_type (build_pointer_type (type));
  	  break;
  
  	case VECTOR_TYPE:
  	  write_string ("U8__vector");
  	  write_type (TREE_TYPE (type));
--- 1505,1514 ----


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