summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo@setantas.net>2011-02-06 00:41:50 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:15:15 -0300
commit0a5cacdb9c25d79df02d7b201ab1f2277caceca3 (patch)
tree42b56d93f8a30bb4109f259b511ff7e6eaeadaff
parente8a7efe5905ab8a1b333e5634081b4afcff7c334 (diff)
The option "avoid protected hack" is now set via command line.sb-1.0.0-rc1
Instead of the old ugly way of compiling the behaviour forever using "#define". Reviewed by Hugo Parente <hugo.lima@openbossa.org> Reviewed by Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r--CMakeLists.txt9
-rw-r--r--data/ShibokenConfig-spec.cmake.in7
-rw-r--r--data/shiboken.pc.in1
-rw-r--r--generator/cppgenerator.cpp252
-rw-r--r--generator/headergenerator.cpp77
-rw-r--r--generator/shibokengenerator.cpp129
-rw-r--r--generator/shibokengenerator.h11
-rw-r--r--tests/CMakeLists.txt7
-rw-r--r--tests/otherbinding/CMakeLists.txt2
-rw-r--r--tests/samplebinding/CMakeLists.txt2
10 files changed, 224 insertions, 273 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cc7a706d..23a0b41e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,6 @@ set(shiboken_MINOR_VERSION "0")
set(shiboken_MICRO_VERSION "0")
set(shiboken_VERSION "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VERSION}.${shiboken_MICRO_VERSION}")
-option(AVOID_PROTECTED_HACK "Avoid protected hack on generated bindings." FALSE)
option(BUILD_TESTS "Build tests." TRUE)
if(MSVC)
@@ -48,14 +47,6 @@ else()
set(PATH_SEP ":")
endif()
-if(WIN32 OR AVOID_PROTECTED_HACK)
- message(STATUS "Avoiding protected hack!")
- add_definitions("-DAVOID_PROTECTED_HACK")
- set(AVOID_PROTECTED_HACK ON)
-else()
- message(STATUS "Using protected hack!")
-endif()
-
# uninstall target
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
diff --git a/data/ShibokenConfig-spec.cmake.in b/data/ShibokenConfig-spec.cmake.in
index 6e037282..74c5f4e5 100644
--- a/data/ShibokenConfig-spec.cmake.in
+++ b/data/ShibokenConfig-spec.cmake.in
@@ -21,11 +21,4 @@ SET(SHIBOKEN_PYTHON_BASENAME "@PYTHON_BASENAME@")
message(STATUS "libshiboken built for @SHIBOKEN_BUILD_TYPE@")
@SBK_ADD_PY_DEBUG_DEFINITION@
-# We don't use just "if (@AVOID_PROTECTED_HACK@)" to avoid require all users to turn on the cmake policy CMP0012
-# for more info type: cmake --help-policy CMP0012
-set(SHIBOKEN_AVOID_PROTECTED_HACK @AVOID_PROTECTED_HACK@)
-if (SHIBOKEN_AVOID_PROTECTED_HACK)
- add_definitions(-DAVOID_PROTECTED_HACK)
- message(STATUS "Avoiding protected hack!")
-endif()
set(SHIBOKEN_BINARY "@CMAKE_INSTALL_PREFIX@/bin/@SHIBOKEN_GENERATOR@")
diff --git a/data/shiboken.pc.in b/data/shiboken.pc.in
index 5a88622d..03728812 100644
--- a/data/shiboken.pc.in
+++ b/data/shiboken.pc.in
@@ -5,7 +5,6 @@ includedir=@CMAKE_INSTALL_PREFIX@/include/shiboken
generator_location=@CMAKE_INSTALL_PREFIX@/bin/@SHIBOKEN_GENERATOR@
python_interpreter=@PYTHON_EXECUTABLE@
python_include_dir=@SBK_PYTHON_INCLUDE_DIR@
-avoid_protected_hack=@AVOID_PROTECTED_HACK@
Name: shiboken
Description: Support library for Python bindings created with Shiboken generator.
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index d7ca1d8b..e410ae52 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -216,12 +216,10 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl
// write license comment
s << licenseComment() << endl;
-#ifndef AVOID_PROTECTED_HACK
- if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
+ if (!avoidProtectedHack() && !metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
s << "//workaround to access protected functions" << endl;
s << "#define protected public" << endl << endl;
}
-#endif
// headers
s << "// default includes" << endl;
@@ -304,14 +302,12 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl
s << "// Native ---------------------------------------------------------" << endl;
s << endl;
-#ifdef AVOID_PROTECTED_HACK
- if (usePySideExtensions()) {
+ if (avoidProtectedHack() && usePySideExtensions()) {
s << "void " << wrapperName(metaClass) << "::pysideInitQtMetaTypes()\n{\n";
Indentation indent(INDENT);
writeInitQtMetaTypeFunctionBody(s, metaClass);
s << "}\n\n";
}
-#endif
foreach (const AbstractMetaFunction* func, filterFunctions(metaClass)) {
if ((func->isPrivate() && !visibilityModifiedToPrivate(func))
@@ -319,26 +315,16 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl
continue;
if (func->isConstructor() && !func->isCopyConstructor() && !func->isUserAdded())
writeConstructorNative(s, func);
-#ifdef AVOID_PROTECTED_HACK
- else if (!metaClass->hasPrivateDestructor() && (func->isVirtual() || func->isAbstract()))
-#else
- else if (func->isVirtual() || func->isAbstract())
-#endif
+ else if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
+ && (func->isVirtual() || func->isAbstract()))
writeVirtualMethodNative(s, func);
}
-#ifdef AVOID_PROTECTED_HACK
- if (!metaClass->hasPrivateDestructor()) {
-#endif
-
- if (usePySideExtensions() && metaClass->isQObject())
- writeMetaObjectMethod(s, metaClass);
-
- writeDestructorNative(s, metaClass);
-
-#ifdef AVOID_PROTECTED_HACK
+ if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) {
+ if (usePySideExtensions() && metaClass->isQObject())
+ writeMetaObjectMethod(s, metaClass);
+ writeDestructorNative(s, metaClass);
}
-#endif
}
Indentation indentation(INDENT);
@@ -710,13 +696,13 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
ac << arg->name() << "_out";
} else {
QString argName = arg->name();
-#ifdef AVOID_PROTECTED_HACK
- const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(arg->type());
- if (metaEnum && metaEnum->isProtected()) {
- argName.prepend(protectedEnumSurrogateName(metaEnum) + '(');
- argName.append(')');
+ if (avoidProtectedHack()) {
+ const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(arg->type());
+ if (metaEnum && metaEnum->isProtected()) {
+ argName.prepend(protectedEnumSurrogateName(metaEnum) + '(');
+ argName.append(')');
+ }
}
-#endif
ac << (convert ? "(" : "") << argName << (convert ? ")" : "");
}
@@ -779,11 +765,12 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
desiredType = '"' + reinterpret_cast<const ContainerTypeEntry*>(func->type()->typeEntry())->typeName() + '"';
} else {
QString typeName = func->type()->typeEntry()->qualifiedCppName();
-#ifdef AVOID_PROTECTED_HACK
- const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(func->type());
- if (metaEnum && metaEnum->isProtected())
- typeName = protectedEnumSurrogateName(metaEnum);
-#endif
+ if (avoidProtectedHack()) {
+ const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(func->type());
+ if (metaEnum && metaEnum->isProtected())
+ typeName = protectedEnumSurrogateName(metaEnum);
+ }
+
if (func->type()->isPrimitive())
desiredType = "\"" + func->type()->name() + "\"";
else
@@ -814,28 +801,25 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, const AbstractMetaFu
writeCodeSnips(s, convRule, CodeSnip::Any, TypeSystem::NativeCode, func);
} else if (!injectedCodeHasReturnValueAttribution(func, TypeSystem::NativeCode)) {
s << INDENT;
-#ifdef AVOID_PROTECTED_HACK
- QString enumName;
- const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(func->type());
- bool isProtectedEnum = metaEnum && metaEnum->isProtected();
- if (isProtectedEnum) {
- enumName = metaEnum->name();
- if (metaEnum->enclosingClass())
- enumName = metaEnum->enclosingClass()->qualifiedCppName() + "::" + enumName;
- s << enumName;
- } else
-#endif
+ QString protectedEnumName;
+ if (avoidProtectedHack()) {
+ const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(func->type());
+ bool isProtectedEnum = metaEnum && metaEnum->isProtected();
+ if (isProtectedEnum) {
+ protectedEnumName = metaEnum->name();
+ if (metaEnum->enclosingClass())
+ protectedEnumName = metaEnum->enclosingClass()->qualifiedCppName() + "::" + protectedEnumName;
+ s << protectedEnumName;
+ }
+ }
+ if (protectedEnumName.isEmpty())
s << translateTypeForWrapperMethod(func->type(), func->implementingClass());
s << " " CPP_RETURN_VAR "(";
-#ifdef AVOID_PROTECTED_HACK
- if (isProtectedEnum)
- s << enumName << '(';
-#endif
+ if (avoidProtectedHack() && !protectedEnumName.isEmpty())
+ s << protectedEnumName << '(';
writeToCppConversion(s, func->type(), func->implementingClass(), PYTHON_RETURN_VAR);
-#ifdef AVOID_PROTECTED_HACK
- if (isProtectedEnum)
+ if (avoidProtectedHack() && !protectedEnumName.isEmpty())
s << ')';
-#endif
s << ')';
s << ';' << endl;
}
@@ -1179,13 +1163,13 @@ void CppGenerator::writeMethodWrapper(QTextStream& s, const AbstractMetaFunction
(!rfunc->implementingClass()->isNamespace() && overloadData.hasInstanceFunction())) {
s << INDENT;
-#ifdef AVOID_PROTECTED_HACK
- QString _wrapperName = wrapperName(rfunc->ownerClass());
- bool hasProtectedMembers = rfunc->ownerClass()->hasProtectedMembers();
- s << (hasProtectedMembers ? _wrapperName : rfunc->ownerClass()->qualifiedCppName());
-#else
- s << rfunc->ownerClass()->qualifiedCppName();
-#endif
+ QString protectedClassWrapperName;
+ if (avoidProtectedHack() && rfunc->ownerClass()->hasProtectedMembers()) {
+ protectedClassWrapperName = wrapperName(rfunc->ownerClass());
+ s << protectedClassWrapperName;
+ } else {
+ s << rfunc->ownerClass()->qualifiedCppName();
+ }
s << "* " CPP_SELF_VAR " = 0;" << endl;
if (rfunc->isOperatorOverload() && rfunc->isBinaryOperator()) {
@@ -1198,9 +1182,8 @@ void CppGenerator::writeMethodWrapper(QTextStream& s, const AbstractMetaFunction
// Sets the C++ "self" (the "this" for the object) if it has one.
QString cppSelfAttribution = CPP_SELF_VAR " = ";
-#ifdef AVOID_PROTECTED_HACK
- cppSelfAttribution += (hasProtectedMembers ? QString("(%1*)").arg(_wrapperName) : "");
-#endif
+ if (avoidProtectedHack() && !protectedClassWrapperName.isEmpty())
+ cppSelfAttribution += QString("(%1*)").arg(protectedClassWrapperName);
cppSelfAttribution += cpythonWrapperCPtr(rfunc->ownerClass(), "self");
// Checks if the underlying C++ object is valid.
@@ -1429,14 +1412,15 @@ void CppGenerator::writeCppSelfDefinition(QTextStream& s, const AbstractMetaFunc
return;
s << INDENT;
-#ifdef AVOID_PROTECTED_HACK
- QString _wrapperName = wrapperName(func->ownerClass());
- bool hasProtectedMembers = func->ownerClass()->hasProtectedMembers();
- s << (hasProtectedMembers ? _wrapperName : func->ownerClass()->qualifiedCppName()) << "* " CPP_SELF_VAR " = ";
- s << (hasProtectedMembers ? QString("(%1*)").arg(_wrapperName) : "");
-#else
- s << func->ownerClass()->qualifiedCppName() << "* " CPP_SELF_VAR " = ";
-#endif
+ if (avoidProtectedHack()) {
+ QString _wrapperName = wrapperName(func->ownerClass());
+ bool hasProtectedMembers = func->ownerClass()->hasProtectedMembers();
+ s << (hasProtectedMembers ? _wrapperName : func->ownerClass()->qualifiedCppName());
+ s << "* " CPP_SELF_VAR " = ";
+ s << (hasProtectedMembers ? QString("(%1*)").arg(_wrapperName) : "");
+ } else {
+ s << func->ownerClass()->qualifiedCppName() << "* " CPP_SELF_VAR " = ";
+ }
s << cpythonWrapperCPtr(func->ownerClass(), "self") << ';' << endl;
if (func->isUserAdded())
s << INDENT << "(void)" CPP_SELF_VAR "; // avoid warnings about unused variables" << endl;
@@ -2097,21 +2081,22 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f
mc << ')';
} else {
if (func->ownerClass()) {
-#ifdef AVOID_PROTECTED_HACK
- if (!func->isProtected()) {
-#endif
- if (func->isStatic())
+ if (!avoidProtectedHack() || !func->isProtected()) {
+ if (func->isStatic()) {
mc << func->ownerClass()->qualifiedCppName() << "::";
- else {
+ } else {
if (func->isConstant()) {
-#ifdef AVOID_PROTECTED_HACK
- mc << "const_cast<const ";
- bool hasProtectedMembers = func->ownerClass()->hasProtectedMembers();
- mc << (hasProtectedMembers ? wrapperName(func->ownerClass()) : func->ownerClass()->qualifiedCppName());
- mc << "*>(" CPP_SELF_VAR ")->";
-#else
- mc << "const_cast<const " << func->ownerClass()->qualifiedCppName() << "*>(" CPP_SELF_VAR ")->";
-#endif
+ if (avoidProtectedHack()) {
+ mc << "const_cast<const ";
+ if (func->ownerClass()->hasProtectedMembers())
+ mc << wrapperName(func->ownerClass());
+ else
+ mc << func->ownerClass()->qualifiedCppName();
+ mc << "*>(" CPP_SELF_VAR ")->";
+ } else {
+ mc << "const_cast<const " << func->ownerClass()->qualifiedCppName();
+ mc << "*>(" CPP_SELF_VAR ")->";
+ }
} else {
mc << CPP_SELF_VAR "->";
}
@@ -2121,8 +2106,6 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f
mc << "::%CLASS_NAME::";
mc << func->originalName();
-
-#ifdef AVOID_PROTECTED_HACK
} else {
if (!func->isStatic())
mc << "((" << wrapperName(func->ownerClass()) << "*) " << CPP_SELF_VAR << ")->";
@@ -2131,28 +2114,21 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f
mc << (func->isProtected() ? wrapperName(func->ownerClass()) : "::" + func->ownerClass()->qualifiedCppName()) << "::";
mc << func->originalName() << "_protected";
}
-#endif
} else {
mc << func->originalName();
}
mc << '(' << userArgs.join(", ") << ')';
if (!func->isAbstract() && func->isVirtual()) {
mc.flush();
-#ifdef AVOID_PROTECTED_HACK
- if (!func->isProtected())
-#endif
- {
+ if (!avoidProtectedHack() || !func->isProtected()) {
QString virtualCall(methodCall);
QString normalCall(methodCall);
-
virtualCall = virtualCall.replace("%CLASS_NAME", func->ownerClass()->qualifiedCppName());
normalCall = normalCall.replace("::%CLASS_NAME::", "");
methodCall = "";
-
- virtualCall = virtualCall.replace("%CLASS_NAME", func->ownerClass()->qualifiedCppName());
- normalCall = normalCall.replace("::%CLASS_NAME::", "");
- methodCall = "";
- mc << "(Shiboken::Object::isUserType(self) ? " << virtualCall << ":" << normalCall << ")";
+ mc << "(Shiboken::Object::isUserType(self) ? ";
+ mc << virtualCall << " : " << normalCall << ")";
+ }
}
}
}
@@ -2162,19 +2138,22 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f
if (isCtor) {
s << "cptr = ";
} else if (func->type() && !func->isInplaceOperator()) {
-#ifdef AVOID_PROTECTED_HACK
- QString enumName;
- const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(func->type());
- if (metaEnum) {
- if (metaEnum->isProtected())
- enumName = protectedEnumSurrogateName(metaEnum);
- else
- enumName = func->type()->cppSignature();
- methodCall.prepend(enumName + '(');
- methodCall.append(')');
- s << enumName;
- } else
-#endif
+ bool writeReturnType = true;
+ if (avoidProtectedHack()) {
+ const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(func->type());
+ if (metaEnum) {
+ QString enumName;
+ if (metaEnum->isProtected())
+ enumName = protectedEnumSurrogateName(metaEnum);
+ else
+ enumName = func->type()->cppSignature();
+ methodCall.prepend(enumName + '(');
+ methodCall.append(')');
+ s << enumName;
+ writeReturnType = false;
+ }
+ }
+ if (writeReturnType)
s << func->type()->cppSignature();
s << " " CPP_RETURN_VAR " = ";
}
@@ -2795,18 +2774,17 @@ void CppGenerator::writeGetterFunction(QTextStream& s, const AbstractMetaField*
!metaType->isPrimitive() &&
metaType->indirections() == 0);
-#ifdef AVOID_PROTECTED_HACK
- if (metaField->isProtected())
+ if (avoidProtectedHack() && metaField->isProtected()) {
cppField = QString("((%1*)%2)->%3()")
- .arg(wrapperName(metaField->enclosingClass()))
- .arg(cpythonWrapperCPtr(metaField->enclosingClass(), "self"))
- .arg(protectedFieldGetterName(metaField));
- else
-#endif
- cppField= QString("%1%2->%3")
- .arg(useReference ? '&' : ' ')
- .arg(cpythonWrapperCPtr(metaField->enclosingClass(), "self"))
- .arg(metaField->name());
+ .arg(wrapperName(metaField->enclosingClass()))
+ .arg(cpythonWrapperCPtr(metaField->enclosingClass(), "self"))
+ .arg(protectedFieldGetterName(metaField));
+ } else {
+ cppField = QString("%1%2->%3")
+ .arg(useReference ? '&' : ' ')
+ .arg(cpythonWrapperCPtr(metaField->enclosingClass(), "self"))
+ .arg(metaField->name());
+ }
if (useReference) {
s << "Shiboken::createWrapper(" << cppField << ");" << endl;
@@ -2846,20 +2824,21 @@ void CppGenerator::writeSetterFunction(QTextStream& s, const AbstractMetaField*
s << INDENT << '}' << endl << endl;
s << INDENT;
-#ifdef AVOID_PROTECTED_HACK
- if (metaField->isProtected()) {
- QString fieldStr = QString("((%1*)%2)->%3").arg(wrapperName(metaField->enclosingClass())).arg(cpythonWrapperCPtr(metaField->enclosingClass(), "self")).arg(protectedFieldSetterName(metaField));
+ if (avoidProtectedHack() && metaField->isProtected()) {
+ QString fieldStr = QString("((%1*)%2)->%3")
+ .arg(wrapperName(metaField->enclosingClass()))
+ .arg(cpythonWrapperCPtr(metaField->enclosingClass(), "self"))
+ .arg(protectedFieldSetterName(metaField));
s << fieldStr << '(';
writeToCppConversion(s, metaField->type(), metaField->enclosingClass(), "value");
s << ')';
} else {
-#endif
- QString fieldStr = QString("%1->%2").arg(cpythonWrapperCPtr(metaField->enclosingClass(), "self")).arg(metaField->name());
+ QString fieldStr = QString("%1->%2")
+ .arg(cpythonWrapperCPtr(metaField->enclosingClass(), "self"))
+ .arg(metaField->name());
s << fieldStr << " = ";
writeToCppConversion(s, metaField->type(), metaField->enclosingClass(), "value");
-#ifdef AVOID_PROTECTED_HACK
}
-#endif
s << ';' << endl << endl;
@@ -3082,18 +3061,14 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
continue;
QString enumValueText;
-#ifdef AVOID_PROTECTED_HACK
- if (!cppEnum->isProtected()) {
-#endif
+ if (!avoidProtectedHack() || !cppEnum->isProtected()) {
enumValueText = "(long) ";
if (cppEnum->enclosingClass())
enumValueText += cppEnum->enclosingClass()->qualifiedCppName() + "::";
enumValueText += enumValue->name();
-#ifdef AVOID_PROTECTED_HACK
} else {
enumValueText += QString::number(enumValue->value());
}
-#endif
bool shouldDecrefNumber = false;
QString enumItemText = "enumItem";
@@ -3430,10 +3405,12 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m
// Fill destrutor
QString dtorClassName = metaClass->qualifiedCppName();
if (!metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
-#ifdef AVOID_PROTECTED_HACK
- if (metaClass->hasProtectedDestructor())
+ if (avoidProtectedHack() && metaClass->hasProtectedDestructor())
+ dtorClassName = wrapperName(metaClass);
+ // call the real destructor
+ if (metaClass->typeEntry()->isValue())
dtorClassName = wrapperName(metaClass);
-#endif
+
s << INDENT << "Shiboken::ObjectType::setDestructorFunction(&" << cpythonTypeName(metaClass) << ", &Shiboken::callCppDestructor<" << dtorClassName << " >);" << endl;
}
@@ -3507,17 +3484,12 @@ void CppGenerator::writeClassRegister(QTextStream& s, const AbstractMetaClass* m
writeRegisterType(s, metaClass);
if (usePySideExtensions()) {
-#ifdef AVOID_PROTECTED_HACK
- if (shouldGenerateCppWrapper(metaClass))
+ if (avoidProtectedHack() && shouldGenerateCppWrapper(metaClass))
s << INDENT << wrapperName(metaClass) << "::pysideInitQtMetaTypes();\n";
else
writeInitQtMetaTypeFunctionBody(s, metaClass);
-#else
- writeInitQtMetaTypeFunctionBody(s, metaClass);
-#endif
}
-
s << '}' << endl << endl;
}
diff --git a/generator/headergenerator.cpp b/generator/headergenerator.cpp
index b52bf7c9..3b0de4fd 100644
--- a/generator/headergenerator.cpp
+++ b/generator/headergenerator.cpp
@@ -86,9 +86,8 @@ void HeaderGenerator::generateClass(QTextStream& s, const AbstractMetaClass* met
s << "#ifndef SBK_" << headerGuard << "_H" << endl;
s << "#define SBK_" << headerGuard << "_H" << endl<< endl;
-#ifndef AVOID_PROTECTED_HACK
- s << "#define protected public" << endl << endl;
-#endif
+ if (!avoidProtectedHack())
+ s << "#define protected public" << endl << endl;
s << "#include <shiboken.h>" << endl << endl;
@@ -113,37 +112,30 @@ void HeaderGenerator::generateClass(QTextStream& s, const AbstractMetaClass* met
writeFunction(s, func);
}
-#ifdef AVOID_PROTECTED_HACK
- if (metaClass->hasProtectedFields()) {
+ if (avoidProtectedHack() && metaClass->hasProtectedFields()) {
foreach (AbstractMetaField* field, metaClass->fields()) {
if (!field->isProtected())
continue;
writeProtectedFieldAccessors(s, field);
}
}
-#endif
//destructor
-#ifdef AVOID_PROTECTED_HACK
- if (!metaClass->hasPrivateDestructor())
-#endif
- s << INDENT << (metaClass->hasVirtualDestructor() || hasVirtualFunction ? "virtual " : "") << "~" << wrapperName << "();" << endl;
+ if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) {
+ s << INDENT;
+ if (metaClass->hasVirtualDestructor() || hasVirtualFunction)
+ s << "virtual ";
+ s << "~" << wrapperName << "();" << endl;
+ }
writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), CodeSnip::Declaration, TypeSystem::NativeCode);
-#ifdef AVOID_PROTECTED_HACK
- if (!metaClass->hasPrivateDestructor()) {
-#endif
-
- if (usePySideExtensions() && metaClass->isQObject()) {
+ if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
+ && usePySideExtensions() && metaClass->isQObject()) {
s << "public:\n";
s << INDENT << "virtual int qt_metacall(QMetaObject::Call call, int id, void** args);\n";
}
-#ifdef AVOID_PROTECTED_HACK
- }
-#endif
-
if (m_inheritedOverloads.size()) {
s << INDENT << "// Inherited overloads, because the using keyword sux" << endl;
writeInheritedOverloads(s);
@@ -169,8 +161,7 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
if (func->isUserAdded())
return;
-#ifdef AVOID_PROTECTED_HACK
- if (func->isProtected() && !func->isConstructor() && !func->isOperatorOverload()) {
+ if (avoidProtectedHack() && func->isProtected() && !func->isConstructor() && !func->isOperatorOverload()) {
s << INDENT << "inline " << (func->isStatic() ? "static " : "");
s << functionSignature(func, "", "_protected", Generator::EnumAsInts|Generator::OriginalTypeDescription) << " { ";
s << (func->type() ? "return " : "");
@@ -192,17 +183,15 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
s << args.join(", ") << ')';
s << "; }" << endl;
}
-#endif
// pure virtual functions need a default implementation
if ((func->isPrivate() && !visibilityModifiedToPrivate(func))
|| (func->isModifiedRemoved() && !func->isAbstract()))
return;
-#ifdef AVOID_PROTECTED_HACK
- if (func->ownerClass()->hasPrivateDestructor() && (func->isAbstract() || func->isVirtual()))
+ if (avoidProtectedHack() && func->ownerClass()->hasPrivateDestructor()
+ && (func->isAbstract() || func->isVirtual()))
return;
-#endif
if (func->isConstructor() || func->isAbstract() || func->isVirtual()) {
s << INDENT;
@@ -252,13 +241,14 @@ void HeaderGenerator::writeTypeConverterDecl(QTextStream& s, const TypeEntry* ty
QString typeT = type->qualifiedCppName() + (isAbstractOrObjectType ? "*" : "");
QString typeName = type->qualifiedCppName();
-#ifdef AVOID_PROTECTED_HACK
- const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(type);
- if (metaEnum && metaEnum->isProtected()) {
- typeT = protectedEnumSurrogateName(metaEnum);
- typeName = typeT;
+ if (avoidProtectedHack()) {
+ const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(type);
+ if (metaEnum && metaEnum->isProtected()) {
+ typeT = protectedEnumSurrogateName(metaEnum);
+ typeName = typeT;
+ }
}
-#endif
+
typeT.prepend("::");
typeName.prepend("::");
@@ -417,10 +407,10 @@ void HeaderGenerator::finishGeneration()
s << "#ifndef " << includeShield << endl;
s << "#define " << includeShield << endl<< endl;
- #ifndef AVOID_PROTECTED_HACK
- s << "//workaround to access protected functions" << endl;
- s << "#define protected public" << endl << endl;
- #endif
+ if (!avoidProtectedHack()) {
+ s << "//workaround to access protected functions" << endl;
+ s << "#define protected public" << endl << endl;
+ }
s << "#include <Python.h>" << endl;
s << "#include <conversions.h>" << endl;
@@ -510,21 +500,20 @@ void HeaderGenerator::finishGeneration()
void HeaderGenerator::writeProtectedEnumSurrogate(QTextStream& s, const AbstractMetaEnum* cppEnum)
{
-#ifdef AVOID_PROTECTED_HACK
- if (cppEnum->isProtected())
+ if (avoidProtectedHack() && cppEnum->isProtected())
s << "enum " << protectedEnumSurrogateName(cppEnum) << " {};" << endl;
-#endif
}
void HeaderGenerator::writeSbkTypeFunction(QTextStream& s, const AbstractMetaEnum* cppEnum)
{
- QString enumName = cppEnum->name();
- if (cppEnum->enclosingClass())
- enumName = cppEnum->enclosingClass()->qualifiedCppName() + "::" + enumName;
-#ifdef AVOID_PROTECTED_HACK
- if (cppEnum->isProtected())
+ QString enumName;
+ if (avoidProtectedHack() && cppEnum->isProtected()) {
enumName = protectedEnumSurrogateName(cppEnum);
-#endif
+ } else {
+ enumName = cppEnum->name();
+ if (cppEnum->enclosingClass())
+ enumName = cppEnum->enclosingClass()->qualifiedCppName() + "::" + enumName;
+ }
s << "template<> inline PyTypeObject* SbkType< ::" << enumName << " >() ";
s << "{ return " << cpythonTypeNameExt(cppEnum->typeEntry()) << "; }\n";
diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp
index 79b19bce..8d8cd423 100644
--- a/generator/shibokengenerator.cpp
+++ b/generator/shibokengenerator.cpp
@@ -31,6 +31,7 @@
#include <limits>
#define NULL_VALUE "NULL"
+#define AVOID_PROTECTED_HACK "avoid-protected-hack"
#define PARENT_CTOR_HEURISTIC "enable-parent-ctor-heuristic"
#define RETURN_VALUE_HEURISTIC "enable-return-value-heuristic"
#define ENABLE_PYSIDE_EXTENSIONS "enable-pyside-extensions"
@@ -176,46 +177,39 @@ QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType*
const AbstractMetaClass* context,
Options options) const
{
- QString result;
+ if (cType->isArray())
+ return translateTypeForWrapperMethod(cType->arrayElementType(), context, options) + "[]";
- if (cType->isArray()) {
- result = translateTypeForWrapperMethod(cType->arrayElementType(), context, options) + "[]";
- } else {
-#ifdef AVOID_PROTECTED_HACK
- if (cType->isEnum()) {
- const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(cType);
- if (metaEnum && metaEnum->isProtected())
- result = protectedEnumSurrogateName(metaEnum);
- }
- if (result.isEmpty())
-#endif
- result = translateType(cType, context, options);
+ if (avoidProtectedHack() && cType->isEnum()) {
+ const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(cType);
+ if (metaEnum && metaEnum->isProtected())
+ return protectedEnumSurrogateName(metaEnum);
}
- return result;
+ return translateType(cType, context, options);
}
-bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass* metaClass)
+bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass* metaClass) const
{
bool result = metaClass->isPolymorphic() || metaClass->hasVirtualDestructor();
-#ifdef AVOID_PROTECTED_HACK
- result = result || metaClass->hasProtectedFields() || metaClass->hasProtectedDestructor();
- if (!result && metaClass->hasProtectedFunctions()) {
- int protectedFunctions = 0;
- int protectedOperators = 0;
- foreach (const AbstractMetaFunction* func, metaClass->functions()) {
- if (!func->isProtected() || func->isSignal() || func->isModifiedRemoved())
- continue;
- else if (func->isOperatorOverload())
- protectedOperators++;
- else
- protectedFunctions++;
+ if (avoidProtectedHack()) {
+ result = result || metaClass->hasProtectedFields() || metaClass->hasProtectedDestructor();
+ if (!result && metaClass->hasProtectedFunctions()) {
+ int protectedFunctions = 0;
+ int protectedOperators = 0;
+ foreach (const AbstractMetaFunction* func, metaClass->functions()) {
+ if (!func->isProtected() || func->isSignal() || func->isModifiedRemoved())
+ continue;
+ else if (func->isOperatorOverload())
+ protectedOperators++;
+ else
+ protectedFunctions++;
+ }
+ result = result || (protectedFunctions > protectedOperators);
}
- result = result || (protectedFunctions > protectedOperators);
+ } else {
+ result = result && !metaClass->hasPrivateDestructor();
}
-#else
- result = result && !metaClass->hasPrivateDestructor();
-#endif
return result && !metaClass->isNamespace();
}
@@ -251,7 +245,7 @@ const AbstractMetaClass* ShibokenGenerator::getProperEnclosingClassForEnum(const
return getProperEnclosingClass(metaEnum->enclosingClass());
}
-QString ShibokenGenerator::wrapperName(const AbstractMetaClass* metaClass)
+QString ShibokenGenerator::wrapperName(const AbstractMetaClass* metaClass) const
{
if (shouldGenerateCppWrapper(metaClass)) {
QString result = metaClass->name();
@@ -511,18 +505,19 @@ static QString baseConversionString(QString typeName)
void ShibokenGenerator::writeBaseConversion(QTextStream& s, const TypeEntry* type)
{
- QString typeName = type->qualifiedCppName().trimmed();
- if (!type->isCppPrimitive())
- typeName.prepend("::");
- if (type->isObject())
- typeName.append('*');
-#ifdef AVOID_PROTECTED_HACK
- if (type->isEnum()) {
+ QString typeName;
+
+ if (avoidProtectedHack() && type->isEnum()) {
const AbstractMetaEnum* metaEnum = findAbstractMetaEnum(type);
if (metaEnum && metaEnum->isProtected())
typeName = protectedEnumSurrogateName(metaEnum);
+ } else {
+ typeName = type->qualifiedCppName().trimmed();
+ if (!type->isCppPrimitive())
+ typeName.prepend("::");
+ if (type->isObject())
+ typeName.append('*');
}
-#endif
s << baseConversionString(typeName);
}
@@ -1073,15 +1068,10 @@ AbstractMetaFunctionList ShibokenGenerator::filterFunctions(const AbstractMetaCl
AbstractMetaFunctionList result;
foreach (AbstractMetaFunction *func, metaClass->functions()) {
//skip signals
- if (func->isSignal()
- || func->isDestructor()
-#ifndef AVOID_PROTECTED_HACK
- || (func->isModifiedRemoved() && !func->isAbstract())) {
-#else
- || (func->isModifiedRemoved() && !func->isAbstract() && !func->isProtected())) {
-#endif
+ if (func->isSignal() || func->isDestructor()
+ || (func->isModifiedRemoved() && !func->isAbstract()
+ && (!avoidProtectedHack() || !func->isProtected())))
continue;
- }
result << func;
}
return result;
@@ -1304,26 +1294,26 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
code.replace("%PYTHON_METHOD_OVERRIDE", "py_override");
}
-#ifdef AVOID_PROTECTED_HACK
- // If the function being processed was added by the user via type system,
- // Shiboken needs to find out if there are other overloads for the same method
- // name and if any of them is of the protected visibility. This is used to replace
- // calls to %FUNCTION_NAME on user written custom code for calls to the protected
- // dispatcher.
- bool hasProtectedOverload = false;
- if (func->isUserAdded()) {
- foreach (const AbstractMetaFunction* f, getFunctionOverloads(func->ownerClass(), func->name()))
- hasProtectedOverload |= f->isProtected();
- }
+ if (avoidProtectedHack()) {
+ // If the function being processed was added by the user via type system,
+ // Shiboken needs to find out if there are other overloads for the same method
+ // name and if any of them is of the protected visibility. This is used to replace
+ // calls to %FUNCTION_NAME on user written custom code for calls to the protected
+ // dispatcher.
+ bool hasProtectedOverload = false;
+ if (func->isUserAdded()) {
+ foreach (const AbstractMetaFunction* f, getFunctionOverloads(func->ownerClass(), func->name()))
+ hasProtectedOverload |= f->isProtected();
+ }
- if (func->isProtected() || hasProtectedOverload) {
- code.replace("%TYPE::%FUNCTION_NAME",
- QString("%1::%2_protected")
- .arg(wrapperName(func->ownerClass()))
- .arg(func->originalName()));
- code.replace("%FUNCTION_NAME", QString("%1_protected").arg(func->originalName()));
+ if (func->isProtected() || hasProtectedOverload) {
+ code.replace("%TYPE::%FUNCTION_NAME",
+ QString("%1::%2_protected")
+ .arg(wrapperName(func->ownerClass()))
+ .arg(func->originalName()));
+ code.replace("%FUNCTION_NAME", QString("%1_protected").arg(func->originalName()));
+ }
}
-#endif
if (func->isConstructor() && shouldGenerateCppWrapper(func->ownerClass()))
code.replace("%TYPE", wrapperName(func->ownerClass()));
@@ -1631,6 +1621,7 @@ QPair< int, int > ShibokenGenerator::getMinMaxArguments(const AbstractMetaFuncti
QMap<QString, QString> ShibokenGenerator::options() const
{
QMap<QString, QString> opts(Generator::options());
+ opts.insert(AVOID_PROTECTED_HACK, "Avoid the use of the '#define protected public' hack.");
opts.insert(PARENT_CTOR_HEURISTIC, "Enable heuristics to detect parent relationship on constructors.");
opts.insert(RETURN_VALUE_HEURISTIC, "Enable heuristics to detect parent relationship on return values (USE WITH CAUTION!)");
opts.insert(ENABLE_PYSIDE_EXTENSIONS, "Enable PySide extensions, such as support for signal/slots, use this if you are creating a binding for a Qt-based library.");
@@ -1646,6 +1637,7 @@ bool ShibokenGenerator::doSetup(const QMap<QString, QString>& args)
m_userReturnValueHeuristic = args.contains(RETURN_VALUE_HEURISTIC);
m_verboseErrorMessagesDisabled = args.contains(DISABLE_VERBOSE_ERROR_MESSAGES);
m_useIsNullAsNbNonZero = args.contains(USE_ISNULL_AS_NB_NONZERO);
+ m_avoidProtectedHack = args.contains(AVOID_PROTECTED_HACK);
return true;
}
@@ -1669,6 +1661,11 @@ bool ShibokenGenerator::useIsNullAsNbNonZero() const
return m_useIsNullAsNbNonZero;
}
+bool ShibokenGenerator::avoidProtectedHack() const
+{
+ return m_avoidProtectedHack;
+}
+
QString ShibokenGenerator::cppApiVariableName(const QString& moduleName) const
{
QString result = moduleName.isEmpty() ? ShibokenGenerator::packageName() : moduleName;
diff --git a/generator/shibokengenerator.h b/generator/shibokengenerator.h
index a238b2c0..c660f2ef 100644
--- a/generator/shibokengenerator.h
+++ b/generator/shibokengenerator.h
@@ -207,14 +207,14 @@ public:
void writeToCppConversion(QTextStream& s, const AbstractMetaClass* metaClass, const QString& argumentName);
/// Verifies if the class should have a C++ wrapper generated for it, instead of only a Python wrapper.
- static bool shouldGenerateCppWrapper(const AbstractMetaClass* metaClass);
+ bool shouldGenerateCppWrapper(const AbstractMetaClass* metaClass) const;
/// Adds enums eligible for generation from classes/namespaces marked not to be generated.
static void lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList& enumList, const AbstractMetaClass* metaClass);
/// Returns the enclosing class for an enum, or NULL if it should be global.
const AbstractMetaClass* getProperEnclosingClassForEnum(const AbstractMetaEnum* metaEnum);
- static QString wrapperName(const AbstractMetaClass* metaClass);
+ QString wrapperName(const AbstractMetaClass* metaClass) const;
static QString fullPythonFunctionName(const AbstractMetaFunction* func);
static QString protectedEnumSurrogateName(const AbstractMetaEnum* metaEnum);
@@ -310,8 +310,10 @@ public:
bool useReturnValueHeuristic() const;
/// Returns true if the user enabled PySide extensions.
bool usePySideExtensions() const;
- /// Return true if the generator should use the result of isNull()const to compute boolean casts.
+ /// Returns true if the generator should use the result of isNull()const to compute boolean casts.
bool useIsNullAsNbNonZero() const;
+ /// Returns true if the generated code should use the "#define protected public" hack.
+ bool avoidProtectedHack() const;
QString cppApiVariableName(const QString& moduleName = QString()) const;
QString getTypeIndexVariableName(const TypeEntry* metaType);
/// Returns true if the user don't want verbose error messages on the generated bindings.
@@ -354,7 +356,7 @@ protected:
const AbstractMetaFunction* metaFunc,
Options options = NoOption) const;
- static AbstractMetaFunctionList filterFunctions(const AbstractMetaClass* metaClass);
+ AbstractMetaFunctionList filterFunctions(const AbstractMetaClass* metaClass);
// All data about extended converters: the type entries of the target type, and a
// list of AbstractMetaClasses accepted as argument for the conversion.
@@ -372,6 +374,7 @@ private:
bool m_usePySideExtensions;
bool m_verboseErrorMessagesDisabled;
bool m_useIsNullAsNbNonZero;
+ bool m_avoidProtectedHack;
};
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index dc7c69f6..b9d60262 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,6 +1,13 @@
add_subdirectory(libsample)
add_subdirectory(libother)
+if(WIN32 OR DEFINED AVOID_PROTECTED_HACK)
+ message(STATUS "Tests will be generated avoiding the protected hack!")
+ set(GENERATOR_EXTRA_FLAGS --avoid-protected-hack)
+else()
+ message(STATUS "Tests will be generated using the protected hack!")
+ set(GENERATOR_EXTRA_FLAGS )
+endif()
add_subdirectory(samplebinding)
add_subdirectory(otherbinding)
diff --git a/tests/otherbinding/CMakeLists.txt b/tests/otherbinding/CMakeLists.txt
index 5a859679..366bdbd5 100644
--- a/tests/otherbinding/CMakeLists.txt
+++ b/tests/otherbinding/CMakeLists.txt
@@ -18,7 +18,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/other-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt" @ONLY)
add_custom_command(OUTPUT ${other_SRC}
-COMMAND ${GENERATORRUNNER_BINARY} --project-file=${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt
+COMMAND ${GENERATORRUNNER_BINARY} --project-file=${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt ${GENERATOR_EXTRA_FLAGS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'other' test binding..."
)
diff --git a/tests/samplebinding/CMakeLists.txt b/tests/samplebinding/CMakeLists.txt
index abe982aa..e21c2286 100644
--- a/tests/samplebinding/CMakeLists.txt
+++ b/tests/samplebinding/CMakeLists.txt
@@ -92,7 +92,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sample-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt" @ONLY)
add_custom_command(OUTPUT ${sample_SRC}
-COMMAND ${GENERATORRUNNER_BINARY} --project-file=${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt
+COMMAND ${GENERATORRUNNER_BINARY} --project-file=${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt ${GENERATOR_EXTRA_FLAGS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running generator for 'sample' test binding..."
)