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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits