r174486 - Don't check whether a friend declaration is correctly formed when instantiating,
Nick Lewycky
nicholas at mxc.ca
Tue Feb 5 21:59:33 PST 2013
Author: nicholas
Date: Tue Feb 5 23:59:33 2013
New Revision: 174486
URL: http://llvm.org/viewvc/llvm-project?rev=174486&view=rev
Log:
Don't check whether a friend declaration is correctly formed when instantiating,
we already checked it when parsing.
Modified:
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/class.access/class.friend/p3-cxx0x.cpp
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=174486&r1=174485&r2=174486&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Feb 5 23:59:33 2013
@@ -10304,47 +10304,49 @@ FriendDecl *Sema::CheckFriendTypeDecl(So
// Do not complain about the form of friend template types during
// template instantiation; we will already have complained when the
// template was declared.
- } else if (!T->isElaboratedTypeSpecifier()) {
- // If we evaluated the type to a record type, suggest putting
- // a tag in front.
- if (const RecordType *RT = T->getAs<RecordType>()) {
- RecordDecl *RD = RT->getDecl();
+ } else {
+ if (!T->isElaboratedTypeSpecifier()) {
+ // If we evaluated the type to a record type, suggest putting
+ // a tag in front.
+ if (const RecordType *RT = T->getAs<RecordType>()) {
+ RecordDecl *RD = RT->getDecl();
- std::string InsertionText = std::string(" ") + RD->getKindName();
+ std::string InsertionText = std::string(" ") + RD->getKindName();
- Diag(TypeRange.getBegin(),
- getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_unelaborated_friend_type :
- diag::ext_unelaborated_friend_type)
- << (unsigned) RD->getTagKind()
- << T
- << FixItHint::CreateInsertion(PP.getLocForEndOfToken(FriendLoc),
- InsertionText);
- } else {
+ Diag(TypeRange.getBegin(),
+ getLangOpts().CPlusPlus11 ?
+ diag::warn_cxx98_compat_unelaborated_friend_type :
+ diag::ext_unelaborated_friend_type)
+ << (unsigned) RD->getTagKind()
+ << T
+ << FixItHint::CreateInsertion(PP.getLocForEndOfToken(FriendLoc),
+ InsertionText);
+ } else {
+ Diag(FriendLoc,
+ getLangOpts().CPlusPlus11 ?
+ diag::warn_cxx98_compat_nonclass_type_friend :
+ diag::ext_nonclass_type_friend)
+ << T
+ << TypeRange;
+ }
+ } else if (T->getAs<EnumType>()) {
Diag(FriendLoc,
getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_nonclass_type_friend :
- diag::ext_nonclass_type_friend)
+ diag::warn_cxx98_compat_enum_friend :
+ diag::ext_enum_friend)
<< T
<< TypeRange;
}
- } else if (T->getAs<EnumType>()) {
- Diag(FriendLoc,
- getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_enum_friend :
- diag::ext_enum_friend)
- << T
- << TypeRange;
- }
- // C++11 [class.friend]p3:
- // A friend declaration that does not declare a function shall have one
- // of the following forms:
- // friend elaborated-type-specifier ;
- // friend simple-type-specifier ;
- // friend typename-specifier ;
- if (getLangOpts().CPlusPlus11 && LocStart != FriendLoc)
- Diag(FriendLoc, diag::err_friend_not_first_in_declaration) << T;
+ // C++11 [class.friend]p3:
+ // A friend declaration that does not declare a function shall have one
+ // of the following forms:
+ // friend elaborated-type-specifier ;
+ // friend simple-type-specifier ;
+ // friend typename-specifier ;
+ if (getLangOpts().CPlusPlus11 && LocStart != FriendLoc)
+ Diag(FriendLoc, diag::err_friend_not_first_in_declaration) << T;
+ }
// If the type specifier in a friend declaration designates a (possibly
// cv-qualified) class type, that class is declared as a friend; otherwise,
Modified: cfe/trunk/test/CXX/class.access/class.friend/p3-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/class.friend/p3-cxx0x.cpp?rev=174486&r1=174485&r2=174486&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class.access/class.friend/p3-cxx0x.cpp (original)
+++ cfe/trunk/test/CXX/class.access/class.friend/p3-cxx0x.cpp Tue Feb 5 23:59:33 2013
@@ -28,14 +28,19 @@ X1<Y2> x1a;
X1<Y3> x1b;
X1<Y1> x1c; // expected-note{{in instantiation of template class 'X1<Y1>' requested here}}
+template<typename T> class B;
+
template<typename T>
class A {
T x;
public:
class foo {};
static int y;
+ template <typename S> friend class B<S>::ty;
};
+template <typename T> class B { typedef int ty; };
+
struct {
// Ill-formed
int friend; // expected-error {{'friend' must appear first in a non-function declaration}}
@@ -53,3 +58,5 @@ struct {
float;
template<typename T> friend class A<T>::foo;
} a;
+
+void testA() { (void)sizeof(A<int>); }
More information about the cfe-commits
mailing list