Improve key-function computation for templates. In particular:
  - All classes can have a key function; templates don't change that.
  non-template classes when computing the key function.
  - We always mark all of the virtual member functions of class
  template instantiations. 
  - The vtable for an instantiation of a class template has weak
  linkage. 

We could probably use available_externally linkage for vtables of
classes instantiated by explicit instantiation declarations (extern
templates), but GCC doesn't do this and I'm not 100% that the ABI
permits it.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92753 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 204d776..ecf95d7 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5702,19 +5702,31 @@
       ClassesWithUnmarkedVirtualMembers.insert(std::make_pair(RD, Loc));
     return;
   }
-  
-  const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
 
-  if (!KeyFunction) {
-    // This record does not have a key function, so we assume that the vtable
-    // will be emitted when it's used by the constructor.
-    if (!isa<CXXConstructorDecl>(MD))
+  switch (RD->getTemplateSpecializationKind()) {
+  case TSK_Undeclared:
+  case TSK_ExplicitSpecialization: {
+    const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
+
+    if (!KeyFunction) {
+      // This record does not have a key function, so we assume that the vtable
+      // will be emitted when it's used by the constructor.
+      if (!isa<CXXConstructorDecl>(MD))
+        return;
+    } else if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) {
+      // We don't have the right key function.
       return;
-  } else if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) {
-    // We don't have the right key function.
-    return;
+    }
+    break;
   }
-  
+
+  case TSK_ImplicitInstantiation:
+  case TSK_ExplicitInstantiationDeclaration:
+  case TSK_ExplicitInstantiationDefinition:
+    // Always mark the virtual members of an instantiated template.
+    break;
+  }
+
   // Mark the members as referenced.
   MarkVirtualMembersReferenced(Loc, RD);
   ClassesWithUnmarkedVirtualMembers.erase(RD);