]> granicus.if.org Git - clang/commitdiff
When a friend is declared in a dependent context, don't even try to
authorDouglas Gregor <dgregor@apple.com>
Fri, 30 Oct 2009 22:42:42 +0000 (22:42 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 30 Oct 2009 22:42:42 +0000 (22:42 +0000)
match it up with a declaration in the outer scope.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85628 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/friend-template.cpp

index fb5eef276058cd9e7b2b8134e63d99aab39f73d2..f7a22d2eb0361f97b85fc4ffbedfac0dedbad583 100644 (file)
@@ -613,11 +613,19 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
       SemanticContext = PrevDecl->getDeclContext();
     } else {
       // Declarations in outer scopes don't matter. However, the outermost
-      // context we computed is the semntic context for our new 
+      // context we computed is the semantic context for our new 
       // declaration.
       PrevDecl = 0;
       SemanticContext = OutermostContext;
     }
+    
+    if (CurContext->isDependentContext()) {
+      // If this is a dependent context, we don't want to link the friend
+      // class template to the template in scope, because that would perform
+      // checking of the template parameter lists that can't be performed
+      // until the outer context is instantiated.
+      PrevDecl = 0;
+    }
   } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S))
     PrevDecl = 0;
 
index f511eb15d2958c1d550671cba9299d4f720c0b0b..f8f22174645e4a0637768366456ee75b12f87194 100644 (file)
@@ -434,9 +434,10 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   // Trigger creation of the type for the instantiation.
   SemaRef.Context.getTypeDeclType(RecordInst);
   
-  // We're done with friends now.
-  if (Inst->getFriendObjectKind())
+  // Finish handling of friends.
+  if (Inst->getFriendObjectKind()) {
     return Inst;
+  }
   
   Owner->addDecl(Inst);
   
index dc277f4657caaf174858eb85c0665d27992c3880..84a8e899dbeab5252338d1ec58b53f4f362cf4fa 100644 (file)
@@ -72,3 +72,22 @@ class Foo {
 };
 
 Foo<int> foo;
+
+template<typename T, T Value>
+struct X2a;
+
+template<typename T, int Size>
+struct X2b;
+
+template<typename T>
+class X3 {
+  template<typename U, U Value>
+  friend struct X2a;
+
+  template<typename U, T Value>
+  friend struct X2b;
+};
+
+X3<int> x3i; // okay
+
+X3<long> x3l; // FIXME: should cause an instantiation-time failure