mstorsjo created this revision.
mstorsjo added reviewers: rnk, majnemer, compnerd, smeenai.

This fixes building Qt as shared libraries with clang in MinGW mode; previously 
subclasses of the QObjectData class (in other DLLs than the base DLL) failed to 
find the typeinfo symbols (that neither were emitted in the base DLL or in the 
subclass component).

If the virtual destructor in the newly added testcase wouldn't be pure (or if 
there'd be another non-pure virtual method), it'd be a key function and things 
would work out as intended. Make sure to locally emit the typeinfo for those 
classes as well.

This matches what GCC does in this specific testcase (although it's unclear 
whether the generic mechanics are the same or different).

This fixes the root issue that spawned PR35146. The difference to GCC that is 
described in that bug still is present though.

I admit that this is a kinda hack-and-slash type of fix since I don't really 
understand how all these concepts fit together. Better suggestions on solving 
that particular issue are welcome.


Repository:
  rC Clang

https://reviews.llvm.org/D42641

Files:
  lib/CodeGen/CGVTables.cpp
  test/CodeGenCXX/dllimport-missing-key.cpp
  test/CodeGenCXX/dllimport-rtti.cpp
  test/CodeGenCXX/dllimport.cpp


Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -658,7 +658,7 @@
 USECLASS(W)
 // vftable:
 // MO1-DAG: @"\01??_SW@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] 
} { [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)] }
-// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant { 
[3 x i8*] } { [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* 
@_ZN1W3fooEv to i8*)] }
+// GO1-DAG: @_ZTV1W = external dllimport unnamed_addr constant { [3 x i8*] }
 
 struct __declspec(dllimport) KeyFuncClass {
   constexpr KeyFuncClass() {}
Index: test/CodeGenCXX/dllimport-rtti.cpp
===================================================================
--- test/CodeGenCXX/dllimport-rtti.cpp
+++ test/CodeGenCXX/dllimport-rtti.cpp
@@ -12,7 +12,7 @@
 // MSVC-DAG: @"\01??_R3S@@8" = linkonce_odr
 
 // GNU-DAG: @_ZTV1S = available_externally dllimport
-// GNU-DAG: @_ZTI1S = external dllimport
+// GNU-DAG: @_ZTI1S = linkonce_odr
 
 struct U : S {
 } u;
Index: test/CodeGenCXX/dllimport-missing-key.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/dllimport-missing-key.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s 
-w | FileCheck --check-prefix=GNU %s
+
+class __declspec(dllimport) QObjectData {
+public:
+    virtual ~QObjectData() = 0;
+    void *ptr;
+
+    int method() const;
+};
+
+QObjectData::~QObjectData() {}
+
+int QObjectData::method() const
+{
+    return 0;
+}
+
+class LocalClass : public QObjectData {
+};
+
+void call() {
+    (new LocalClass())->method();
+}
+
+// GNU-DAG: @_ZTV11QObjectData = external dllimport
+// GNU-DAG: @_ZTS11QObjectData = linkonce_odr
+// GNU-DAG: @_ZTI11QObjectData = linkonce_odr
Index: lib/CodeGen/CGVTables.cpp
===================================================================
--- lib/CodeGen/CGVTables.cpp
+++ lib/CodeGen/CGVTables.cpp
@@ -884,6 +884,9 @@
   if (CGM.getTarget().getCXXABI().isMicrosoft())
     return false;
 
+  if (CGM.getTriple().isWindowsGNUEnvironment() && 
RD->hasAttr<DLLImportAttr>())
+    return true;
+
   // If we have an explicit instantiation declaration (and not a
   // definition), the vtable is defined elsewhere.
   TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();


Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -658,7 +658,7 @@
 USECLASS(W)
 // vftable:
 // MO1-DAG: @"\01??_SW@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)] }
-// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] }
+// GO1-DAG: @_ZTV1W = external dllimport unnamed_addr constant { [3 x i8*] }
 
 struct __declspec(dllimport) KeyFuncClass {
   constexpr KeyFuncClass() {}
Index: test/CodeGenCXX/dllimport-rtti.cpp
===================================================================
--- test/CodeGenCXX/dllimport-rtti.cpp
+++ test/CodeGenCXX/dllimport-rtti.cpp
@@ -12,7 +12,7 @@
 // MSVC-DAG: @"\01??_R3S@@8" = linkonce_odr
 
 // GNU-DAG: @_ZTV1S = available_externally dllimport
-// GNU-DAG: @_ZTI1S = external dllimport
+// GNU-DAG: @_ZTI1S = linkonce_odr
 
 struct U : S {
 } u;
Index: test/CodeGenCXX/dllimport-missing-key.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/dllimport-missing-key.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s
+
+class __declspec(dllimport) QObjectData {
+public:
+    virtual ~QObjectData() = 0;
+    void *ptr;
+
+    int method() const;
+};
+
+QObjectData::~QObjectData() {}
+
+int QObjectData::method() const
+{
+    return 0;
+}
+
+class LocalClass : public QObjectData {
+};
+
+void call() {
+    (new LocalClass())->method();
+}
+
+// GNU-DAG: @_ZTV11QObjectData = external dllimport
+// GNU-DAG: @_ZTS11QObjectData = linkonce_odr
+// GNU-DAG: @_ZTI11QObjectData = linkonce_odr
Index: lib/CodeGen/CGVTables.cpp
===================================================================
--- lib/CodeGen/CGVTables.cpp
+++ lib/CodeGen/CGVTables.cpp
@@ -884,6 +884,9 @@
   if (CGM.getTarget().getCXXABI().isMicrosoft())
     return false;
 
+  if (CGM.getTriple().isWindowsGNUEnvironment() && RD->hasAttr<DLLImportAttr>())
+    return true;
+
   // If we have an explicit instantiation declaration (and not a
   // definition), the vtable is defined elsewhere.
   TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to