Ensure code generation for friend declarations in class templates.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80418 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 4cb5a27..521394b 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -37,7 +37,7 @@
   if (!Ctx)
     Ctx = D->getDeclContext();
   
-  for (; !Ctx->isFileContext(); Ctx = Ctx->getParent()) {
+  while (!Ctx->isFileContext()) {
     // Add template arguments from a class template instantiation.
     if (ClassTemplateSpecializationDecl *Spec 
           = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
@@ -46,18 +46,26 @@
         break;
       
       Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
-      continue;
     } 
     
     // Add template arguments from a function template specialization.
-    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
+    else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
       // FIXME: Check whether this is an explicit specialization.
       if (const TemplateArgumentList *TemplateArgs
             = Function->getTemplateSpecializationArgs())
         Result.addOuterTemplateArguments(TemplateArgs);
-      
-      continue;
+
+      // If this is a friend declaration and it declares an entity at
+      // namespace scope, take arguments from its lexical parent
+      // instead of its semantic parent.
+      if (Function->getFriendObjectKind() &&
+          Function->getDeclContext()->isFileContext()) {
+        Ctx = Function->getLexicalDeclContext();
+        continue;
+      }
     }
+
+    Ctx = Ctx->getParent();
   }
   
   return Result;