aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp13
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp96
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h10
3 files changed, 89 insertions, 30 deletions
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 29220c739..67f8f1a7b 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -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;
@@ -5404,8 +5404,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 +5824,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/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 002ab8cfb..12efb68c3 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.
@@ -2174,17 +2187,19 @@ bool ShibokenGenerator::hasMultipleInheritanceInAncestry(const AbstractMetaClass
return hasMultipleInheritanceInAncestry(metaClass->baseClass());
}
-typedef QMap<QString, AbstractMetaFunctionList> FunctionGroupMap;
-typedef FunctionGroupMap::const_iterator FunctionGroupMapIt;
-
bool ShibokenGenerator::classNeedsGetattroFunction(const AbstractMetaClass* metaClass)
{
+ return getGeneratorClassInfo(metaClass).needsGetattroFunction;
+}
+
+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 +2227,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()
@@ -2358,23 +2373,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 +2551,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..ebfc059de 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.
@@ -440,6 +444,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;