search.c (get_abstract_virtuals): Complain about virtuals with no final overrider.
[platform/upstream/gcc.git] / gcc / cp / friend.c
index 89c7928..0b71f09 100644 (file)
@@ -64,7 +64,7 @@ is_friend (type, supplicant)
              tree friends = TREE_VALUE (list);
              for (; friends ; friends = TREE_CHAIN (friends))
                {
-                 if (comptypes (ctype, TREE_PURPOSE (friends), 1))
+                 if (same_type_p (ctype, TREE_PURPOSE (friends)))
                    return 1;
 
                  if (TREE_VALUE (friends) == NULL_TREE)
@@ -86,8 +86,8 @@ is_friend (type, supplicant)
                     FUNCTION_MEMBER_P bit can go.  */
                  if ((flag_guiding_decls 
                       || DECL_FUNCTION_MEMBER_P (supplicant))
-                     && comptypes (TREE_TYPE (supplicant),
-                                   TREE_TYPE (TREE_VALUE (friends)), 1))
+                     && same_type_p (TREE_TYPE (supplicant),
+                                     TREE_TYPE (TREE_VALUE (friends))))
                    return 1;
 
                  if (TREE_CODE (TREE_VALUE (friends)) == TEMPLATE_DECL
@@ -112,7 +112,7 @@ is_friend (type, supplicant)
 
          if (TREE_CODE (t) == TEMPLATE_DECL ? 
              is_specialization_of (TYPE_MAIN_DECL (supplicant), t) :
-             comptypes (supplicant, t, 1))
+             same_type_p (supplicant, t))
            return 1;
        }
     }      
@@ -255,10 +255,9 @@ make_friend_class (type, friend_type)
       error ("`friend' declaration in signature definition");
       return;
     }
-  if (IS_SIGNATURE (friend_type))
+  if (IS_SIGNATURE (friend_type) || ! IS_AGGR_TYPE (friend_type))
     {
-      error ("signature type `%s' declared `friend'",
-            IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type)));
+      cp_error ("invalid type `%T' declared `friend'", friend_type);
       return;
     }
 
@@ -279,7 +278,7 @@ make_friend_class (type, friend_type)
        friends with itself; this means that each instantiation is
        friends with all other instantiations.  */
     is_template_friend = 1;
-  else if (comptypes (type, friend_type, 1))
+  else if (same_type_p (type, friend_type))
     {
       pedwarn ("class `%s' is implicitly friends with itself",
               TYPE_NAME_STRING (type));
@@ -298,7 +297,7 @@ make_friend_class (type, friend_type)
         /* Stop if we find the same type on the list.  */
         && !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ?
              friend_type == TREE_VALUE (classes) :
-             comptypes (TREE_VALUE (classes), friend_type, 1)))
+             same_type_p (TREE_VALUE (classes), friend_type)))
     classes = TREE_CHAIN (classes);
   if (classes) 
     cp_warning ("`%T' is already a friend of `%T'",
@@ -367,26 +366,27 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
            DECL_CONSTRUCTOR_P (decl) = 1;
 
          /* This will set up DECL_ARGUMENTS for us.  */
-         grokclassfn (ctype, cname, decl, flags, quals);
+         grokclassfn (ctype, decl, flags, quals);
 
          if (is_friend_template)
            decl = DECL_TI_TEMPLATE (push_template_decl (decl));
 
-         if (TYPE_SIZE (ctype) != 0 && template_class_depth (ctype) == 0)
-           decl = check_classfn (ctype, decl);
-
-         /* TYPE_BEING_DEFINED is a hack for nested classes having
-             member functions of the enclosing class as friends. Will
-             go away as parsing of classes gets rewritten. */
-         if (TREE_TYPE (decl) != error_mark_node)
+         /* A nested class may declare a member of an enclosing class
+            to be a friend, so we do lookup here even if CTYPE is in
+            the process of being defined.  */
+         if (TYPE_SIZE (ctype) != 0 || TYPE_BEING_DEFINED (ctype))
            {
-             if (TYPE_BEING_DEFINED (ctype) ||
-                 TYPE_SIZE (ctype) || template_class_depth (ctype) > 0)
+             /* But, we defer looup in template specializations until
+                they are fully specialized.  */
+             if (template_class_depth (ctype) == 0)
+               decl = check_classfn (ctype, decl);
+
+             if (decl)
                add_friend (current_class_type, decl);
-             else
-               cp_error ("member `%D' declared as friend before type `%T' defined",
-                         decl, ctype);
            }
+         else
+           cp_error ("member `%D' declared as friend before type `%T' defined",
+                     decl, ctype);
        }
       else
        {
@@ -404,20 +404,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
          decl = void_type_node;
        }
     }
-  else if (TREE_CODE (decl) == FUNCTION_DECL
-          && (MAIN_NAME_P (declarator)
-              || (IDENTIFIER_LENGTH (declarator) > 10
-                  && IDENTIFIER_POINTER (declarator)[0] == '_'
-                  && IDENTIFIER_POINTER (declarator)[1] == '_'
-                  && strncmp (IDENTIFIER_POINTER (declarator)+2,
-                              "builtin_", 8) == 0)))
-    {
-      /* raw "main", and builtin functions never gets overloaded,
-        but they can become friends.  */
-      add_friend (current_class_type, decl);
-      DECL_FRIEND_P (decl) = 1;
-      decl = void_type_node;
-    }
   /* A global friend.
      @@ or possibly a friend from a base class ?!?  */
   else if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -427,7 +413,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
 
         Note that because classes all wind up being top-level
         in their scope, their friend wind up in top-level scope as well.  */
-      set_mangled_name_for_decl (decl);
       DECL_ARGUMENTS (decl) = parmdecls;
       if (funcdef_flag)
        DECL_CLASS_CONTEXT (decl) = current_class_type;