[cfe-commits] r83672 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/SemaTemplate/friend-template.cpp

Douglas Gregor dgregor at apple.com
Fri Oct 9 14:11:42 PDT 2009


Author: dgregor
Date: Fri Oct  9 16:11:42 2009
New Revision: 83672

URL: http://llvm.org/viewvc/llvm-project?rev=83672&view=rev
Log:
When declaring a friend class template, we may end up finding an
injected-class-name (e.g., when we're referring to other
specializations of the current class template). Make sure that we see
the template rather than the injected-class-name. Fixes PR4768.

Modified:
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/SemaTemplate/friend-template.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=83672&r1=83671&r2=83672&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Oct  9 16:11:42 2009
@@ -616,6 +616,22 @@
   // whether this is a valid redeclaration.
   ClassTemplateDecl *PrevClassTemplate
     = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);
+
+  // We may have found the injected-class-name of a class template,
+  // class template partial specialization, or class template specialization. 
+  // In these cases, grab the template that is being defined or specialized.
+  if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) && 
+      cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) {
+    PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext());
+    PrevClassTemplate 
+      = cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate();
+    if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) {
+      PrevClassTemplate
+        = cast<ClassTemplateSpecializationDecl>(PrevDecl)
+            ->getSpecializedTemplate();
+    }
+  }
+
   if (PrevClassTemplate) {
     // Ensure that the template parameter lists are compatible.
     if (!TemplateParameterListsAreEqual(TemplateParams,

Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=83672&r1=83671&r2=83672&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/friend-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/friend-template.cpp Fri Oct  9 16:11:42 2009
@@ -28,3 +28,19 @@
   template<typename T> void f0(T) { }
   template<typename T> void f1(T) { } // expected-error{{redefinition}}
 }
+
+// PR4768
+template<typename T>
+struct X0 {
+  template<typename U> friend struct X0;
+};
+
+template<typename T>
+struct X0<T*> {
+  template<typename U> friend struct X0;
+};
+
+template<>
+struct X0<int> {
+  template<typename U> friend struct X0;
+};





More information about the cfe-commits mailing list