diff options
-rw-r--r-- | cppgenerator.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp index 543034ed6..49fb4f2ed 100644 --- a/cppgenerator.cpp +++ b/cppgenerator.cpp @@ -184,6 +184,18 @@ void CppGenerator::generateClass(QTextStream &s, const AbstractMetaClass *metaCl s << "using namespace Shiboken;" << endl << endl; + // If the class has any method with "reference-count" modifications + // the support system will need C++ STL's pair and map. + if (hasMethodsWithReferenceCountModifications(metaClass)) { + s << "#include <map>" << endl; + s << "#include <utility>" << endl; + s << "using std::make_pair;" << endl; + s << "typedef std::pair<PyObject*, const char*> SbkRefCountKey;" << endl; + s << "typedef std::map<SbkRefCountKey, PyObject*> SbkRefCountMap;" << endl; + s << "static SbkRefCountMap sbk_refcount_map;" << endl; + s << endl; + } + // class inject-code native/beginning if (!metaClass->typeEntry()->codeSnips().isEmpty()) { writeCodeSnips(s, metaClass->typeEntry()->codeSnips(), CodeSnip::Beginning, TypeSystem::NativeCode, 0, 0, metaClass); @@ -1496,10 +1508,14 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f // Ownership transference between C++ and Python. QList<ArgumentModification> ownership_mods; + // Python object reference management. + QList<ArgumentModification> refcount_mods; foreach (FunctionModification func_mod, func->modifications()) { foreach (ArgumentModification arg_mod, func_mod.argument_mods) { if (!arg_mod.ownerships.isEmpty() && arg_mod.ownerships.contains(TypeSystem::TargetLangCode)) ownership_mods.append(arg_mod); + else if (!arg_mod.referenceCounts.isEmpty()) + refcount_mods.append(arg_mod); } } @@ -1527,6 +1543,28 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f } s << endl; } + + } else if (!refcount_mods.isEmpty()) { + foreach (ArgumentModification arg_mod, refcount_mods) { + if (arg_mod.referenceCounts.first().action != ReferenceCount::Add) + continue; + const AbstractMetaClass* wrappedClass = 0; + QString pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass); + if (!wrappedClass) { + s << "#error Invalid reference count modification for argument " << arg_mod.index << endl << endl; + break; + } + + s << INDENT << "SbkRefCountKey sbk_refcount_key = make_pair(self, \"" << func->minimalSignature() << "\");" << endl; + s << INDENT << "SbkRefCountMap::iterator sbk_refcount_iter = sbk_refcount_map.find(sbk_refcount_key);" << endl; + s << INDENT << "if (sbk_refcount_iter != sbk_refcount_map.end())" << endl; + { + Indentation indent(INDENT); + s << INDENT << "Py_XDECREF(sbk_refcount_iter->second);" << endl; + } + s << INDENT << "Py_INCREF(" << pyArgName << ");" << endl; + s << INDENT << "sbk_refcount_map[sbk_refcount_key] = " << pyArgName << ';' << endl; + } } } |