]> granicus.if.org Git - clang/commitdiff
Revert "[MS] Don't expect vftables to be provided for extern template instantiations"
authorReid Kleckner <rnk@google.com>
Tue, 21 Jun 2016 19:51:52 +0000 (19:51 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 21 Jun 2016 19:51:52 +0000 (19:51 +0000)
This reverts commit r273296, it broke the Windows self-host.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273305 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 640fbf47aeab5e5f7842bdaad762f900bc959cd7..e43acc4de78f06af6493cdbe7f57c0341db69cba 100644 (file)
@@ -2545,13 +2545,14 @@ public:
         MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)),
         WhichVFPtr(*Which),
         Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
-    // 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.
+    // 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.
     if (Context.getLangOpts().RTTIData)
-      HasRTTIComponent = true;
+      if (MostDerivedClass->hasAttr<DLLImportAttr>() ||
+          MostDerivedClass->getTemplateSpecializationKind() !=
+              TSK_ExplicitInstantiationDeclaration)
+        HasRTTIComponent = true;
 
     LayoutVFTable();
 
index da9b7421879bf60039221d94514b1c1dacfd6f7f..38461446de585c82d2d06ac369028a6b42609fab 100644 (file)
@@ -794,10 +794,6 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
       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;
@@ -843,9 +839,9 @@ CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
 bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
   assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");
 
-  // 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())
+  // 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>())
     return false;
 
   // If we have an explicit instantiation declaration (and not a
index df0689423872c29401bba93ee111ea154dc5f83a..9cce6f8698c8f35b0713069d0bf03e4b85c78509 100644 (file)
@@ -537,5 +537,5 @@ template <class> struct B : virtual A {
 
 extern template class B<int>;
 template B<int>::B();
-// CHECK-DAG: @"\01??_8?$B@H@Test30@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 4], comdat
+// CHECK-DAG: @"\01??_8?$B@H@Test30@@7B@" = external unnamed_addr constant [2 x i32]{{$}}
 }
index 0c9b58bbb4d40efa2b938bdc93225fe8542c12a9..d94c9c1a90931473c682877974a7cfcc2c63a55f 100644 (file)
@@ -33,7 +33,7 @@ struct __declspec(dllexport) V {
 
 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@Z" to i8*)]
@@ -49,7 +49,5 @@ template <class> struct Y : virtual X {
 
 extern template class Y<int>;
 template Y<int>::Y();
-// RTTI-DAG: [[VTABLE_Y:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$Y@H@@6B@" to i8*), i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)], comdat($"\01??_7?$Y@H@@6B@")
-// RTTI-DAG: @"\01??_7?$Y@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@H@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (i8* (%struct.Y*, i32)* @"\01??_G?$Y@H@@UAEPAXI@Z" to i8*)], comdat
+// RTTI-DAG: @"\01??_7?$Y@H@@6B@" = external unnamed_addr constant [1 x i8*]
+// NO-RTTI-DAG: @"\01??_7?$Y@H@@6B@" = external unnamed_addr constant [1 x i8*]