From a47855649e55188ed94ed6d3f5c4d884df71fe50 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 5 Jun 1998 21:57:05 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 11 ++++++++ gcc/cp/call.c | 79 +++++++++++++++++++++++++++++++++++------------------- gcc/cp/pt.c | 4 --- gcc/cp/semantics.c | 6 +++++ gcc/cp/spew.c | 11 ++++++-- 5 files changed, 77 insertions(+), 34 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 94090a4..04ff5dc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +1998-06-05 Jason Merrill + + * 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 * g++spec.c (lang_specific_pre_link, lang_specific_extra_ofiles): diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 03cc6f3..7007cdf 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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) + { + 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 `~%D' does not match type `%T' of expression", + cp_error ("destructor name `~%T' does not match type `%T' of expression", name, basetype); return cp_convert (void_type_node, instance); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 765f836..c5c98f8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c888f5b..c2d6875 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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 } diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c index 0c9e4e3..1d2cea1 100644 --- a/gcc/cp/spew.c +++ b/gcc/cp/spew.c @@ -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; -- 2.7.4