Commit 90e734a8 by Jason Merrill Committed by Jason Merrill

call.c (build_field_call): Unify 'this' and non-'this' cases.

	* call.c (build_field_call): Unify 'this' and non-'this' cases.
	* typeck.c (build_indirect_ref): Check for 'this' sooner.

From-SVN: r26012
parent 92a217ad
1999-03-27 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_field_call): Unify 'this' and non-'this' cases.
* typeck.c (build_indirect_ref): Check for 'this' sooner.
Fri Mar 26 10:20:34 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> Fri Mar 26 10:20:34 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* call.c (op_error): Const-ify a char*. * call.c (op_error): Const-ify a char*.
......
...@@ -128,92 +128,40 @@ build_field_call (basetype_path, instance_ptr, name, parms) ...@@ -128,92 +128,40 @@ build_field_call (basetype_path, instance_ptr, name, parms)
if (name == ctor_identifier || name == dtor_identifier) if (name == ctor_identifier || name == dtor_identifier)
return NULL_TREE; return NULL_TREE;
if (instance_ptr == current_class_ptr) /* Speed up the common case. */
{ if (instance_ptr == current_class_ptr
/* Check to see if we really have a reference to an instance variable && IDENTIFIER_CLASS_VALUE (name) == NULL_TREE)
with `operator()()' overloaded. */ return NULL_TREE;
field = IDENTIFIER_CLASS_VALUE (name);
if (field == NULL_TREE)
{
cp_error ("`this' has no member named `%D'", name);
return error_mark_node;
}
if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL)
{
/* If it's a field, try overloading operator (),
or calling if the field is a pointer-to-function. */
instance = build_component_ref_1 (current_class_ref, field, 0);
if (instance == error_mark_node)
return error_mark_node;
if (TYPE_LANG_SPECIFIC (TREE_TYPE (instance)))
return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, instance, parms, NULL_TREE);
if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE)
return build_function_call (instance, parms);
else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE)
return build_function_call (instance, expr_tree_cons (NULL_TREE, current_class_ptr, parms));
}
}
return NULL_TREE;
}
/* Check to see if this is not really a reference to an instance variable
with `operator()()' overloaded. */
field = lookup_field (basetype_path, name, 1, 0); field = lookup_field (basetype_path, name, 1, 0);
/* This can happen if the reference was ambiguous or for access if (field == error_mark_node || field == NULL_TREE)
violations. */ return field;
if (field == error_mark_node)
return error_mark_node;
if (field && (TREE_CODE (field) == FIELD_DECL || if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL)
TREE_CODE (field) == VAR_DECL))
{ {
tree basetype; /* If it's a field, try overloading operator (),
tree ftype = TREE_TYPE (field); or calling if the field is a pointer-to-function. */
instance = build_indirect_ref (instance_ptr, NULL_PTR);
instance = build_component_ref_1 (instance, field, 0);
if (TREE_CODE (ftype) == REFERENCE_TYPE) if (instance == error_mark_node)
ftype = TREE_TYPE (ftype); return error_mark_node;
if (TYPE_LANG_SPECIFIC (ftype)) if (IS_AGGR_TYPE (TREE_TYPE (instance)))
{ return build_opfncall (CALL_EXPR, LOOKUP_NORMAL,
/* Make the next search for this field very short. */ instance, parms, NULL_TREE);
basetype = DECL_FIELD_CONTEXT (field); else if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE)
instance_ptr = convert_pointer_to (basetype, instance_ptr);
instance = build_indirect_ref (instance_ptr, NULL_PTR);
return build_opfncall (CALL_EXPR, LOOKUP_NORMAL,
build_component_ref_1 (instance, field, 0),
parms, NULL_TREE);
}
if (TREE_CODE (ftype) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (ftype)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (ftype)) == METHOD_TYPE)
{
/* This is a member which is a pointer to function. */
tree ref
= build_component_ref_1 (build_indirect_ref (instance_ptr,
NULL_PTR),
field, LOOKUP_COMPLAIN);
if (ref == error_mark_node)
return error_mark_node;
return build_function_call (ref, parms);
}
}
else if (TREE_CODE (ftype) == METHOD_TYPE)
{ {
error ("invalid call via pointer-to-member function"); if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE)
return error_mark_node; return build_function_call (instance, parms);
else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance)))
== METHOD_TYPE)
return build_function_call
(instance, expr_tree_cons (NULL_TREE, instance_ptr, parms));
} }
else
return NULL_TREE;
} }
return NULL_TREE; return NULL_TREE;
} }
......
...@@ -2345,13 +2345,13 @@ build_indirect_ref (ptr, errorstring) ...@@ -2345,13 +2345,13 @@ build_indirect_ref (ptr, errorstring)
if (ptr == error_mark_node) if (ptr == error_mark_node)
return error_mark_node; return error_mark_node;
if (ptr == current_class_ptr)
return current_class_ref;
pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
? ptr : default_conversion (ptr)); ? ptr : default_conversion (ptr));
type = TREE_TYPE (pointer); type = TREE_TYPE (pointer);
if (ptr == current_class_ptr)
return current_class_ref;
if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE) if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
{ {
/* [expr.unary.op] /* [expr.unary.op]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment