spew.c (yylex): Also return the TYPE_DECL if got_object.
authorJason Merrill <jason@yorick.cygnus.com>
Fri, 5 Jun 1998 21:57:05 +0000 (21:57 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 5 Jun 1998 21:57:05 +0000 (17:57 -0400)
* 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
gcc/cp/call.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/spew.c

index 94090a4277cac7953e0155c4a77209a9667fd5ca..04ff5dc88eb29a57ab4bd2b2f11d24bd6dc5fa33 100644 (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):
index 03cc6f36506e398d68c238189260d2fc912fec58..7007cdf44ed2ca2fbd951f7be56e680ae426838f 100644 (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)
+       {
+         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);
        }
index 765f8368c5fac729606dece1bd9488c9c156687d..c5c98f81a1474971f0bf4ff90d803c2dec473d94 100644 (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);
          }
index c888f5bbc9cd75101243b84a181a2441bbc2bc1a..c2d687539d0ebe10ebc2736878bdb88a10dcf752 100644 (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
 }
index 0c9e4e39918f4f5e40c80835e7c999be98d8299a..1d2cea1d46f1e4f21ff57a4e7d16d4b87fd50565 100644 (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;