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