diff options
author | Christian Tismer <tismer@stackless.com> | 2017-04-28 18:55:08 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2017-05-09 08:33:51 +0000 |
commit | c088cec468d6d908adeaeceec46022d10b55fb75 (patch) | |
tree | b14038747689f101961fbae1e270763f73b59cc2 | |
parent | 388d512b0903455236ec1057e8213204000f5b5d (diff) |
Fix headergenerator to build under C++11
For a long time, headergenerator.cpp did only generate destructors,
when the following condition was set:
if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) {
// generate destructor
}
The condition does not work for C++11.
When trying to remove the protected hack, I remembered that
I used an ugly CMake trick to make VS 2015 work. This hack
provided exactly the missing destructors.
I tried very hard to make this hack into a patch for Linux and
macOS, too. Unfortunately, when built without the protected hack,
Clang enforces a destructor declaration, but then the linker reports
an unresolved symbol. I have found no way to circumvent this.
Conclusion: Unless we find a way to make Clang work correctly,
we have to leave the protected hack as-is on macOS.
But then, the whole effort of hack removal makes no more sense.
Fortunately, the ugly work-around on Windows is gone, now.
So this change involves shiboken and PySide, and probably the one
will not work without the other.
Task-number: PYSIDE-504
Change-Id: I92b372c15fd2a4280a249de4c099eeb1f18fedd3
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r-- | generator/generator.h | 30 | ||||
-rw-r--r-- | generator/shiboken2/headergenerator.cpp | 9 |
2 files changed, 37 insertions, 2 deletions
diff --git a/generator/generator.h b/generator/generator.h index 386b9d5..f734ff9 100644 --- a/generator/generator.h +++ b/generator/generator.h @@ -63,6 +63,36 @@ QString getClassTargetFullName(const AbstractMetaEnum* metaEnum, bool includePac QString getClassTargetFullName(const AbstractMetaType *metaType, bool includePackageName = true); QString getFilteredCppSignatureString(QString signature); +/** + * PYSIDE-504: Handling the "protected hack" + * + * The problem: Creating wrappers when the class has private destructors. + * You can see an example on Windows in qclipboard_wrapper.h and others. + * Simply search for the text "// C++11: need to declare (unimplemented) destructor". + * + * The protected hack is the definition "#define protected public". + * For most compilers, this "hack" is enabled, because the problem of private + * destructors simply vanishes. + * + * If one does not want to use this hack, then a new problem arises: + * C++11 requires that a destructor is declared in a wrapper class when it is + * private in the base class. There is no implementation allowed! + * + * Unfortunately, MSVC in recent versions supports C++11, and due to restrictive + * rules, it is impossible to use the hack with this compiler. + * More unfortunate: Clang, when C++11 is enabled, also enforces a declaration + * of a private destructor, but it falsely then creates a linker error! + * + * Originally, we wanted to remove the protected hack. But due to the Clang + * problem, we gave up on removal of the protected hack and use it always + * when we can. This might change again when the Clang problem is solved. + */ + +#ifdef Q_CC_MSVC +const int alwaysGenerateDestructor = 1; +#else +const int alwaysGenerateDestructor = 0; +#endif /** * A GeneratorContext object contains a pointer to an AbstractMetaClass and/or a specialized diff --git a/generator/shiboken2/headergenerator.cpp b/generator/shiboken2/headergenerator.cpp index ea308f5..5ef5d56 100644 --- a/generator/shiboken2/headergenerator.cpp +++ b/generator/shiboken2/headergenerator.cpp @@ -148,11 +148,16 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte } //destructor - if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) { + // PYSIDE-504: When C++ 11 is used, then the destructor must always be written. + // See generator.h for further reference. + if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor() || alwaysGenerateDestructor) { s << INDENT; + if (avoidProtectedHack() && metaClass->hasPrivateDestructor()) + s << "// C++11: need to declare (unimplemented) destructor because " + "the base class destructor is private." << endl; if (metaClass->hasVirtualDestructor() || hasVirtualFunction) s << "virtual "; - s << "~" << wrapperName << "();" << endl; + s << '~' << wrapperName << "();" << endl; } writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode); |