aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp194
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h2
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.cpp131
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.h23
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.cpp27
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.h2
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang_enums.h6
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp16
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.cpp99
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.h25
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp14
11 files changed, 348 insertions, 191 deletions
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index c6b50a94e..5e914a989 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -284,7 +284,6 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
metaFunction->setArguments(arguments);
metaFunction->setReverseOperator(true);
}
- metaFunction->setFunctionType(AbstractMetaFunction::NormalFunction);
metaFunction->setVisibility(AbstractMetaFunction::Public);
metaFunction->setOriginalAttributes(metaFunction->attributes());
setupFunctionDefaults(metaFunction, baseoperandClass);
@@ -296,57 +295,54 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
}
}
-void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item,
+bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item,
AbstractMetaClass *currentClass)
{
- ArgumentList arguments = item->arguments();
- if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
- AbstractMetaClass *streamClass = argumentToClass(arguments.at(0), currentClass);
- AbstractMetaClass *streamedClass = argumentToClass(arguments.at(1), currentClass);
-
- if (streamClass && streamedClass && (streamClass->isStream())) {
- AbstractMetaFunction *streamFunction = traverseFunction(item, streamedClass);
-
- if (streamFunction) {
- // Strip first argument, since that is the containing object
- AbstractMetaArgumentList arguments = streamFunction->arguments();
- if (!streamClass->typeEntry()->generateCode())
- arguments.takeLast();
- else
- arguments.takeFirst();
-
- streamFunction->setArguments(arguments);
-
- *streamFunction += AbstractMetaAttributes::FinalInTargetLang;
- *streamFunction += AbstractMetaAttributes::Public;
- streamFunction->setOriginalAttributes(streamFunction->attributes());
-
-// streamFunction->setType(0);
-
- AbstractMetaClass *funcClass;
+ ArgumentList itemArguments = item->arguments();
+ if (itemArguments.size() != 2 || item->accessPolicy() != CodeModel::Public)
+ return false;
+ auto streamClass = argumentToClass(itemArguments.at(0), currentClass);
+ if (streamClass == nullptr || !streamClass->isStream())
+ return false;
+ auto streamedClass = argumentToClass(itemArguments.at(1), currentClass);
+ if (streamedClass == nullptr)
+ return false;
+
+ AbstractMetaFunction *streamFunction = traverseFunction(item, streamedClass);
+ if (!streamFunction)
+ return false;
+
+ // Strip first argument, since that is the containing object
+ AbstractMetaArgumentList arguments = streamFunction->arguments();
+ if (!streamClass->typeEntry()->generateCode())
+ arguments.takeLast();
+ else
+ arguments.takeFirst();
- if (!streamClass->typeEntry()->generateCode()) {
- AbstractMetaArgumentList reverseArgs = reverseList(streamFunction->arguments());
- streamFunction->setArguments(reverseArgs);
- streamFunction->setReverseOperator(true);
- funcClass = streamedClass;
- } else {
- funcClass = streamClass;
- }
+ streamFunction->setArguments(arguments);
- setupFunctionDefaults(streamFunction, funcClass);
- funcClass->addFunction(AbstractMetaFunctionCPtr(streamFunction));
- if (funcClass == streamClass)
- funcClass->typeEntry()->addExtraInclude(streamedClass->typeEntry()->include());
- else
- funcClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
+ *streamFunction += AbstractMetaAttributes::FinalInTargetLang;
+ *streamFunction += AbstractMetaAttributes::Public;
+ streamFunction->setOriginalAttributes(streamFunction->attributes());
- } else {
- delete streamFunction;
- }
+ AbstractMetaClass *funcClass;
- }
+ if (!streamClass->typeEntry()->generateCode()) {
+ AbstractMetaArgumentList reverseArgs = reverseList(streamFunction->arguments());
+ streamFunction->setArguments(reverseArgs);
+ streamFunction->setReverseOperator(true);
+ funcClass = streamedClass;
+ } else {
+ funcClass = streamClass;
}
+
+ setupFunctionDefaults(streamFunction, funcClass);
+ funcClass->addFunction(AbstractMetaFunctionCPtr(streamFunction));
+ if (funcClass == streamClass)
+ funcClass->typeEntry()->addExtraInclude(streamedClass->typeEntry()->include());
+ else
+ funcClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
+ return true;
}
void AbstractMetaBuilderPrivate::sortLists()
@@ -542,39 +538,20 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
registerToStringCapabilityIn(dom);
- {
- FunctionList binaryOperators = dom->findFunctions(QStringLiteral("operator=="));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator!=")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator<=")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator>=")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator<")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator+")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator/")));
- // Filter binary operators, skipping for example
- // class Iterator { ... Value *operator*() ... };
- const FunctionList potentiallyBinaryOperators =
- dom->findFunctions(QStringLiteral("operator*"))
- + dom->findFunctions(QStringLiteral("operator&"));
- for (const FunctionModelItem &item : potentiallyBinaryOperators) {
- if (!item->arguments().isEmpty())
- binaryOperators.append(item);
- }
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator-")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator&")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator|")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator^")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator~")));
- binaryOperators.append(dom->findFunctions(QStringLiteral("operator>")));
-
- for (const FunctionModelItem &item : qAsConst(binaryOperators))
- traverseOperatorFunction(item, nullptr);
- }
-
- {
- const FunctionList streamOperators = dom->findFunctions(QLatin1String("operator<<"))
- + dom->findFunctions(QLatin1String("operator>>"));
- for (const FunctionModelItem &item : streamOperators)
- traverseStreamOperator(item, nullptr);
+ for (const auto &func : dom->functions()) {
+ switch (func->functionType()) {
+ case CodeModel::ComparisonOperator:
+ case CodeModel::ArithmeticOperator:
+ case CodeModel::BitwiseOperator:
+ case CodeModel::LogicalOperator:
+ traverseOperatorFunction(func, nullptr);
+ break;
+ case CodeModel::ShiftOperator:
+ if (!traverseStreamOperator(func, nullptr))
+ traverseOperatorFunction(func, nullptr);
+ default:
+ break;
+ }
}
ReportHandler::startProgress("Checking inconsistencies in function modifications...");
@@ -1553,12 +1530,13 @@ static void applyDefaultExpressionModifications(const FunctionModificationList &
}
}
+static AbstractMetaFunction::FunctionType functionTypeFromName(const QString &);
+
bool AbstractMetaBuilderPrivate::traverseAddedGlobalFunction(const AddedFunctionPtr &addedFunc)
{
AbstractMetaFunction *metaFunction = traverseAddedFunctionHelper(addedFunc);
if (metaFunction == nullptr)
return false;
- metaFunction->setFunctionType(AbstractMetaFunction::NormalFunction);
m_globalFunctions << AbstractMetaFunctionCPtr(metaFunction);
return true;
}
@@ -1581,6 +1559,7 @@ AbstractMetaFunction *
auto metaFunction = new AbstractMetaFunction(addedFunc);
metaFunction->setType(returnType.value());
+ metaFunction->setFunctionType(functionTypeFromName(addedFunc->name()));
const auto &args = addedFunc->arguments();
@@ -1666,13 +1645,6 @@ bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunction
if (te->name() == metaFunction->name())
metaFunction->setFunctionType(AbstractMetaFunction::CopyConstructorFunction);
}
- } else {
- auto type = AbstractMetaFunction::NormalFunction;
- if (metaFunction->name() == QLatin1String("__getattro__"))
- type = AbstractMetaFunction::GetAttroFunction;
- else if (metaFunction->name() == QLatin1String("__setattro__"))
- type = AbstractMetaFunction::SetAttroFunction;
- metaFunction->setFunctionType(type);
}
metaFunction->setDeclaringClass(metaClass);
@@ -1733,6 +1705,42 @@ static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeM
case CodeModel::Destructor:
result = AbstractMetaFunction::DestructorFunction;
break;
+ case CodeModel::AssignmentOperator:
+ result = AbstractMetaFunction::AssignmentOperatorFunction;
+ break;
+ case CodeModel::CallOperator:
+ result = AbstractMetaFunction::CallOperator;
+ break;
+ case CodeModel::ConversionOperator:
+ result = AbstractMetaFunction::ConversionOperator;
+ break;
+ case CodeModel::DereferenceOperator:
+ result = AbstractMetaFunction::DereferenceOperator;
+ break;
+ case CodeModel::ReferenceOperator:
+ result = AbstractMetaFunction::ReferenceOperator;
+ break;
+ case CodeModel::ArrowOperator:
+ result = AbstractMetaFunction::ArrowOperator;
+ break;
+ case CodeModel::ArithmeticOperator:
+ result = AbstractMetaFunction::ArithmeticOperator;
+ break;
+ case CodeModel::BitwiseOperator:
+ result = AbstractMetaFunction::BitwiseOperator;
+ break;
+ case CodeModel::LogicalOperator:
+ result = AbstractMetaFunction::LogicalOperator;
+ break;
+ case CodeModel::ShiftOperator:
+ result = AbstractMetaFunction::ShiftOperator;
+ break;
+ case CodeModel::SubscriptOperator:
+ result = AbstractMetaFunction::SubscriptOperator;
+ break;
+ case CodeModel::ComparisonOperator:
+ result = AbstractMetaFunction::ComparisonOperator;
+ break;
case CodeModel::Normal:
break;
case CodeModel::Signal:
@@ -1745,6 +1753,18 @@ static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeM
return result;
}
+static AbstractMetaFunction::FunctionType functionTypeFromName(const QString &name)
+{
+ if (name == u"__getattro__")
+ return AbstractMetaFunction::GetAttroFunction;
+ if (name == u"__setattro__")
+ return AbstractMetaFunction::SetAttroFunction;
+ const auto typeOpt = _FunctionModelItem::functionTypeFromName(name);
+ if (typeOpt.has_value())
+ return functionTypeFromCodeModel(typeOpt.value());
+ return AbstractMetaFunction::NormalFunction;
+}
+
// Apply the <array> modifications of the arguments
static bool applyArrayArgumentModifications(const FunctionModificationList &functionMods,
AbstractMetaFunction *func,
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
index 2dc650ef9..4fd13adc9 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
@@ -103,7 +103,7 @@ public:
void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent);
void applyFunctionModifications(AbstractMetaFunction* func);
void traverseFields(const ScopeModelItem &item, AbstractMetaClass *parent);
- void traverseStreamOperator(const FunctionModelItem &functionItem,
+ bool traverseStreamOperator(const FunctionModelItem &functionItem,
AbstractMetaClass *currentClass);
void traverseOperatorFunction(const FunctionModelItem &item,
AbstractMetaClass *currentClass);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
index f9e5dcaf4..5ccf36e00 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
@@ -31,6 +31,7 @@
#include "abstractmetalang.h"
#include "abstractmetalang_helpers.h"
#include "abstractmetatype.h"
+#include <codemodel.h>
#include "documentation.h"
#include "messages.h"
#include "modifications.h"
@@ -551,9 +552,18 @@ bool AbstractMetaFunction::isConstructor() const
|| d->m_functionType == MoveConstructorFunction;
}
-bool AbstractMetaFunction::isNormal() const
+bool AbstractMetaFunction::needsReturnType() const
{
- return functionType() == NormalFunction || isSlot() || isInGlobalScope();
+ switch (d->m_functionType) {
+ case AbstractMetaFunction::ConstructorFunction:
+ case AbstractMetaFunction::CopyConstructorFunction:
+ case AbstractMetaFunction::MoveConstructorFunction:
+ case AbstractMetaFunction::DestructorFunction:
+ return false;
+ default:
+ break;
+ }
+ return true;
}
bool AbstractMetaFunction::isInGlobalScope() const
@@ -936,7 +946,7 @@ bool AbstractMetaFunction::generateExceptionHandling() const
bool AbstractMetaFunction::isConversionOperator() const
{
- return isConversionOperator(originalName());
+ return d->m_functionType == ConversionOperator;
}
bool AbstractMetaFunction::isOperatorOverload(const QString &funcName)
@@ -955,70 +965,34 @@ bool AbstractMetaFunction::isOperatorOverload(const QString &funcName)
bool AbstractMetaFunction::isOperatorOverload() const
{
- return isOperatorOverload(originalName());
+ return d->m_functionType == AssignmentOperatorFunction
+ || (d->m_functionType >= FirstOperator && d->m_functionType <= LastOperator);
}
bool AbstractMetaFunction::isArithmeticOperator() const
{
- if (!isOperatorOverload())
- return false;
-
- QString name = originalName();
-
- // It's a dereference operator!
- if (name == QLatin1String("operator*") && d->m_arguments.isEmpty())
- return false;
-
- return name == QLatin1String("operator+") || name == QLatin1String("operator+=")
- || name == QLatin1String("operator-") || name == QLatin1String("operator-=")
- || name == QLatin1String("operator*") || name == QLatin1String("operator*=")
- || name == QLatin1String("operator/") || name == QLatin1String("operator/=")
- || name == QLatin1String("operator%") || name == QLatin1String("operator%=")
- || name == QLatin1String("operator++") || name == QLatin1String("operator--");
+ return d->m_functionType == ArithmeticOperator;
}
bool AbstractMetaFunction::isBitwiseOperator() const
{
- if (!isOperatorOverload())
- return false;
-
- QString name = originalName();
- return name == QLatin1String("operator<<") || name == QLatin1String("operator<<=")
- || name == QLatin1String("operator>>") || name == QLatin1String("operator>>=")
- || name == QLatin1String("operator&") || name == QLatin1String("operator&=")
- || name == QLatin1String("operator|") || name == QLatin1String("operator|=")
- || name == QLatin1String("operator^") || name == QLatin1String("operator^=")
- || name == QLatin1String("operator~");
+ return d->m_functionType == BitwiseOperator
+ || d->m_functionType == ShiftOperator;
}
bool AbstractMetaFunction::isComparisonOperator() const
{
- if (!isOperatorOverload())
- return false;
-
- QString name = originalName();
- return name == QLatin1String("operator<") || name == QLatin1String("operator<=")
- || name == QLatin1String("operator>") || name == QLatin1String("operator>=")
- || name == QLatin1String("operator==") || name == QLatin1String("operator!=");
+ return d->m_functionType == ComparisonOperator;
}
bool AbstractMetaFunction::isLogicalOperator() const
{
- if (!isOperatorOverload())
- return false;
-
- QString name = originalName();
- return name == QLatin1String("operator!")
- || name == QLatin1String("operator&&")
- || name == QLatin1String("operator||");
+ return d->m_functionType == LogicalOperator;
}
bool AbstractMetaFunction::isSubscriptOperator() const
{
- if (!isOperatorOverload())
- return false;
-
- return originalName() == QLatin1String("operator[]");
+ return d->m_functionType == SubscriptOperator;
}
bool AbstractMetaFunction::isAssignmentOperator() const
@@ -1027,20 +1001,6 @@ bool AbstractMetaFunction::isAssignmentOperator() const
|| d->m_functionType == MoveAssignmentOperatorFunction;
}
-bool AbstractMetaFunction::isOtherOperator() const
-{
- if (!isOperatorOverload())
- return false;
-
- return !isArithmeticOperator()
- && !isBitwiseOperator()
- && !isComparisonOperator()
- && !isLogicalOperator()
- && !isConversionOperator()
- && !isSubscriptOperator()
- && !isAssignmentOperator();
-}
-
int AbstractMetaFunction::arityOfOperator() const
{
if (!isOperatorOverload() || isCallOperator())
@@ -1060,15 +1020,14 @@ int AbstractMetaFunction::arityOfOperator() const
bool AbstractMetaFunction::isInplaceOperator() const
{
- if (!isOperatorOverload())
- return false;
+ static const QSet<QStringView> inplaceOperators =
+ {
+ u"operator+=", u"operator&=", u"operator-=", u"operator|=",
+ u"operator*=", u"operator^=", u"operator/=", u"operator<<=",
+ u"operator%=", u"operator>>="
+ };
- QString name = originalName();
- return name == QLatin1String("operator+=") || name == QLatin1String("operator&=")
- || name == QLatin1String("operator-=") || name == QLatin1String("operator|=")
- || name == QLatin1String("operator*=") || name == QLatin1String("operator^=")
- || name == QLatin1String("operator/=") || name == QLatin1String("operator<<=")
- || name == QLatin1String("operator%=") || name == QLatin1String("operator>>=");
+ return isOperatorOverload() && inplaceOperators.contains(originalName());
}
bool AbstractMetaFunction::isVirtual() const
@@ -1107,6 +1066,38 @@ AbstractMetaFunction::find(const AbstractMetaFunctionCList &haystack,
return {};
}
+bool AbstractMetaFunction::matches(OperatorQueryOptions query) const
+{
+ bool result = false;
+ switch (d->m_functionType) {
+ case AbstractMetaFunction::AssignmentOperatorFunction:
+ result = query.testFlag(OperatorQueryOption::AssignmentOp);
+ break;
+ case AbstractMetaFunction::ConversionOperator:
+ result = query.testFlag(OperatorQueryOption::ConversionOp);
+ break;
+ case AbstractMetaFunction::ArithmeticOperator:
+ result = query.testFlag(OperatorQueryOption::ArithmeticOp);
+ break;
+ case AbstractMetaFunction::BitwiseOperator:
+ case AbstractMetaFunction::ShiftOperator:
+ result = query.testFlag(OperatorQueryOption::BitwiseOp);
+ break;
+ case AbstractMetaFunction::LogicalOperator:
+ result = query.testFlag(OperatorQueryOption::LogicalOp);
+ break;
+ case AbstractMetaFunction::SubscriptOperator:
+ result = query.testFlag(OperatorQueryOption::SubscriptionOp);
+ break;
+ case AbstractMetaFunction::ComparisonOperator:
+ result = query.testFlag(OperatorQueryOption::ComparisonOp);
+ break;
+ default:
+ break;
+ }
+ return result;
+}
+
void AbstractMetaFunction::setAllowThreadModification(TypeSystem::AllowThread am)
{
d->m_allowThreadModification = am;
@@ -1148,8 +1139,6 @@ TypeSystem::SnakeCase AbstractMetaFunction::snakeCase() const
case AbstractMetaFunction::SignalFunction:
case AbstractMetaFunction::EmptyFunction:
case AbstractMetaFunction::SlotFunction:
- if (isOperatorOverload())
- return TypeSystem::SnakeCase::Disabled;
break;
default:
return TypeSystem::SnakeCase::Disabled;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.h b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
index 9c33c93a4..1d5c8885a 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
@@ -29,6 +29,7 @@
#ifndef ABSTRACTMETAFUNCTION_H
#define ABSTRACTMETAFUNCTION_H
+#include "abstractmetalang_enums.h"
#include "abstractmetalang_typedefs.h"
#include "abstractmetaargument.h"
#include "abstractmetaattributes.h"
@@ -65,7 +66,20 @@ public:
EmptyFunction,
SlotFunction,
GetAttroFunction,
- SetAttroFunction
+ SetAttroFunction,
+ CallOperator,
+ FirstOperator = CallOperator,
+ ConversionOperator,
+ DereferenceOperator, // Iterator's operator *
+ ReferenceOperator, // operator &
+ ArrowOperator,
+ ArithmeticOperator,
+ BitwiseOperator,
+ LogicalOperator,
+ ShiftOperator,
+ SubscriptOperator,
+ ComparisonOperator,
+ LastOperator = ComparisonOperator
};
Q_ENUM(FunctionType)
@@ -135,12 +149,11 @@ public:
bool isOperatorOverload() const;
bool isArithmeticOperator() const;
- bool isBitwiseOperator() const;
+ bool isBitwiseOperator() const; // Includes shift operator
bool isComparisonOperator() const;
bool isLogicalOperator() const;
bool isSubscriptOperator() const;
bool isAssignmentOperator() const; // Assignment or move assignment
- bool isOtherOperator() const;
/**
* Informs the arity of the operator or -1 if the function is not
@@ -190,7 +203,7 @@ public:
bool isDeprecated() const;
bool isDestructor() const { return functionType() == DestructorFunction; }
bool isConstructor() const;
- bool isNormal() const;
+ bool needsReturnType() const;
bool isInGlobalScope() const;
bool isSignal() const { return functionType() == SignalFunction; }
bool isSlot() const { return functionType() == SlotFunction; }
@@ -278,6 +291,8 @@ public:
static AbstractMetaFunctionCPtr
find(const AbstractMetaFunctionCList &haystack, const QString &needle);
+ bool matches(OperatorQueryOptions) const;
+
// for the meta builder only
void setAllowThreadModification(TypeSystem::AllowThread am);
void setExceptionHandlingModification(TypeSystem::ExceptionHandling em);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
index b9705de02..32befc400 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
@@ -221,14 +221,7 @@ AbstractMetaFunctionCList AbstractMetaClass::operatorOverloads(OperatorQueryOpti
| FunctionQueryOption::Visible);
AbstractMetaFunctionCList returned;
for (const auto &f : list) {
- if ((query.testFlag(OperatorQueryOption::ArithmeticOp) && f->isArithmeticOperator())
- || (query.testFlag(OperatorQueryOption::BitwiseOp) && f->isBitwiseOperator())
- || (query.testFlag(OperatorQueryOption::ComparisonOp) && f->isComparisonOperator())
- || (query.testFlag(OperatorQueryOption::LogicalOp) && f->isLogicalOperator())
- || (query.testFlag(OperatorQueryOption::SubscriptionOp) && f->isSubscriptOperator())
- || (query.testFlag(OperatorQueryOption::AssignmentOp) && f->isAssignmentOperator())
- || (query.testFlag(OperatorQueryOption::ConversionOp) && f->isConversionOperator())
- || (query.testFlag(OperatorQueryOption::OtherOp) && f->isOtherOperator()))
+ if (f->matches(query))
returned += f;
}
@@ -1094,6 +1087,22 @@ static void addExtraIncludesForFunction(AbstractMetaClass *metaClass,
addExtraIncludeForType(metaClass, argument.type());
}
+static bool addSuperFunction(const AbstractMetaFunctionCPtr &f)
+{
+ switch (f->functionType()) {
+ case AbstractMetaFunction::ConstructorFunction:
+ case AbstractMetaFunction::CopyConstructorFunction:
+ case AbstractMetaFunction::MoveConstructorFunction:
+ case AbstractMetaFunction::AssignmentOperatorFunction:
+ case AbstractMetaFunction::MoveAssignmentOperatorFunction:
+ case AbstractMetaFunction::DestructorFunction:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
void AbstractMetaClass::fixFunctions()
{
if (d->m_functionsFixed)
@@ -1139,7 +1148,7 @@ void AbstractMetaClass::fixFunctions()
// we generally don't care about private functions, but we have to get the ones that are
// virtual in case they override abstract functions.
- bool add = (sf->isNormal() || sf->isSignal() || sf->isEmptyFunction());
+ bool add = addSuperFunction(sf);
for (const auto &cf : qAsConst(nonRemovedFuncs)) {
AbstractMetaFunctionPtr f(qSharedPointerConstCast<AbstractMetaFunction>(cf));
const AbstractMetaFunction::CompareResult cmp = cf->compareTo(sf.data());
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h
index 50bbdae08..2100f0eaa 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h
@@ -114,7 +114,7 @@ public:
* /return list of operator overload methods that meet the
* query criteria
*/
- AbstractMetaFunctionCList operatorOverloads(OperatorQueryOptions query = OperatorQueryOption::AllOperators) const;
+ AbstractMetaFunctionCList operatorOverloads(OperatorQueryOptions query) const;
bool hasArithmeticOperatorOverload() const;
bool hasBitwiseOperatorOverload() const;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
index 33c4a5aa8..fd8f158d3 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
@@ -63,11 +63,7 @@ enum class OperatorQueryOption {
LogicalOp = 0x08, // Logical: !, &&, ||
ConversionOp = 0x10, // Conversion: operator [const] TYPE()
SubscriptionOp = 0x20, // Subscription: []
- AssignmentOp = 0x40, // Assignment: =
- OtherOp = 0x80, // The remaining operators: call(), etc
- AllOperators = ArithmeticOp | BitwiseOp | ComparisonOp
- | LogicalOp | ConversionOp | SubscriptionOp
- | AssignmentOp | OtherOp
+ AssignmentOp = 0x40 // Assignment: =
};
Q_DECLARE_FLAGS(OperatorQueryOptions, OperatorQueryOption)
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
index 9006e2321..cf489eb2e 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
@@ -1235,13 +1235,25 @@ bool Builder::endToken(const CXCursor &cursor)
break;
case CXCursor_Constructor:
d->qualifyConstructor(cursor);
- d->m_currentFunction.clear();
+ if (!d->m_currentFunction.isNull()) {
+ d->m_currentFunction->_determineType();
+ d->m_currentFunction.clear();
+ }
break;
case CXCursor_Destructor:
case CXCursor_CXXMethod:
case CXCursor_FunctionDecl:
case CXCursor_FunctionTemplate:
- d->m_currentFunction.clear();
+ if (!d->m_currentFunction.isNull()) {
+ d->m_currentFunction->_determineType();
+ d->m_currentFunction.clear();
+ }
+ break;
+ case CXCursor_ConversionFunction:
+ if (!d->m_currentFunction.isNull()) {
+ d->m_currentFunction->setFunctionType(CodeModel::ConversionOperator);
+ d->m_currentFunction.clear();
+ }
break;
case CXCursor_Namespace:
d->popScope();
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
index 5d1835c47..0f1e61a5b 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
@@ -34,6 +34,7 @@
#include <QtCore/QDebug>
#include <QtCore/QDir>
+#include <QtCore/QRegularExpression>
#include <algorithm>
#include <functional>
@@ -903,6 +904,104 @@ QString _FunctionModelItem::typeSystemSignature() const // For dumping out type
return result;
}
+using NameFunctionTypeHash = QHash<QStringView, CodeModel::FunctionType>;
+
+static const NameFunctionTypeHash &nameToOperatorFunction()
+{
+ static const NameFunctionTypeHash result = {
+ {u"operator=", CodeModel::AssignmentOperator},
+ {u"operator+", CodeModel::ArithmeticOperator},
+ {u"operator+=", CodeModel::ArithmeticOperator},
+ {u"operator-", CodeModel::ArithmeticOperator},
+ {u"operator-=", CodeModel::ArithmeticOperator},
+ {u"operator*", CodeModel::ArithmeticOperator},
+ {u"operator*=", CodeModel::ArithmeticOperator},
+ {u"operator/", CodeModel::ArithmeticOperator},
+ {u"operator/=", CodeModel::ArithmeticOperator},
+ {u"operator%", CodeModel::ArithmeticOperator},
+ {u"operator%=", CodeModel::ArithmeticOperator},
+ {u"operator++", CodeModel::ArithmeticOperator},
+ {u"operator--", CodeModel::ArithmeticOperator},
+ {u"operator&", CodeModel::BitwiseOperator},
+ {u"operator&=", CodeModel::BitwiseOperator},
+ {u"operator|", CodeModel::BitwiseOperator},
+ {u"operator|=", CodeModel::BitwiseOperator},
+ {u"operator^", CodeModel::BitwiseOperator},
+ {u"operator^=", CodeModel::BitwiseOperator},
+ {u"operator~", CodeModel::BitwiseOperator},
+ {u"operator<<", CodeModel::ShiftOperator},
+ {u"operator<<=", CodeModel::ShiftOperator},
+ {u"operator>>", CodeModel::ShiftOperator},
+ {u"operator>>=", CodeModel::ShiftOperator},
+ {u"operator<", CodeModel::ComparisonOperator},
+ {u"operator<=", CodeModel::ComparisonOperator},
+ {u"operator>", CodeModel::ComparisonOperator},
+ {u"operator>=", CodeModel::ComparisonOperator},
+ {u"operator==", CodeModel::ComparisonOperator},
+ {u"operator!=", CodeModel::ComparisonOperator},
+ {u"operator!", CodeModel::LogicalOperator},
+ {u"operator&&", CodeModel::LogicalOperator},
+ {u"operator||", CodeModel::LogicalOperator},
+ {u"operator[]", CodeModel::SubscriptOperator},
+ {u"operator()", CodeModel::CallOperator}, // Can be void
+ {u"operator->", CodeModel::ArrowOperator}
+ };
+ return result;
+}
+
+std::optional<CodeModel::FunctionType> _FunctionModelItem::functionTypeFromName(QStringView name)
+{
+ const auto it = nameToOperatorFunction().constFind(name);
+ if (it != nameToOperatorFunction().constEnd())
+ return it.value();
+ // This check is only for added functions. Clang detects this
+ // by cursor type CXCursor_ConversionFunction.
+ if (name.startsWith(u"operator "))
+ return CodeModel::ConversionOperator;
+ return {};
+}
+
+// Check for operators, etc. unless it is a specific type like a constructor
+CodeModel::FunctionType _FunctionModelItem::_determineTypeHelper() const
+{
+ switch (m_functionType) {
+ case CodeModel::Constructor:
+ case CodeModel::CopyConstructor:
+ case CodeModel::MoveConstructor:
+ case CodeModel::Destructor:
+ case CodeModel::Signal:
+ case CodeModel::Slot:
+ return m_functionType; // nothing to do here
+ default:
+ break;
+ }
+ const QString &functionName = name();
+ const auto newTypeOpt = _FunctionModelItem::functionTypeFromName(functionName);
+ if (!newTypeOpt.has_value())
+ return m_functionType;
+
+ auto newType = newTypeOpt.value();
+ // It's some sort of dereference operator?!
+ if (m_arguments.isEmpty()) {
+ switch (newType) {
+ case CodeModel::ArithmeticOperator:
+ if (functionName == u"operator*")
+ return CodeModel::DereferenceOperator;
+ case CodeModel::BitwiseOperator:
+ if (functionName == u"operator&")
+ return CodeModel::ReferenceOperator;
+ default:
+ break;
+ }
+ }
+ return newType;
+}
+
+void _FunctionModelItem::_determineType()
+{
+ m_functionType = _determineTypeHelper();
+}
+
#ifndef QT_NO_DEBUG_STREAM
void _FunctionModelItem::formatDebug(QDebug &d) const
{
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.h b/sources/shiboken6/ApiExtractor/parser/codemodel.h
index d1703cb33..cb15e5985 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.h
@@ -43,6 +43,8 @@
#include <QtCore/QStringList>
#include <QtCore/QList>
+#include <optional>
+
QT_FORWARD_DECLARE_CLASS(QDebug)
#define DECLARE_MODEL_NODE(k) \
@@ -70,7 +72,19 @@ public:
MoveConstructor,
Destructor,
Signal,
- Slot
+ Slot,
+ AssignmentOperator,
+ CallOperator,
+ ConversionOperator,
+ DereferenceOperator, // Iterator's operator *
+ ReferenceOperator, // operator &
+ ArrowOperator,
+ ArithmeticOperator,
+ BitwiseOperator,
+ LogicalOperator,
+ ShiftOperator,
+ SubscriptOperator,
+ ComparisonOperator
};
Q_ENUM(FunctionType)
@@ -190,7 +204,7 @@ public:
ClassList classes() const { return m_classes; }
EnumList enums() const { return m_enums; }
- inline FunctionList functions() const { return m_functions; }
+ inline const FunctionList &functions() const { return m_functions; }
TypeDefList typeDefs() const { return m_typeDefs; }
TemplateTypeAliasList templateTypeAliases() const { return m_templateTypeAliases; }
VariableList variables() const { return m_variables; }
@@ -455,6 +469,8 @@ public:
CodeModel::FunctionType functionType() const;
void setFunctionType(CodeModel::FunctionType functionType);
+ static std::optional<CodeModel::FunctionType> functionTypeFromName(QStringView name);
+
bool isDeleted() const;
void setDeleted(bool d);
@@ -495,11 +511,16 @@ public:
QString typeSystemSignature() const; // For dumping out type system files
+ // Private, for usage by the clang builder.
+ void _determineType();
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
private:
+ CodeModel::FunctionType _determineTypeHelper() const;
+
ArgumentList m_arguments;
CodeModel::FunctionType m_functionType;
union {
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 9a7a3f12b..67584eff1 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -1364,13 +1364,10 @@ QString ShibokenGenerator::functionSignature(const AbstractMetaFunctionCPtr &fun
{
StringStream s(TextStream::Language::Cpp);
// The actual function
- if (!(func->isEmptyFunction() ||
- func->isNormal() ||
- func->isSignal())) {
- options |= Generator::SkipReturnType;
- } else {
+ if (func->isEmptyFunction() || func->needsReturnType())
s << functionReturnType(func, options) << ' ';
- }
+ else
+ options |= Generator::SkipReturnType;
// name
QString name(func->originalName());
@@ -2219,15 +2216,14 @@ static bool isGroupable(const AbstractMetaFunctionCPtr &func)
case AbstractMetaFunction::SignalFunction:
case AbstractMetaFunction::GetAttroFunction:
case AbstractMetaFunction::SetAttroFunction:
+ case AbstractMetaFunction::ArrowOperator: // weird operator overloads
+ case AbstractMetaFunction::SubscriptOperator:
return false;
default:
break;
}
if (func->isModifiedRemoved() && !func->isAbstract())
return false;
- // weird operator overloads
- if (func->name() == QLatin1String("operator[]") || func->name() == QLatin1String("operator->")) // FIXME: what about cast operators?
- return false;
return true;
}