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