aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/typeck2.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-07-04 05:05:19 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-07-04 05:05:19 +0000
commitd6b4ea8592e338addbd24be14708f66eaa4ac63e (patch)
tree613039e905b0fbc1fe50e07889b99fdc172e8d14 /gcc/cp/typeck2.c
parent5f1989e65d23624efdbf26bde56f375e3caa6a22 (diff)
downloadgcc-d6b4ea8592e338addbd24be14708f66eaa4ac63e.zip
gcc-d6b4ea8592e338addbd24be14708f66eaa4ac63e.tar.gz
gcc-d6b4ea8592e338addbd24be14708f66eaa4ac63e.tar.bz2
call.c (build_addr_func): Handle bound pointers-to-members.
* call.c (build_addr_func): Handle bound pointers-to-members. (build_method_call): Do not call resolve_offset_ref. (implicit_conversion): Likewise. (resolve_scoped_fn_name): Use finish_non_static_data_member, not resolve_offset_ref. (resolve_args): Do not call resolve_offset_ref. (build_conditional_expr): Likewise. (build_new_method_call): Likewise. * cp-tree.def (OFFSET_REF): Update documentation. (cp_convert_to_pointer): Update handling of conversions from pointers to members to pointers. (ocp_convert): Do not call resolve_offset_ref. (convert_to_void): Likewise. (build_expr_type_conversion): Likewise. (delete_sanity): Likewise. (resolve_offset_ref): Simplify greatly. (build_vec_delete): Do not call resolve_offset_ref. * parser.c (cp_parser_postfix_expression): Call resolve_offset_ref if appropriate. (cp_parser_unary_expression): Use cp_parser_simple_cast_expression. (cp_parser_delete_expression): Likewise. (cp_parser_cast_expression): Likewise. (cp_parser_pm_expression): Use cp_parser_binary_op. (cp_parser_simple_cast_expression): New function. * rtti.c (build_dynamic_cast_1): Do not call resolve_offset_ref. * semantics.c (finish_increment_expr): Likewise. (finish_typeof): Likewise. * tree.c (lvalue_p_1): Do not handle OFFSET_REF. * typeck.c (require_complete_type): Do not handle OFFSET_REFs. (decay_conversion): Do not call resolve_offset_ref. (finish_class_member_access_expr): Likewise. (convert_arguments): Likewise. (build_x_binary_op): Handle DOTSTAR_EXPR. (condition_conversion): Do not call resolve_offset_ref. (unary_complex_lvalue): Likewise. (build_static_cast): Likewise. (build_reinterpret_cast): Likewise. (build_const_cast): Likewise. (build_c_cast): Likewise. (build_modify_expr): Likewise. (convert_for_assignment): Likewise. (convert_for_initialization): Likewise. * typeck2.c (build_x_arrow): Likewise. (build_m_component_ref): Simplify. * g++.old-deja/g++.jason/typeid1.C: Add dg-error marker. * g++.old-deja/g++.mike/net36.C: Tweak error messages. From-SVN: r68911
Diffstat (limited to 'gcc/cp/typeck2.c')
-rw-r--r--gcc/cp/typeck2.c92
1 files changed, 30 insertions, 62 deletions
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 0587816..9d9ade1 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -993,12 +993,6 @@ build_x_arrow (tree datum)
if (processing_template_decl)
return build_min_nt (ARROW_EXPR, rval);
- if (TREE_CODE (rval) == OFFSET_REF)
- {
- rval = resolve_offset_ref (datum);
- type = TREE_TYPE (rval);
- }
-
if (TREE_CODE (type) == REFERENCE_TYPE)
{
rval = convert_from_reference (rval);
@@ -1048,72 +1042,32 @@ build_x_arrow (tree datum)
return error_mark_node;
}
-/* Make an expression to refer to the COMPONENT field of
- structure or union value DATUM. COMPONENT is an arbitrary
- expression. DATUM has not already been checked out to be of
- aggregate type.
-
- For C++, COMPONENT may be a TREE_LIST. This happens when we must
- return an object of member type to a method of the current class,
- but there is not yet enough typing information to know which one.
- As a special case, if there is only one method by that name,
- it is returned. Otherwise we return an expression which other
- routines will have to know how to deal with later. */
+/* Return an expression for "DATUM .* COMPONENT". DATUM has not
+ already been checked out to be of aggregate type. */
tree
build_m_component_ref (tree datum, tree component)
{
- tree type;
+ tree ptrmem_type;
tree objtype;
- tree field_type;
- int type_quals;
+ tree type;
tree binfo;
- if (processing_template_decl)
- return build_min_nt (DOTSTAR_EXPR, datum, component);
-
datum = decay_conversion (datum);
if (datum == error_mark_node || component == error_mark_node)
return error_mark_node;
- objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
-
- if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
- {
- type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
- field_type = type;
- }
- else if (TYPE_PTRMEM_P (TREE_TYPE (component)))
- {
- type = TREE_TYPE (TREE_TYPE (component));
- field_type = TREE_TYPE (type);
-
- /* Compute the type of the field, as described in [expr.ref]. */
- type_quals = TYPE_UNQUALIFIED;
- if (TREE_CODE (field_type) == REFERENCE_TYPE)
- /* The standard says that the type of the result should be the
- type referred to by the reference. But for now, at least,
- we do the conversion from reference type later. */
- ;
- else
- {
- type_quals = (cp_type_quals (field_type)
- | cp_type_quals (TREE_TYPE (datum)));
-
- /* There's no such thing as a mutable pointer-to-member, so
- things are not as complex as they are for references to
- non-static data members. */
- field_type = cp_build_qualified_type (field_type, type_quals);
- }
- }
- else
+ ptrmem_type = TREE_TYPE (component);
+ if (!TYPE_PTRMEM_P (ptrmem_type)
+ && !TYPE_PTRMEMFUNC_P (ptrmem_type))
{
error ("`%E' cannot be used as a member pointer, since it is of type `%T'",
- component, TREE_TYPE (component));
+ component, ptrmem_type);
return error_mark_node;
}
-
+
+ objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
if (! IS_AGGR_TYPE (objtype))
{
error ("cannot apply member pointer `%E' to `%E', which is of non-aggregate type `%T'",
@@ -1121,21 +1075,35 @@ build_m_component_ref (tree datum, tree component)
return error_mark_node;
}
- binfo = lookup_base (objtype, TYPE_METHOD_BASETYPE (type),
+ 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_METHOD_BASETYPE (type), objtype);
+ type, objtype);
return error_mark_node;
}
else if (binfo == error_mark_node)
return error_mark_node;
- component = build (OFFSET_REF, field_type, datum, component);
- if (TREE_CODE (type) == OFFSET_TYPE)
- component = resolve_offset_ref (component);
- return component;
+ if (TYPE_PTRMEM_P (ptrmem_type))
+ {
+ /* Compute the type of the field, as described in [expr.ref].
+ There's no such thing as a mutable pointer-to-member, so
+ things are not as complex as they are for references to
+ non-static data members. */
+ type = cp_build_qualified_type (type,
+ (cp_type_quals (type)
+ | cp_type_quals (TREE_TYPE (datum))));
+
+ datum = build_base_path (PLUS_EXPR, build_address (datum), binfo, 1);
+ component = cp_convert (ptrdiff_type_node, component);
+ datum = build (PLUS_EXPR, build_pointer_type (type), datum, component);
+ return build_indirect_ref (datum, 0);
+ }
+ else
+ return build (OFFSET_REF, type, datum, component);
}
/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */