r260548 - Revert "Revert r260388 "[MS ABI] Never reference dllimport'd vtables""

David Majnemer via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 11 09:49:28 PST 2016


Author: majnemer
Date: Thu Feb 11 11:49:28 2016
New Revision: 260548

URL: http://llvm.org/viewvc/llvm-project?rev=260548&view=rev
Log:
Revert "Revert r260388 "[MS ABI] Never reference dllimport'd vtables""

This reverts commit r260449.

We would supress our emission of vftable definitions if we thought
another translation unit would provide the definition because we saw an
explicit instantiation declaration.  This is not the case with
dllimport, we want to synthesize a definition of the vftable regardless.

This fixes PR26569.

Added:
    cfe/trunk/test/CodeGenCXX/PR26569.cpp
Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/lib/AST/VTableBuilder.cpp
    cfe/trunk/lib/CodeGen/CGVTables.cpp
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
    cfe/trunk/test/CodeGenCXX/dllimport-rtti.cpp
    cfe/trunk/test/CodeGenCXX/dllimport.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-vftables.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=260548&r1=260547&r2=260548&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Feb 11 11:49:28 2016
@@ -2599,7 +2599,10 @@ void MicrosoftMangleContextImpl::mangleC
   // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
   // is always '6' for vftables.
   MicrosoftCXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "\01??_7";
+  if (Derived->hasAttr<DLLImportAttr>())
+    Mangler.getStream() << "\01??_S";
+  else
+    Mangler.getStream() << "\01??_7";
   Mangler.mangleName(Derived);
   Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
   for (const CXXRecordDecl *RD : BasePath)

Modified: cfe/trunk/lib/AST/VTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/VTableBuilder.cpp?rev=260548&r1=260547&r2=260548&view=diff
==============================================================================
--- cfe/trunk/lib/AST/VTableBuilder.cpp (original)
+++ cfe/trunk/lib/AST/VTableBuilder.cpp Thu Feb 11 11:49:28 2016
@@ -2416,7 +2416,7 @@ private:
   MethodVFTableLocationsTy MethodVFTableLocations;
 
   /// \brief Does this class have an RTTI component?
-  bool HasRTTIComponent;
+  bool HasRTTIComponent = false;
 
   /// MethodInfo - Contains information about a method in a vtable.
   /// (Used for computing 'this' pointer adjustment thunks.
@@ -2546,11 +2546,13 @@ public:
         WhichVFPtr(*Which),
         Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
     // Only include the RTTI component if we know that we will provide a
-    // definition of the vftable.
-    HasRTTIComponent = Context.getLangOpts().RTTIData &&
-                       !MostDerivedClass->hasAttr<DLLImportAttr>() &&
-                       MostDerivedClass->getTemplateSpecializationKind() !=
-                           TSK_ExplicitInstantiationDeclaration;
+    // definition of the vftable.  We always provide the definition of
+    // dllimported classes.
+    if (Context.getLangOpts().RTTIData)
+      if (MostDerivedClass->hasAttr<DLLImportAttr>() ||
+          MostDerivedClass->getTemplateSpecializationKind() !=
+              TSK_ExplicitInstantiationDeclaration)
+        HasRTTIComponent = true;
 
     LayoutVFTable();
 

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=260548&r1=260547&r2=260548&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Thu Feb 11 11:49:28 2016
@@ -838,6 +838,11 @@ CodeGenVTables::GenerateClassData(const
 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>())
+    return false;
+
   // If we have an explicit instantiation declaration (and not a
   // definition), the vtable is defined elsewhere.
   TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=260548&r1=260547&r2=260548&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Feb 11 11:49:28 2016
@@ -1673,7 +1673,16 @@ llvm::GlobalVariable *MicrosoftCXXABI::g
   SmallString<256> VFTableName;
   mangleVFTableName(getMangleContext(), RD, VFPtr, VFTableName);
 
-  llvm::GlobalValue::LinkageTypes VFTableLinkage = CGM.getVTableLinkage(RD);
+  // Classes marked __declspec(dllimport) need vftables generated on the
+  // import-side in order to support features like constexpr.  No other
+  // translation unit relies on the emission of the local vftable, translation
+  // units are expected to generate them as needed.
+  //
+  // Because of this unique behavior, we maintain this logic here instead of
+  // getVTableLinkage.
+  llvm::GlobalValue::LinkageTypes VFTableLinkage =
+      RD->hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
+                                   : CGM.getVTableLinkage(RD);
   bool VFTableComesFromAnotherTU =
       llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
       llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
@@ -1746,9 +1755,7 @@ llvm::GlobalVariable *MicrosoftCXXABI::g
   if (C)
     VTable->setComdat(C);
 
-  if (RD->hasAttr<DLLImportAttr>())
-    VFTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
-  else if (RD->hasAttr<DLLExportAttr>())
+  if (RD->hasAttr<DLLExportAttr>())
     VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
 
   VFTablesMap[ID] = VFTable;

Added: cfe/trunk/test/CodeGenCXX/PR26569.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/PR26569.cpp?rev=260548&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/PR26569.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/PR26569.cpp Thu Feb 11 11:49:28 2016
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -emit-llvm -O1 -disable-llvm-optzns %s -o - | FileCheck %s
+
+class A {
+  virtual void m_fn1();
+};
+template <typename>
+class B : A {};
+
+extern template class __declspec(dllimport) B<int>;
+class __declspec(dllexport) C : B<int> {};
+
+// CHECK: @[[VTABLE_C:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1 at A@@EAEXXZ" to i8*)]
+// CHECK: @[[VTABLE_B:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4?$B at H@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1 at A@@EAEXXZ" to i8*)], comdat($"\01??_S?$B at H@@6B@")
+// CHECK: @[[VTABLE_A:.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i8*), i8* bitcast (void (%class.A*)* @"\01?m_fn1 at A@@EAEXXZ" to i8*)], comdat($"\01??_7A@@6B@")
+// CHECK: @"\01??_7C@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_C]], i32 0, i32 1)
+// CHECK: @"\01??_S?$B at H@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_B]], i32 0, i32 1)
+// CHECK: @"\01??_7A@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* @[[VTABLE_A]], i32 0, i32 1)

Modified: cfe/trunk/test/CodeGenCXX/dllimport-rtti.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport-rtti.cpp?rev=260548&r1=260547&r2=260548&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport-rtti.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllimport-rtti.cpp Thu Feb 11 11:49:28 2016
@@ -4,7 +4,8 @@
 struct __declspec(dllimport) S {
   virtual void f() {}
 } s;
-// MSVC-DAG: @"\01??_7S@@6B@" = available_externally dllimport
+// MSVC: [[VF_S:.*]] = private unnamed_addr constant [2 x i8*]
+// MSVC-DAG: @"\01??_SS@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VF_S]], i32 0, i32 1)
 // MSVC-DAG: @"\01??_R0?AUS@@@8" = linkonce_odr
 // MSVC-DAG: @"\01??_R1A@?0A at EA@S@@8" = linkonce_odr
 // MSVC-DAG: @"\01??_R2S@@8" = linkonce_odr

Modified: cfe/trunk/test/CodeGenCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport.cpp?rev=260548&r1=260547&r2=260548&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllimport.cpp Thu Feb 11 11:49:28 2016
@@ -614,7 +614,7 @@ USEMEMFUNC(V, foo)
 struct __declspec(dllimport) W { virtual void foo() {} };
 USECLASS(W)
 // vftable:
-// MO1-DAG: @"\01??_7W@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo at W@@UAEXXZ" to i8*)]
+// MO1-DAG: @"\01??_SW@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo at W@@UAEXXZ" to i8*)]
 // GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
 
 struct __declspec(dllimport) KeyFuncClass {

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vftables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vftables.cpp?rev=260548&r1=260547&r2=260548&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vftables.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vftables.cpp Thu Feb 11 11:49:28 2016
@@ -4,8 +4,6 @@
 // RTTI-DAG: $"\01??_7S@@6B@" = comdat largest
 // RTTI-DAG: $"\01??_7V@@6B@" = comdat largest
 
-// RTTI-NOT: @"\01??_R4U@@6B@"
-
 struct S {
   virtual ~S();
 } s;
@@ -19,9 +17,10 @@ struct __declspec(dllimport) U {
   virtual ~U();
 } u;
 
-// RTTI-DAG: @"\01??_7U@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI at Z" to i8*)]
+// RTTI-DAG: [[VTABLE_U:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4U@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI at Z" to i8*)]
+// RTTI-DAG: @"\01??_SU@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_U]], i32 0, i32 1)
 
-// NO-RTTI-DAG: @"\01??_7U@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI at Z" to i8*)]
+// NO-RTTI-DAG: @"\01??_SU@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI at Z" to i8*)]
 
 struct __declspec(dllexport) V {
   virtual ~V();




More information about the cfe-commits mailing list