aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1998-06-05 21:57:05 +0000
committerJason Merrill <jason@gcc.gnu.org>1998-06-05 17:57:05 -0400
commita47855649e55188ed94ed6d3f5c4d884df71fe50 (patch)
tree0d8b3af3ac0f813a34ca81018ae0dc5d23965642 /gcc
parente211a323f625b6a8a49d13f644ef21f76d0e2453 (diff)
downloadgcc-a47855649e55188ed94ed6d3f5c4d884df71fe50.zip
gcc-a47855649e55188ed94ed6d3f5c4d884df71fe50.tar.gz
gcc-a47855649e55188ed94ed6d3f5c4d884df71fe50.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/call.c79
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/cp/semantics.c6
-rw-r--r--gcc/cp/spew.c11
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 <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):
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;