spew.c (yylex): Also return the TYPE_DECL if got_object.

* spew.c (yylex): Also return the TYPE_DECL if got_object.
	Don't clear got_object after '~'.
	* call.c (build_scoped_method_call): Tweak destructor handling.
	(build_method_call): Likewise.
	* pt.c (tsubst_copy, case METHOD_CALL_EXPR): Don't mess with
	TYPE_MAIN_VARIANT for destructors.
	* semantics.c (finish_object_call_expr): Complain about calling a
	TYPE_DECL.

From-SVN: r20256
This commit is contained in:
Jason Merrill 1998-06-05 21:57:05 +00:00 committed by Jason Merrill
parent e211a323f6
commit a47855649e
5 changed files with 77 additions and 34 deletions

View File

@ -1,3 +1,14 @@
1998-06-05 Jason Merrill <jason@yorick.cygnus.com>
* spew.c (yylex): Also return the TYPE_DECL if got_object.
Don't clear got_object after '~'.
* call.c (build_scoped_method_call): Tweak destructor handling.
(build_method_call): Likewise.
* pt.c (tsubst_copy, case METHOD_CALL_EXPR): Don't mess with
TYPE_MAIN_VARIANT for destructors.
* semantics.c (finish_object_call_expr): Complain about calling a
TYPE_DECL.
1998-06-05 Per Bothner <bothner@cygnus.com>
* g++spec.c (lang_specific_pre_link, lang_specific_extra_ofiles):

View File

@ -356,6 +356,7 @@ build_scoped_method_call (exp, basetype, name, parms)
@@ But we do have to check access privileges later. */
tree binfo, decl;
tree type = TREE_TYPE (exp);
tree tmp;
if (type == error_mark_node
|| basetype == error_mark_node)
@ -363,7 +364,8 @@ build_scoped_method_call (exp, basetype, name, parms)
if (processing_template_decl)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
if (TREE_CODE (name) == BIT_NOT_EXPR
&& TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
{
tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
if (type)
@ -384,22 +386,42 @@ build_scoped_method_call (exp, basetype, name, parms)
else
binfo = NULL_TREE;
/* Check the destructor call syntax. */
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
tmp = TREE_OPERAND (name, 0);
if (TREE_CODE (tmp) == TYPE_DECL)
tmp = TREE_TYPE (tmp);
else if (TREE_CODE_CLASS (TREE_CODE (tmp)) == 't')
/* OK */;
else if (TREE_CODE (tmp) == IDENTIFIER_NODE)
{
if (IS_AGGR_TYPE (basetype) && tmp == constructor_name (basetype))
tmp = basetype;
else
tmp = get_type_value (tmp);
}
else
my_friendly_abort (980605);
if (! (tmp && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (tmp)))
{
cp_error ("qualified type `%T' does not match destructor name `~%T'",
basetype, TREE_OPERAND (name, 0));
return error_mark_node;
}
}
/* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
that explicit ~int is caught in the parser; this deals with typedefs
and template parms. */
if (TREE_CODE (name) == BIT_NOT_EXPR && ! IS_AGGR_TYPE (basetype))
{
tree tmp;
if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype))
cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
exp, basetype, type);
name = TREE_OPERAND (name, 0);
if (! (name == TYPE_MAIN_VARIANT (basetype)
|| ((tmp = get_type_value (name))
&& (TYPE_MAIN_VARIANT (basetype)
== TYPE_MAIN_VARIANT (tmp)))))
cp_error ("qualified type `%T' does not match destructor name `~%T'",
basetype, name);
return cp_convert (void_type_node, exp);
}
@ -434,17 +456,6 @@ build_scoped_method_call (exp, basetype, name, parms)
/* Call to a destructor. */
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
/* Explicit call to destructor. */
name = TREE_OPERAND (name, 0);
if (! (name == TYPE_MAIN_VARIANT (TREE_TYPE (decl))
|| name == constructor_name (TREE_TYPE (decl))
|| TREE_TYPE (decl) == get_type_value (name)))
{
cp_error
("qualified type `%T' does not match destructor name `~%T'",
TREE_TYPE (decl), name);
return error_mark_node;
}
if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
return cp_convert (void_type_node, exp);
@ -599,7 +610,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (processing_template_decl)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
if (TREE_CODE (name) == BIT_NOT_EXPR
&& TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
{
tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
if (type)
@ -635,6 +647,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
tree tmp;
flags |= LOOKUP_DESTRUCTOR;
name = TREE_OPERAND (name, 0);
if (parms)
@ -642,14 +655,24 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype = TREE_TYPE (instance);
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
if (! (name == TYPE_MAIN_VARIANT (basetype)
|| (IS_AGGR_TYPE (basetype)
&& name == constructor_name (basetype))
|| ((tmp = get_type_value (name))
&& (TYPE_MAIN_VARIANT (basetype)
== TYPE_MAIN_VARIANT (tmp)))))
if (TREE_CODE (name) == TYPE_DECL)
tmp = TREE_TYPE (name);
else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
tmp = name;
else if (TREE_CODE (name) == IDENTIFIER_NODE)
{
cp_error ("destructor name `~%D' does not match type `%T' of expression",
if (IS_AGGR_TYPE (basetype) && tmp == constructor_name (basetype))
tmp = basetype;
else
tmp = get_type_value (tmp);
}
else
my_friendly_abort (980605);
if (! (tmp && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (tmp)))
{
cp_error ("destructor name `~%T' does not match type `%T' of expression",
name, basetype);
return cp_convert (void_type_node, instance);
}

View File

@ -5220,8 +5220,6 @@ tsubst_copy (t, args, in_decl)
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
name = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl);
if (TREE_CODE (name) != IDENTIFIER_NODE)
name = TYPE_MAIN_VARIANT (name);
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
}
else if (TREE_CODE (name) == SCOPE_REF
@ -5230,8 +5228,6 @@ tsubst_copy (t, args, in_decl)
tree base = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl);
name = TREE_OPERAND (name, 1);
name = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl);
if (TREE_CODE (name) != IDENTIFIER_NODE)
name = TYPE_MAIN_VARIANT (name);
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
name = build_nt (SCOPE_REF, base, name);
}

View File

@ -919,6 +919,12 @@ finish_object_call_expr (fn, object, args)
tree real_fn = build_component_ref (object, fn, NULL_TREE, 1);
return finish_call_expr (real_fn, args);
#else
if (TREE_CODE (fn) == TYPE_DECL)
{
cp_error ("calling type `%T' like a method", fn);
return error_mark_node;
}
return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
#endif
}

View File

@ -327,7 +327,10 @@ yylex ()
case NSNAME:
case PTYPENAME:
lastiddecl = trrr;
if (got_scope)
/* If this got special lookup, remember it. In these cases,
we don't have to worry about being a declarator-id. */
if (got_scope || got_object)
tmp_token.yylval.ttype = trrr;
break;
@ -379,7 +382,11 @@ yylex ()
consume_token ();
}
got_object = NULL_TREE;
/* class member lookup only applies to the first token after the object
expression, except for explicit destructor calls. */
if (tmp_token.yychar != '~')
got_object = NULL_TREE;
yylval = tmp_token.yylval;
yychar = tmp_token.yychar;
end_of_file = tmp_token.end_of_file;