aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator/shiboken
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/generator/shiboken')
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp18
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.cpp45
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.h3
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp101
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h28
5 files changed, 110 insertions, 85 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index 2db5cb63e..3f1c72988 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -581,17 +581,13 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
s << "}\n\n";
}
- const auto &funcs = filterFunctions(metaClass);
int maxOverrides = 0;
writeCacheResetNative(s, classContext);
- for (const auto &func : funcs) {
- const bool notAbstract = !func->isAbstract();
- if ((func->isPrivate() && notAbstract && !func->isVisibilityModifiedToPrivate())
- || (func->isModifiedRemoved() && notAbstract))
- continue;
- if (func->functionType() == AbstractMetaFunction::ConstructorFunction && !func->isUserAdded())
+ for (const auto &func : metaClass->functions()) {
+ const auto generation = functionGeneration(func);
+ if (generation.testFlag(FunctionGenerationFlag::WrapperConstructor))
writeConstructorNative(s, classContext, func);
- else if (shouldWriteVirtualMethodNative(func))
+ else if (generation.testFlag(FunctionGenerationFlag::VirtualMethod))
writeVirtualMethodNative(s, func, maxOverrides++);
}
@@ -1124,12 +1120,6 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
const AbstractMetaFunctionCPtr &func,
int cacheIndex) const
{
- // skip metaObject function, this will be written manually ahead
- if (usePySideExtensions() && func->ownerClass() && func->ownerClass()->isQObject() &&
- ((func->name() == u"metaObject"_s)
- || (func->name() == u"qt_metacall")))
- return;
-
const TypeEntry *retType = func->type().typeEntry();
const QString funcName = func->isOperatorOverload()
? pythonOperatorFunctionName(func) : func->definitionNames().constFirst();
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.cpp b/sources/shiboken6/generator/shiboken/headergenerator.cpp
index 9465bce8c..01bb5d578 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp
@@ -138,15 +138,13 @@ void HeaderGenerator::generateClass(TextStream &s, const GeneratorContext &class
s << '\n';
}
- const auto &funcs = filterFunctions(metaClass);
int maxOverrides = 0;
- for (const auto &func : funcs) {
- if (!func->attributes().testFlag(AbstractMetaFunction::FinalCppMethod)) {
- writeFunction(s, func);
- // PYSIDE-803: Build a boolean cache for unused overrides.
- if (shouldWriteVirtualMethodNative(func))
- maxOverrides++;
- }
+ for (const auto &func : metaClass->functions()) {
+ const auto generation = functionGeneration(func);
+ writeFunction(s, func, generation);
+ // PYSIDE-803: Build a boolean cache for unused overrides.
+ if (generation.testFlag(FunctionGenerationFlag::VirtualMethod))
+ maxOverrides++;
}
if (!maxOverrides)
maxOverrides = 1;
@@ -247,43 +245,34 @@ void HeaderGenerator::writeMemberFunctionWrapper(TextStream &s,
s << "); }\n";
}
-void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func)
+void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ FunctionGeneration generation)
{
// do not write copy ctors here.
- if (!func->isPrivate() && func->functionType() == AbstractMetaFunction::CopyConstructorFunction) {
+ if (generation.testFlag(FunctionGenerationFlag::WrapperSpecialCopyConstructor)) {
writeCopyCtor(s, func->ownerClass());
return;
}
- if (func->isUserAdded())
- return;
- if (avoidProtectedHack() && func->isProtected() && !func->isConstructor()
- && !func->isOperatorOverload()) {
+ if (generation.testFlag(FunctionGenerationFlag::ProtectedWrapper))
writeMemberFunctionWrapper(s, func, u"_protected"_s);
- }
-
- // pure virtual functions need a default implementation
- const bool notAbstract = !func->isAbstract();
- if ((func->isPrivate() && notAbstract && !func->isVisibilityModifiedToPrivate())
- || (func->isModifiedRemoved() && notAbstract))
- return;
- if (avoidProtectedHack() && func->ownerClass()->hasPrivateDestructor()
- && (func->isAbstract() || func->isVirtual()))
- return;
-
- if (func->functionType() == AbstractMetaFunction::ConstructorFunction) {
+ if (generation.testFlag(FunctionGenerationFlag::WrapperConstructor)) {
Options option = func->hasSignatureModifications()
? Generator::OriginalTypeDescription : Generator::NoOption;
s << functionSignature(func, {}, {}, option) << ";\n";
return;
}
- if (func->isAbstract() || func->isVirtual()) {
+ const bool isVirtual = generation.testFlag(FunctionGenerationFlag::VirtualMethod);
+ if (isVirtual || generation.testFlag(FunctionGenerationFlag::QMetaObjectMethod)) {
s << functionSignature(func, {}, {}, Generator::OriginalTypeDescription)
<< " override;\n";
- // Check if this method hide other methods in base classes
+ }
+
+ // Check if this method hide other methods in base classes
+ if (isVirtual) {
for (const auto &f : func->ownerClass()->functions()) {
if (f != func
&& !f->isConstructor()
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.h b/sources/shiboken6/generator/shiboken/headergenerator.h
index 3771d45cf..3adaa247b 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.h
+++ b/sources/shiboken6/generator/shiboken/headergenerator.h
@@ -54,7 +54,8 @@ protected:
private:
void writeCopyCtor(TextStream &s, const AbstractMetaClass *metaClass) const;
- void writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func);
+ void writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ FunctionGeneration generation);
void writeSbkTypeFunction(TextStream &s, const AbstractMetaEnum &cppEnum) const;
static void writeSbkTypeFunction(TextStream &s, const AbstractMetaClass *cppClass) ;
static void writeSbkTypeFunction(TextStream &s, const AbstractMetaType &metaType) ;
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index bac9ed6b5..268cb7c25 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -199,13 +199,70 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass *metaCl
&& wrapper.testFlag(AbstractMetaClass::CppProtectedHackWrapper));
}
-bool ShibokenGenerator::shouldWriteVirtualMethodNative(const AbstractMetaFunctionCPtr &func) const
+ShibokenGenerator::FunctionGeneration
+ ShibokenGenerator::functionGeneration(const AbstractMetaFunctionCPtr &func) const
{
- // PYSIDE-803: Extracted this because it is used multiple times.
- const AbstractMetaClass *metaClass = func->ownerClass();
- return (!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
- && ((func->isVirtual() || func->isAbstract())
- && !func->attributes().testFlag(AbstractMetaFunction::FinalCppMethod));
+ FunctionGeneration result;
+
+ const auto functionType = func->functionType();
+ switch (functionType) {
+ case AbstractMetaFunction::ConversionOperator:
+ case AbstractMetaFunction::AssignmentOperatorFunction:
+ case AbstractMetaFunction::MoveAssignmentOperatorFunction:
+ case AbstractMetaFunction::DestructorFunction:
+ case AbstractMetaFunction::SignalFunction:
+ case AbstractMetaFunction::GetAttroFunction:
+ case AbstractMetaFunction::SetAttroFunction:
+ return result;
+ default:
+ if (func->isUserAdded() || func->usesRValueReferences())
+ return result;
+ break;
+ }
+
+ const bool notModifiedRemoved = !func->isModifiedRemoved();
+ const bool isPrivate = func->isPrivate() && !func->isVisibilityModifiedToPrivate();
+ switch (functionType) {
+ case AbstractMetaFunction::ConstructorFunction:
+ if (!isPrivate && notModifiedRemoved)
+ result.setFlag(FunctionGenerationFlag::WrapperConstructor);
+ return result;
+ case AbstractMetaFunction::CopyConstructorFunction:
+ if (!isPrivate && notModifiedRemoved)
+ result.setFlag(FunctionGenerationFlag::WrapperSpecialCopyConstructor);
+ return result;
+ case AbstractMetaFunction::NormalFunction:
+ case AbstractMetaFunction::SlotFunction:
+ if (avoidProtectedHack() && func->isProtected())
+ result.setFlag(FunctionGenerationFlag::ProtectedWrapper);
+ break;
+ default:
+ break;
+ }
+
+ // Check on virtuals (including operators).
+ const bool isAbstract = func->isAbstract();
+ if (!(isAbstract || func->isVirtual())
+ || func->attributes().testFlag(AbstractMetaFunction::FinalCppMethod)) {
+ return result;
+ }
+
+ // MetaObject virtuals only need to be declared; CppGenerator creates a
+ // special implementation.
+ if (functionType == AbstractMetaFunction::NormalFunction
+ && usePySideExtensions() && func->ownerClass()->isQObject()) {
+ const QString &name = func->name();
+ if (name == u"metaObject"_s || name == u"qt_metacall") {
+ result.setFlag(FunctionGenerationFlag::QMetaObjectMethod);
+ return result;
+ }
+ }
+
+ // Pure virtual functions need a default implementation even if private.
+ if (isAbstract || (notModifiedRemoved && !isPrivate))
+ result.setFlag(FunctionGenerationFlag::VirtualMethod);
+
+ return result;
}
AbstractMetaFunctionCList ShibokenGenerator::implicitConversions(const TypeEntry *t) const
@@ -1152,38 +1209,6 @@ void ShibokenGenerator::writeUnusedVariableCast(TextStream &s, const QString &va
s << "SBK_UNUSED(" << variableName<< ")\n";
}
-static bool filterFunction(const AbstractMetaFunctionCPtr &func, bool avoidProtectedHack)
-{
- switch (func->functionType()) {
- case AbstractMetaFunction::DestructorFunction:
- case AbstractMetaFunction::SignalFunction:
- case AbstractMetaFunction::GetAttroFunction:
- case AbstractMetaFunction::SetAttroFunction:
- return false;
- default:
- break;
- }
- if (func->usesRValueReferences())
- return false;
- if (func->isModifiedRemoved() && !func->isAbstract()
- && (!avoidProtectedHack || !func->isProtected())) {
- return false;
- }
- return true;
-}
-
-AbstractMetaFunctionCList ShibokenGenerator::filterFunctions(const AbstractMetaClass *metaClass) const
-{
- AbstractMetaFunctionCList result;
- const AbstractMetaFunctionCList &funcs = metaClass->functions();
- result.reserve(funcs.size());
- for (const auto &func : funcs) {
- if (filterFunction(func, avoidProtectedHack()))
- result.append(func);
- }
- return result;
-}
-
ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverters() const
{
ExtendedConverterData extConvs;
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index e1f717644..14829d08f 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -52,6 +52,27 @@ QT_FORWARD_DECLARE_CLASS(TextStream)
class ShibokenGenerator : public Generator
{
public:
+ /// Besides the actual bindings (see AbstractMetaFunction::generateBinding(),
+ /// some functions need to be generated into the wrapper class
+ /// (virtual method/avoid protected hack expose).
+ enum class FunctionGenerationFlag
+ {
+ None = 0x0,
+ /// Virtual method overridable in Python
+ VirtualMethod = 0x1,
+ /// Special QObject virtuals
+ QMetaObjectMethod = 0x2,
+ /// Needs a protected wrapper for avoidProtectedHack()
+ /// public "foo_protected()" calling "foo()"
+ ProtectedWrapper = 0x4, //
+ /// Pass through constructor
+ WrapperConstructor = 0x8,
+ /// Generate a special copy constructor
+ /// "FooBar_Wrapper(const Foo&)" for constructing a wrapper from a value
+ WrapperSpecialCopyConstructor = 0x10
+ };
+ Q_DECLARE_FLAGS(FunctionGeneration, FunctionGenerationFlag);
+
enum class AttroCheckFlag
{
None = 0x0,
@@ -176,8 +197,8 @@ protected:
/// Verifies if the class should have a C++ wrapper generated for it, instead of only a Python wrapper.
bool shouldGenerateCppWrapper(const AbstractMetaClass *metaClass) const;
- /// Condition to call WriteVirtualMethodNative. Was extracted because also used to count these calls.
- bool shouldWriteVirtualMethodNative(const AbstractMetaFunctionCPtr &func) const;
+ /// Returns which functions need to be generated into the wrapper class
+ FunctionGeneration functionGeneration(const AbstractMetaFunctionCPtr &func) const;
// Return a list of implicit conversions if generation is enabled.
AbstractMetaFunctionCList implicitConversions(const TypeEntry *t) const;
@@ -297,8 +318,6 @@ protected:
static void writeUnusedVariableCast(TextStream &s, const QString &variableName);
- AbstractMetaFunctionCList filterFunctions(const AbstractMetaClass *metaClass) const;
-
// All data about extended converters: the type entries of the target type, and a
// list of AbstractMetaClasses accepted as argument for the conversion.
using ExtendedConverterData = QHash<const TypeEntry *, AbstractMetaClassCList>;
@@ -446,6 +465,7 @@ private:
static const TypeSystemConverterRegExps &typeSystemConvRegExps();
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(ShibokenGenerator::FunctionGeneration);
Q_DECLARE_OPERATORS_FOR_FLAGS(ShibokenGenerator::AttroCheck);
extern const QString CPP_ARG;