aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp45
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h3
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.cpp7
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.h2
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.cpp112
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.h16
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang_enums.h1
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.h1
9 files changed, 158 insertions, 35 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index 16fe8e01b..e8c82c247 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -499,16 +499,12 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) {
cls->fixFunctions();
- const bool couldAddDefaultCtors = cls->isConstructible()
- && !cls->isNamespace()
- && (cls->attributes() & AbstractMetaAttributes::HasRejectedConstructor) == 0;
- if (couldAddDefaultCtors) {
- if (!cls->hasConstructors())
- cls->addDefaultConstructor();
- if (cls->typeEntry()->isValue() && !cls->isAbstract() && !cls->hasCopyConstructor())
- cls->addDefaultCopyConstructor(ancestorHasPrivateCopyConstructor(cls));
- }
+ if (cls->canAddDefaultConstructor())
+ cls->addDefaultConstructor();
+ if (cls->canAddDefaultCopyConstructor())
+ cls->addDefaultCopyConstructor();
}
+
const auto &allEntries = types->entries();
ReportHandler::startProgress("Detecting inconsistencies in typesystem ("
@@ -1804,10 +1800,25 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func
}
AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem,
- const AbstractMetaClass *currentClass)
+ AbstractMetaClass *currentClass)
{
- if (functionItem->isDeleted() || !functionItem->templateParameters().isEmpty())
+ if (!functionItem->templateParameters().isEmpty())
+ return nullptr;
+
+ if (functionItem->isDeleted()) {
+ switch (functionItem->functionType()) {
+ case CodeModel::Constructor:
+ if (functionItem->isDefaultConstructor())
+ currentClass->setHasDeletedDefaultConstructor(true);
+ break;
+ case CodeModel::CopyConstructor:
+ currentClass->setHasDeletedCopyConstructor(true);
+ break;
+ default:
+ break;
+ }
return nullptr;
+ }
QString functionName = functionItem->name();
QString className;
if (currentClass) {
@@ -2622,18 +2633,6 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::getBaseClasses(const AbstractM
return baseClasses;
}
-bool AbstractMetaBuilderPrivate::ancestorHasPrivateCopyConstructor(const AbstractMetaClass *metaClass) const
-{
- if (metaClass->hasPrivateCopyConstructor())
- return true;
- const AbstractMetaClassList &baseClasses = getBaseClasses(metaClass);
- for (const AbstractMetaClass *cls : baseClasses) {
- if (ancestorHasPrivateCopyConstructor(cls))
- return true;
- }
- return false;
-}
-
std::optional<AbstractMetaType>
AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes,
const AbstractMetaType &metaType)
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
index 8191bc161..e7e6f8e10 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
@@ -118,7 +118,7 @@ public:
AbstractMetaClass *metaClass,
QString *errorMessage);
AbstractMetaFunction *traverseFunction(const FunctionModelItem &function,
- const AbstractMetaClass *currentClass);
+ AbstractMetaClass *currentClass);
std::optional<AbstractMetaField> traverseField(const VariableModelItem &field,
const AbstractMetaClass *cls);
void checkFunctionModifications();
@@ -173,7 +173,6 @@ public:
TypeInfo *info = Q_NULLPTR,
ComplexTypeEntry **baseContainerType = Q_NULLPTR) const;
AbstractMetaClassList getBaseClasses(const AbstractMetaClass *metaClass) const;
- bool ancestorHasPrivateCopyConstructor(const AbstractMetaClass *metaClass) const;
static bool inheritTemplate(AbstractMetaClass *subclass,
const AbstractMetaClass *templateClass,
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
index 5ccf36e00..93e73b6d9 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
@@ -552,6 +552,13 @@ bool AbstractMetaFunction::isConstructor() const
|| d->m_functionType == MoveConstructorFunction;
}
+bool AbstractMetaFunction::isDefaultConstructor() const
+{
+ return d->m_functionType == ConstructorFunction
+ && (d->m_arguments.isEmpty()
+ || d->m_arguments.constFirst().hasDefaultValueExpression());
+}
+
bool AbstractMetaFunction::needsReturnType() const
{
switch (d->m_functionType) {
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.h b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
index 0c604f1e3..290f334f7 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
@@ -202,6 +202,8 @@ public:
bool isDeprecated() const;
bool isDestructor() const { return functionType() == DestructorFunction; }
bool isConstructor() const;
+ bool isCopyConstructor() const { return functionType() == CopyConstructorFunction; }
+ bool isDefaultConstructor() const;
bool needsReturnType() const;
bool isInGlobalScope() const;
bool isSignal() const { return functionType() == SignalFunction; }
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
index e80bc4371..f3dc44dee 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
@@ -56,6 +56,8 @@ public:
m_hasNonpublic(false),
m_hasNonPrivateConstructor(false),
m_hasPrivateConstructor(false),
+ m_hasDeletedDefaultConstructor(false),
+ m_hasDeletedCopyConstructor(false),
m_functionsFixed(false),
m_inheritanceDone(false),
m_hasPrivateDestructor(false),
@@ -75,6 +77,8 @@ public:
uint m_hasNonpublic : 1;
uint m_hasNonPrivateConstructor : 1;
uint m_hasPrivateConstructor : 1;
+ uint m_hasDeletedDefaultConstructor : 1;
+ uint m_hasDeletedCopyConstructor : 1;
uint m_functionsFixed : 1;
uint m_inheritanceDone : 1; // m_baseClasses has been populated from m_baseClassNames
uint m_hasPrivateDestructor : 1;
@@ -759,8 +763,9 @@ void AbstractMetaClass::addDefaultConstructor()
this->setHasNonPrivateConstructor(true);
}
-void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate)
+void AbstractMetaClass::addDefaultCopyConstructor()
{
+ d->m_hasNonPrivateConstructor = true;
auto f = new AbstractMetaFunction;
f->setType(AbstractMetaType::createVoid());
f->setOriginalName(name());
@@ -780,10 +785,7 @@ void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate)
f->addArgument(arg);
AbstractMetaAttributes::Attributes attr = FinalInTargetLang | AddedMethod;
- if (isPrivate)
- attr |= AbstractMetaAttributes::Private;
- else
- attr |= AbstractMetaAttributes::Public;
+ attr |= AbstractMetaAttributes::Public;
f->setAttributes(attr);
f->setImplementingClass(this);
f->setOriginalAttributes(f->attributes());
@@ -811,6 +813,26 @@ void AbstractMetaClass::setHasPrivateConstructor(bool value)
d->m_hasPrivateConstructor = value;
}
+bool AbstractMetaClass::hasDeletedDefaultConstructor() const
+{
+ return d->m_hasDeletedDefaultConstructor;
+}
+
+void AbstractMetaClass::setHasDeletedDefaultConstructor(bool value)
+{
+ d->m_hasDeletedDefaultConstructor = value;
+}
+
+bool AbstractMetaClass::hasDeletedCopyConstructor() const
+{
+ return d->m_hasDeletedCopyConstructor;
+}
+
+void AbstractMetaClass::setHasDeletedCopyConstructor(bool value)
+{
+ d->m_hasDeletedCopyConstructor = value;
+}
+
bool AbstractMetaClass::hasPrivateDestructor() const
{
return d->m_hasPrivateDestructor;
@@ -843,9 +865,81 @@ void AbstractMetaClass::setHasVirtualDestructor(bool value)
d->m_hasVirtuals = d->m_isPolymorphic = 1;
}
-bool AbstractMetaClass::isConstructible() const
+bool AbstractMetaClass::isDefaultConstructible() const
+{
+ // Private constructors are skipped by the builder.
+ if (hasDeletedDefaultConstructor() || hasPrivateConstructor())
+ return false;
+ const AbstractMetaFunctionCList ctors =
+ queryFunctions(FunctionQueryOption::Constructors);
+ for (const auto &ct : ctors) {
+ if (ct->isDefaultConstructor())
+ return ct->visibility() == AbstractMetaAttributes::Public;
+ }
+ return ctors.isEmpty() && isImplicitlyDefaultConstructible();
+}
+
+// Non-comprehensive check for default constructible field
+// (non-ref or not const value).
+static bool defaultConstructibleField(const AbstractMetaField &f)
+{
+ const auto &type = f.type();
+ return type.referenceType() == NoReference
+ && !(type.indirections() == 0 && type.isConstant()); // no const values
+}
+
+bool AbstractMetaClass::isImplicitlyDefaultConstructible() const
+{
+ return std::all_of(d->m_fields.cbegin(), d->m_fields.cend(),
+ defaultConstructibleField)
+ && std::all_of(d->m_baseClasses.cbegin(), d->m_baseClasses.cend(),
+ [] (const AbstractMetaClass *c) {
+ return c->isDefaultConstructible();
+ });
+}
+
+static bool canAddDefaultConstructorHelper(const AbstractMetaClass *cls)
+{
+ return !cls->isNamespace()
+ && !cls->attributes().testFlag(AbstractMetaAttributes::HasRejectedConstructor)
+ && !cls->hasPrivateDestructor();
+}
+
+bool AbstractMetaClass::canAddDefaultConstructor() const
+{
+ return canAddDefaultConstructorHelper(this) && !hasConstructors()
+ && !hasPrivateConstructor() && isImplicitlyDefaultConstructible();
+}
+
+bool AbstractMetaClass::isCopyConstructible() const
{
- return (hasNonPrivateConstructor() || !hasPrivateConstructor()) && !hasPrivateDestructor();
+ // Private constructors are skipped by the builder.
+ if (hasDeletedCopyConstructor() || hasPrivateCopyConstructor())
+ return false;
+ const AbstractMetaFunctionCList copyCtors =
+ queryFunctions(FunctionQueryOption::CopyConstructor);
+ return copyCtors.isEmpty()
+ ? isImplicitlyCopyConstructible()
+ : copyCtors.constFirst()->visibility() == AbstractMetaAttributes::Public;
+}
+
+bool AbstractMetaClass::isImplicitlyCopyConstructible() const
+{
+ // Fields are currently not considered
+ return std::all_of(d->m_baseClasses.cbegin(), d->m_baseClasses.cend(),
+ [] (const AbstractMetaClass *c) {
+ return c->isCopyConstructible();
+ });
+}
+
+bool AbstractMetaClass::canAddDefaultCopyConstructor() const
+{
+ if (!canAddDefaultConstructorHelper(this)
+ || !d->m_typeEntry->isValue() || isAbstract()
+ || hasPrivateCopyConstructor() || hasCopyConstructor()) {
+ return false;
+ }
+ return isImplicitlyCopyConstructible();
}
bool AbstractMetaClass::generateExceptionHandling() const
@@ -947,8 +1041,10 @@ bool AbstractMetaClass::queryFunction(const AbstractMetaFunction *f, FunctionQue
return false;
}
- if (!query.testFlag(FunctionQueryOption::Constructors) && f->isConstructor())
+ if (query.testFlag(FunctionQueryOption::CopyConstructor)
+ && (!f->isCopyConstructor() || f->ownerClass() != f->implementingClass())) {
return false;
+ }
// Destructors are never included in the functions of a class currently
/*
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h
index e1e90863f..31a470667 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h
@@ -78,7 +78,7 @@ public:
bool hasPrivateCopyConstructor() const;
void addDefaultConstructor();
- void addDefaultCopyConstructor(bool isPrivate = false);
+ void addDefaultCopyConstructor();
bool hasNonPrivateConstructor() const;
void setHasNonPrivateConstructor(bool value);
@@ -86,6 +86,12 @@ public:
bool hasPrivateConstructor() const;
void setHasPrivateConstructor(bool value);
+ bool hasDeletedDefaultConstructor() const;
+ void setHasDeletedDefaultConstructor(bool value);
+
+ bool hasDeletedCopyConstructor() const;
+ void setHasDeletedCopyConstructor(bool value);
+
bool hasPrivateDestructor() const;
void setHasPrivateDestructor(bool value);
@@ -95,7 +101,13 @@ public:
bool hasVirtualDestructor() const;
void setHasVirtualDestructor(bool value);
- bool isConstructible() const;
+ bool isDefaultConstructible() const;
+ bool isImplicitlyDefaultConstructible() const;
+ bool canAddDefaultConstructor() const;
+
+ bool isCopyConstructible() const;
+ bool isImplicitlyCopyConstructible() const;
+ bool canAddDefaultCopyConstructor() const;
bool generateExceptionHandling() const;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
index fd8f158d3..d2e50acba 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
@@ -33,6 +33,7 @@
enum class FunctionQueryOption {
Constructors = 0x0000001, // Only constructors
+ CopyConstructor = 0x0000002, // Only copy constructors
//Destructors = 0x0000002, // Only destructors. Not included in class.
FinalInTargetLangFunctions = 0x0000008, // Only functions that are non-virtual in TargetLang
ClassImplements = 0x0000020, // Only functions implemented by the current class
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
index 2621838fe..8a4ab153b 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
@@ -784,6 +784,12 @@ void _FunctionModelItem::setVariadics(bool isVariadics)
m_isVariadics = isVariadics;
}
+bool _FunctionModelItem::isDefaultConstructor() const
+{
+ return m_functionType == CodeModel::Constructor
+ && (m_arguments.isEmpty() || m_arguments.constFirst()->defaultValue());
+}
+
bool _FunctionModelItem::isNoExcept() const
{
return m_exceptionSpecification == ExceptionSpecification::NoExcept;
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.h b/sources/shiboken6/ApiExtractor/parser/codemodel.h
index db61a65e7..e4c2ab55d 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.h
@@ -502,6 +502,7 @@ public:
bool isVariadics() const;
void setVariadics(bool isVariadics);
+ bool isDefaultConstructor() const;
bool isSimilar(const FunctionModelItem &other) const;