[PATCH] D21544: [MS] Don't expect vftables to be provided for extern template instantiations

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 20 18:21:19 PDT 2016


rnk created this revision.
rnk added a reviewer: majnemer.
rnk added a subscriber: cfe-commits.

MSVC doesn't provide them. PR28223

I left behind the machinery in case we want to resurrect available_externally
vftable emission to support devirtualization.

http://reviews.llvm.org/D21544

Files:
  lib/AST/VTableBuilder.cpp
  lib/CodeGen/CGVTables.cpp
  test/CodeGenCXX/microsoft-abi-vbtables.cpp
  test/CodeGenCXX/microsoft-abi-vftables.cpp

Index: test/CodeGenCXX/microsoft-abi-vftables.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -33,7 +33,7 @@
 
 namespace {
 struct W {
-  virtual ~W();
+  virtual ~W() {}
 } w;
 }
 // RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI at Z" to i8*)]
@@ -49,5 +49,7 @@
 
 extern template class Y<int>;
 template Y<int>::Y();
-// RTTI-DAG: @"\01??_7?$Y at H@@6B@" = external unnamed_addr constant [1 x i8*]
-// NO-RTTI-DAG: @"\01??_7?$Y at H@@6B@" = external unnamed_addr constant [1 x i8*]
+// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$Y at H@@6B@" to i8*), i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y at H@@UAEPAXI at Z" to i8*)], comdat($"\01??_7?$Y at H@@6B@")
+// RTTI-DAG: @"\01??_7?$Y at H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_Y]], i32 0, i32 1)
+
+// NO-RTTI-DAG: @"\01??_7?$Y at H@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y at H@@UAEPAXI at Z" to i8*)], comdat
Index: test/CodeGenCXX/microsoft-abi-vbtables.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-vbtables.cpp
+++ test/CodeGenCXX/microsoft-abi-vbtables.cpp
@@ -537,5 +537,5 @@
 
 extern template class B<int>;
 template B<int>::B();
-// CHECK-DAG: @"\01??_8?$B at H@Test30@@7B@" = external unnamed_addr constant [2 x i32]{{$}}
+// CHECK-DAG: @"\01??_8?$B at H@Test30@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 4], comdat
 }
Index: lib/CodeGen/CGVTables.cpp
===================================================================
--- lib/CodeGen/CGVTables.cpp
+++ lib/CodeGen/CGVTables.cpp
@@ -794,6 +794,10 @@
       return DiscardableODRLinkage;
 
     case TSK_ExplicitInstantiationDeclaration:
+      // Explicit instantiations in MSVC do not provide vtables, so we must emit
+      // our own.
+      if (getTarget().getCXXABI().isMicrosoft())
+        return DiscardableODRLinkage;
       return shouldEmitAvailableExternallyVTable(*this, RD)
                  ? llvm::GlobalVariable::AvailableExternallyLinkage
                  : llvm::GlobalVariable::ExternalLinkage;
@@ -839,9 +843,9 @@
 bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
   assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");
 
-  // We always synthesize vtables on the import side regardless of whether or
-  // not it is an explicit instantiation declaration.
-  if (CGM.getTarget().getCXXABI().isMicrosoft() && RD->hasAttr<DLLImportAttr>())
+  // We always synthesize vtables if they are needed in the MS ABI. MSVC doesn't
+  // emit them even if there is an explicit template instantiation.
+  if (CGM.getTarget().getCXXABI().isMicrosoft())
     return false;
 
   // If we have an explicit instantiation declaration (and not a
Index: lib/AST/VTableBuilder.cpp
===================================================================
--- lib/AST/VTableBuilder.cpp
+++ lib/AST/VTableBuilder.cpp
@@ -2545,14 +2545,13 @@
         MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)),
         WhichVFPtr(*Which),
         Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
-    // Only include the RTTI component if we know that we will provide a
-    // definition of the vftable.  We always provide the definition of
-    // dllimported classes.
+    // Provide the RTTI component if RTTIData is enabled. If the vftable would
+    // be available externally, we should not provide the RTTI componenent. It
+    // is currently impossible to get available externally vftables with either
+    // dllimport or extern template instantiations, but eventually we may add a
+    // flag to support additional devirtualization that needs this.
     if (Context.getLangOpts().RTTIData)
-      if (MostDerivedClass->hasAttr<DLLImportAttr>() ||
-          MostDerivedClass->getTemplateSpecializationKind() !=
-              TSK_ExplicitInstantiationDeclaration)
-        HasRTTIComponent = true;
+      HasRTTIComponent = true;
 
     LayoutVFTable();
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D21544.61331.patch
Type: text/x-patch
Size: 4312 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160621/1e4db059/attachment.bin>


More information about the cfe-commits mailing list