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:
parent
e211a323f6
commit
a47855649e
|
@ -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):
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue