OSDN Git Service

PR c++/51852
[pf3gnuchains/gcc-fork.git] / gcc / cp / friend.c
index 090f84d..e532a30 100644 (file)
@@ -1,6 +1,6 @@
 /* Help friends in C++.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2007, 2008  Free Software Foundation, Inc.
+   2007, 2008, 2010, 2011  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -23,12 +23,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "rtl.h"
-#include "expr.h"
 #include "cp-tree.h"
 #include "flags.h"
 #include "output.h"
-#include "toplev.h"
 
 /* Friend data structures are described in cp-tree.h.  */
 
@@ -229,10 +226,19 @@ make_friend_class (tree type, tree friend_type, bool complain)
 
   if (! MAYBE_CLASS_TYPE_P (friend_type))
     {
-      error ("invalid type %qT declared %<friend%>", friend_type);
+      /* N1791: If the type specifier in a friend declaration designates a
+        (possibly cv-qualified) class type, that class is declared as a
+        friend; otherwise, the friend declaration is ignored.
+
+         So don't complain in C++0x mode.  */
+      if (cxx_dialect < cxx0x)
+       pedwarn (input_location, complain ? 0 : OPT_pedantic,
+                "invalid type %qT declared %<friend%>", friend_type);
       return;
     }
 
+  friend_type = cv_unqualified (friend_type);
+
   if (friend_depth)
     /* If the TYPE is a template then it makes sense for it to be
        friends with itself; this means that each instantiation is
@@ -308,7 +314,7 @@ make_friend_class (tree type, tree friend_type, bool complain)
            }
          else
            {
-             decl = lookup_member (ctype, name, 0, true);
+             decl = lookup_member (ctype, name, 0, true, tf_warning_or_error);
              if (!decl)
                {
                  error ("%qT is not a member of %qT", name, ctype);
@@ -568,11 +574,13 @@ do_friend (tree ctype, tree declarator, tree decl,
          if (warn)
            {
              static int explained;
-             warning (OPT_Wnon_template_friend, "friend declaration "
-                      "%q#D declares a non-template function", decl);
-             if (! explained)
+             bool warned;
+
+             warned = warning (OPT_Wnon_template_friend, "friend declaration "
+                               "%q#D declares a non-template function", decl);
+             if (! explained && warned)
                {
-                 inform ("(if this is not what you intended, make sure "
+                 inform (input_location, "(if this is not what you intended, make sure "
                          "the function template has already been declared "
                          "and add <> after the function name here) ");
                  explained = 1;