Commit 50ad9642 by Mark Mitchell Committed by Mark Mitchell

Rework build_component_ref.

	* call.c (build_vfield_ref): Do not go through build_component_ref.
	(build_field_call): Use build_class_member_access_expr.
	(build_user_type_conversion_1): Use BASELINK_FUNCTIONS.
	(build_object_call): Likewise.
	* class.c (convert_to_base): New function.
	(type_requires_array_cookie): Use BASELINK_FUNCTIONS.
	(instantiate_type): Handle BASELINKs.
	* cp-tree.def (BASELINK): New tree code.
	* cp-tree.h (BASELINK_P): Reimplement.
	(SET_BASELINK_P): Remove.
	(BASELINK_BINFO): Reimplement.
	(BASELINK_FUNCTIONS): Likewise.
	(BASELINK_ACCESS_BINFO): Likewise.
	(BASELINK_OPTYPE): Likewise.
	(convert_to_base): New function.
	(name_p): Likewise.
	(build_object_ref): Remove.
	(build_component_ref_1): Likewise.
	(build_component_ref): Likewise.
	(build_x_component_ref): Likewise.
	(build_class_member_access_expr): New function.
	(finish_class_member_access_expr): Likewise.
	(build_ptrmemfunc_access_expr): Likewise.
	* decl.c (grokdeclarator): Handle BASELINKs.
	* decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using
	finish_class_member_access_expr.
	(arg_assoc): Handle BASELINKs.
	(do_class_using_decl): Likewise.
	* error.c (dump_decl): Likewise.
	(dump_expr): Use build_ptrmemfunc_access_expr.
	* except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find
	destructors.
	(build_throw): Use BASELINK_FUNCTIONS.
	* init.c (perform_member_init): Use
	build_class_member_access_expr.
	(build_offset_ref): Handle BASELINKs.  Use
	build_class_member_access_expr.
	* method.c (hack_identifier): Likewise.
	* parse.y (do_id): Use BASELINK, not TREE_LIST.
	(primary): Remove uses of build_object_ref.
	* pt.c (lookup_template_function): Handle BASELINKs.
	(resolve_overloaded_unification): Likewise.
	* search.c (build_baselink): Build a BASELINK, not a TREE_LIST.
	(lookup_field): Use BASELINK, not TREE_LIST.
	(lookup_fnfiels): Likewise.
	(setup_class_bindings): Likewise.
	* semantics.c (finish_object_call_expr): Do not use
	build_method_call when we already know what function is being
	called.
	* spew.c (identifier_type): Use BASELINK, not TREE_LIST.
	* tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not
	TREE_CHAIN.
	(name_p): New function.
	* typeck.c (build_object_ref): Remove.
	(build_component_ref_1): Likewise.
	(build_x_component_ref): Likewise.
	(build_class_member_access_expr): New function.
	(finish_class_member_access_expr): Likewise.
	(build_ptrmemfunc_access_expr): Likewise.
	(get_member_function_from_ptrfunc): Use
	build_ptrmemfunc_access_expr.
	(build_binary_op): Likewise.
	(build_unary_op): Likewise.
	(build_ptrmemfunc): Likewise.
	(pfn_from_ptrmemfunc): Likewise.
	* typeck2.c (build_m_component_ref): Adjust comment.

	* g++.dg/abi/offsetof.C: Tweak error messages.
	* g++.old-deja/g++.mike/p10769a.C: Likewise.

From-SVN: r56117
parent 774b5662
2002-08-07 Mark Mitchell <mark@codesourcery.com>
Rework build_component_ref.
* call.c (build_vfield_ref): Do not go through build_component_ref.
(build_field_call): Use build_class_member_access_expr.
(build_user_type_conversion_1): Use BASELINK_FUNCTIONS.
(build_object_call): Likewise.
* class.c (convert_to_base): New function.
(type_requires_array_cookie): Use BASELINK_FUNCTIONS.
(instantiate_type): Handle BASELINKs.
* cp-tree.def (BASELINK): New tree code.
* cp-tree.h (BASELINK_P): Reimplement.
(SET_BASELINK_P): Remove.
(BASELINK_BINFO): Reimplement.
(BASELINK_FUNCTIONS): Likewise.
(BASELINK_ACCESS_BINFO): Likewise.
(BASELINK_OPTYPE): Likewise.
(convert_to_base): New function.
(name_p): Likewise.
(build_object_ref): Remove.
(build_component_ref_1): Likewise.
(build_component_ref): Likewise.
(build_x_component_ref): Likewise.
(build_class_member_access_expr): New function.
(finish_class_member_access_expr): Likewise.
(build_ptrmemfunc_access_expr): Likewise.
* decl.c (grokdeclarator): Handle BASELINKs.
* decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using
finish_class_member_access_expr.
(arg_assoc): Handle BASELINKs.
(do_class_using_decl): Likewise.
* error.c (dump_decl): Likewise.
(dump_expr): Use build_ptrmemfunc_access_expr.
* except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find
destructors.
(build_throw): Use BASELINK_FUNCTIONS.
* init.c (perform_member_init): Use
build_class_member_access_expr.
(build_offset_ref): Handle BASELINKs. Use
build_class_member_access_expr.
* method.c (hack_identifier): Likewise.
* parse.y (do_id): Use BASELINK, not TREE_LIST.
(primary): Remove uses of build_object_ref.
* pt.c (lookup_template_function): Handle BASELINKs.
(resolve_overloaded_unification): Likewise.
* search.c (build_baselink): Build a BASELINK, not a TREE_LIST.
(lookup_field): Use BASELINK, not TREE_LIST.
(lookup_fnfiels): Likewise.
(setup_class_bindings): Likewise.
* semantics.c (finish_object_call_expr): Do not use
build_method_call when we already know what function is being
called.
* spew.c (identifier_type): Use BASELINK, not TREE_LIST.
* tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not
TREE_CHAIN.
(name_p): New function.
* typeck.c (build_object_ref): Remove.
(build_component_ref_1): Likewise.
(build_x_component_ref): Likewise.
(build_class_member_access_expr): New function.
(finish_class_member_access_expr): Likewise.
(build_ptrmemfunc_access_expr): Likewise.
(get_member_function_from_ptrfunc): Use
build_ptrmemfunc_access_expr.
(build_binary_op): Likewise.
(build_unary_op): Likewise.
(build_ptrmemfunc): Likewise.
(pfn_from_ptrmemfunc): Likewise.
* typeck2.c (build_m_component_ref): Adjust comment.
2002-08-07 Neil Booth <neil@daikokuya.co.uk>
* Make-lang.in (CXX_C_OBJS): Update.
......
......@@ -106,21 +106,18 @@ tree
build_vfield_ref (datum, type)
tree datum, type;
{
tree rval;
if (datum == error_mark_node)
return error_mark_node;
if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE)
datum = convert_from_reference (datum);
if (! TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type))
rval = build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
datum, TYPE_VFIELD (type));
else
rval = build_component_ref (datum, DECL_NAME (TYPE_VFIELD (type)), NULL_TREE, 0);
if (TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (type)
&& !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
datum = convert_to_base (datum, type, /*check_access=*/false);
return rval;
return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
datum, TYPE_VFIELD (type));
}
/* Build a call to a member of an object. I.e., one that overloads
......@@ -139,7 +136,9 @@ build_field_call (tree instance_ptr, tree decl, tree parms)
/* If it's a field, try overloading operator (),
or calling if the field is a pointer-to-function. */
instance = build_indirect_ref (instance_ptr, NULL);
instance = build_component_ref_1 (instance, decl, 0);
instance = build_class_member_access_expr (instance, decl,
/*access_path=*/NULL_TREE,
/*preserve_reference=*/false);
if (instance == error_mark_node)
return error_mark_node;
......@@ -2500,7 +2499,7 @@ build_user_type_conversion_1 (totype, expr, flags)
{
tree t;
ctors = TREE_VALUE (ctors);
ctors = BASELINK_FUNCTIONS (ctors);
t = build_int_2 (0, 0);
TREE_TYPE (t) = build_pointer_type (totype);
......@@ -2796,10 +2795,10 @@ build_object_call (obj, args)
if (fns)
{
tree base = BINFO_TYPE (TREE_PURPOSE (fns));
tree base = BINFO_TYPE (BASELINK_BINFO (fns));
mem_args = tree_cons (NULL_TREE, build_this (obj), args);
for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
......
......@@ -358,6 +358,24 @@ build_base_path (code, expr, binfo, nonnull)
return expr;
}
/* Convert OBJECT to the base TYPE. If CHECK_ACCESS is true, an error
message is emitted if TYPE is inaccessible. OBJECT is assumed to
be non-NULL. */
tree
convert_to_base (tree object, tree type, bool check_access)
{
tree binfo;
binfo = lookup_base (TREE_TYPE (object), type,
check_access ? ba_check : ba_ignore,
NULL);
if (!binfo || TREE_CODE (binfo) == error_mark_node)
return error_mark_node;
return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1);
}
/* Virtual function things. */
......@@ -4201,7 +4219,7 @@ type_requires_array_cookie (type)
if (!fns || fns == error_mark_node)
return false;
/* Loop through all of the functions. */
for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
{
tree fn;
tree second_parm;
......@@ -6003,6 +6021,9 @@ instantiate_type (lhstype, rhs, flags)
return error_mark_node;
}
if (TREE_CODE (rhs) == BASELINK)
rhs = BASELINK_FUNCTIONS (rhs);
/* We don't overwrite rhs if it is an overloaded function.
Copying it would destroy the tree link. */
if (TREE_CODE (rhs) != OVERLOAD)
......
......@@ -89,6 +89,20 @@ DEFTREECODE (THROW_EXPR, "throw_expr", 'e', 1)
these to avoid actually creating instances of the empty classes. */
DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", 'e', 0)
/* A reference to a member function or member functions from a base
class. BASELINK_FUNCTIONS gives the FUNCTION_DECL,
TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the
functions. BASELINK_BINFO gives the base from which the functions
come, i.e., the base to which the `this' pointer must be converted
before the functions are called. BASELINK_ACCESS_BINFO gives the
base used to name the functions.
A BASELINK is an expression; the TREE_TYPE of the BASELINK gives
the type of the expression. This type is either a FUNCTION_TYPE,
METHOD_TYPE, or `unknown_type_node' indicating that the function is
overloaded. */
DEFTREECODE (BASELINK, "baselink", 'e', 3)
/* Template definition. The following fields have the specified uses,
although there are other macros in cp-tree.h that should be used for
accessing this data.
......
......@@ -57,7 +57,6 @@ struct diagnostic_context;
(TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out).
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE).
INHERITED_VALUE_BINDING_P (in CPLUS_BINDING)
BASELINK_P (in TREE_LIST)
ICS_ELLIPSIS_FLAG (in _CONV)
BINFO_ACCESS (in BINFO)
2: IDENTIFIER_OPNAME_P.
......@@ -361,32 +360,28 @@ struct tree_overload GTY(())
tree function;
};
/* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO
indicating a particular base class, and whose TREE_VALUE is a
(possibly overloaded) function from that base class. */
/* Returns true iff NODE is a BASELINK. */
#define BASELINK_P(NODE) \
(TREE_CODE (NODE) == TREE_LIST && TREE_LANG_FLAG_1 (NODE))
#define SET_BASELINK_P(NODE) \
(TREE_LANG_FLAG_1 (NODE) = 1)
/* The BINFO indicated the base from which the BASELINK_FUNCTIONS came. */
(TREE_CODE (NODE) == BASELINK)
/* The BINFO indicating the base from which the BASELINK_FUNCTIONS came. */
#define BASELINK_BINFO(NODE) \
(TREE_PURPOSE (NODE))
/* The functions referred to by the BASELINK; either a FUNCTION_DECL
or an OVERLOAD. */
(TREE_OPERAND (BASELINK_CHECK (NODE), 0))
/* The functions referred to by the BASELINK; either a FUNCTION_DECL,
a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR. */
#define BASELINK_FUNCTIONS(NODE) \
(TREE_VALUE (NODE))
(TREE_OPERAND (BASELINK_CHECK (NODE), 1))
/* The BINFO in which the search for the functions indicated by this baselink
began. This base is used to determine the accessibility of functions
selected by overload resolution. */
#define BASELINK_ACCESS_BINFO(NODE) \
(TREE_TYPE (NODE))
(TREE_OPERAND (BASELINK_CHECK (NODE), 2))
/* For a type-conversion operator, the BASELINK_OPTYPE indicates the type
to which the conversion should occur. This value is important if
the BASELINK_FUNCTIONS include a template conversion operator --
the BASELINK_OPTYPE can be used to determine what type the user
requested. */
#define BASELINK_OPTYPE(NODE) \
(TREE_CHAIN (NODE))
(TREE_CHAIN (BASELINK_CHECK (NODE)))
#define WRAPPER_ZC(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->z_c)
......@@ -3525,6 +3520,7 @@ extern tree perform_implicit_conversion PARAMS ((tree, tree));
/* in class.c */
extern tree build_base_path PARAMS ((enum tree_code, tree, tree, int));
extern tree convert_to_base (tree, tree, bool);
extern tree build_vbase_path PARAMS ((enum tree_code, tree, tree, tree, int));
extern tree build_vtbl_ref PARAMS ((tree, tree));
extern tree build_vfn_ref PARAMS ((tree, tree));
......@@ -4238,6 +4234,7 @@ extern tree cp_build_qualified_type_real PARAMS ((tree, int, tsubst_flags
cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning)
extern tree build_shared_int_cst PARAMS ((int));
extern special_function_kind special_function_p PARAMS ((tree));
extern bool name_p (tree);
extern int count_trees PARAMS ((tree));
extern int char_type_p PARAMS ((tree));
extern void verify_stmt_tree PARAMS ((tree));
......@@ -4277,10 +4274,8 @@ extern tree cxx_sizeof_or_alignof_type PARAMS ((tree, enum tree_code, int));
#define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false)
extern tree inline_conversion PARAMS ((tree));
extern tree decay_conversion PARAMS ((tree));
extern tree build_object_ref PARAMS ((tree, tree, tree));
extern tree build_component_ref_1 PARAMS ((tree, tree, int));
extern tree build_component_ref PARAMS ((tree, tree, tree, int));
extern tree build_x_component_ref PARAMS ((tree, tree, tree));
extern tree build_class_member_access_expr (tree, tree, tree, bool);
extern tree finish_class_member_access_expr (tree, tree);
extern tree build_x_indirect_ref PARAMS ((tree, const char *));
extern tree build_indirect_ref PARAMS ((tree, const char *));
extern tree build_array_ref PARAMS ((tree, tree));
......@@ -4321,6 +4316,7 @@ extern tree check_return_expr PARAMS ((tree));
build_binary_op(code, arg1, arg2, 1)
#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
#define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR, true)
extern tree build_ptrmemfunc_access_expr (tree, tree);
/* in typeck2.c */
extern void cxx_incomplete_type_diagnostic PARAMS ((tree, tree, int));
......
......@@ -10001,6 +10001,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
next = 0;
break;
case BASELINK:
next = &BASELINK_FUNCTIONS (decl);
break;
default:
internal_error ("`%D' as declarator", decl);
}
......@@ -11133,6 +11137,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
declarator = TREE_OPERAND (declarator, 0);
break;
case BASELINK:
declarator = BASELINK_FUNCTIONS (declarator);
break;
case RECORD_TYPE:
case UNION_TYPE:
case ENUMERAL_TYPE:
......
......@@ -3369,17 +3369,8 @@ build_expr_from_tree (t)
case COMPONENT_REF:
{
tree object = build_expr_from_tree (TREE_OPERAND (t, 0));
tree field = TREE_OPERAND (t, 1);
/* We use a COMPONENT_REF to indicate things of the form `x.b'
and `x.A::b'. We must distinguish between those cases
here. */
if (TREE_CODE (field) == SCOPE_REF)
return build_object_ref (object,
TREE_OPERAND (field, 0),
TREE_OPERAND (field, 1));
else
return build_x_component_ref (object, field, NULL_TREE);
return finish_class_member_access_expr (object,
TREE_OPERAND (t, 1));
}
case THROW_EXPR:
......@@ -4283,6 +4274,8 @@ arg_assoc (k, n)
n = TREE_OPERAND (n, 1);
while (TREE_CODE (n) == TREE_LIST)
n = TREE_VALUE (n);
if (TREE_CODE (n) == BASELINK)
n = BASELINK_FUNCTIONS (n);
if (TREE_CODE (n) == FUNCTION_DECL)
return arg_assoc_type (k, TREE_TYPE (n));
......@@ -4647,6 +4640,13 @@ do_class_using_decl (decl)
}
if (TREE_CODE (name) == TYPE_DECL || TREE_CODE (name) == TEMPLATE_DECL)
name = DECL_NAME (name);
else if (BASELINK_P (name))
{
name = BASELINK_FUNCTIONS (name);
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
name = TREE_OPERAND (name, 0);
name = DECL_NAME (get_first_fn (name));
}
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
......
......@@ -990,6 +990,10 @@ dump_decl (t, flags)
print_tree_identifier (scratch_buffer, DECL_NAME (t));
break;
case BASELINK:
dump_decl (BASELINK_FUNCTIONS (t), flags);
break;
default:
sorry_for_unsupported_tree (t);
/* Fallthrough to error. */
......@@ -1826,7 +1830,7 @@ dump_expr (t, flags)
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
{
tree idx = build_component_ref (t, pfn_identifier, NULL_TREE, 0);
tree idx = build_ptrmemfunc_access_expr (t, pfn_identifier);
if (integer_zerop (idx))
{
......
......@@ -174,17 +174,13 @@ static int
dtor_nothrow (type)
tree type;
{
tree fn;
if (type == NULL_TREE)
return 0;
if (! TYPE_HAS_DESTRUCTOR (type))
return 1;
fn = lookup_member (type, dtor_identifier, 0, 0);
fn = TREE_VALUE (fn);
return TREE_NOTHROW (fn);
return TREE_NOTHROW (CLASSTYPE_DESTRUCTORS (type));
}
/* Build up a call to __cxa_end_catch, to destroy the exception object
......@@ -753,7 +749,7 @@ build_throw (exp)
{
cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
complete_dtor_identifier, 0);
cleanup = TREE_VALUE (cleanup);
cleanup = BASELINK_FUNCTIONS (cleanup);
mark_used (cleanup);
cxx_mark_addressable (cleanup);
/* Pretend it's a normal function. */
......
......@@ -232,8 +232,9 @@ perform_member_init (member, init, explicit)
tree decl;
tree type = TREE_TYPE (member);
decl = build_component_ref (current_class_ref, member, NULL_TREE, explicit);
decl = build_class_member_access_expr (current_class_ref, member,
/*access_path=*/NULL_TREE,
/*preserve_reference=*/true);
if (decl == error_mark_node)
return;
......@@ -305,8 +306,9 @@ perform_member_init (member, init, explicit)
{
tree expr;
expr = build_component_ref (current_class_ref, member, NULL_TREE,
explicit);
expr = build_class_member_access_expr (current_class_ref, member,
/*access_path=*/NULL_TREE,
/*preserve_reference=*/false);
expr = build_delete (type, expr, sfk_complete_destructor,
LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
......@@ -1668,10 +1670,15 @@ build_offset_ref (type, name)
decl = maybe_dummy_object (type, &basebinfo);
member = lookup_member (basebinfo, name, 1, 0);
if (member == error_mark_node)
return error_mark_node;
if (BASELINK_P (name))
member = name;
else
{
member = lookup_member (basebinfo, name, 1, 0);
if (member == error_mark_node)
return error_mark_node;
}
/* A lot of this logic is now handled in lookup_member. */
if (member && BASELINK_P (member))
......@@ -1703,7 +1710,7 @@ build_offset_ref (type, name)
return t;
}
if (!really_overloaded_fn (t))
if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t))
{
/* Get rid of a potential OVERLOAD around it */
t = OVL_CURRENT (t);
......@@ -1848,7 +1855,9 @@ resolve_offset_ref (exp)
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type), &binfo);
return build_component_ref (base, member, binfo, 1);
return build_class_member_access_expr (base, member,
/*access_path=*/NULL_TREE,
/*preserve_reference=*/false);
}
/* Ensure that we have an object. */
......@@ -3332,9 +3341,10 @@ push_base_cleanups ()
continue;
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (member)))
{
tree this_member = (build_component_ref
(current_class_ref, DECL_NAME (member),
NULL_TREE, 0));
tree this_member = (build_class_member_access_expr
(current_class_ref, member,
/*access_path=*/NULL_TREE,
/*preserve_reference=*/false));
tree this_type = TREE_TYPE (member);
expr = build_delete (this_type, this_member,
sfk_complete_destructor,
......
......@@ -161,12 +161,26 @@ hack_identifier (value, name)
return error_mark_node;
}
TREE_USED (current_class_ptr) = 1;
if (processing_template_decl)
value = build_min_nt (COMPONENT_REF, current_class_ref, name);
else
{
tree access_type = current_class_type;
while (!DERIVED_FROM_P (context_for_name_lookup (value),
access_type))
{
access_type = TYPE_CONTEXT (access_type);
while (DECL_P (access_type))
access_type = DECL_CONTEXT (access_type);
}
/* Mark so that if we are in a constructor, and then find that
this field was initialized by a base initializer,
we can emit an error message. */
TREE_USED (value) = 1;
value = build_component_ref (current_class_ref, name, NULL_TREE, 1);
enforce_access (access_type, value);
value
= build_class_member_access_expr (current_class_ref, value,
/*access_path=*/NULL_TREE,
/*preserve_reference=*/false);
}
}
else if ((TREE_CODE (value) == FUNCTION_DECL
&& DECL_FUNCTION_MEMBER_P (value))
......@@ -179,7 +193,7 @@ hack_identifier (value, name)
value = OVL_CURRENT (value);
decl = maybe_dummy_object (DECL_CONTEXT (value), 0);
value = build_component_ref (decl, name, NULL_TREE, 1);
value = finish_class_member_access_expr (decl, name);
}
else if (really_overloaded_fn (value))
;
......
......@@ -1520,11 +1520,11 @@ notype_unqualified_id:
do_id:
{
/* If lastiddecl is a TREE_LIST, it's a baselink, which
means that we're in an expression like S::f<int>, so
don't do_identifier; we only do that for unqualified
/* If lastiddecl is a BASELINK we're in an
expression like S::f<int>, so don't
do_identifier; we only do that for unqualified
identifiers. */
if (!lastiddecl || TREE_CODE (lastiddecl) != TREE_LIST)
if (!lastiddecl || !BASELINK_P (lastiddecl))
$$ = do_identifier ($<ttype>-1, 1, NULL_TREE);
else
$$ = $<ttype>-1;
......@@ -1718,20 +1718,15 @@ primary:
| overqualified_id LEFT_RIGHT
{ $$ = parse_finish_call_expr ($1, NULL_TREE, 0); }
| object object_template_id %prec UNARY
{
$$ = build_x_component_ref ($$, $2, NULL_TREE);
}
{ $$ = finish_class_member_access_expr ($$, $2); }
| object object_template_id '(' nonnull_exprlist ')'
{ $$ = finish_object_call_expr ($2, $1, $4); }
| object object_template_id LEFT_RIGHT
{ $$ = finish_object_call_expr ($2, $1, NULL_TREE); }
| object unqualified_id %prec UNARY
{ $$ = build_x_component_ref ($$, $2, NULL_TREE); }
{ $$ = finish_class_member_access_expr ($$, $2); }
| object overqualified_id %prec UNARY
{ if (processing_template_decl)
$$ = build_min_nt (COMPONENT_REF, $1, $2);
else
$$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
{ $$ = finish_class_member_access_expr ($1, $2); }
| object unqualified_id '(' nonnull_exprlist ')'
{ $$ = finish_object_call_expr ($2, $1, $4); }
| object unqualified_id LEFT_RIGHT
......@@ -4147,14 +4142,20 @@ parse_finish_call_expr (tree fn, tree args, int koenig)
else
template_id = NULL_TREE;
if (TREE_CODE (name) == OVERLOAD)
name = DECL_NAME (get_first_fn (name));
fn = lookup_member (scope, name, /*protect=*/1,
/*prefer_type=*/0);
if (BASELINK_P (fn) && template_id)
BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR,
BASELINK_FUNCTIONS (fn),
template_args);
if (BASELINK_P (name))
fn = name;
else
{
if (TREE_CODE (name) == OVERLOAD)
name = DECL_NAME (get_first_fn (name));
fn = lookup_member (scope, name, /*protect=*/1,
/*prefer_type=*/0);
if (BASELINK_P (fn) && template_id)
BASELINK_FUNCTIONS (fn)
= build_nt (TEMPLATE_ID_EXPR,
BASELINK_FUNCTIONS (fn),
template_args);
}
if (BASELINK_P (fn)
&& current_class_type
&& DERIVED_FROM_P (scope, current_class_type))
......@@ -4216,9 +4217,19 @@ parse_finish_call_expr (tree fn, tree args, int koenig)
if (DERIVED_FROM_P (scope, current_class_type)
&& current_class_ref)
return finish_object_call_expr (fn,
current_class_ref,
args);
{
fn = build_baselink (lookup_base (current_class_type,
scope,
ba_any,
NULL),
TYPE_BINFO (current_class_type),
fn,
/*optype=*/NULL_TREE);
return finish_object_call_expr (fn,
current_class_ref,
args);
}
access_scope = current_class_type;
while (!DERIVED_FROM_P (scope, access_scope))
......
......@@ -3833,10 +3833,20 @@ lookup_template_function (fns, arglist)
my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
|| TREE_CODE (fns) == OVERLOAD
|| BASELINK_P (fns)
|| TREE_CODE (fns) == IDENTIFIER_NODE
|| TREE_CODE (fns) == LOOKUP_EXPR,
20020730);
if (BASELINK_P (fns))
{
BASELINK_FUNCTIONS (fns) = build (TEMPLATE_ID_EXPR,
unknown_type_node,
BASELINK_FUNCTIONS (fns),
arglist);
return fns;
}
type = TREE_TYPE (fns);
if (TREE_CODE (fns) == OVERLOAD || !type)
type = unknown_type_node;
......@@ -8193,8 +8203,8 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
arg = TREE_OPERAND (arg, 1);
/* Strip baselink information. */
while (TREE_CODE (arg) == TREE_LIST)
arg = TREE_VALUE (arg);
if (BASELINK_P (arg))
arg = BASELINK_FUNCTIONS (arg);
if (TREE_CODE (arg) == TEMPLATE_ID_EXPR)
{
......
......@@ -300,8 +300,10 @@ lookup_base_r (binfo, base, access, within_current_scope,
canonical). If KIND_PTR is non-NULL, fill with information about
what kind of base we discovered.
If ba_quiet bit is set in ACCESS, then do not issue an error, and
return NULL_TREE for failure. */
If the base is inaccessible, or ambiguous, and the ba_quiet bit is
not set in ACCESS, then an error is issued and error_mark_node is
returned. If the ba_quiet bit is set, then no error is issued and
NULL_TREE is returned. */
tree
lookup_base (t, base, access, kind_ptr)
......@@ -1385,9 +1387,10 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
|| TREE_CODE (functions) == OVERLOAD,
20020730);
my_friendly_assert (!optype || TYPE_P (optype), 20020730);
my_friendly_assert (TREE_TYPE (functions), 20020805);
baselink = build_tree_list (NULL_TREE, NULL_TREE);
SET_BASELINK_P (baselink);
baselink = build (BASELINK, TREE_TYPE (functions), NULL_TREE,
NULL_TREE, NULL_TREE);
BASELINK_BINFO (baselink) = binfo;
BASELINK_ACCESS_BINFO (baselink) = access_binfo;
BASELINK_FUNCTIONS (baselink) = functions;
......@@ -1522,7 +1525,7 @@ lookup_field (xbasetype, name, protect, want_type)
tree rval = lookup_member (xbasetype, name, protect, want_type);
/* Ignore functions. */
if (rval && TREE_CODE (rval) == TREE_LIST)
if (rval && BASELINK_P (rval))
return NULL_TREE;
return rval;
......@@ -1539,7 +1542,7 @@ lookup_fnfields (xbasetype, name, protect)
tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/0);
/* Ignore non-functions. */
if (rval && TREE_CODE (rval) != TREE_LIST)
if (rval && !BASELINK_P (rval))
return NULL_TREE;
return rval;
......@@ -2436,7 +2439,7 @@ setup_class_bindings (name, type_binding_p)
{
if (BASELINK_P (value_binding))
/* NAME is some overloaded functions. */
value_binding = TREE_VALUE (value_binding);
value_binding = BASELINK_FUNCTIONS (value_binding);
pushdecl_class_level (value_binding);
}
}
......
......@@ -1400,7 +1400,10 @@ finish_object_call_expr (fn, object, args)
}
}
return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
if (name_p (fn))
return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
else
return build_new_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
}
/* Finish a qualified member function call using OBJECT and ARGS as
......
......@@ -595,8 +595,8 @@ identifier_type (decl)
if (looking_for_template && really_overloaded_fn (decl))
{
/* See through a baselink. */
if (TREE_CODE (decl) == TREE_LIST)
decl = TREE_VALUE (decl);
if (TREE_CODE (decl) == BASELINK)
decl = BASELINK_FUNCTIONS (decl);
for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
......
......@@ -964,7 +964,7 @@ really_overloaded_fn (x)
if (BASELINK_P (x))
x = BASELINK_FUNCTIONS (x);
return (TREE_CODE (x) == OVERLOAD
&& (TREE_CHAIN (x) != NULL_TREE
&& (OVL_CHAIN (x)
|| DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (x))));
}
......@@ -2446,8 +2446,8 @@ cxx_unsave_expr_now (tp)
}
/* Returns the kind of special function that DECL (a FUNCTION_DECL)
is. Note that this sfk_none is zero, so this function can be used
as a predicate to test whether or not DECL is a special function. */
is. Note that sfk_none is zero, so this function can be used as a
predicate to test whether or not DECL is a special function. */
special_function_kind
special_function_p (decl)
......@@ -2476,6 +2476,22 @@ special_function_p (decl)
return sfk_none;
}
/* Returns true if and only if NODE is a name, i.e., a node created
by the parser when processing an id-expression. */
bool
name_p (tree node)
{
if (TREE_CODE (node) == TEMPLATE_ID_EXPR)
node = TREE_OPERAND (node, 0);
return (/* An ordinary unqualified name. */
TREE_CODE (node) == IDENTIFIER_NODE
/* A destructor name. */
|| TREE_CODE (node) == BIT_NOT_EXPR
/* A qualified name. */
|| TREE_CODE (node) == SCOPE_REF);
}
/* Returns non-zero if TYPE is a character type, including wchar_t. */
int
......
......@@ -1196,8 +1196,8 @@ build_m_component_ref (datum, component)
| cp_type_quals (TREE_TYPE (datum)));
/* There's no such thing as a mutable pointer-to-member, so
we don't need to deal with that here like we do in
build_component_ref. */
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);
}
}
......
2002-08-07 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/offsetof.C: Tweak error messages.
* g++.old-deja/g++.mike/p10769a.C: Likewise.
2002-08-08 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/bitfld-3.c: New test.
......
......@@ -18,5 +18,5 @@ struct C: public B { };
int main ()
{
return ((unsigned long) &((C*)0)->i) != sizeof(void*); // { dg-warning "offsetof" "" }
return ((unsigned long) &((C*)0)->i) != sizeof(void*); // { dg-warning "offsetof|invalid" "" }
}
......@@ -9,7 +9,7 @@ class A {
public:
void f1a() { ok += 3; }
void f1b() { ok += 5; }
void f2a() { ok += 7; } // gets bogus error XFAIL *-*-*
void f2a() { ok += 7; }
void f2b() { }
static void (*table[2][2])();
void main();
......
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