When a friend is declared in a dependent context, don't even try to
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
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index fb5eef2..f7a22d2 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -613,11 +613,19 @@
       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;
 
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index f511eb1..f8f2217 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -434,9 +434,10 @@
   // 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);
   
diff --git a/test/SemaTemplate/friend-template.cpp b/test/SemaTemplate/friend-template.cpp
index dc277f4..84a8e89 100644
--- a/test/SemaTemplate/friend-template.cpp
+++ b/test/SemaTemplate/friend-template.cpp
@@ -72,3 +72,22 @@
 };
 
 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