Re-land "[MS] Don't expect vftables to be provided for extern template instantiations"

Reverts r273305 and re-instates r273296.

We needed to fix a bug in Sema::MarkVTableUsed to ensure that operator
delete lookup occurs when the vtable is referenced. We already had a
special case to look up operator delete when dllimport was used, but I
think should really mark virtual destructors referenced any time the
vtable is used.

llvm-svn: 274147
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index d8bb3d0..948ad5f 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13425,20 +13425,18 @@
     // checks (i.e. operator delete() lookup) when the vtable is marked used, as
     // the deleting destructor is emitted with the vtable, not with the
     // destructor definition as in the Itanium ABI.
-    // If it has a definition, we do the check at that point instead.
     if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-      if (Class->hasUserDeclaredDestructor() &&
-          !Class->getDestructor()->isDefined() &&
-          !Class->getDestructor()->isDeleted()) {
-        CXXDestructorDecl *DD = Class->getDestructor();
-        ContextRAII SavedContext(*this, DD);
-        CheckDestructor(DD);
-      } else if (Class->hasAttr<DLLImportAttr>()) {
-        // We always synthesize vtables on the import side. To make sure
-        // CheckDestructor gets called, mark the destructor referenced.
-        assert(Class->getDestructor() &&
-               "The destructor has always been declared on a dllimport class");
-        MarkFunctionReferenced(Loc, Class->getDestructor());
+      CXXDestructorDecl *DD = Class->getDestructor();
+      if (DD && DD->isVirtual() && !DD->isDeleted()) {
+        if (Class->hasUserDeclaredDestructor() && !DD->isDefined()) {
+          // If this is an out-of-line declaration, marking it referenced will
+          // not do anything. Manually call CheckDestructor to look up operator
+          // delete().
+          ContextRAII SavedContext(*this, DD);
+          CheckDestructor(DD);
+        } else {
+          MarkFunctionReferenced(Loc, Class->getDestructor());
+        }
       }
     }
   }