aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2017-04-28 18:55:08 +0200
committerChristian Tismer <tismer@stackless.com>2017-05-09 08:33:51 +0000
commitc088cec468d6d908adeaeceec46022d10b55fb75 (patch)
treeb14038747689f101961fbae1e270763f73b59cc2
parent388d512b0903455236ec1057e8213204000f5b5d (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.h30
-rw-r--r--generator/shiboken2/headergenerator.cpp9
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);