diff options
Diffstat (limited to 'sources/shiboken2/generator/shiboken2/cppgenerator.cpp')
-rw-r--r-- | sources/shiboken2/generator/shiboken2/cppgenerator.cpp | 528 |
1 files changed, 313 insertions, 215 deletions
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index ce74c9887..be42adb0f 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -36,6 +36,7 @@ #include <QtCore/QDir> #include <QtCore/QMetaObject> +#include <QtCore/QRegularExpression> #include <QtCore/QTextStream> #include <QtCore/QDebug> #include <QMetaType> @@ -153,13 +154,15 @@ QString CppGenerator::fileNameForContext(GeneratorContext &context) const } } -QList<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass, +QVector<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(const AbstractMetaClass* metaClass, uint queryIn) { // ( func_name, num_args ) => func_list - QMap<QPair<QString, int >, AbstractMetaFunctionList> results; + typedef QMap<QPair<QString, int >, AbstractMetaFunctionList> ResultMap; + ResultMap results; const AbstractMetaClass::OperatorQueryOptions query(queryIn); - foreach (AbstractMetaFunction* func, metaClass->operatorOverloads(query)) { + const AbstractMetaFunctionList &funcs = metaClass->operatorOverloads(query); + for (AbstractMetaFunction *func : funcs) { if (func->isModifiedRemoved() || func->usesRValueReferences() || func->name() == QLatin1String("operator[]") @@ -176,7 +179,11 @@ QList<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(con QPair<QString, int > op(func->name(), args); results[op].append(func); } - return results.values(); + QVector<AbstractMetaFunctionList> result; + result.reserve(results.size()); + for (ResultMap::const_iterator it = results.cbegin(), end = results.cend(); it != end; ++it) + result.append(it.value()); + return result; } bool CppGenerator::hasBoolCast(const AbstractMetaClass* metaClass) const @@ -203,6 +210,13 @@ static const char includeQDebug[] = "#endif\n" "#include <QDebug>\n"; +static QString chopType(QString s) +{ + if (s.endsWith(QLatin1String("_Type"))) + s.chop(5); + return s; +} + /*! Function used to write the class generated binding code on the buffer \param s the output buffer @@ -252,7 +266,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) s << endl << "// main header" << endl << "#include \"" << headerfile << '"' << endl; s << endl << "// inner classes" << endl; - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) { + const AbstractMetaClassList &innerClasses = metaClass->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) { GeneratorContext innerClassContext(innerClass); if (shouldGenerate(innerClass)) { QString headerfile = fileNameForContext(innerClassContext); @@ -262,16 +277,16 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } AbstractMetaEnumList classEnums = metaClass->enums(); - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) + for (AbstractMetaClass *innerClass : innerClasses) lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass); //Extra includes s << endl << "// Extra includes" << endl; - QList<Include> includes = metaClass->typeEntry()->extraIncludes(); - foreach (AbstractMetaEnum* cppEnum, classEnums) + QVector<Include> includes = metaClass->typeEntry()->extraIncludes(); + for (AbstractMetaEnum *cppEnum : qAsConst(classEnums)) includes.append(cppEnum->typeEntry()->extraIncludes()); qSort(includes.begin(), includes.end()); - foreach (const Include &inc, includes) + for (const Include &inc : qAsConst(includes)) s << inc.toString() << endl; s << endl; @@ -324,15 +339,19 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) s << "}\n\n"; } - foreach (const AbstractMetaFunction* func, filterFunctions(metaClass)) { - if ((func->isPrivate() && !visibilityModifiedToPrivate(func)) - || (func->isModifiedRemoved() && !func->isAbstract())) + const AbstractMetaFunctionList &funcs = filterFunctions(metaClass); + for (const AbstractMetaFunction *func : funcs) { + const bool notAbstract = !func->isAbstract(); + if ((func->isPrivate() && notAbstract && !visibilityModifiedToPrivate(func)) + || (func->isModifiedRemoved() && notAbstract)) continue; - if (func->functionType() == AbstractMetaFunction::ConstructorFunction && !func->isUserAdded()) + if (func->functionType() == AbstractMetaFunction::ConstructorFunction && !func->isUserAdded()) { writeConstructorNative(s, func); - else if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) - && (func->isVirtual() || func->isAbstract())) + } else if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) + && ((func->isVirtual() || func->isAbstract()) + && (func->attributes() & AbstractMetaAttributes::FinalCppMethod) == 0)) { writeVirtualMethodNative(s, func); + } } if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) { @@ -357,7 +376,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; QSet<QString> seenSignatures; - foreach (AbstractMetaFunction* func, it.value()) { + for (AbstractMetaFunction *func : it.value()) { if (!func->isAssignmentOperator() && !func->usesRValueReferences() && !func->isCastOperator() @@ -375,7 +394,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) if (overloads.isEmpty()) continue; - const AbstractMetaFunction* rfunc = overloads.first(); + const AbstractMetaFunction* rfunc = overloads.constFirst(); if (m_sequenceProtocol.contains(rfunc->name()) || m_mappingProtocol.contains(rfunc->name())) continue; @@ -411,7 +430,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) AbstractMetaType *pointerToInnerType = buildAbstractMetaTypeFromString(pointerToInnerTypeName); - AbstractMetaFunction *mutableRfunc = overloads.first(); + AbstractMetaFunction *mutableRfunc = overloads.constFirst(); mutableRfunc->replaceType(pointerToInnerType); } else if (smartPointerTypeEntry->refCountMethodName().isEmpty() || smartPointerTypeEntry->refCountMethodName() != rfunc->name()) { @@ -434,8 +453,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } } - QString className = cpythonTypeName(metaClass); - className.remove(QRegExp(QLatin1String("_Type$"))); + const QString className = chopType(cpythonTypeName(metaClass)); if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) { writeCopyFunction(s, classContext); @@ -484,15 +502,15 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } if (supportsNumberProtocol(metaClass) && !metaClass->typeEntry()->isSmartPointer()) { - QList<AbstractMetaFunctionList> opOverloads = filterGroupedOperatorFunctions( + const QVector<AbstractMetaFunctionList> opOverloads = filterGroupedOperatorFunctions( metaClass, AbstractMetaClass::ArithmeticOp | AbstractMetaClass::LogicalOp | AbstractMetaClass::BitwiseOp); - foreach (const AbstractMetaFunctionList &allOverloads, opOverloads) { + for (const AbstractMetaFunctionList &allOverloads : opOverloads) { AbstractMetaFunctionList overloads; - foreach (AbstractMetaFunction* func, allOverloads) { + for (AbstractMetaFunction *func : allOverloads) { if (!func->isModifiedRemoved() && !func->isPrivate() && (func->ownerClass() == func->implementingClass() || func->isAbstract())) @@ -521,7 +539,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) } if (shouldGenerateGetSetList(metaClass) && !classContext.forSmartPointer()) { - foreach (const AbstractMetaField* metaField, metaClass->fields()) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (const AbstractMetaField *metaField : fields) { if (metaField->isStatic()) continue; writeGetterFunction(s, metaField, classContext); @@ -532,7 +551,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) s << "// Getters and Setters for " << metaClass->name() << endl; s << "static PyGetSetDef " << cpythonGettersSettersDefinitionName(metaClass) << "[] = {" << endl; - foreach (const AbstractMetaField* metaField, metaClass->fields()) { + for (const AbstractMetaField *metaField : fields) { if (metaField->isStatic()) continue; @@ -562,7 +581,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext) writeTypeDiscoveryFunction(s, metaClass); - foreach (AbstractMetaEnum* cppEnum, classEnums) { + for (AbstractMetaEnum *cppEnum : qAsConst(classEnums)) { if (cppEnum->isAnonymous() || cppEnum->isPrivate()) continue; @@ -593,7 +612,7 @@ void CppGenerator::writeConstructorNative(QTextStream& s, const AbstractMetaFunc s << " : "; writeFunctionCall(s, func); s << " {" << endl; - const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last(); + const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast(); writeCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, func, lastArg); s << INDENT << "// ... middle" << endl; writeCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, func, lastArg); @@ -614,7 +633,8 @@ static bool allArgumentsRemoved(const AbstractMetaFunction* func) { if (func->arguments().isEmpty()) return false; - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (!func->argumentRemoved(arg->argumentIndex() + 1)) return false; } @@ -666,19 +686,24 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun QString defaultReturnExpr; if (retType) { - foreach (const FunctionModification &mod, func->modifications()) { - foreach (const ArgumentModification &argMod, mod.argument_mods) { + const FunctionModificationList &mods = func->modifications(); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argMod : mod.argument_mods) { if (argMod.index == 0 && !argMod.replacedDefaultExpression.isEmpty()) { - QRegExp regex(QLatin1String("%(\\d+)")); + static const QRegularExpression regex(QStringLiteral("%(\\d+)")); + Q_ASSERT(regex.isValid()); defaultReturnExpr = argMod.replacedDefaultExpression; - int offset = 0; - while ((offset = regex.indexIn(defaultReturnExpr, offset)) != -1) { - int argId = regex.cap(1).toInt() - 1; + for (int offset = 0; ; ) { + const QRegularExpressionMatch match = regex.match(defaultReturnExpr, offset); + if (!match.hasMatch()) + break; + const int argId = match.capturedRef(1).toInt() - 1; if (argId < 0 || argId > func->arguments().count()) { qCWarning(lcShiboken) << "The expression used in return value contains an invalid index."; break; } - defaultReturnExpr.replace(regex.cap(0), func->arguments()[argId]->name()); + defaultReturnExpr.replace(match.captured(0), func->arguments().at(argId)->name()); + offset = match.capturedStart(1); } } } @@ -709,7 +734,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun //Write declaration/native injected code if (func->hasInjectedCode()) { CodeSnipList snips = func->injectedCodeSnips(); - const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last(); + const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast(); writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode, func, lastArg); s << endl; } @@ -732,7 +757,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun CodeSnipList snips; if (func->hasInjectedCode()) { snips = func->injectedCodeSnips(); - const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last(); + const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast(); writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::ShellCode, func, lastArg); s << endl; } @@ -764,7 +789,8 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun s << "PyTuple_New(0));" << endl; } else { QStringList argConversions; - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (func->argumentRemoved(arg->argumentIndex() + 1)) continue; @@ -810,8 +836,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun bool invalidateReturn = false; QSet<int> invalidateArgs; - foreach (const FunctionModification &funcMod, func->modifications()) { - foreach (const ArgumentModification &argMod, funcMod.argument_mods) { + const FunctionModificationList &mods = func->modifications(); + for (const FunctionModification &funcMod : mods) { + for (const ArgumentModification &argMod : funcMod.argument_mods) { if (argMod.resetAfterUse && !invalidateArgs.contains(argMod.index)) { invalidateArgs.insert(argMod.index); s << INDENT << "bool invalidateArg" << argMod.index; @@ -830,7 +857,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun if (injectedCodeUsesPySelf(func)) s << INDENT << "PyObject* pySelf = BindingManager::instance().retrieveWrapper(this);" << endl; - const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last(); + const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast(); writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode, func, lastArg); s << endl; } @@ -908,7 +935,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun Indentation indentation(INDENT); s << INDENT << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR ".object());" << endl; } - foreach (int argIndex, invalidateArgs) { + for (int argIndex : qAsConst(invalidateArgs)) { s << INDENT << "if (invalidateArg" << argIndex << ')' << endl; Indentation indentation(INDENT); s << INDENT << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" PYTHON_ARGS ", "; @@ -916,8 +943,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun } - foreach (const FunctionModification &funcMod, func->modifications()) { - foreach (const ArgumentModification &argMod, funcMod.argument_mods) { + const FunctionModificationList &funcMods = func->modifications(); + for (const FunctionModification &funcMod : funcMods) { + for (const ArgumentModification &argMod : funcMod.argument_mods) { if (argMod.ownerships.contains(TypeSystem::NativeCode) && argMod.index == 0 && argMod.ownerships[TypeSystem::NativeCode] == TypeSystem::CppOwnership) { s << INDENT << "if (Shiboken::Object::checkType(" PYTHON_RETURN_VAR "))" << endl; @@ -929,7 +957,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun if (func->hasInjectedCode()) { s << endl; - const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last(); + const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast(); writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, func, lastArg); } @@ -1019,7 +1047,6 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry* { if (!enumType) return; - QString enumFlagName = enumType->isFlags() ? QLatin1String("flag") : QLatin1String("enum"); QString typeName = fixedCppTypeName(enumType); QString enumPythonType = cpythonTypeNameExt(enumType); QString cppTypeName = getFullTypeName(enumType).trimmed(); @@ -1043,7 +1070,8 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry* code.clear(); - c << INDENT << "int castCppIn = *((" << cppTypeName << "*)cppIn);" << endl; + c << INDENT << "const int castCppIn = int(*reinterpret_cast<const " + << cppTypeName << " *>(cppIn));" << endl; c << INDENT; c << "return "; if (enumType->isFlags()) @@ -1090,11 +1118,12 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla s << "// Type conversion functions." << endl << endl; AbstractMetaEnumList classEnums = metaClass->enums(); - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) + const AbstractMetaClassList &innerClasses = metaClass->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass); if (!classEnums.isEmpty()) s << "// Python to C++ enum conversion." << endl; - foreach (const AbstractMetaEnum* metaEnum, classEnums) + for (const AbstractMetaEnum *metaEnum : qAsConst(classEnums)) writeEnumConverterFunctions(s, metaEnum); if (metaClass->isNamespace()) @@ -1204,7 +1233,8 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla // Implicit conversions. AbstractMetaFunctionList implicitConvs; if (!customConversion || !customConversion->replaceOriginalTargetToNativeConversions()) { - foreach (AbstractMetaFunction* func, implicitConversions(metaClass->typeEntry())) { + const AbstractMetaFunctionList &allImplicitConvs = implicitConversions(metaClass->typeEntry()); + for (AbstractMetaFunction *func : allImplicitConvs) { if (!func->isUserAdded()) implicitConvs << func; } @@ -1214,7 +1244,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla s << "// Implicit conversions." << endl; AbstractMetaType* targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); - foreach (const AbstractMetaFunction* conv, implicitConvs) { + for (const AbstractMetaFunction* conv : qAsConst(implicitConvs)) { if (conv->isModifiedRemoved()) continue; @@ -1229,7 +1259,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla // Constructor that does implicit conversion. if (!conv->typeReplaced(1).isEmpty()) continue; - const AbstractMetaType* sourceType = conv->arguments().first()->type(); + const AbstractMetaType* sourceType = conv->arguments().constFirst()->type(); typeCheck = cpythonCheckFunction(sourceType); bool isUserPrimitiveWithoutTargetLangName = isUserPrimitive(sourceType) && sourceType->typeEntry()->targetLangApiName() == sourceType->typeEntry()->name(); @@ -1273,7 +1303,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla } const AbstractMetaType* sourceType = conv->isConversionOperator() ? buildAbstractMetaTypeFromAbstractMetaClass(conv->ownerClass()) - : conv->arguments().first()->type(); + : conv->arguments().constFirst()->type(); writePythonToCppConversionFunctions(s, sourceType, targetType, typeCheck, toCppConv, toCppPreConv); } @@ -1288,7 +1318,7 @@ void CppGenerator::writeCustomConverterFunctions(QTextStream& s, const CustomCon if (toCppConversions.isEmpty()) return; s << "// Python to C++ conversions for type '" << customConversion->ownerType()->qualifiedCppName() << "'." << endl; - foreach (CustomConversion::TargetToNativeConversion* toNative, toCppConversions) + for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions) writePythonToCppConversionFunctions(s, toNative, customConversion->ownerType()); s << endl; } @@ -1368,7 +1398,8 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas // Add implicit conversions. AbstractMetaFunctionList implicitConvs; if (!customConversion || !customConversion->replaceOriginalTargetToNativeConversions()) { - foreach (AbstractMetaFunction* func, implicitConversions(metaClass->typeEntry())) { + const AbstractMetaFunctionList &allImplicitConvs = implicitConversions(metaClass->typeEntry()); + for (AbstractMetaFunction *func : allImplicitConvs) { if (!func->isUserAdded()) implicitConvs << func; } @@ -1378,7 +1409,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas s << INDENT << "// Add implicit conversions to type converter." << endl; AbstractMetaType* targetType = buildAbstractMetaTypeFromAbstractMetaClass(metaClass); - foreach (const AbstractMetaFunction* conv, implicitConvs) { + for (const AbstractMetaFunction *conv : qAsConst(implicitConvs)) { if (conv->isModifiedRemoved()) continue; const AbstractMetaType* sourceType; @@ -1388,7 +1419,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas // Constructor that does implicit conversion. if (!conv->typeReplaced(1).isEmpty()) continue; - sourceType = conv->arguments().first()->type(); + sourceType = conv->arguments().constFirst()->type(); } QString toCpp = pythonToCppFunctionName(sourceType, targetType); QString isConv = convertibleToCppFunctionName(sourceType, targetType); @@ -1406,7 +1437,7 @@ void CppGenerator::writeCustomConverterRegister(QTextStream& s, const CustomConv if (toCppConversions.isEmpty()) return; s << INDENT << "// Add user defined implicit conversions to type converter." << endl; - foreach (CustomConversion::TargetToNativeConversion* toNative, toCppConversions) { + for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions) { QString toCpp = pythonToCppFunctionName(toNative, customConversion->ownerType()); QString isConv = convertibleToCppFunctionName(toNative, customConversion->ownerType()); writeAddPythonToCppConversion(s, converterVar, toCpp, isConv); @@ -1516,8 +1547,10 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun QSet<QString> argNamesSet; if (usePySideExtensions() && metaClass->isQObject()) { // Write argNames variable with all known argument names. - foreach (const AbstractMetaFunction* func, overloadData.overloads()) { - foreach (const AbstractMetaArgument* arg, func->arguments()) { + const OverloadData::MetaFunctionList &overloads = overloadData.overloads(); + for (const AbstractMetaFunction *func : overloads) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (const AbstractMetaArgument *arg : arguments) { if (arg->defaultValueExpression().isEmpty() || func->argumentRemoved(arg->argumentIndex() + 1)) continue; argNamesSet << arg->name(); @@ -1595,7 +1628,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun // (first "1") and the flag indicating that the Python wrapper holds an C++ wrapper // is marked as true (the second "1"). Otherwise the default values apply: // Python owns it and C++ wrapper is false. - if (shouldGenerateCppWrapper(overloads.first()->ownerClass())) + if (shouldGenerateCppWrapper(overloads.constFirst()->ownerClass())) s << INDENT << "Shiboken::Object::setHasCppWrapper(sbkSelf, true);" << endl; // Need to check if a wrapper for same pointer is already registered // Caused by bug PYSIDE-217, where deleted objects' wrappers are not released @@ -1621,8 +1654,9 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun // Constructor code injections, position=end bool hasCodeInjectionsAtEnd = false; - foreach(AbstractMetaFunction* func, overloads) { - foreach (const CodeSnip &cs, func->injectedCodeSnips()) { + for (AbstractMetaFunction *func : overloads) { + const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips(); + for (const CodeSnip &cs : injectedCodeSnips) { if (cs.position == TypeSystem::CodeSnipPositionEnd) { hasCodeInjectionsAtEnd = true; break; @@ -1632,9 +1666,10 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun if (hasCodeInjectionsAtEnd) { // FIXME: C++ arguments are not available in code injection on constructor when position = end. s << INDENT << "switch(overloadId) {" << endl; - foreach(AbstractMetaFunction* func, overloads) { + for (AbstractMetaFunction *func : overloads) { Indentation indent(INDENT); - foreach (const CodeSnip &cs, func->injectedCodeSnips()) { + const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips(); + for (const CodeSnip &cs : injectedCodeSnips) { if (cs.position == TypeSystem::CodeSnipPositionEnd) { s << INDENT << "case " << metaClass->functions().indexOf(func) << ':' << endl; s << INDENT << '{' << endl; @@ -1812,10 +1847,10 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overl s << INDENT << '}'; } } - QList<int> invalidArgsLength = overloadData.invalidArgumentLengths(); + const QVector<int> invalidArgsLength = overloadData.invalidArgumentLengths(); if (!invalidArgsLength.isEmpty()) { QStringList invArgsLen; - foreach (int i, invalidArgsLength) + for (int i : qAsConst(invalidArgsLength)) invArgsLen << QStringLiteral("numArgs == %1").arg(i); if (usesNamedArguments && (!ownerClassIsQObject || minArgs > 0)) s << " else "; @@ -1943,9 +1978,11 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData) s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", \"" << funcName << "\", 0);" << endl; } else { QStringList overloadSignatures; - foreach (const AbstractMetaFunction* f, overloadData.overloads()) { + const OverloadData::MetaFunctionList &overloads = overloadData.overloads(); + for (const AbstractMetaFunction *f : overloads) { QStringList args; - foreach(AbstractMetaArgument* arg, f->arguments()) { + const AbstractMetaArgumentList &arguments = f->arguments(); + for (AbstractMetaArgument *arg : arguments) { QString strArg; AbstractMetaType* argType = arg->type(); if (isCString(argType)) { @@ -1961,7 +1998,9 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData) strArg = QLatin1String("1-unicode"); } else { strArg = ptp->name(); - strArg.remove(QRegExp(QLatin1String("^signed\\s+"))); + static const QRegularExpression regex(QStringLiteral("^signed\\s+")); + Q_ASSERT(regex.isValid()); + strArg.remove(regex); if (strArg == QLatin1String("double")) strArg = QLatin1String("float"); } @@ -2043,9 +2082,13 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream& s, const QString& pyOb static QString pythonToCppConverterForArgumentName(const QString& argumentName) { - static QRegExp pyArgsRegex(QLatin1String(PYTHON_ARGS"(\\[\\d+[-]?\\d*\\])")); - pyArgsRegex.indexIn(argumentName); - return QLatin1String(PYTHON_TO_CPP_VAR) + pyArgsRegex.cap(1); + static const QRegularExpression pyArgsRegex(QLatin1String(PYTHON_ARGS"(\\[\\d+[-]?\\d*\\])")); + Q_ASSERT(pyArgsRegex.isValid()); + const QRegularExpressionMatch match = pyArgsRegex.match(argumentName); + QString result = QLatin1String(PYTHON_TO_CPP_VAR); + if (match.hasMatch()) + result += match.captured(1); + return result; } void CppGenerator::writeTypeCheck(QTextStream& s, const AbstractMetaType* argType, QString argumentName, bool isNumber, QString customType, bool rejectNull) @@ -2085,20 +2128,26 @@ static void checkTypeViability(const AbstractMetaFunction* func, const AbstractM if (!type || !type->typeEntry()->isPrimitive() || type->indirections() == 0 + || (type->indirections() == 1 && type->typeUsagePattern() == AbstractMetaType::NativePointerAsArrayPattern) || ShibokenGenerator::isCString(type) || func->argumentRemoved(argIdx) || !func->typeReplaced(argIdx).isEmpty() || !func->conversionRule(TypeSystem::All, argIdx).isEmpty() || func->hasInjectedCode()) return; - QString prefix; + QString message; + QTextStream str(&message); + str << "There's no user provided way (conversion rule, argument" + " removal, custom code, etc) to handle the primitive "; + if (argIdx == 0) + str << "return type '" << type->cppSignature() << '\''; + else + str << "type '" << type->cppSignature() << "' of argument " << argIdx; + str << " in function '"; if (func->ownerClass()) - prefix = func->ownerClass()->qualifiedCppName() + QLatin1String("::"); - qCWarning(lcShiboken).noquote().nospace() - << QString::fromLatin1("There's no user provided way (conversion rule, argument removal, custom code, etc) " - "to handle the primitive %1 type '%2' in function '%3%4'.") - .arg(argIdx == 0 ? QStringLiteral("return") : QStringLiteral("argument"), - type->cppSignature(), prefix, func->signature()); + str << func->ownerClass()->qualifiedCppName() << "::"; + str << func->signature() << "'."; + qCWarning(lcShiboken).noquote().nospace() << message; } static void checkTypeViability(const AbstractMetaFunction* func) @@ -2114,9 +2163,10 @@ static void checkTypeViability(const AbstractMetaFunction* func) void CppGenerator::writeTypeCheck(QTextStream& s, const OverloadData* overloadData, QString argumentName) { QSet<const TypeEntry*> numericTypes; - - foreach (OverloadData* od, overloadData->previousOverloadData()->nextOverloadData()) { - foreach (const AbstractMetaFunction* func, od->overloads()) { + const OverloadDataList &overloads = overloadData->previousOverloadData()->nextOverloadData(); + for (OverloadData *od : overloads) { + const OverloadData::MetaFunctionList &odOverloads = od->overloads(); + for (const AbstractMetaFunction *func : odOverloads) { checkTypeViability(func); const AbstractMetaType* argType = od->argument(func)->type(); if (!argType->isPrimitive()) @@ -2174,6 +2224,23 @@ const AbstractMetaType* CppGenerator::getArgumentType(const AbstractMetaFunction return argType; } +static inline QString arrayHandleType(const AbstractMetaTypeCList &nestedArrayTypes) +{ + switch (nestedArrayTypes.size()) { + case 1: + return QStringLiteral("Shiboken::Conversions::ArrayHandle<") + + nestedArrayTypes.constLast()->minimalSignature() + + QLatin1Char('>'); + case 2: + return QStringLiteral("Shiboken::Conversions::Array2Handle<") + + nestedArrayTypes.constLast()->minimalSignature() + + QStringLiteral(", ") + + QString::number(nestedArrayTypes.constFirst()->arrayElementCount()) + + QLatin1Char('>'); + } + return QString(); +} + void CppGenerator::writePythonToCppTypeConversion(QTextStream& s, const AbstractMetaType* type, const QString& pyIn, @@ -2195,7 +2262,13 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream& s, && !isCppPrimitive(type) && isNotContainerEnumOrFlags && !(treatAsPointer || isPointerOrObjectType); - QString typeName = getFullTypeNameWithoutModifiers(type); + + const AbstractMetaTypeCList nestedArrayTypes = type->nestedArrayTypes(); + const bool isCppPrimitiveArray = !nestedArrayTypes.isEmpty() + && nestedArrayTypes.constLast()->isCppPrimitive(); + QString typeName = isCppPrimitiveArray + ? arrayHandleType(nestedArrayTypes) + : getFullTypeNameWithoutModifiers(type); bool isProtectedEnum = false; @@ -2212,7 +2285,9 @@ void CppGenerator::writePythonToCppTypeConversion(QTextStream& s, } s << INDENT << typeName; - if (treatAsPointer || isPointerOrObjectType) { + if (isCppPrimitiveArray) { + s << ' ' << cppOut; + } else if (treatAsPointer || isPointerOrObjectType) { s << "* " << cppOut; if (!defaultValue.isEmpty()) s << " = " << defaultValue; @@ -2280,7 +2355,7 @@ static void addConversionRuleCodeSnippet(CodeSnipList& snippetList, QString& rul } else { rule.replace(QLatin1String("%out"), outputName); } - CodeSnip snip(0, snippetLanguage); + CodeSnip snip(snippetLanguage); snip.position = (snippetLanguage == TypeSystem::NativeCode) ? TypeSystem::CodeSnipPositionAny : TypeSystem::CodeSnipPositionBeginning; snip.addCode(rule); snippetList << snip; @@ -2289,7 +2364,8 @@ static void addConversionRuleCodeSnippet(CodeSnipList& snippetList, QString& rul void CppGenerator::writeConversionRule(QTextStream& s, const AbstractMetaFunction* func, TypeSystem::Language language) { CodeSnipList snippets; - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { QString rule = func->conversionRule(language, arg->argumentIndex() + 1); addConversionRuleCodeSnippet(snippets, rule, language, TypeSystem::TargetLangCode, arg->name(), arg->name()); @@ -2317,7 +2393,7 @@ void CppGenerator::writeOverloadedFunctionDecisor(QTextStream& s, const Overload { s << INDENT << "// Overloaded function decisor" << endl; const AbstractMetaFunction* rfunc = overloadData.referenceFunction(); - QList<const AbstractMetaFunction*> functionOverloads = overloadData.overloadsWithoutRepetition(); + const OverloadData::MetaFunctionList &functionOverloads = overloadData.overloadsWithoutRepetition(); for (int i = 0; i < functionOverloads.count(); i++) s << INDENT << "// " << i << ": " << functionOverloads.at(i)->minimalSignature() << endl; writeOverloadedFunctionDecisorEngine(s, &overloadData); @@ -2351,7 +2427,8 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov // variable to be used further on this method on the conditional that identifies default // method calls. if (!hasDefaultCall) { - foreach (const AbstractMetaFunction* func, parentOverloadData->overloads()) { + const OverloadData::MetaFunctionList &overloads = parentOverloadData->overloads(); + for (const AbstractMetaFunction *func : overloads) { if (parentOverloadData->isFinalOccurrence(func)) { referenceFunction = func; hasDefaultCall = true; @@ -2392,6 +2469,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov // If the next argument has a default value the decisor can perform a method call; // it just need to check if the number of arguments received from Python are equal // to the number of parameters preceding the argument with the default value. + const OverloadDataList &overloads = parentOverloadData->nextOverloadData(); if (hasDefaultCall) { isFirst = false; int numArgs = parentOverloadData->argPos() + 1; @@ -2399,7 +2477,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov { Indentation indent(INDENT); const AbstractMetaFunction* func = referenceFunction; - foreach (OverloadData* overloadData, parentOverloadData->nextOverloadData()) { + for (OverloadData *overloadData : overloads) { const AbstractMetaFunction* defValFunc = overloadData->getFunctionWithDefaultValue(); if (defValFunc) { func = defValFunc; @@ -2412,7 +2490,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov s << INDENT << '}'; } - foreach (OverloadData* overloadData, parentOverloadData->nextOverloadData()) { + for (OverloadData *overloadData : overloads) { bool signatureFound = overloadData->overloads().size() == 1 && !overloadData->getFunctionWithDefaultValue() && !overloadData->findNextArgWithDefault(); @@ -2438,7 +2516,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov if (func->isConstructor() && func->arguments().count() == 1) { const AbstractMetaClass* ownerClass = func->ownerClass(); const ComplexTypeEntry* baseContainerType = ownerClass->typeEntry()->baseContainerType(); - if (baseContainerType && baseContainerType == func->arguments().first()->type()->typeEntry() && isCopyable(ownerClass)) { + if (baseContainerType && baseContainerType == func->arguments().constFirst()->type()->typeEntry() && isCopyable(ownerClass)) { tck << '!' << cpythonCheckFunction(ownerClass->typeEntry()) << pyArgName << ')' << endl; Indentation indent(INDENT); tck << INDENT << "&& "; @@ -2453,17 +2531,17 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov if (od->nextOverloadData().isEmpty() || od->nextArgumentHasDefaultValue() || od->nextOverloadData().size() != 1 - || od->overloads().size() != od->nextOverloadData().first()->overloads().size()) { + || od->overloads().size() != od->nextOverloadData().constFirst()->overloads().size()) { overloadData = od; od = 0; } else { - od = od->nextOverloadData().first(); + od = od->nextOverloadData().constFirst(); } } if (usePyArgs && signatureFound) { AbstractMetaArgumentList args = refFunc->arguments(); - int lastArgIsVarargs = (int) (args.size() > 1 && args.last()->type()->isVarargs()); + int lastArgIsVarargs = (int) (args.size() > 1 && args.constLast()->type()->isVarargs()); int numArgs = args.size() - OverloadData::numberOfRemovedArguments(refFunc) - lastArgIsVarargs; typeChecks.prepend(QString::fromLatin1("numArgs %1 %2").arg(lastArgIsVarargs ? QLatin1String(">=") : QLatin1String("==")).arg(numArgs)); } else if (sequenceArgCount > 1) { @@ -2501,13 +2579,13 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov void CppGenerator::writeFunctionCalls(QTextStream &s, const OverloadData &overloadData, GeneratorContext &context) { - QList<const AbstractMetaFunction*> overloads = overloadData.overloadsWithoutRepetition(); + const OverloadData::MetaFunctionList &overloads = overloadData.overloadsWithoutRepetition(); s << INDENT << "// Call function/method" << endl; s << INDENT << (overloads.count() > 1 ? "switch (overloadId) " : "") << '{' << endl; { Indentation indent(INDENT); if (overloads.count() == 1) { - writeSingleFunctionCall(s, overloadData, overloads.first(), context); + writeSingleFunctionCall(s, overloadData, overloads.constFirst(), context); } else { for (int i = 0; i < overloads.count(); i++) { const AbstractMetaFunction* func = overloads.at(i); @@ -2818,21 +2896,22 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream& s, const Abs QString code; QTextStream c(&code); c << INDENT << QString::fromLatin1("%1& cppOutRef = *((%1*)cppOut);").arg(cppTypeName) << endl; - code.append(toCppConversions.first()->conversion()); + code.append(toCppConversions.constFirst()->conversion()); for (int i = 0; i < containerType->instantiations().count(); ++i) { const AbstractMetaType* type = containerType->instantiations().at(i); QString typeName = getFullTypeName(type); if (type->isValue() && isValueTypeWithCopyConstructorOnly(type)) { - static QRegExp regex(QLatin1String(CONVERTTOCPP_REGEX)); - int pos = 0; - while ((pos = regex.indexIn(code, pos)) != -1) { - pos += regex.matchedLength(); - QStringList list = regex.capturedTexts(); - QString varName = list.at(1); - QString leftCode = code.left(pos); + static const QRegularExpression regex(QLatin1String(CONVERTTOCPP_REGEX)); + Q_ASSERT(regex.isValid()); + for (int pos = 0; ; ) { + const QRegularExpressionMatch match = regex.match(code, pos); + if (!match.hasMatch()) + break; + pos = match.capturedEnd(); + const QString varName = match.captured(1); QString rightCode = code.mid(pos); rightCode.replace(varName, QLatin1Char('*') + varName); - code = leftCode + rightCode; + code.replace(pos, code.size() - pos, rightCode); } typeName.append(QLatin1Char('*')); } @@ -2867,7 +2946,7 @@ void CppGenerator::writeAddPythonToCppConversion(QTextStream& s, const QString& void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMetaFunction* func, bool usePyArgs) { - AbstractMetaArgumentList args = OverloadData::getArgumentsWithDefaultValues(func); + const AbstractMetaArgumentList &args = OverloadData::getArgumentsWithDefaultValues(func); if (args.isEmpty()) return; @@ -2878,7 +2957,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMe { Indentation indent(INDENT); s << INDENT << "PyObject* "; - foreach (const AbstractMetaArgument* arg, args) { + for (const AbstractMetaArgument *arg : args) { int pyArgIndex = arg->argumentIndex() - OverloadData::numberOfRemovedArguments(func, arg->argumentIndex()); QString pyArgName = usePyArgs ? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(pyArgIndex) @@ -2903,7 +2982,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMe } } s << INDENT << '}' << endl; - if (arg != args.last()) + if (arg != args.constLast()) s << INDENT; } } @@ -2953,7 +3032,8 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f { s << INDENT << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << endl; if (func->isConstructor()) { - foreach (const CodeSnip &cs, func->injectedCodeSnips()) { + const CodeSnipList &snips = func->injectedCodeSnips(); + for (const CodeSnip &cs : snips) { if (cs.position == TypeSystem::CodeSnipPositionEnd) { s << INDENT << "overloadId = " << func->ownerClass()->functions().indexOf(const_cast<AbstractMetaFunction* const>(func)) << ';' << endl; break; @@ -2990,7 +3070,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f removedArgs++; } } else if (maxArgs != 0 && !func->arguments().isEmpty()) { - lastArg = func->arguments().last(); + lastArg = func->arguments().constLast(); } writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode, func, lastArg); @@ -3065,7 +3145,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f firstArg.remove(1, 1); // remove the de-reference operator QString secondArg = QLatin1String(CPP_ARG0); - if (!func->isUnaryOperator() && shouldDereferenceArgumentPointer(func->arguments().first())) { + if (!func->isUnaryOperator() && shouldDereferenceArgumentPointer(func->arguments().constFirst())) { secondArg.prepend(QLatin1String("(*")); secondArg.append(QLatin1Char(')')); } @@ -3255,11 +3335,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f bool hasReturnPolicy = false; // Ownership transference between C++ and Python. - QList<ArgumentModification> ownership_mods; + QVector<ArgumentModification> ownership_mods; // Python object reference management. - QList<ArgumentModification> refcount_mods; - foreach (const FunctionModification &func_mod, func->modifications()) { - foreach (const ArgumentModification &arg_mod, func_mod.argument_mods) { + QVector<ArgumentModification> refcount_mods; + const FunctionModificationList &funcMods = func->modifications(); + for (const FunctionModification &func_mod : funcMods) { + for (const 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()) @@ -3273,7 +3354,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f if (!ownership_mods.isEmpty()) { s << endl << INDENT << "// Ownership transferences." << endl; - foreach (const ArgumentModification &arg_mod, ownership_mods) { + for (const ArgumentModification &arg_mod : qAsConst(ownership_mods)) { const AbstractMetaClass* wrappedClass = 0; QString pyArgName = argumentNameFromIndex(func, arg_mod.index, &wrappedClass); if (!wrappedClass) { @@ -3304,8 +3385,8 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f } } else if (!refcount_mods.isEmpty()) { - foreach (const ArgumentModification &arg_mod, refcount_mods) { - ReferenceCount refCount = arg_mod.referenceCounts.first(); + for (const ArgumentModification &arg_mod : qAsConst(refcount_mods)) { + ReferenceCount refCount = arg_mod.referenceCounts.constFirst(); if (refCount.action != ReferenceCount::Set && refCount.action != ReferenceCount::Remove && refCount.action != ReferenceCount::Add) { @@ -3331,7 +3412,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f s << INDENT << "Shiboken::Object::removeReference("; s << "reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR "), \""; - QString varName = arg_mod.referenceCounts.first().varName; + QString varName = arg_mod.referenceCounts.constFirst().varName; if (varName.isEmpty()) varName = func->minimalSignature() + QString().number(arg_mod.index); @@ -3349,15 +3430,15 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass* metaClass) { QStringList result; - AbstractMetaClassList baseClases = getBaseClasses(metaClass); + const AbstractMetaClassList &baseClases = getBaseClasses(metaClass); if (!baseClases.isEmpty()) { - foreach (const AbstractMetaClass* baseClass, baseClases) { + 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())); } - foreach (const AbstractMetaClass* baseClass, baseClases) + for (const AbstractMetaClass *baseClass : baseClases) result.append(getAncestorMultipleInheritance(baseClass)); } return result; @@ -3366,7 +3447,7 @@ QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, const AbstractMetaClass* metaClass) { QString className = metaClass->qualifiedCppName(); - QStringList ancestors = getAncestorMultipleInheritance(metaClass); + const QStringList ancestors = getAncestorMultipleInheritance(metaClass); s << "static int mi_offsets[] = { "; for (int i = 0; i < ancestors.size(); i++) s << "-1, "; @@ -3382,7 +3463,7 @@ void CppGenerator::writeMultipleInheritanceInitializerFunction(QTextStream& s, c s << INDENT << "const " << className << "* class_ptr = reinterpret_cast<const " << className << "*>(cptr);" << endl; s << INDENT << "size_t base = (size_t) class_ptr;" << endl; - foreach (const QString &ancestor, ancestors) + for (const QString &ancestor : ancestors) s << INDENT << "offsets.insert(" << ancestor << ");" << endl; s << endl; @@ -3410,7 +3491,8 @@ void CppGenerator::writeSpecialCastFunction(QTextStream& s, const AbstractMetaCl s << "{\n"; s << INDENT << className << "* me = reinterpret_cast< ::" << className << "*>(obj);\n"; bool firstClass = true; - foreach (const AbstractMetaClass* baseClass, getAllAncestors(metaClass)) { + const AbstractMetaClassList &allAncestors = getAllAncestors(metaClass); + for (const AbstractMetaClass *baseClass : allAncestors) { s << INDENT << (!firstClass ? "else " : "") << "if (desiredType == reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(baseClass->typeEntry()) << "))\n"; Indentation indent(INDENT); s << INDENT << "return static_cast< ::" << baseClass->qualifiedCppName() << "*>(me);\n"; @@ -3528,10 +3610,11 @@ void CppGenerator::writeContainerConverterInitialization(QTextStream& s, const A writeAddPythonToCppConversion(s, converterObject(type), toCpp, isConv); } -void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, const QList<const AbstractMetaClass*>& conversions) +void CppGenerator::writeExtendedConverterInitialization(QTextStream& s, const TypeEntry* externalType, + const QVector<const AbstractMetaClass*>& conversions) { s << INDENT << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl; - foreach (const AbstractMetaClass* sourceClass, conversions) { + for (const AbstractMetaClass *sourceClass : conversions) { const QString converterVar = QLatin1String("reinterpret_cast<SbkObjectType *>(") + cppApiVariableName(externalType->targetLangPackage()) + QLatin1Char('[') + getTypeIndexVariableName(externalType) + QLatin1String("])"); @@ -3586,7 +3669,8 @@ bool CppGenerator::supportsSequenceProtocol(const AbstractMetaClass* metaClass) bool CppGenerator::shouldGenerateGetSetList(const AbstractMetaClass* metaClass) { - foreach (AbstractMetaField* f, metaClass->fields()) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (const AbstractMetaField *f : fields) { if (!f->isStatic()) return true; } @@ -3604,11 +3688,11 @@ void CppGenerator::writeClassDefinition(QTextStream &s, QString tp_hash(QLatin1Char('0')); QString tp_call = tp_hash; QString cppClassName = metaClass->qualifiedCppName(); - QString className = cpythonTypeName(metaClass); - className.remove(QRegExp(QLatin1String("_Type$"))); + const QString className = chopType(cpythonTypeName(metaClass)); QString baseClassName(QLatin1Char('0')); AbstractMetaFunctionList ctors; - foreach (AbstractMetaFunction* f, metaClass->queryFunctions(AbstractMetaClass::Constructors)) { + const AbstractMetaFunctionList &allCtors = metaClass->queryFunctions(AbstractMetaClass::Constructors); + for (AbstractMetaFunction *f : allCtors) { if (!f->isPrivate() && !f->isModifiedRemoved() && !classContext.forSmartPointer()) ctors.append(f); } @@ -3641,8 +3725,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s, tp_dealloc = QLatin1String("&SbkDeallocQAppWrapper"); else tp_dealloc = QLatin1String("&SbkDeallocWrapper"); - // avoid constFirst to stay Qt 5.5 compatible - tp_init = (onlyPrivCtor || ctors.isEmpty()) ? QLatin1String("0") : cpythonFunctionName(ctors.first()); + tp_init = (onlyPrivCtor || ctors.isEmpty()) ? QLatin1String("0") : cpythonFunctionName(ctors.constFirst()); } QString tp_getattro(QLatin1Char('0')); @@ -3679,7 +3762,8 @@ void CppGenerator::writeClassDefinition(QTextStream &s, // search for special functions ShibokenGenerator::clearTpFuncs(); - foreach (AbstractMetaFunction* func, metaClass->functions()) { + const AbstractMetaFunctionList &funcs = metaClass->functions(); + for (AbstractMetaFunction *func : funcs) { if (m_tpFuncs.contains(func->name())) m_tpFuncs[func->name()] = cpythonFunctionName(func); } @@ -3788,11 +3872,7 @@ void CppGenerator::writeMappingMethods(QTextStream &s, const AbstractMetaClass *metaClass, GeneratorContext &context) { - - QMap<QString, QString> funcs; - - QHash< QString, QPair< QString, QString > >::const_iterator it = m_mappingProtocol.begin(); - for (; it != m_mappingProtocol.end(); ++it) { + for (auto it = m_mappingProtocol.cbegin(), end = m_mappingProtocol.cend(); it != end; ++it) { const AbstractMetaFunction* func = metaClass->findFunction(it.key()); if (!func) continue; @@ -3806,7 +3886,7 @@ void CppGenerator::writeMappingMethods(QTextStream &s, writeCppSelfDefinition(s, func, context); - const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last(); + const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast(); writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, lastArg); s << '}' << endl << endl; } @@ -3816,12 +3896,9 @@ void CppGenerator::writeSequenceMethods(QTextStream &s, const AbstractMetaClass *metaClass, GeneratorContext &context) { - - QMap<QString, QString> funcs; bool injectedCode = false; - QHash< QString, QPair< QString, QString > >::const_iterator it = m_sequenceProtocol.begin(); - for (; it != m_sequenceProtocol.end(); ++it) { + for (auto it = m_sequenceProtocol.cbegin(), end = m_sequenceProtocol.cend(); it != end; ++it) { const AbstractMetaFunction* func = metaClass->findFunction(it.key()); if (!func) continue; @@ -3836,7 +3913,7 @@ void CppGenerator::writeSequenceMethods(QTextStream &s, writeCppSelfDefinition(s, func, context); - const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last(); + const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().constLast(); writeCodeSnips(s, snips,TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, lastArg); s << '}' << endl << endl; } @@ -3900,7 +3977,7 @@ void CppGenerator::writeTypeAsMappingDefinition(QTextStream& s, const AbstractMe QString baseName = cpythonBaseName(metaClass); s << INDENT << "memset(&" << baseName << "_TypeAsMapping, 0, sizeof(PyMappingMethods));" << endl; - for (QHash<QString, QString>::const_iterator it = m_mpFuncs.cbegin(), end = m_mpFuncs.end(); it != end; ++it) { + for (auto it = m_mpFuncs.cbegin(), end = m_mpFuncs.cend(); it != end; ++it) { const QString &mpName = it.key(); if (funcs[mpName].isEmpty()) continue; @@ -3936,13 +4013,13 @@ void CppGenerator::writeTypeAsNumberDefinition(QTextStream& s, const AbstractMet nb.insert(QLatin1String("__ixor__"), QString()); nb.insert(QLatin1String("__ior__"), QString()); - QList<AbstractMetaFunctionList> opOverloads = + const QVector<AbstractMetaFunctionList> opOverloads = filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ArithmeticOp | AbstractMetaClass::LogicalOp | AbstractMetaClass::BitwiseOp); - foreach (const AbstractMetaFunctionList &opOverload, opOverloads) { + for (const AbstractMetaFunctionList &opOverload : opOverloads) { const AbstractMetaFunction* rfunc = opOverload[0]; QString opName = ShibokenGenerator::pythonOperatorFunctionName(rfunc); nb[opName] = cpythonFunctionName(rfunc); @@ -4001,8 +4078,7 @@ void CppGenerator::writeTpClearFunction(QTextStream& s, const AbstractMetaClass* void CppGenerator::writeCopyFunction(QTextStream &s, GeneratorContext &context) { const AbstractMetaClass *metaClass = context.metaClass(); - QString className = cpythonTypeName(metaClass); - className.remove(QRegExp(QLatin1String("_Type$"))); + const QString className = chopType(cpythonTypeName(metaClass)); s << "static PyObject* " << className << "___copy__(PyObject* " PYTHON_SELF_VAR ")" << endl; s << "{" << endl; writeCppSelfDefinition(s, context, false, true); @@ -4181,7 +4257,8 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co s << INDENT << "switch (op) {" << endl; { Indentation indent(INDENT); - foreach (const AbstractMetaFunctionList &overloads, filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ComparisonOp)) { + const QVector<AbstractMetaFunctionList> &groupedFuncs = filterGroupedOperatorFunctions(metaClass, AbstractMetaClass::ComparisonOp); + for (const AbstractMetaFunctionList &overloads : groupedFuncs) { const AbstractMetaFunction* rfunc = overloads[0]; QString operatorId = ShibokenGenerator::pythonRichCompareOperatorId(rfunc); @@ -4193,15 +4270,16 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co op = op.right(op.size() - QLatin1String("operator").size()); int alternativeNumericTypes = 0; - foreach (const AbstractMetaFunction* func, overloads) { + for (const AbstractMetaFunction *func : overloads) { if (!func->isStatic() && - ShibokenGenerator::isNumber(func->arguments()[0]->type()->typeEntry())) + ShibokenGenerator::isNumber(func->arguments().at(0)->type()->typeEntry())) alternativeNumericTypes++; } bool first = true; OverloadData overloadData(overloads, this); - foreach (OverloadData* od, overloadData.nextOverloadData()) { + const OverloadDataList &nextOverloads = overloadData.nextOverloadData(); + for (OverloadData *od : nextOverloads) { const AbstractMetaFunction* func = od->referenceFunction(); if (func->isStatic()) continue; @@ -4227,7 +4305,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co // If the function is user added, use the inject code if (func->isUserAdded()) { CodeSnipList snips = func->injectedCodeSnips(); - writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, func->arguments().last()); + writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, func->arguments().constLast()); } else { QString expression = QString::fromLatin1("%1%2 %3 (%4" CPP_ARG0 ")") .arg(func->isPointerOperator() ? QLatin1String("&") : QString(), @@ -4308,7 +4386,7 @@ void CppGenerator::writeMethodDefinitionEntry(QTextStream& s, const AbstractMeta void CppGenerator::writeMethodDefinition(QTextStream& s, const AbstractMetaFunctionList overloads) { Q_ASSERT(!overloads.isEmpty()); - const AbstractMetaFunction* func = overloads.first(); + const AbstractMetaFunction* func = overloads.constFirst(); if (m_tpFuncs.contains(func->name())) return; @@ -4349,18 +4427,10 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction int idx = overloads.length() - 1; bool multiple = idx > 0; -// after merging, the #if may be removed! -#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) for (const AbstractMetaFunction *f : overloads) { QStringList args; const AbstractMetaArgumentList &arguments = f->arguments(); - for (AbstractMetaArgument *arg : arguments) { -#else - foreach (const AbstractMetaFunction *f, overloads) { - QStringList args; - const AbstractMetaArgumentList &arguments = f->arguments(); - foreach (const AbstractMetaArgument *arg, arguments) { -#endif + for (const AbstractMetaArgument *arg : arguments) { QString strArg = resolveRetOrArgType(arg->type()); if (!arg->defaultValueExpression().isEmpty()) { strArg += QLatin1Char('='); @@ -4378,9 +4448,8 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction // now calculate the return type. s << funcName << '(' << args.join(QLatin1Char(',')) << ')'; AbstractMetaType *returnType = getTypeWithoutContainer(f->type()); - if (returnType) { + if (returnType) s << "->" << resolveRetOrArgType(returnType); - } s << endl; } } @@ -4390,7 +4459,7 @@ void CppGenerator::writeEnumsInitialization(QTextStream& s, AbstractMetaEnumList if (enums.isEmpty()) return; s << INDENT << "// Initialization of enums." << endl << endl; - foreach (const AbstractMetaEnum* cppEnum, enums) { + for (const AbstractMetaEnum *cppEnum : qAsConst(enums)) { if (cppEnum->isPrivate()) continue; writeEnumInitialization(s, cppEnum); @@ -4402,6 +4471,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu const AbstractMetaClass* enclosingClass = getProperEnclosingClassForEnum(cppEnum); const AbstractMetaClass* upper = enclosingClass ? enclosingClass->enclosingClass() : 0; bool hasUpperEnclosingClass = upper && upper->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass; + const EnumTypeEntry *enumTypeEntry = cppEnum->typeEntry(); QString enclosingObjectVariable; if (enclosingClass) enclosingObjectVariable = QLatin1Char('&') + cpythonTypeName(enclosingClass); @@ -4414,14 +4484,17 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu s << (cppEnum->isAnonymous() ? "anonymous enum identified by enum value" : "enum"); s << " '" << cppEnum->name() << "'." << endl; + QString enumVarTypeObj; if (!cppEnum->isAnonymous()) { - FlagsTypeEntry* flags = cppEnum->typeEntry()->flags(); + FlagsTypeEntry* flags = enumTypeEntry->flags(); if (flags) { s << INDENT << cpythonTypeNameExt(flags) << " = PySide::QFlags::create(\"" << flags->flagsName() << "\", &" << cpythonEnumName(cppEnum) << "_as_number);" << endl; } - s << INDENT << cpythonTypeNameExt(cppEnum->typeEntry()) << " = Shiboken::Enum::"; + enumVarTypeObj = cpythonTypeNameExt(enumTypeEntry); + + s << INDENT << enumVarTypeObj << " = Shiboken::Enum::"; s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnum" : "createGlobalEnum"); s << '(' << enclosingObjectVariable << ',' << endl; { @@ -4441,8 +4514,9 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu } } - foreach (const AbstractMetaEnumValue* enumValue, cppEnum->values()) { - if (cppEnum->typeEntry()->isEnumValueRejected(enumValue->name())) + const AbstractMetaEnumValueList &enumValues = cppEnum->values(); + for (const AbstractMetaEnumValue *enumValue : enumValues) { + if (enumTypeEntry->isEnumValueRejected(enumValue->name())) continue; QString enumValueText; @@ -4450,12 +4524,16 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu enumValueText = QLatin1String("(long) "); if (cppEnum->enclosingClass()) enumValueText += cppEnum->enclosingClass()->qualifiedCppName() + QLatin1String("::"); + // Fully qualify the value which is required for C++ 11 enum classes. + if (!cppEnum->isAnonymous()) + enumValueText += cppEnum->name() + QLatin1String("::"); enumValueText += enumValue->name(); } else { enumValueText += QString::number(enumValue->value()); } - if (cppEnum->isAnonymous()) { + switch (enumTypeEntry->enumKind()) { + case EnumTypeEntry::AnonymousEnum: if (enclosingClass || hasUpperEnclosingClass) { s << INDENT << '{' << endl; { @@ -4478,15 +4556,27 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu s << INDENT << "return " << m_currentErrorCode << ';' << endl; } } - } else { + break; + case EnumTypeEntry::CEnum: { s << INDENT << "if (!Shiboken::Enum::"; s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem" : "createGlobalEnumItem"); - s << '(' << cpythonTypeNameExt(cppEnum->typeEntry()) << ',' << endl; + s << '(' << enumVarTypeObj << ',' << endl; Indentation indent(INDENT); s << INDENT << enclosingObjectVariable << ", \"" << enumValue->name() << "\", "; s << enumValueText << "))" << endl; s << INDENT << "return " << m_currentErrorCode << ';' << endl; } + break; + case EnumTypeEntry::EnumClass: { + s << INDENT << "if (!Shiboken::Enum::createScopedEnumItem(" + << enumVarTypeObj << ',' << endl; + Indentation indent(INDENT); + s << INDENT << enumVarTypeObj<< ", \"" << enumValue->name() << "\", " + << enumValueText << "))" << endl + << INDENT << "return " << m_currentErrorCode << ';' << endl; + } + break; + } } writeEnumConverterInitialization(s, cppEnum); @@ -4500,10 +4590,12 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu void CppGenerator::writeSignalInitialization(QTextStream& s, const AbstractMetaClass* metaClass) { // Try to check something and print some warnings - foreach (const AbstractMetaFunction* cppSignal, metaClass->cppSignalFunctions()) { + const AbstractMetaFunctionList &signalFuncs = metaClass->cppSignalFunctions(); + for (const AbstractMetaFunction *cppSignal : signalFuncs) { if (cppSignal->declaringClass() != metaClass) continue; - foreach (AbstractMetaArgument* arg, cppSignal->arguments()) { + const AbstractMetaArgumentList &arguments = cppSignal->arguments(); + for (AbstractMetaArgument *arg : arguments) { AbstractMetaType* metaType = arg->type(); const QByteArray origType = QMetaObject::normalizedType(qPrintable(metaType->originalTypeDescription())); @@ -4704,9 +4796,8 @@ void CppGenerator::writeClassRegister(QTextStream &s, s << "// Multiple signatures have their index \"n:\" in front." << endl; s << "const char " << initFunctionName << "_SignaturesString[] = \"\"" << endl; QString line; - while (signatureStream.readLineInto(&line)) { + while (signatureStream.readLineInto(&line)) s << INDENT << '"' << line << "\\n\"" << endl; - } s << ';' << endl << endl; s << "void init_" << initFunctionName; s << "(PyObject* " << enclosingObjectVariable << ")" << endl; @@ -4747,7 +4838,7 @@ void CppGenerator::writeClassRegister(QTextStream &s, if (metaClass->baseClassNames().size() > 1) { s << INDENT << "PyObject* " << pyTypeBasesVariable << " = PyTuple_Pack(" << baseClasses.size() << ',' << endl; QStringList bases; - foreach (const AbstractMetaClass* base, baseClasses) + for (const AbstractMetaClass *base : baseClasses) bases << QLatin1String("(PyObject*)") + cpythonTypeNameExt(base->typeEntry()); Indentation indent(INDENT); QString separator; @@ -4842,7 +4933,8 @@ void CppGenerator::writeClassRegister(QTextStream &s, } AbstractMetaEnumList classEnums = metaClass->enums(); - foreach (AbstractMetaClass* innerClass, metaClass->innerClasses()) + const AbstractMetaClassList &innerClasses = metaClass->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) lookForEnumsInClassesNotToBeGenerated(classEnums, innerClass); ErrorCode errorCode(QString::null); @@ -4852,7 +4944,8 @@ void CppGenerator::writeClassRegister(QTextStream &s, writeSignalInitialization(s, metaClass); // Write static fields - foreach (const AbstractMetaField* field, metaClass->fields()) { + const AbstractMetaFieldList &fields = metaClass->fields(); + for (const AbstractMetaField *field : fields) { if (!field->isStatic()) continue; s << INDENT << QLatin1String("PyDict_SetItemString(") + cpythonTypeName(metaClass) + QLatin1String(".super.ht_type.tp_dict, \""); @@ -4897,7 +4990,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont const AbstractMetaClass* enclosingClass = metaClass->enclosingClass(); while (enclosingClass) { if (enclosingClass->typeEntry()->generateCode()) - nameVariants << (enclosingClass->name() + QLatin1String("::") + nameVariants.last()); + nameVariants << (enclosingClass->name() + QLatin1String("::") + nameVariants.constLast()); enclosingClass = enclosingClass->enclosingClass(); } @@ -4912,7 +5005,8 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont bool canBeValue = false; if (!isObjectType(metaClass)) { // check if there's a empty ctor - foreach (AbstractMetaFunction* func, metaClass->functions()) { + const AbstractMetaFunctionList &funcs = metaClass->functions(); + for (AbstractMetaFunction *func : funcs) { if (func->isConstructor() && !func->arguments().count()) { canBeValue = true; break; @@ -4921,7 +5015,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont } if (canBeValue) { - foreach (const QString &name, nameVariants) { + for (const QString &name : qAsConst(nameVariants)) { if (name == QLatin1String("iterator")) { qCWarning(lcShiboken).noquote().nospace() << QString::fromLatin1("%1:%2 FIXME:\n" @@ -4935,9 +5029,10 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorCont } } - foreach (AbstractMetaEnum* metaEnum, metaClass->enums()) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (AbstractMetaEnum *metaEnum : enums) { if (!metaEnum->isPrivate() && !metaEnum->isAnonymous()) { - foreach (const QString &name, nameVariants) + for (const QString &name : qAsConst(nameVariants)) s << INDENT << "qRegisterMetaType< ::" << metaEnum->typeEntry()->qualifiedCppName() << " >(\"" << name << "::" << metaEnum->name() << "\");" << endl; if (metaEnum->typeEntry()->flags()) { @@ -4965,8 +5060,8 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream& s, const AbstractMeta s << INDENT << "return cptr;" << endl; } } else if (metaClass->isPolymorphic()) { - AbstractMetaClassList ancestors = getAllAncestors(metaClass); - foreach (AbstractMetaClass* ancestor, ancestors) { + const AbstractMetaClassList &ancestors = getAllAncestors(metaClass); + for (AbstractMetaClass *ancestor : ancestors) { if (ancestor->baseClass()) continue; if (ancestor->isPolymorphic()) { @@ -5077,7 +5172,8 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &conte } s << INDENT << '}' << endl; - foreach (const AbstractMetaFunction* func, getMethodsWithBothStaticAndNonStaticMethods(metaClass)) { + const AbstractMetaFunctionList &funcs = getMethodsWithBothStaticAndNonStaticMethods(metaClass); + for (const AbstractMetaFunction *func : funcs) { QString defName = cpythonMethodDefinitionName(func); s << INDENT << "static PyMethodDef non_static_" << defName << " = {" << endl; { @@ -5172,7 +5268,7 @@ bool CppGenerator::finishGeneration() const FunctionGroupMap &functionGroups = getFunctionGroups(); for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) { AbstractMetaFunctionList overloads; - foreach (AbstractMetaFunction* func, it.value()) { + for (AbstractMetaFunction *func : it.value()) { if (!func->isModifiedRemoved()) { overloads.append(func); if (func->typeEntry()) @@ -5203,7 +5299,7 @@ bool CppGenerator::finishGeneration() } const AbstractMetaClassList lst = classesTopologicalSorted(additionalDependencies); - foreach (const AbstractMetaClass* cls, lst) { + for (const AbstractMetaClass *cls : lst){ if (!shouldGenerate(cls)) continue; @@ -5219,7 +5315,8 @@ bool CppGenerator::finishGeneration() } // Initialize smart pointer types. - foreach (const AbstractMetaType *metaType, instantiatedSmartPointers()) { + const QVector<const AbstractMetaType *> &smartPtrs = instantiatedSmartPointers(); + for (const AbstractMetaType *metaType : smartPtrs) { GeneratorContext context(0, metaType, true); QString initFunctionName = getInitFunctionName(context); s_classInitDecl << "void init_" << initFunctionName << "(PyObject* module);" << endl; @@ -5255,13 +5352,14 @@ bool CppGenerator::finishGeneration() } s << "#include \"" << getModuleHeaderFileName() << '"' << endl << endl; - foreach (const Include& include, includes) + for (const Include &include : qAsConst(includes)) s << include; s << endl; // Global enums AbstractMetaEnumList globalEnums = this->globalEnums(); - foreach (const AbstractMetaClass* metaClass, classes()) { + const AbstractMetaClassList &classList = classes(); + for (const AbstractMetaClass *metaClass : classList) { const AbstractMetaClass* encClass = metaClass->enclosingClass(); if (encClass && encClass->typeEntry()->codeGeneration() != TypeEntry::GenerateForSubclass) continue; @@ -5273,13 +5371,13 @@ bool CppGenerator::finishGeneration() //Extra includes s << endl << "// Extra includes" << endl; - QList<Include> extraIncludes; + QVector<Include> extraIncludes; if (moduleEntry) extraIncludes = moduleEntry->extraIncludes(); - foreach (AbstractMetaEnum* cppEnum, globalEnums) + for (AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) extraIncludes.append(cppEnum->typeEntry()->extraIncludes()); qSort(extraIncludes.begin(), extraIncludes.end()); - foreach (const Include& inc, extraIncludes) + for (const Include &inc : qAsConst(extraIncludes)) s << inc; s << endl; @@ -5334,7 +5432,7 @@ bool CppGenerator::finishGeneration() s << "// Enum definitions "; s << "------------------------------------------------------------" << endl; - foreach (const AbstractMetaEnum* cppEnum, globalEnums) { + for (const AbstractMetaEnum *cppEnum : qAsConst(globalEnums)) { if (cppEnum->isAnonymous() || cppEnum->isPrivate()) continue; writeEnumConverterFunctions(s, cppEnum); @@ -5350,10 +5448,10 @@ bool CppGenerator::finishGeneration() } } - QStringList requiredModules = typeDb->requiredTargetImports(); + const QStringList &requiredModules = typeDb->requiredTargetImports(); if (!requiredModules.isEmpty()) s << "// Required modules' type and converter arrays." << endl; - foreach (const QString& requiredModule, requiredModules) { + for (const QString &requiredModule : requiredModules) { s << "PyTypeObject** " << cppApiVariableName(requiredModule) << ';' << endl; s << "SbkConverter** " << convertersVariableName(requiredModule) << ';' << endl; } @@ -5367,7 +5465,7 @@ bool CppGenerator::finishGeneration() for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) { const TypeEntry *externalType = it.key(); s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName() << '.' << endl; - foreach (const AbstractMetaClass* sourceClass, extendedConverters[externalType]) { + for (const AbstractMetaClass *sourceClass : it.value()) { AbstractMetaType* sourceType = buildAbstractMetaTypeFromAbstractMetaClass(sourceClass); AbstractMetaType* targetType = buildAbstractMetaTypeFromTypeEntry(externalType); writePythonToCppConversionFunctions(s, sourceType, targetType); @@ -5375,10 +5473,10 @@ bool CppGenerator::finishGeneration() } } - QList<const CustomConversion*> typeConversions = getPrimitiveCustomConversions(); + const QVector<const CustomConversion *> &typeConversions = getPrimitiveCustomConversions(); if (!typeConversions.isEmpty()) { s << endl << "// Primitive Type converters." << endl << endl; - foreach (const CustomConversion* conversion, typeConversions) { + for (const CustomConversion *conversion : typeConversions) { s << "// C++ to Python conversion for type '" << conversion->ownerType()->qualifiedCppName() << "'." << endl; writeCppToPythonFunction(s, conversion); writeCustomConverterFunctions(s, conversion); @@ -5386,10 +5484,10 @@ bool CppGenerator::finishGeneration() s << endl; } - QList<const AbstractMetaType*> containers = instantiatedContainers(); + const QVector<const AbstractMetaType *> &containers = instantiatedContainers(); if (!containers.isEmpty()) { s << "// Container Type converters." << endl << endl; - foreach (const AbstractMetaType* container, containers) { + for (const AbstractMetaType *container : containers) { s << "// C++ to Python conversion for type '" << container->cppSignature() << "'." << endl; writeContainerConverterFunctions(s, container); } @@ -5426,7 +5524,7 @@ bool CppGenerator::finishGeneration() s << endl; } - foreach (const QString& requiredModule, typeDb->requiredTargetImports()) { + for (const QString& requiredModule : requiredModules) { s << INDENT << "{" << endl; { Indentation indentation(INDENT); @@ -5468,7 +5566,7 @@ bool CppGenerator::finishGeneration() if (!typeConversions.isEmpty()) { s << endl; - foreach (const CustomConversion* conversion, typeConversions) { + for (const CustomConversion *conversion : typeConversions) { writePrimitiveConverterInitialization(s, conversion); s << endl; } @@ -5476,7 +5574,7 @@ bool CppGenerator::finishGeneration() if (!containers.isEmpty()) { s << endl; - foreach (const AbstractMetaType* container, containers) { + for (const AbstractMetaType *container : containers) { writeContainerConverterInitialization(s, container); s << endl; } @@ -5493,7 +5591,8 @@ bool CppGenerator::finishGeneration() writeEnumsInitialization(s, globalEnums); s << INDENT << "// Register primitive types converters." << endl; - foreach(const PrimitiveTypeEntry* pte, primitiveTypes()) { + const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes(); + for (const PrimitiveTypeEntry *pte : primitiveTypeList) { if (!pte->generateCode() || !pte->isCppPrimitive()) continue; const TypeEntry *referencedType = pte->basicReferencedTypeEntry(); @@ -5534,7 +5633,7 @@ bool CppGenerator::finishGeneration() } if (usePySideExtensions()) { - foreach (AbstractMetaEnum* metaEnum, globalEnums) + for (AbstractMetaEnum *metaEnum : qAsConst(globalEnums)) if (!metaEnum->isAnonymous()) { s << INDENT << "qRegisterMetaType< ::" << metaEnum->typeEntry()->qualifiedCppName() << " >(\"" << metaEnum->name() << "\");" << endl; } @@ -5547,9 +5646,8 @@ bool CppGenerator::finishGeneration() s << "// Multiple signatures have their index \"n:\" in front." << endl; s << "const char " << moduleName() << "_SignaturesString[] = \"\"" << endl; QString line; - while (signatureStream.readLineInto(&line)) { + while (signatureStream.readLineInto(&line)) s << INDENT << '"' << line << "\\n\"" << endl; - } s << ';' << endl; // finish the rest of __signature__ initialization. s << INDENT << "FinishSignatureInitialization(module, " << moduleName() @@ -5693,7 +5791,7 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext & s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = " CPP_SELF_VAR "->begin();" << endl; s << INDENT << "for (Py_ssize_t pos = 0; pos < _i; pos++) _item++;" << endl; - const AbstractMetaType* itemType = metaClass->templateBaseClassInstantiations().first(); + const AbstractMetaType* itemType = metaClass->templateBaseClassInstantiations().constFirst(); s << INDENT << "return "; writeToPythonConversion(s, itemType, metaClass, QLatin1String("*_item")); |