This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Minor cleanups
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 3 Jul 2003 11:19:51 -0700
- Subject: C++ PATCH: Minor cleanups
- Reply-to: mark at codesourcery dot com
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 ----