[cfe-commits] r78332 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclCXX.cpp test/CXX/class/class.friend/p1.cpp
John McCall
rjmccall at apple.com
Thu Aug 6 13:49:32 PDT 2009
Author: rjmccall
Date: Thu Aug 6 15:49:32 2009
New Revision: 78332
URL: http://llvm.org/viewvc/llvm-project?rev=78332&view=rev
Log:
Permit a class to friend its members in C++0x, without restriction.
Permit a class to friend its class members in C++ 98, as long as extensions
are enabled (and even when they aren't, only give an extwarn about it).
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/class/class.friend/p1.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=78332&r1=78331&r2=78332&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Aug 6 15:49:32 2009
@@ -299,6 +299,8 @@
"friends can only be classes or functions">;
def err_friend_is_member : Error<
"friends cannot be members of the declaring class">;
+def extwarn_friend_inner_class : ExtWarn<
+ "C++ 98 does not allow inner classes as friends">;
def err_unelaborated_friend_type : Error<
"must specify '%select{class|union}0' in a friend "
"%select{class|union}0 declaration">;
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=78332&r1=78331&r2=78332&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Aug 6 15:49:32 2009
@@ -3359,12 +3359,20 @@
Diag(DS.getFriendSpecLoc(), diag::err_friend_decl_defines_class)
<< RD->getSourceRange();
- // C++ [class.friend]p1: A friend of a class is a function or
- // class that is not a member of the class . . .
- // Definitions currently get treated in a way that causes this
- // error, so only report it if we didn't see a definition.
- else if (RD->getDeclContext() == CurContext)
- Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
+ // C++98 [class.friend]p1: A friend of a class is a function
+ // or class that is not a member of the class . . .
+ // But that's a silly restriction which nobody implements for
+ // inner classes, and C++0x removes it anyway, so we only report
+ // this
+ // But no-one implements it that way, and C++0x removes this
+ // restriction, so we only report it (as a warning) if we're being
+ // pedantic. Ideally this would real -pedantic mode
+ //
+ // Also, definitions currently get treated in a way that causes
+ // this error, so only report it if we didn't see a definition.
+ else if (RD->getDeclContext() == CurContext &&
+ !(getLangOptions().CPlusPlus0x || getLangOptions().GNUMode))
+ Diag(DS.getFriendSpecLoc(), diag::extwarn_friend_inner_class);
return DeclPtrTy::make(RD);
}
@@ -3468,7 +3476,10 @@
// C++ [class.friend]p1: A friend of a class is a function or
// class that is not a member of the class . . .
- if (FD && DC == CurContext)
+ // C++0x changes this for both friend types and functions.
+ // Most C++ 98 compilers do seem to give an error here, so
+ // we do, too.
+ if (FD && DC == CurContext && !getLangOptions().CPlusPlus0x)
Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
}
Modified: cfe/trunk/test/CXX/class/class.friend/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.friend/p1.cpp?rev=78332&r1=78331&r2=78332&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.friend/p1.cpp (original)
+++ cfe/trunk/test/CXX/class/class.friend/p1.cpp Thu Aug 6 15:49:32 2009
@@ -32,8 +32,8 @@
void a_member();
friend void A::a_member(); // expected-error {{ friends cannot be members of the declaring class }}
friend void a_member(); // okay (because we ignore class scopes when looking up friends)
- friend class A::AInner; // expected-error {{ friends cannot be members of the declaring class }}
- friend class AInner; // expected-error {{ friends cannot be members of the declaring class }}
+ friend class A::AInner; // this is okay as an extension
+ friend class AInner; // okay, refers to ::AInner
friend void Derived::missing_member(); // expected-error {{ no function named 'missing_member' with type 'void ()' was found in the specified scope }}
More information about the cfe-commits
mailing list