aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-05-06 21:19:07 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-05-06 21:19:07 +0200
commit91b93e1021ccc06d13e0d66a43bf7f9063faeff3 (patch)
treef5270164466b42367d4df63d723b3a4db4d7d0fe /sources/shiboken2
parentedae6185cef9c0ddd7c7c88bfa97c5043ba0d78a (diff)
parent06f97eca45ddadf4f04229cf14d5dc0bbd867316 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'sources/shiboken2')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp39
-rw-r--r--sources/shiboken2/ApiExtractor/reporthandler.cpp72
-rw-r--r--sources/shiboken2/ApiExtractor/reporthandler.h11
-rw-r--r--sources/shiboken2/doc/contents.rst18
-rw-r--r--sources/shiboken2/doc/index.rst19
-rw-r--r--sources/shiboken2/generator/main.cpp5
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp54
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.h3
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.h3
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp103
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h16
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp4
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.h4
-rw-r--r--sources/shiboken2/libshiboken/embed/embedding_generator.py6
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h5
-rw-r--r--sources/shiboken2/libshiboken/pep384impl_doc.rst3
16 files changed, 203 insertions, 162 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 6e95e79e7..7e998d315 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -428,20 +428,20 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
// Start the generation...
const ClassList &typeValues = dom->classes();
- ReportHandler::setProgressReference(typeValues);
+
+ ReportHandler::startProgress("Generating class model ("
+ + QByteArray::number(typeValues.size()) + ")...");
for (const ClassModelItem &item : typeValues) {
- ReportHandler::progress(QStringLiteral("Generating class model (%1)...")
- .arg(typeValues.size()));
if (AbstractMetaClass *cls = traverseClass(dom, item, nullptr))
addAbstractMetaClass(cls, item.data());
}
// We need to know all global enums
const EnumList &enums = dom->enums();
- ReportHandler::setProgressReference(enums);
+
+ ReportHandler::startProgress("Generating enum model ("
+ + QByteArray::number(enums.size()) + ")...");
for (const EnumModelItem &item : enums) {
- ReportHandler::progress(QStringLiteral("Generating enum model (%1)...")
- .arg(enums.size()));
AbstractMetaEnum *metaEnum = traverseEnum(item, 0, QSet<QString>());
if (metaEnum) {
if (metaEnum->typeEntry()->generateCode())
@@ -450,10 +450,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
}
const auto &namespaceTypeValues = dom->namespaces();
- ReportHandler::setProgressReference(namespaceTypeValues);
+ ReportHandler::startProgress("Generating namespace model ("
+ + QByteArray::number(namespaceTypeValues.size()) + ")...");
for (const NamespaceModelItem &item : namespaceTypeValues) {
- ReportHandler::progress(QStringLiteral("Generating namespace model (%1)...")
- .arg(namespaceTypeValues.size()));
if (AbstractMetaClass *metaClass = traverseNamespace(dom, item))
addAbstractMetaClass(metaClass, item.data());
}
@@ -461,10 +460,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
// Go through all typedefs to see if we have defined any
// specific typedefs to be used as classes.
const TypeDefList typeDefs = dom->typeDefs();
- ReportHandler::setProgressReference(typeDefs);
+ ReportHandler::startProgress("Resolving typedefs ("
+ + QByteArray::number(typeDefs.size()) + ")...");
for (const TypeDefModelItem &typeDef : typeDefs) {
- ReportHandler::progress(QStringLiteral("Resolving typedefs (%1)...")
- .arg(typeDefs.size()));
if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, nullptr))
addAbstractMetaClass(cls, typeDef.data());
}
@@ -506,16 +504,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
m_globalFunctions << metaFunc;
}
- ReportHandler::setProgressReference(m_metaClasses);
+ ReportHandler::startProgress("Fixing class inheritance...");
for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) {
- ReportHandler::progress(QLatin1String("Fixing class inheritance..."));
if (!cls->isInterface() && !cls->isNamespace())
setupInheritance(cls);
}
- ReportHandler::setProgressReference(m_metaClasses);
+ ReportHandler::startProgress("Detecting inconsistencies in class model...");
for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) {
- ReportHandler::progress(QLatin1String("Detecting inconsistencies in class model..."));
cls->fixFunctions();
if (!cls->typeEntry()) {
@@ -538,8 +534,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + QLatin1String("$ConcreteWrapper"));
}
const auto &allEntries = types->entries();
- ReportHandler::progress(QStringLiteral("Detecting inconsistencies in typesystem (%1)...")
- .arg(allEntries.size()));
+
+ ReportHandler::startProgress("Detecting inconsistencies in typesystem ("
+ + QByteArray::number(allEntries.size()) + ")...");
for (auto it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) {
TypeEntry *entry = it.value();
if (!entry->isPrimitive()) {
@@ -638,8 +635,12 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
traverseStreamOperator(item, nullptr);
}
+ ReportHandler::startProgress("Checking inconsistencies in function modifications...");
+
checkFunctionModifications();
+ ReportHandler::startProgress("Writing log files...");
+
// sort all classes topologically
m_metaClasses = classesTopologicalSorted(m_metaClasses);
@@ -673,6 +674,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
}
m_itemToClass.clear();
+
+ ReportHandler::endProgress();
}
static bool metaEnumLessThan(const AbstractMetaEnum *e1, const AbstractMetaEnum *e2)
diff --git a/sources/shiboken2/ApiExtractor/reporthandler.cpp b/sources/shiboken2/ApiExtractor/reporthandler.cpp
index 6ff5b8d03..c0c323029 100644
--- a/sources/shiboken2/ApiExtractor/reporthandler.cpp
+++ b/sources/shiboken2/ApiExtractor/reporthandler.cpp
@@ -52,22 +52,13 @@ static int m_warningCount = 0;
static int m_suppressedCount = 0;
static ReportHandler::DebugLevel m_debugLevel = ReportHandler::NoDebug;
static QSet<QString> m_reportedWarnings;
-static QString m_progressBuffer;
static QString m_prefix;
-static int m_step_size = 0;
-static int m_step = -1;
+static bool m_withinProgress = false;
static int m_step_warning = 0;
static QElapsedTimer m_timer;
Q_LOGGING_CATEGORY(lcShiboken, "qt.shiboken")
-static void printProgress()
-{
- std::printf("%s", m_progressBuffer.toUtf8().data());
- std::fflush(stdout);
- m_progressBuffer.clear();
-}
-
void ReportHandler::install()
{
qInstallMessageHandler(ReportHandler::messageOutput);
@@ -94,12 +85,6 @@ int ReportHandler::warningCount()
return m_warningCount;
}
-void ReportHandler::setProgressReference(int max)
-{
- m_step_size = max;
- m_step = -1;
-}
-
bool ReportHandler::isSilent()
{
return m_silent;
@@ -136,38 +121,45 @@ void ReportHandler::messageOutput(QtMsgType type, const QMessageLogContext &cont
fprintf(stderr, "%s\n", qPrintable(qFormatLogMessage(type, context, message)));
}
-void ReportHandler::progress(const QString& str, ...)
+static QByteArray timeStamp()
+{
+ const qint64 elapsed = m_timer.elapsed();
+ return elapsed > 5000
+ ? QByteArray::number(elapsed / 1000) + 's'
+ : QByteArray::number(elapsed) + "ms";
+}
+
+void ReportHandler::startProgress(const QByteArray& str)
{
if (m_silent)
return;
- if (m_step == -1) {
- QTextStream buf(&m_progressBuffer);
- buf.setFieldWidth(45);
- buf.setFieldAlignment(QTextStream::AlignLeft);
- buf << str;
- printProgress();
- m_step = 0;
- }
- m_step++;
- if (m_step >= m_step_size) {
- if (m_step_warning == 0) {
- m_progressBuffer = QLatin1String("[" COLOR_GREEN "OK" COLOR_END "]\n");
- } else {
- m_progressBuffer = QLatin1String("[" COLOR_YELLOW "WARNING" COLOR_END "]\n");
- }
- printProgress();
- m_step_warning = 0;
- }
+ if (m_withinProgress)
+ endProgress();
+
+ m_withinProgress = true;
+ const auto ts = '[' + timeStamp() + ']';
+ std::printf("%s %8s %-60s", qPrintable(m_prefix), ts.constData(), str.constData());
+ std::fflush(stdout);
+}
+
+void ReportHandler::endProgress()
+{
+ if (m_silent)
+ return;
+
+ m_withinProgress = false;
+ const char *endMessage = m_step_warning == 0
+ ? "[" COLOR_GREEN "OK" COLOR_END "]\n"
+ : "[" COLOR_YELLOW "WARNING" COLOR_END "]\n";
+ std::fputs(endMessage, stdout);
+ std::fflush(stdout);
+ m_step_warning = 0;
}
QByteArray ReportHandler::doneMessage()
{
- QByteArray result = "Done, " + m_prefix.toUtf8() + ' ';
- const qint64 elapsed = m_timer.elapsed();
- result += elapsed > 5000
- ? QByteArray::number(elapsed / 1000) + 's'
- : QByteArray::number(elapsed) + "ms";
+ QByteArray result = "Done, " + m_prefix.toUtf8() + ' ' + timeStamp();
if (m_warningCount)
result += ", " + QByteArray::number(m_warningCount) + " warnings";
if (m_suppressedCount)
diff --git a/sources/shiboken2/ApiExtractor/reporthandler.h b/sources/shiboken2/ApiExtractor/reporthandler.h
index 8f97cb506..08ab7d23c 100644
--- a/sources/shiboken2/ApiExtractor/reporthandler.h
+++ b/sources/shiboken2/ApiExtractor/reporthandler.h
@@ -48,15 +48,8 @@ public:
static int suppressedCount();
- template <typename T>
- static void setProgressReference(T collection)
- {
- setProgressReference(collection.count());
- }
-
- static void setProgressReference(int max);
-
- static void progress(const QString &str, ...);
+ static void startProgress(const QByteArray &str);
+ static void endProgress();
static bool isDebug(DebugLevel level)
{ return debugLevel() >= level; }
diff --git a/sources/shiboken2/doc/contents.rst b/sources/shiboken2/doc/contents.rst
deleted file mode 100644
index 7cdc0063e..000000000
--- a/sources/shiboken2/doc/contents.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-Table of contents
-*****************
-.. toctree::
- :maxdepth: 3
-
- overview.rst
- samplebinding.rst
- commandlineoptions.rst
- projectfile.rst
- typesystemvariables.rst
- typeconverters.rst
- codeinjectionsemantics.rst
- sequenceprotocol.rst
- ownership.rst
- wordsofadvice.rst
- shibokenmodule.rst
- faq.rst
- typesystem.rst
diff --git a/sources/shiboken2/doc/index.rst b/sources/shiboken2/doc/index.rst
index 4cc5b204e..9403293ac 100644
--- a/sources/shiboken2/doc/index.rst
+++ b/sources/shiboken2/doc/index.rst
@@ -18,11 +18,22 @@ properly handle the data structures or types.
The final outcome of this process is a set of wrappers written in CPython,
which can be used as a module in your python code.
-Refer to the following topics for more information and examples:
+Table of contents
+*****************
.. toctree::
:maxdepth: 1
- overview
- samplebinding
- contents
+ overview.rst
+ samplebinding.rst
+ commandlineoptions.rst
+ projectfile.rst
+ typesystemvariables.rst
+ typeconverters.rst
+ codeinjectionsemantics.rst
+ sequenceprotocol.rst
+ ownership.rst
+ wordsofadvice.rst
+ shibokenmodule.rst
+ faq.rst
+ typesystem.rst
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 9beaf47c7..ac576d657 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -624,7 +624,10 @@ int main(int argc, char *argv[])
for (const GeneratorPtr &g : qAsConst(generators)) {
g->setOutputDirectory(outputDirectory);
g->setLicenseComment(licenseComment);
- if (!g->setup(extractor) || !g->generate()) {
+ ReportHandler::startProgress(QByteArray("Running ") + g->name() + "...");
+ const bool ok = g->setup(extractor) && g->generate();
+ ReportHandler::endProgress();
+ if (!ok) {
errorPrint(QLatin1String("Error running generator: ")
+ QLatin1String(g->name()) + QLatin1Char('.'));
return EXIT_FAILURE;
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 29220c739..58788d5ef 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -330,8 +330,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
// The multiple inheritance initialization function
// needs the 'set' class from C++ STL.
- if (hasMultipleInheritanceInAncestry(metaClass))
- s << "#include <set>" << endl;
+ if (getMultipleInheritingClass(metaClass) != nullptr)
+ s << "#include <algorithm>\n#include <set>\n";
if (metaClass->generateExceptionHandling())
s << "#include <exception>" << endl;
@@ -453,8 +453,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
s << endl << "// Target ---------------------------------------------------------" << endl << endl;
s << "extern \"C\" {" << endl;
- const FunctionGroupMap &functionGroups = getFunctionGroups(metaClass);
- for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
+ const auto &functionGroups = getFunctionGroups(metaClass);
+ for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
QSet<QString> seenSignatures;
bool staticEncountered = false;
@@ -1726,7 +1726,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
}
{
Indentation indentation(INDENT);
- s << INDENT << "Shiboken::ObjectType::copyMultimpleheritance(type, myType);" << endl;
+ s << INDENT << "Shiboken::ObjectType::copyMultipleInheritance(type, myType);" << endl;
}
if (!metaClass->isAbstract())
s << INDENT << '}' << endl << endl;
@@ -3553,11 +3553,18 @@ QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass
const AbstractMetaClassList &baseClases = getBaseClasses(metaClass);
if (!baseClases.isEmpty()) {
for (const AbstractMetaClass *baseClass : baseClases) {
- result.append(QString::fromLatin1("((size_t) static_cast<const %1*>(class_ptr)) - base")
- .arg(baseClass->qualifiedCppName()));
- result.append(QString::fromLatin1("((size_t) static_cast<const %1*>((%2*)((void*)class_ptr))) - base")
- .arg(baseClass->qualifiedCppName(), metaClass->qualifiedCppName()));
+ QString offset;
+ QTextStream(&offset) << "reinterpret_cast<uintptr_t>(static_cast<const "
+ << baseClass->qualifiedCppName() << "*>(class_ptr)) - base";
+ result.append(offset);
+ offset.clear();
+ QTextStream(&offset) << "reinterpret_cast<uintptr_t>(static_cast<const "
+ << baseClass->qualifiedCppName() << "*>(static_cast<const "
+ << metaClass->qualifiedCppName()
+ << "*>(static_cast<const void*>(class_ptr)))) - base";
+ result.append(offset);
}
+
for (const AbstractMetaClass *baseClass : baseClases)
result.append(getAncestorMultipleInheritance(baseClass));
}
@@ -3579,25 +3586,17 @@ void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, c
{
Indentation indent(INDENT);
s << INDENT << "std::set<int> offsets;" << endl;
- s << INDENT << "std::set<int>::iterator it;" << endl;
- s << INDENT << "const " << className << "* class_ptr = reinterpret_cast<const " << className << "*>(cptr);" << endl;
- s << INDENT << "size_t base = (size_t) class_ptr;" << endl;
+ s << INDENT << "const auto* class_ptr = reinterpret_cast<const " << className << "*>(cptr);" << endl;
+ s << INDENT << "const auto base = reinterpret_cast<uintptr_t>(class_ptr);" << endl;
for (const QString &ancestor : ancestors)
- s << INDENT << "offsets.insert(" << ancestor << ");" << endl;
+ s << INDENT << "offsets.insert(int(" << ancestor << "));" << endl;
s << endl;
s << INDENT << "offsets.erase(0);" << endl;
s << endl;
- s << INDENT << "int i = 0;" << endl;
- s << INDENT << "for (it = offsets.begin(); it != offsets.end(); it++) {" << endl;
- {
- Indentation indent(INDENT);
- s << INDENT << "mi_offsets[i] = *it;" << endl;
- s << INDENT << "i++;" << endl;
- }
- s << INDENT << '}' << endl;
+ s << INDENT << "std::copy(offsets.cbegin(), offsets.cend(), mi_offsets);\n";
}
s << INDENT << '}' << endl;
s << INDENT << "return mi_offsets;" << endl;
@@ -3748,8 +3747,6 @@ void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const Ty
QString CppGenerator::multipleInheritanceInitializerFunctionName(const AbstractMetaClass* metaClass)
{
- if (!hasMultipleInheritanceInAncestry(metaClass))
- return QString();
return cpythonBaseName(metaClass->typeEntry()) + QLatin1String("_mi_init");
}
@@ -5050,7 +5047,7 @@ void CppGenerator::writeClassRegister(QTextStream &s,
if (miClass == metaClass) {
s << multipleInheritanceInitializerFunctionName(miClass) << ";" << endl;
} else {
- s << "Shiboken::ObjectType::getMultipleIheritanceFunction(reinterpret_cast<SbkObjectType*>(";
+ s << "Shiboken::ObjectType::getMultipleInheritanceFunction(reinterpret_cast<SbkObjectType*>(";
s << cpythonTypeNameExt(miClass->typeEntry()) << "));" << endl;
}
s << INDENT << "Shiboken::ObjectType::setMultipleInheritanceFunction(";
@@ -5404,8 +5401,8 @@ bool CppGenerator::finishGeneration()
Indentation indent(INDENT);
- const FunctionGroupMap &functionGroups = getFunctionGroups();
- for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
+ const auto functionGroups = getGlobalFunctionGroups();
+ for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
for (AbstractMetaFunction *func : it.value()) {
if (!func->isModifiedRemoved()) {
@@ -5824,7 +5821,10 @@ bool CppGenerator::writeParentChildManagement(QTextStream& s, const AbstractMeta
const int numArgs = func->arguments().count();
bool ctorHeuristicEnabled = func->isConstructor() && useCtorHeuristic() && useHeuristicPolicy;
- bool usePyArgs = pythonFunctionWrapperUsesListOfArguments(OverloadData(getFunctionGroups(func->implementingClass())[func->name()], this));
+ const auto &groups = func->implementingClass()
+ ? getFunctionGroups(func->implementingClass())
+ : getGlobalFunctionGroups();
+ bool usePyArgs = pythonFunctionWrapperUsesListOfArguments(OverloadData(groups[func->name()], this));
ArgumentOwner argOwner = getArgumentOwner(func, argIndex);
ArgumentOwner::Action action = argOwner.action;
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h
index d2e04dba2..519e12b7b 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.h
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h
@@ -38,6 +38,9 @@ class CppGenerator : public ShibokenGenerator
{
public:
CppGenerator();
+
+ const char *name() const override { return "Source generator"; }
+
protected:
QString fileNameSuffix() const override;
QString fileNameForContext(GeneratorContext &context) const override;
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.h b/sources/shiboken2/generator/shiboken2/headergenerator.h
index 821531aab..f59e0fd9a 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.h
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.h
@@ -42,6 +42,9 @@ class HeaderGenerator : public ShibokenGenerator
{
public:
OptionDescriptions options() const override { return OptionDescriptions(); }
+
+ const char *name() const override { return "Header generator"; }
+
protected:
QString fileNameSuffix() const override;
QString fileNameForContext(GeneratorContext &context) const override;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 002ab8cfb..44405c700 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -118,6 +118,16 @@ static QString resolveScopePrefix(const AbstractMetaEnum *metaEnum,
return resolveScopePrefix(parts, value);
}
+struct GeneratorClassInfoCacheEntry
+{
+ ShibokenGenerator::FunctionGroups functionGroups;
+ bool needsGetattroFunction = false;
+};
+
+using GeneratorClassInfoCache = QHash<const AbstractMetaClass *, GeneratorClassInfoCacheEntry>;
+
+Q_GLOBAL_STATIC(GeneratorClassInfoCache, generatorClassInfoCache)
+
ShibokenGenerator::ShibokenGenerator()
{
if (m_pythonPrimitiveTypeName.isEmpty())
@@ -1739,7 +1749,10 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
argsRemoved++;
}
- OverloadData od(getFunctionGroups(func->implementingClass())[func->name()], this);
+ const auto &groups = func->implementingClass()
+ ? getFunctionGroups(func->implementingClass())
+ : getGlobalFunctionGroups();
+ OverloadData od(groups[func->name()], this);
bool usePyArgs = pythonFunctionWrapperUsesListOfArguments(od);
// Replace %PYARG_# variables.
@@ -2165,26 +2178,19 @@ bool ShibokenGenerator::injectedCodeUsesArgument(const AbstractMetaFunction* fun
return false;
}
-bool ShibokenGenerator::hasMultipleInheritanceInAncestry(const AbstractMetaClass* metaClass)
+bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* metaClass)
{
- if (!metaClass || metaClass->baseClassNames().isEmpty())
- return false;
- if (metaClass->baseClassNames().size() > 1)
- return true;
- return hasMultipleInheritanceInAncestry(metaClass->baseClass());
+ return getGeneratorClassInfo(metaClass).needsGetattroFunction;
}
-typedef QMap<QString, AbstractMetaFunctionList> FunctionGroupMap;
-typedef FunctionGroupMap::const_iterator FunctionGroupMapIt;
-
-bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* metaClass)
+bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass* metaClass)
{
if (!metaClass)
return false;
if (metaClass->typeEntry()->isSmartPointer())
return true;
- const FunctionGroupMap &functionGroup = getFunctionGroups(metaClass);
- for (FunctionGroupMapIt it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) {
+ const auto &functionGroup = getFunctionGroups(metaClass);
+ for (auto it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
for (AbstractMetaFunction *func : qAsConst(it.value())) {
if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved()
@@ -2212,8 +2218,8 @@ AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStatic
{
AbstractMetaFunctionList methods;
if (metaClass) {
- const FunctionGroupMap &functionGroups = getFunctionGroups(metaClass);
- for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
+ const auto &functionGroups = getFunctionGroups(metaClass);
+ for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
AbstractMetaFunctionList overloads;
for (AbstractMetaFunction *func : qAsConst(it.value())) {
if (func->isAssignmentOperator() || func->isCastOperator() || func->isModifiedRemoved()
@@ -2254,7 +2260,7 @@ AbstractMetaClassList ShibokenGenerator::getBaseClasses(const AbstractMetaClass*
const AbstractMetaClass* ShibokenGenerator::getMultipleInheritingClass(const AbstractMetaClass* metaClass)
{
if (!metaClass || metaClass->baseClassNames().isEmpty())
- return 0;
+ return nullptr;
if (metaClass->baseClassNames().size() > 1)
return metaClass;
return getMultipleInheritingClass(metaClass->baseClass());
@@ -2358,23 +2364,56 @@ static bool isGroupable(const AbstractMetaFunction* func)
return true;
}
-QMap< QString, AbstractMetaFunctionList > ShibokenGenerator::getFunctionGroups(const AbstractMetaClass* scope)
+ShibokenGenerator::FunctionGroups ShibokenGenerator::getGlobalFunctionGroups() const
{
- AbstractMetaFunctionList lst = scope ? scope->functions() : globalFunctions();
+ const AbstractMetaFunctionList &lst = globalFunctions();
+ FunctionGroups results;
+ for (AbstractMetaFunction *func : lst) {
+ if (isGroupable(func))
+ results[func->name()].append(func);
+ }
+ return results;
+}
- QMap<QString, AbstractMetaFunctionList> results;
- for (AbstractMetaFunction *func : qAsConst(lst)) {
+const GeneratorClassInfoCacheEntry &ShibokenGenerator::getGeneratorClassInfo(const AbstractMetaClass *scope)
+{
+ auto cache = generatorClassInfoCache();
+ auto it = cache->find(scope);
+ if (it == cache->end()) {
+ it = cache->insert(scope, {});
+ it.value().functionGroups = getFunctionGroupsImpl(scope);
+ it.value().needsGetattroFunction = classNeedsGetattroFunctionImpl(scope);
+ }
+ return it.value();
+}
+
+ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroups(const AbstractMetaClass *scope)
+{
+ Q_ASSERT(scope);
+ return getGeneratorClassInfo(scope).functionGroups;
+}
+
+ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroupsImpl(const AbstractMetaClass *scope)
+{
+ const AbstractMetaFunctionList &lst = scope->functions();
+
+ FunctionGroups results;
+ for (AbstractMetaFunction *func : lst) {
if (isGroupable(func)) {
- AbstractMetaFunctionList &list = results[func->name()];
- // If there are virtuals methods in the mix (PYSIDE-570,
- // QFileSystemModel::index(QString,int) and
- // QFileSystemModel::index(int,int,QModelIndex)) override, make sure
- // the overriding method of the most-derived class is seen first
- // and inserted into the "seenSignatures" set.
- if (func->isVirtual())
- list.prepend(func);
- else
- list.append(func);
+ auto it = results.find(func->name());
+ if (it == results.end()) {
+ results.insert(func->name(), AbstractMetaFunctionList(1, func));
+ } else {
+ // If there are virtuals methods in the mix (PYSIDE-570,
+ // QFileSystemModel::index(QString,int) and
+ // QFileSystemModel::index(int,int,QModelIndex)) override, make sure
+ // the overriding method of the most-derived class is seen first
+ // and inserted into the "seenSignatures" set.
+ if (func->isVirtual())
+ it.value().prepend(func);
+ else
+ it.value().append(func);
+ }
}
}
return results;
@@ -2503,8 +2542,8 @@ bool ShibokenGenerator::doSetup()
Q_ASSERT(moduleEntry);
getCode(snips, moduleEntry);
- const FunctionGroupMap &functionGroups = getFunctionGroups();
- for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
+ const auto &functionGroups = getGlobalFunctionGroups();
+ for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
for (AbstractMetaFunction *func : it.value())
getCode(snips, func->injectedCodeSnips());
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index 80b172778..f5f291526 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -54,6 +54,7 @@ extern const char *END_ALLOW_THREADS;
class DocParser;
class CodeSnip;
class OverloadData;
+struct GeneratorClassInfoCacheEntry;
QT_FORWARD_DECLARE_CLASS(QTextStream)
@@ -63,6 +64,8 @@ QT_FORWARD_DECLARE_CLASS(QTextStream)
class ShibokenGenerator : public Generator
{
public:
+ using FunctionGroups = QMap<QString, AbstractMetaFunctionList>; // Sorted
+
ShibokenGenerator();
~ShibokenGenerator() override;
@@ -99,7 +102,8 @@ protected:
* Example of return value: { "foo" -> ["foo(int)", "foo(int, long)], "bar" -> "bar(double)"}
* \param scope Where to search for functions, null means all global functions.
*/
- QMap<QString, AbstractMetaFunctionList> getFunctionGroups(const AbstractMetaClass* scope = 0);
+ FunctionGroups getGlobalFunctionGroups() const;
+ static FunctionGroups getFunctionGroups(const AbstractMetaClass *scope);
/**
* Returns all different inherited overloads of func, and includes func as well.
@@ -179,8 +183,8 @@ protected:
Options options = NoOption,
int arg_count = -1) const;
- /// Returns true if there are cases of multiple inheritance in any of its ancestors.
- bool hasMultipleInheritanceInAncestry(const AbstractMetaClass* metaClass);
+ /// Returns the top-most class that has multiple inheritance in the ancestry.
+ static const AbstractMetaClass *getMultipleInheritingClass(const AbstractMetaClass* metaClass);
/// Returns true if the class needs to have a getattro function.
bool classNeedsGetattroFunction(const AbstractMetaClass* metaClass);
@@ -194,8 +198,6 @@ protected:
/// Returns a list of parent classes for a given class.
AbstractMetaClassList getBaseClasses(const AbstractMetaClass* metaClass) const;
- const AbstractMetaClass* getMultipleInheritingClass(const AbstractMetaClass* metaClass);
-
void writeToPythonConversion(QTextStream& s, const AbstractMetaType* type,
const AbstractMetaClass* context, const QString& argumentName);
void writeToCppConversion(QTextStream& s, const AbstractMetaType* type, const AbstractMetaClass* context, const QString& inArgName, const QString& outArgName);
@@ -440,6 +442,10 @@ protected:
static QStringList m_knownPythonTypes;
private:
+ static const GeneratorClassInfoCacheEntry &getGeneratorClassInfo(const AbstractMetaClass *scope);
+ static FunctionGroups getFunctionGroupsImpl(const AbstractMetaClass *scope);
+ static bool classNeedsGetattroFunctionImpl(const AbstractMetaClass *metaClass);
+
QString translateTypeForWrapperMethod(const AbstractMetaType* cType,
const AbstractMetaClass* context,
Options opt = NoOption) const;
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index 3a043d849..6ea793a79 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -711,7 +711,7 @@ void setTypeDiscoveryFunctionV2(SbkObjectType* type, TypeDiscoveryFuncV2 func)
PepType_SOTP(type)->type_discovery = func;
}
-void copyMultimpleheritance(SbkObjectType* type, SbkObjectType* other)
+void copyMultipleInheritance(SbkObjectType *type, SbkObjectType *other)
{
PepType_SOTP(type)->mi_init = PepType_SOTP(other)->mi_init;
PepType_SOTP(type)->mi_offsets = PepType_SOTP(other)->mi_offsets;
@@ -723,7 +723,7 @@ void setMultipleInheritanceFunction(SbkObjectType* type, MultipleInheritanceInit
PepType_SOTP(type)->mi_init = function;
}
-MultipleInheritanceInitFunction getMultipleIheritanceFunction(SbkObjectType* type)
+MultipleInheritanceInitFunction getMultipleInheritanceFunction(SbkObjectType *type)
{
return PepType_SOTP(type)->mi_init;
}
diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h
index d12b7222b..55445b026 100644
--- a/sources/shiboken2/libshiboken/basewrapper.h
+++ b/sources/shiboken2/libshiboken/basewrapper.h
@@ -184,9 +184,9 @@ LIBSHIBOKEN_API void setOriginalName(SbkObjectType* self, const char* nam
LIBSHIBOKEN_API const char* getOriginalName(SbkObjectType* self);
LIBSHIBOKEN_API void setTypeDiscoveryFunctionV2(SbkObjectType* self, TypeDiscoveryFuncV2 func);
-LIBSHIBOKEN_API void copyMultimpleheritance(SbkObjectType* self, SbkObjectType* other);
+LIBSHIBOKEN_API void copyMultipleInheritance(SbkObjectType *self, SbkObjectType *other);
LIBSHIBOKEN_API void setMultipleInheritanceFunction(SbkObjectType* self, MultipleInheritanceInitFunction func);
-LIBSHIBOKEN_API MultipleInheritanceInitFunction getMultipleIheritanceFunction(SbkObjectType* self);
+LIBSHIBOKEN_API MultipleInheritanceInitFunction getMultipleInheritanceFunction(SbkObjectType *self);
LIBSHIBOKEN_API void setDestructorFunction(SbkObjectType* self, ObjectDestructor func);
diff --git a/sources/shiboken2/libshiboken/embed/embedding_generator.py b/sources/shiboken2/libshiboken/embed/embedding_generator.py
index b6bfb1467..77aa5c329 100644
--- a/sources/shiboken2/libshiboken/embed/embedding_generator.py
+++ b/sources/shiboken2/libshiboken/embed/embedding_generator.py
@@ -92,7 +92,7 @@ def create_zipfile(limited_api):
flag = '-b' if sys.version_info >= (3,) else ''
os.chdir(work_dir)
- # Limited API: Remove all left-over py[co] files first, in case we use '--reuse-build'.
+ # Remove all left-over py[co] and other files first, in case we use '--reuse-build'.
# Note that we could improve that with the PyZipfile function to use .pyc files
# in different folders, but that makes only sense when COIN allows us to have
# multiple Python versions in parallel.
@@ -100,9 +100,9 @@ def create_zipfile(limited_api):
for root, dirs, files in os.walk(work_dir):
for name in files:
fpath = os.path.join(root, name)
- if name.endswith(".pyc") or name.endswith(".pyo"):
+ ew = name.endswith
+ if ew(".pyc") or ew(".pyo") or ew(".zip") or ew(".inc"):
os.remove(fpath)
-
# We copy every Python file into this dir, but only for the right version.
# For testing in the source dir, we need to filter.
if sys.version_info[0] == 3:
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index ffbc570a8..93f718988 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -201,7 +201,12 @@ LIBSHIBOKEN_API int Pep_GetVerboseFlag(void);
LIBSHIBOKEN_API char *_PepUnicode_AsString(PyObject *);
+#if PY_VERSION_HEX < 0x03000000
#define PyUnicode_GET_SIZE(op) PyUnicode_GetSize((PyObject *)(op))
+#else
+// PyUnicode_GetSize is deprecated in favor of PyUnicode_GetLength
+#define PyUnicode_GET_SIZE(op) PyUnicode_GetLength((PyObject *)(op))
+#endif
#else
#define _PepUnicode_AsString PyUnicode_AsUTF8
diff --git a/sources/shiboken2/libshiboken/pep384impl_doc.rst b/sources/shiboken2/libshiboken/pep384impl_doc.rst
index ab286dd3e..2f3b7ea97 100644
--- a/sources/shiboken2/libshiboken/pep384impl_doc.rst
+++ b/sources/shiboken2/libshiboken/pep384impl_doc.rst
@@ -70,7 +70,8 @@ supported. We redefined it as macro ``Py_VerboseFlag`` which calls ``Pep_Verbose
unicodeobject.h
---------------
-The macro ``PyUnicode_GET_SIZE`` was redefined to call into ``PyUnicode_GetSize``.
+The macro ``PyUnicode_GET_SIZE`` was redefined to call into ``PyUnicode_GetSize``
+for Python 2, and ``PyUnicode_GetLength`` for Python 3.
Function ``_PyUnicode_AsString`` is unavailable and was replaced by a macro
that calls ``_PepUnicode_AsString``. The implementation was a bit involved,
and it would be better to change the code and replace this function.