diff options
Diffstat (limited to 'sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp')
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp | 799 |
1 files changed, 488 insertions, 311 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index e71841ec3..3d2afd8bf 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -30,18 +30,16 @@ #include "reporthandler.h" #include "typedatabase.h" -#include "parser/ast.h" -#include "parser/binder.h" -#include "parser/control.h" -#include "parser/default_visitor.h" -#include "parser/dumptree.h" -#include "parser/lexer.h" -#include "parser/parser.h" -#include "parser/tokens.h" +#include <clangparser/clangbuilder.h> +#include <clangparser/clangutils.h> + +#include "parser/codemodel.h" #include <QDebug> +#include <QDir> #include <QFile> #include <QFileInfo> +#include <QRegularExpression> #include <QTextCodec> #include <QTextStream> #include <QVariant> @@ -165,23 +163,44 @@ QSet<QString> AbstractMetaBuilder::qtMetaTypeDeclaredTypeNames() const return d->m_qmetatypeDeclaredTypenames; } +static QString msgNoFunctionForModification(const QString &signature, const QString &className, + const QStringList &possibleSignatures, + const AbstractMetaFunctionList &allFunctions) +{ + QString result; + QTextStream str(&result); + str << "signature '" << signature << "' for function modification in '" + << className << "' not found."; + if (possibleSignatures.isEmpty()) { + str << " No candidates were found. Member functions: "; + for (int f = 0, size = allFunctions.size(); f < size; ++f) { + if (f) + str << ", "; + str << allFunctions.at(f)->minimalSignature(); + } + } else { + str << " Possible candidates: " << possibleSignatures.join(QLatin1String(", ")); + } + return result; +} + void AbstractMetaBuilderPrivate::checkFunctionModifications() { TypeDatabase *types = TypeDatabase::instance(); - SingleTypeEntryHash entryHash = types->entries(); - QList<TypeEntry*> entries = entryHash.values(); + const SingleTypeEntryHash entryHash = types->entries(); - foreach (TypeEntry* entry, entries) { + for (SingleTypeEntryHash::const_iterator it = entryHash.cbegin(), end = entryHash.cend(); it != end; ++it) { + const TypeEntry *entry = it.value(); if (!entry) continue; if (!entry->isComplex() || entry->codeGeneration() == TypeEntry::GenerateNothing) continue; - ComplexTypeEntry* centry = static_cast<ComplexTypeEntry*>(entry); + const ComplexTypeEntry* centry = static_cast<const ComplexTypeEntry*>(entry); FunctionModificationList modifications = centry->functionModifications(); - foreach (const FunctionModification &modification, modifications) { - QString signature = modification.signature; + for (const FunctionModification &modification : qAsConst(modifications)) { + QString signature = modification.signature(); QString name = signature.trimmed(); name.truncate(name.indexOf(QLatin1Char('('))); @@ -190,11 +209,12 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications() if (!clazz) continue; - AbstractMetaFunctionList functions = clazz->functions(); + const AbstractMetaFunctionList functions = clazz->functions(); bool found = false; QStringList possibleSignatures; - foreach (AbstractMetaFunction *function, functions) { - if (function->minimalSignature() == signature && function->implementingClass() == clazz) { + for (AbstractMetaFunction *function : functions) { + if (function->implementingClass() == clazz + && modification.matches(function->minimalSignature())) { found = true; break; } @@ -207,8 +227,8 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications() if (!found) { qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("signature '%1' for function modification in '%2' not found. Possible candidates: %3") - .arg(signature, clazz->qualifiedCppName(), possibleSignatures.join(QLatin1String(", "))); + << msgNoFunctionForModification(signature, clazz->qualifiedCppName(), + possibleSignatures, functions); } } } @@ -329,7 +349,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(FunctionModelItem item AbstractMetaClass* oldCurrentClass = m_currentClass; m_currentClass = baseoperandClass; AbstractMetaFunction *metaFunction = traverseFunction(item); - if (metaFunction && !metaFunction->isInvalid()) { + if (metaFunction) { // Strip away first argument, since that is the containing object AbstractMetaArgumentList arguments = metaFunction->arguments(); if (firstArgumentIsSelf || unaryOperator) { @@ -378,8 +398,7 @@ void AbstractMetaBuilderPrivate::traverseStreamOperator(FunctionModelItem item) m_currentClass = streamedClass; AbstractMetaFunction *streamFunction = traverseFunction(item); - if (streamFunction && !streamFunction->isInvalid()) { - QString name = item->name(); + if (streamFunction) { streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction); // Strip first argument, since that is the containing object AbstractMetaArgumentList arguments = streamFunction->arguments(); @@ -427,7 +446,8 @@ void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom, const TypeDatabase *types, const NamespaceModelItem &scope) { - foreach (const ClassModelItem &item, scope->classes()) { + const ClassList &scopeClasses = scope->classes(); + for (const ClassModelItem &item : scopeClasses) { QString qualifiedName = item->qualifiedName().join(colonColon()); TypeEntry* entry = types->findType(qualifiedName); if (entry) { @@ -437,7 +457,7 @@ void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom, } const NamespaceList &namespaces = scope->namespaces(); - foreach (const NamespaceModelItem &n, namespaces) { + for (const NamespaceModelItem &n : namespaces) { if (scope != n) fixQObjectForScope(dom, types, n); } @@ -445,29 +465,26 @@ void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom, void AbstractMetaBuilderPrivate::sortLists() { - foreach (AbstractMetaClass *cls, m_metaClasses) + for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) cls->sortFunctions(); } -FileModelItem AbstractMetaBuilderPrivate::buildDom(QIODevice *input) +FileModelItem AbstractMetaBuilderPrivate::buildDom(const QByteArrayList &arguments, + unsigned clangFlags) { - Q_ASSERT(input); - - if (!input->isOpen() && !input->open(QIODevice::ReadOnly)) - return FileModelItem(); - - QByteArray contents = input->readAll(); - input->close(); - - Control control; - Parser p(&control); - pool __pool; - - TranslationUnitAST* ast = p.parse(contents, contents.size(), &__pool); - - CodeModel model; - Binder binder(&model, p.location()); - return binder.run(ast); + clang::Builder builder; + FileModelItem result = clang::parse(arguments, clangFlags, builder) + ? builder.dom() : FileModelItem(); + const clang::BaseVisitor::Diagnostics &diagnostics = builder.diagnostics(); + if (const int diagnosticsCount = diagnostics.size()) { + QDebug d = qWarning(); + d.nospace(); + d.noquote(); + d << "Clang: " << diagnosticsCount << " diagnostic messages:\n"; + for (int i = 0; i < diagnosticsCount; ++i) + d << " " << diagnostics.at(i) << '\n'; + } + return result; } void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) @@ -482,7 +499,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) // Start the generation... const ClassList &typeValues = dom->classes(); ReportHandler::setProgressReference(typeValues); - foreach (const ClassModelItem &item, typeValues) { + for (const ClassModelItem &item : typeValues) { ReportHandler::progress(QLatin1String("Generating class model...")); AbstractMetaClass *cls = traverseClass(dom, item); if (!cls) @@ -492,8 +509,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } // We need to know all global enums - ReportHandler::setProgressReference(dom->enums()); - foreach (const EnumModelItem &item, dom->enums()) { + const EnumList &enums = dom->enums(); + ReportHandler::setProgressReference(enums); + for (const EnumModelItem &item : enums) { ReportHandler::progress(QLatin1String("Generating enum model...")); AbstractMetaEnum *metaEnum = traverseEnum(item, 0, QSet<QString>()); if (metaEnum) { @@ -504,7 +522,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) const QSet<NamespaceModelItem> &namespaceTypeValues = dom->uniqueNamespaces(); ReportHandler::setProgressReference(namespaceTypeValues); - foreach (NamespaceModelItem item, namespaceTypeValues) { + for (NamespaceModelItem item : namespaceTypeValues) { ReportHandler::progress(QLatin1String("Generating namespace model...")); AbstractMetaClass *metaClass = traverseNamespace(dom, item); if (metaClass) @@ -513,9 +531,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. - TypeDefList typeDefs = dom->typeDefs(); + const TypeDefList typeDefs = dom->typeDefs(); ReportHandler::setProgressReference(typeDefs); - foreach (const TypeDefModelItem &typeDef, typeDefs) { + for (const TypeDefModelItem &typeDef : typeDefs) { ReportHandler::progress(QLatin1String("Resolving typedefs...")); AbstractMetaClass* cls = traverseTypeDef(dom, typeDef); addAbstractMetaClass(cls); @@ -523,14 +541,15 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) figureOutEnumValues(); - foreach (const ClassModelItem &item, typeValues) + for (const ClassModelItem &item : typeValues) traverseClassMembers(item); - foreach (const NamespaceModelItem &item, namespaceTypeValues) + for (const NamespaceModelItem &item : namespaceTypeValues) traverseNamespaceMembers(item); // Global functions - foreach (const FunctionModelItem &func, dom->functions()) { + const FunctionList &functions = dom->functions(); + for (const FunctionModelItem &func : functions) { if (func->accessPolicy() != CodeModel::Public || func->name().startsWith(QLatin1String("operator"))) continue; @@ -558,14 +577,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } ReportHandler::setProgressReference(m_metaClasses); - foreach (AbstractMetaClass* cls, m_metaClasses) { + for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { ReportHandler::progress(QLatin1String("Fixing class inheritance...")); if (!cls->isInterface() && !cls->isNamespace()) setupInheritance(cls); } ReportHandler::setProgressReference(m_metaClasses); - foreach (AbstractMetaClass* cls, m_metaClasses) { + for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { ReportHandler::progress(QLatin1String("Detecting inconsistencies in class model...")); cls->fixFunctions(); @@ -574,7 +593,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) << QStringLiteral("class '%1' does not have an entry in the type system") .arg(cls->name()); } else { - bool couldAddDefaultCtors = !cls->isFinalInCpp() && !cls->isInterface() && !cls->isNamespace(); + const bool couldAddDefaultCtors = !cls->isFinalInCpp() && !cls->isInterface() && !cls->isNamespace() + && (cls->attributes() & AbstractMetaAttributes::HasRejectedConstructor) == 0; if (couldAddDefaultCtors) { if (!cls->hasConstructors()) cls->addDefaultConstructor(); @@ -586,11 +606,10 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) if (cls->isAbstract() && !cls->isInterface()) cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + QLatin1String("$ConcreteWrapper")); } - TypeEntryHash allEntries = types->allEntries(); + const TypeEntryHash allEntries = types->allEntries(); ReportHandler::progress(QLatin1String("Detecting inconsistencies in typesystem...")); - foreach (QList<TypeEntry*> entries, allEntries) { - foreach (TypeEntry* entry, entries) { - + for (TypeEntryHash::const_iterator it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) { + for (TypeEntry *entry : it.value()) { if (entry->isPrimitive()) continue; @@ -606,9 +625,10 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) .arg(entry->qualifiedCppName()); } else if (entry->generateCode() && entry->type() == TypeEntry::FunctionType) { const FunctionTypeEntry* fte = static_cast<const FunctionTypeEntry*>(entry); - foreach (const QString &signature, fte->signatures()) { + const QStringList &signatures = fte->signatures(); + for (const QString &signature : signatures) { bool ok = false; - foreach (AbstractMetaFunction* func, m_globalFunctions) { + for (AbstractMetaFunction* func : qAsConst(m_globalFunctions)) { if (signature == func->minimalSignature()) { ok = true; break; @@ -628,7 +648,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) if (cls) { enumFound = cls->findEnum(entry->targetLangName()); } else { // Global enum - foreach (AbstractMetaEnum* metaEnum, m_enums) { + for (AbstractMetaEnum *metaEnum : qAsConst(m_enums)) { if (metaEnum->typeEntry() == entry) { enumFound = true; break; @@ -647,14 +667,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) } { - FunctionList hashFunctions = dom->findFunctions(QLatin1String("qHash")); - foreach (const FunctionModelItem &item, hashFunctions) + const FunctionList &hashFunctions = dom->findFunctions(QLatin1String("qHash")); + for (const FunctionModelItem &item : hashFunctions) registerHashFunction(item); } { - FunctionList hashFunctions = dom->findFunctions(QLatin1String("operator<<")); - foreach (const FunctionModelItem &item, hashFunctions) + const FunctionList &streamOps = dom->findFunctions(QLatin1String("operator<<")); + for (const FunctionModelItem &item : streamOps) registerToStringCapability(item); } @@ -671,7 +691,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) const FunctionList potentiallyBinaryOperators = dom->findFunctions(QStringLiteral("operator*")) + dom->findFunctions(QStringLiteral("operator&")); - foreach (const FunctionModelItem &item, potentiallyBinaryOperators) { + for (const FunctionModelItem &item : potentiallyBinaryOperators) { if (!item->arguments().isEmpty()) binaryOperators.append(item); } @@ -682,14 +702,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) binaryOperators.append(dom->findFunctions(QStringLiteral("operator~"))); binaryOperators.append(dom->findFunctions(QStringLiteral("operator>"))); - foreach (const FunctionModelItem &item, binaryOperators) + for (const FunctionModelItem &item : qAsConst(binaryOperators)) traverseOperatorFunction(item); } { - FunctionList streamOperators = dom->findFunctions(QLatin1String("operator<<")) - + dom->findFunctions(QLatin1String("operator>>")); - foreach (const FunctionModelItem &item, streamOperators) + const FunctionList streamOperators = dom->findFunctions(QLatin1String("operator<<")) + + dom->findFunctions(QLatin1String("operator>>")); + for (const FunctionModelItem &item : streamOperators) traverseStreamOperator(item); } @@ -699,7 +719,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) // sort all classes topologically m_metaClasses = classesTopologicalSorted(); - foreach (AbstractMetaClass* cls, m_metaClasses) { + for (AbstractMetaClass* cls : qAsConst(m_metaClasses)) { // setupEquals(cls); // setupComparable(cls); setupClonable(cls); @@ -719,7 +739,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) m_currentClass = 0; // Functions added to the module on the type system. - foreach (const AddedFunction &addedFunc, types->globalUserFunctions()) { + const AddedFunctionList &globalUserFunctions = types->globalUserFunctions(); + for (const AddedFunction &addedFunc : globalUserFunctions) { AbstractMetaFunction* metaFunc = traverseFunction(addedFunc); metaFunc->setFunctionType(AbstractMetaFunction::NormalFunction); m_globalFunctions << metaFunc; @@ -728,13 +749,15 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) std::puts(""); } -bool AbstractMetaBuilder::build(QIODevice *input) +bool AbstractMetaBuilder::build(const QByteArrayList &arguments, unsigned clangFlags) { - FileModelItem dom = d->buildDom(input); - const bool result = dom.data() != Q_NULLPTR; - if (result) - d->traverseDom(dom); - return result; + const FileModelItem dom = d->buildDom(arguments, clangFlags); + if (dom.isNull()) + return false; + if (ReportHandler::isDebug(ReportHandler::MediumDebug)) + qCDebug(lcShiboken) << dom.data(); + d->traverseDom(dom); + return true; } void AbstractMetaBuilder::setLogDirectory(const QString& logDir) @@ -801,8 +824,8 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel pushScope(namespaceItem); m_namespacePrefix = currentScope()->qualifiedName().join(colonColon()); - ClassList classes = namespaceItem->classes(); - foreach (const ClassModelItem &cls, classes) { + const ClassList &classes = namespaceItem->classes(); + for (const ClassModelItem &cls : classes) { AbstractMetaClass* mjc = traverseClass(dom, cls); if (mjc) { metaClass->addInnerClass(mjc); @@ -814,7 +837,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. const TypeDefList typeDefs = namespaceItem->typeDefs(); - foreach (const TypeDefModelItem &typeDef, typeDefs) { + for (const TypeDefModelItem &typeDef : typeDefs) { AbstractMetaClass *cls = traverseTypeDef(dom, typeDef); if (cls) { metaClass->addInnerClass(cls); @@ -825,7 +848,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel // Traverse namespaces recursively const QSet<NamespaceModelItem> &innerNamespaces = namespaceItem->uniqueNamespaces(); - foreach (const NamespaceModelItem &ni, innerNamespaces) { + for (const NamespaceModelItem &ni : innerNamespaces) { AbstractMetaClass* mjc = traverseNamespace(dom, ni); if (mjc) { metaClass->addInnerClass(mjc); @@ -985,8 +1008,8 @@ void AbstractMetaBuilderPrivate::figureOutEnumValuesForClass(AbstractMetaClass * if (classes->contains(metaClass)) return; - AbstractMetaEnumList enums = metaClass->enums(); - foreach (AbstractMetaEnum* e, enums) { + const AbstractMetaEnumList &enums = metaClass->enums(); + for (AbstractMetaEnum* e : enums) { if (!e) { qCWarning(lcShiboken).noquote().nospace() << "bad enum in class " << metaClass->name(); continue; @@ -1009,10 +1032,10 @@ void AbstractMetaBuilderPrivate::figureOutEnumValues() // Keep a set of classes that we already traversed. We use this to // enforce that we traverse base classes prior to subclasses. QSet<AbstractMetaClass*> classes; - foreach (AbstractMetaClass *c, m_metaClasses) + for (AbstractMetaClass *c : qAsConst(m_metaClasses)) figureOutEnumValuesForClass(c, &classes); - foreach (AbstractMetaEnum* metaEnum, m_globalEnums) { + for (AbstractMetaEnum* metaEnum : qAsConst(m_globalEnums)) { AbstractMetaEnumValueList enumValues = metaEnum->values(); int value = 0; for (int i = 0; i < enumValues.size(); ++i) { @@ -1025,9 +1048,11 @@ void AbstractMetaBuilderPrivate::figureOutEnumValues() void AbstractMetaBuilderPrivate::figureOutDefaultEnumArguments() { - foreach (AbstractMetaClass* metaClass, m_metaClasses) { - foreach (AbstractMetaFunction* metaFunction, metaClass->functions()) { - foreach (AbstractMetaArgument *arg, metaFunction->arguments()) { + for (AbstractMetaClass* metaClass : qAsConst(m_metaClasses)) { + const AbstractMetaFunctionList &functions = metaClass->functions(); + for (AbstractMetaFunction* metaFunction : functions) { + const AbstractMetaArgumentList &arguments = metaFunction->arguments(); + for (AbstractMetaArgument *arg : arguments) { QString expr = arg->defaultValueExpression(); if (expr.isEmpty()) continue; @@ -1063,7 +1088,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte typeEntry = TypeDatabase::instance()->findType(qualifiedName); } else { QStringList tmpQualifiedName = enumItem->qualifiedName(); - foreach (const EnumeratorModelItem& enumValue, enumItem->enumerators()) { + const EnumeratorList &enums = enumItem->enumerators(); + for (const EnumeratorModelItem& enumValue : enums) { tmpQualifiedName.removeLast(); tmpQualifiedName << enumValue->name(); qualifiedName = tmpQualifiedName.join(colonColon()); @@ -1079,10 +1105,11 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte if (m_currentClass) className = m_currentClass->typeEntry()->qualifiedCppName(); - if (TypeDatabase::instance()->isEnumRejected(className, enumName)) { + QString rejectReason; + if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) { if (typeEntry) typeEntry->setCodeGeneration(TypeEntry::GenerateNothing); - m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::GenerationDisabled); + m_rejectedEnums.insert(qualifiedName + rejectReason, AbstractMetaBuilder::GenerationDisabled); return 0; } @@ -1119,7 +1146,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte if (ReportHandler::isDebug(ReportHandler::MediumDebug)) qCDebug(lcShiboken) << " - traversing enum " << metaEnum->fullName(); - foreach (const EnumeratorModelItem &value, enumItem->enumerators()) { + const EnumeratorList &enums = enumItem->enumerators(); + for (const EnumeratorModelItem &value : enums) { AbstractMetaEnumValue *metaEnumValue = q->createMetaEnumValue(); metaEnumValue->setName(value->name()); @@ -1148,7 +1176,8 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte metaEnum->setOriginalAttributes(metaEnum->attributes()); // Register all enum values on Type database - foreach(EnumeratorModelItem e, enumItem->enumerators()) { + const EnumeratorList &enumerators = enumItem->enumerators(); + for (EnumeratorModelItem e : enumItem->enumerators()) { QString name; if (enclosing) { name += enclosing->name(); @@ -1255,7 +1284,15 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem AbstractMetaClass *metaClass = q->createMetaClass(); metaClass->setTypeEntry(type); - metaClass->setBaseClassNames(classItem->baseClasses()); + + QStringList baseClassNames; + const QVector<_ClassModelItem::BaseClass> &baseClasses = classItem->baseClasses(); + for (const _ClassModelItem::BaseClass &baseClass : baseClasses) { + if (baseClass.accessPolicy == CodeModel::Public) + baseClassNames.append(baseClass.name); + } + + metaClass->setBaseClassNames(baseClassNames); *metaClass += AbstractMetaAttributes::Public; if (type->stream()) metaClass->setStream(true); @@ -1271,7 +1308,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem } TemplateParameterList template_parameters = classItem->templateParameters(); - QList<TypeEntry *> template_args; + QVector<TypeEntry *> template_args; template_args.clear(); for (int i = 0; i < template_parameters.size(); ++i) { const TemplateParameterModelItem ¶m = template_parameters.at(i); @@ -1288,7 +1325,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem // Inner classes { const ClassList &innerClasses = classItem->classes(); - foreach (const ClassModelItem &ci, innerClasses) { + for (const ClassModelItem &ci : innerClasses) { AbstractMetaClass *cl = traverseClass(dom, ci); if (cl) { cl->setEnclosingClass(metaClass); @@ -1302,7 +1339,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. const TypeDefList typeDefs = classItem->typeDefs(); - foreach (const TypeDefModelItem &typeDef, typeDefs) { + for (const TypeDefModelItem &typeDef : typeDefs) { AbstractMetaClass *cls = traverseTypeDef(dom, typeDef); if (cls) { cls->setEnclosingClass(metaClass); @@ -1329,7 +1366,7 @@ void AbstractMetaBuilderPrivate::traverseScopeMembers(ScopeModelItem item, // Inner classes const ClassList &innerClasses = item->classes(); - foreach (const ClassModelItem& ci, innerClasses) + for (const ClassModelItem& ci : innerClasses) traverseClassMembers(ci); } @@ -1380,7 +1417,7 @@ void AbstractMetaBuilderPrivate::traverseNamespaceMembers(NamespaceModelItem ite // Inner namespaces const QSet<NamespaceModelItem> &innerNamespaces = item->uniqueNamespaces(); - foreach (const NamespaceModelItem &ni, innerNamespaces) + for (const NamespaceModelItem &ni : innerNamespaces) traverseNamespaceMembers(ni); m_currentClass = oldCurrentClass; @@ -1410,8 +1447,9 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(VariableModelItem f if (field->accessPolicy() == CodeModel::Private) return 0; - if (TypeDatabase::instance()->isFieldRejected(className, fieldName)) { - m_rejectedFields.insert(qualifiedFieldSignatureWithType(className, field), + QString rejectReason; + if (TypeDatabase::instance()->isFieldRejected(className, fieldName, &rejectReason)) { + m_rejectedFields.insert(qualifiedFieldSignatureWithType(className, field) + rejectReason, AbstractMetaBuilder::GenerationDisabled); return 0; } @@ -1455,7 +1493,8 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(VariableModelItem f void AbstractMetaBuilderPrivate::traverseFields(ScopeModelItem scope_item, AbstractMetaClass *metaClass) { - foreach (const VariableModelItem &field, scope_item->variables()) { + const VariableList &variables = scope_item->variables(); + for (const VariableModelItem &field : variables) { AbstractMetaField* metaField = traverseField(field, metaClass); if (metaField && !metaField->isModifiedRemoved()) { @@ -1491,7 +1530,9 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF return; TypeDatabase* types = TypeDatabase::instance(); - QString castTo = metaFunction->name().remove(QRegExp(QLatin1String("^operator "))).trimmed(); + static const QRegularExpression operatorRegExp(QStringLiteral("^operator ")); + Q_ASSERT(operatorRegExp.isValid()); + QString castTo = metaFunction->name().remove(operatorRegExp).trimmed(); if (castTo.endsWith(QLatin1Char('&'))) castTo.chop(1); @@ -1542,7 +1583,7 @@ static bool _compareAbstractMetaFunctions(const AbstractMetaFunction* func, cons // "QList(const QList &)" to "QList(const QList<T> &)". static bool _fixFunctionModelItemTypes(FunctionModelItem& function, const AbstractMetaClass* metaClass) { - const QList<TypeEntry *> &templateTypes = metaClass->templateArguments(); + const QVector<TypeEntry *> &templateTypes = metaClass->templateArguments(); if (templateTypes.isEmpty()) return false; @@ -1577,14 +1618,18 @@ static bool _fixFunctionModelItemTypes(FunctionModelItem& function, const Abstra return templateTypeFixed; } -AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem) +AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem, + bool *constructorRejected) { + *constructorRejected = false; AbstractMetaFunctionList result; const FunctionList &scopeFunctionList = scopeItem->functions(); result.reserve(scopeFunctionList.size()); - foreach (const FunctionModelItem &function, scopeItem->functions()) { + for (const FunctionModelItem &function : scopeFunctionList) { if (AbstractMetaFunction *metaFunction = traverseFunction(function)) result.append(metaFunction); + else if (function->functionType() == CodeModel::Constructor) + *constructorRejected = true; } return result; } @@ -1613,15 +1658,17 @@ private: }; AbstractMetaFunctionList AbstractMetaBuilderPrivate::templateClassFunctionList(const ScopeModelItem &scopeItem, - AbstractMetaClass *metaClass) + AbstractMetaClass *metaClass, + bool *constructorRejected) { AbstractMetaFunctionList result; AbstractMetaFunctionList unchangedFunctions; + *constructorRejected = false; const FunctionList &scopeFunctionList = scopeItem->functions(); result.reserve(scopeFunctionList.size()); unchangedFunctions.reserve(scopeFunctionList.size()); - foreach (FunctionModelItem function, scopeItem->functions()) { + for (FunctionModelItem function : scopeFunctionList) { // This fixes method's arguments and return types that are templates // but the template variable wasn't declared in the C++ header. const bool templateTypeFixed =_fixFunctionModelItemTypes(function, metaClass); @@ -1629,6 +1676,8 @@ AbstractMetaFunctionList AbstractMetaBuilderPrivate::templateClassFunctionList(c result.append(metaFunction); if (!templateTypeFixed) unchangedFunctions.append(metaFunction); + } else if (function->functionType() == CodeModel::Constructor) { + *constructorRejected = true; } } @@ -1647,12 +1696,15 @@ AbstractMetaFunctionList AbstractMetaBuilderPrivate::templateClassFunctionList(c void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, AbstractMetaClass *metaClass) { - + bool constructorRejected = false; const AbstractMetaFunctionList functions = metaClass->templateArguments().isEmpty() - ? classFunctionList(scopeItem) - : templateClassFunctionList(scopeItem, metaClass); + ? classFunctionList(scopeItem, &constructorRejected) + : templateClassFunctionList(scopeItem, metaClass, &constructorRejected); - foreach (AbstractMetaFunction *metaFunction, functions) { + if (constructorRejected) + *metaClass += AbstractMetaAttributes::HasRejectedConstructor; + + for (AbstractMetaFunction *metaFunction : functions){ metaFunction->setOriginalAttributes(metaFunction->attributes()); if (metaClass->isNamespace()) *metaFunction += AbstractMetaAttributes::Static; @@ -1681,8 +1733,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, const bool isInvalidDestructor = metaFunction->isDestructor() && metaFunction->isPrivate(); const bool isInvalidConstructor = metaFunction->isConstructor() - && ((metaFunction->isPrivate() && metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction) - || metaFunction->isInvalid()); + && (metaFunction->isPrivate() && metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction); if ((isInvalidDestructor || isInvalidConstructor) && !metaClass->hasNonPrivateConstructor()) { *metaClass += AbstractMetaAttributes::Final; @@ -1697,7 +1748,6 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, metaClass->setForceShellClass(true); if (!metaFunction->isDestructor() - && !metaFunction->isInvalid() && !(metaFunction->isPrivate() && metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction)) { setupFunctionDefaults(metaFunction, metaClass); @@ -1736,15 +1786,16 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass) { // Add the functions added by the typesystem - foreach (const AddedFunction &addedFunc, metaClass->typeEntry()->addedFunctions()) + const AddedFunctionList &addedFunctions = metaClass->typeEntry()->addedFunctions(); + for (const AddedFunction &addedFunc : addedFunctions) traverseFunction(addedFunc, metaClass); } void AbstractMetaBuilderPrivate::applyFunctionModifications(AbstractMetaFunction *func) { - FunctionModificationList mods = func->modifications(func->implementingClass()); + const FunctionModificationList &mods = func->modifications(func->implementingClass()); AbstractMetaFunction& funcRef = *func; - foreach (const FunctionModification &mod, mods) { + for (const FunctionModification &mod : mods) { if (mod.isRenameModifier()) { func->setOriginalName(func->name()); func->setName(mod.renamedTo()); @@ -1866,8 +1917,8 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass) } metaClass->addInterface(iface); - AbstractMetaClassList interfaces = iface->interfaces(); - foreach (AbstractMetaClass* iface, interfaces) + const AbstractMetaClassList &interfaces = iface->interfaces(); + for (AbstractMetaClass* iface : interfaces) metaClass->addInterface(iface); } } @@ -1879,8 +1930,8 @@ void AbstractMetaBuilderPrivate::traverseEnums(ScopeModelItem scopeItem, AbstractMetaClass *metaClass, const QStringList &enumsDeclarations) { - EnumList enums = scopeItem->enums(); - foreach (const EnumModelItem &enumItem, enums) { + const EnumList &enums = scopeItem->enums(); + for (const EnumModelItem &enumItem : enums) { AbstractMetaEnum* metaEnum = traverseEnum(enumItem, metaClass, QSet<QString>::fromList(enumsDeclarations)); if (metaEnum) { metaClass->addEnum(metaEnum); @@ -1911,7 +1962,7 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu metaFunction->setType(translateType(addedFunc.version(), addedFunc.returnType())); - QList<AddedFunction::TypeInfo> args = addedFunc.arguments(); + QVector<AddedFunction::TypeInfo> args = addedFunc.arguments(); AbstractMetaArgumentList metaArguments; for (int i = 0; i < args.count(); ++i) { @@ -1969,7 +2020,8 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu } metaFunction->setOriginalAttributes(metaFunction->attributes()); - fixArgumentNames(metaFunction); + if (!metaArguments.isEmpty()) + fixArgumentNames(metaFunction, metaFunction->modifications(m_currentClass)); if (metaClass) { const AbstractMetaArgumentList fargs = metaFunction->arguments(); @@ -1997,12 +2049,10 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu return metaFunction; } -void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func) +void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods) { - if (func->arguments().isEmpty()) - return; - foreach (const FunctionModification &mod, func->modifications(m_currentClass)) { - foreach (const ArgumentModification &argMod, mod.argument_mods) { + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argMod : mod.argument_mods) { if (!argMod.renamed_to.isEmpty()) { AbstractMetaArgument* arg = func->arguments().at(argMod.index - 1); arg->setOriginalName(arg->name()); @@ -2011,62 +2061,158 @@ void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func) } } - int i = 1; - foreach (AbstractMetaArgument* arg, func->arguments()) { - if (arg->name().isEmpty()) - arg->setName(QLatin1String("arg__") + QString::number(i), false); - ++i; + AbstractMetaArgumentList arguments = func->arguments(); + for (int i = 0, size = arguments.size(); i < size; ++i) { + if (arguments.at(i)->name().isEmpty()) + arguments[i]->setName(QLatin1String("arg__") + QString::number(i + 1), false); } } static QString functionSignature(FunctionModelItem functionItem) { QStringList args; - foreach (const ArgumentModelItem &arg, functionItem->arguments()) + const ArgumentList &arguments = functionItem->arguments(); + for (const ArgumentModelItem &arg : arguments) args << arg->type().toString(); return functionItem->name() + QLatin1Char('(') + args.join(QLatin1Char(',')) + QLatin1Char(')'); } -static inline QString functionSignatureWithReturnType(FunctionModelItem functionItem) +static inline QString qualifiedFunctionSignatureWithType(const FunctionModelItem &functionItem, + const QString &className = QString()) +{ + QString result = functionItem->type().toString() + QLatin1Char(' '); + if (!className.isEmpty()) + result += className + colonColon(); + result += functionSignature(functionItem); + return result; +} + +static inline QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n) { - return functionSignature(functionItem) - + QStringLiteral(" -> ") + functionItem->type().toString(); + QString result; + QTextStream str(&result); + str << "unmatched type '" << arg->type().toString() << "' in parameter #" + << (n + 1); + if (!arg->name().isEmpty()) + str << " \"" << arg->name() << '"'; + return result; } -static inline QString qualifiedFunctionSignatureWithType(const QString &className, - FunctionModelItem functionItem) +static inline QString msgVoidParameterType(const ArgumentModelItem &arg, int n) { - return className + colonColon() + functionSignatureWithReturnType(functionItem); + QString result; + QTextStream str(&result); + str << "'void' encountered at parameter #" << (n + 1); + if (!arg->name().isEmpty()) + str << " \"" << arg->name() << '"'; + return result; +} + +static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeModel::FunctionType ft) +{ + AbstractMetaFunction::FunctionType result = AbstractMetaFunction::NormalFunction; + switch (ft) { + case CodeModel::Constructor: + result = AbstractMetaFunction::ConstructorFunction; + break; + case CodeModel::CopyConstructor: + result = AbstractMetaFunction::CopyConstructorFunction; + break; + case CodeModel::MoveConstructor: + result = AbstractMetaFunction::MoveConstructorFunction; + break; + case CodeModel::Destructor: + result = AbstractMetaFunction::DestructorFunction; + break; + case CodeModel::Normal: + break; + case CodeModel::Signal: + result = AbstractMetaFunction::SignalFunction; + break; + case CodeModel::Slot: + result = AbstractMetaFunction::SlotFunction; + break; + } + return result; +} + +static inline QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason) +{ + return function + QLatin1String(": Cannot use parameter ") + QString::number(i + 1) + + QLatin1String(" as an array: ") + reason; +} + +bool AbstractMetaBuilderPrivate::setArrayArgumentType(AbstractMetaFunction *func, + const FunctionModelItem &functionItem, + int i) +{ + if (i < 0 || i >= func->arguments().size()) { + qCWarning(lcShiboken).noquote() + << msgCannotSetArrayUsage(func->minimalSignature(), i, + QLatin1String("Index out of range.")); + return false; + } + AbstractMetaType *metaType = func->arguments().at(i)->type(); + if (metaType->indirections() == 0) { + qCWarning(lcShiboken).noquote() + << msgCannotSetArrayUsage(func->minimalSignature(), i, + QLatin1String("Type does not have indirections.")); + return false; + } + TypeInfo elementType = functionItem->arguments().at(i)->type(); + elementType.setIndirections(elementType.indirections() - 1); + bool ok; + AbstractMetaType *element = translateType(elementType, &ok); + if (element == nullptr || !ok) { + qCWarning(lcShiboken).noquote() + << msgCannotSetArrayUsage(func->minimalSignature(), i, + QLatin1String("Cannot translate element type ") + elementType.toString()); + return false; + } + metaType->setArrayElementType(element); + metaType->setTypeUsagePattern(AbstractMetaType::NativePointerAsArrayPattern); + return true; } AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModelItem functionItem) { + if (!functionItem->templateParameters().isEmpty()) + return nullptr; QString functionName = functionItem->name(); QString className; - QString rejectedFunctionSignature; - if (m_currentClass) + if (m_currentClass) { + // Clang: Skip qt_metacast(), qt_metacall(), expanded from Q_OBJECT + // and overridden metaObject(), QGADGET helpers + if (functionName == QLatin1String("qt_check_for_QGADGET_macro") + || functionName.startsWith(QLatin1String("qt_meta"))) { + return nullptr; + } className = m_currentClass->typeEntry()->qualifiedCppName(); + if (functionName == QLatin1String("metaObject") && className != QLatin1String("QObject")) + return nullptr; + } + + // Store original signature with unresolved typedefs for message/log purposes + const QString originalQualifiedSignatureWithReturn = + qualifiedFunctionSignatureWithType(functionItem, className); - if (TypeDatabase::instance()->isFunctionRejected(className, functionName)) { - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); - m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::GenerationDisabled); + QString rejectReason; + if (TypeDatabase::instance()->isFunctionRejected(className, functionName, &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); return 0; } else if (TypeDatabase::instance()->isFunctionRejected(className, - functionSignature(functionItem))) { - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); - m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::GenerationDisabled); + functionSignature(functionItem), &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); return 0; } - Q_ASSERT(functionItem->functionType() == CodeModel::Normal - || functionItem->functionType() == CodeModel::Signal - || functionItem->functionType() == CodeModel::Slot); - if (functionItem->isFriend()) return 0; AbstractMetaFunction *metaFunction = q->createMetaFunction(); + // Additional check for assignment/move assignment down below + metaFunction->setFunctionType(functionTypeFromCodeModel(functionItem->functionType())); metaFunction->setConstant(functionItem->isConstant()); if (ReportHandler::isDebug(ReportHandler::MediumDebug)) @@ -2100,43 +2246,39 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel else *metaFunction += AbstractMetaAttributes::Protected; - - QString strippedClassName = className; - int cc_pos = strippedClassName.lastIndexOf(colonColon()); - if (cc_pos > 0) - strippedClassName = strippedClassName.mid(cc_pos + 2); - - TypeInfo functionType = functionItem->type(); - if (functionName.startsWith(QLatin1Char('~'))) { - metaFunction->setFunctionType(AbstractMetaFunction::DestructorFunction); - metaFunction->setInvalid(true); - } else if (stripTemplateArgs(functionName) == strippedClassName) { - metaFunction->setFunctionType(AbstractMetaFunction::ConstructorFunction); - // Check for Copy/Move down below + switch (metaFunction->functionType()) { + case AbstractMetaFunction::DestructorFunction: + break; + case AbstractMetaFunction::ConstructorFunction: metaFunction->setExplicit(functionItem->isExplicit()); metaFunction->setName(m_currentClass->name()); - } else { + break; + default: { + TypeInfo returnType = functionItem->type(); + + if (TypeDatabase::instance()->isReturnTypeRejected(className, returnType.toString(), &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); + delete metaFunction; + return nullptr; + } + bool ok; - AbstractMetaType* type = translateType(functionType, &ok); + AbstractMetaType *type = translateType(returnType, &ok); if (!ok) { Q_ASSERT(type == 0); qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("skipping function '%1::%2', unmatched return type '%3'") - .arg(className, functionItem->name(), + << QStringLiteral("skipping function '%1', unmatched return type '%2'") + .arg(originalQualifiedSignatureWithReturn, functionItem->type().toString()); - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); - m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedReturnType); - metaFunction->setInvalid(true); - return metaFunction; + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType); + delete metaFunction; + return nullptr; } metaFunction->setType(type); - - if (functionItem->functionType() == CodeModel::Signal) - metaFunction->setFunctionType(AbstractMetaFunction::SignalFunction); - else if (functionItem->functionType() == CodeModel::Slot) - metaFunction->setFunctionType(AbstractMetaFunction::SlotFunction); + } + break; } ArgumentList arguments = functionItem->arguments(); @@ -2153,29 +2295,37 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel for (int i = 0; i < arguments.size(); ++i) { ArgumentModelItem arg = arguments.at(i); + if (TypeDatabase::instance()->isArgumentTypeRejected(className, arg->type().toString(), &rejectReason)) { + m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); + delete metaFunction; + return nullptr; + } + bool ok; AbstractMetaType* metaType = translateType(arg->type(), &ok); if (!ok) { Q_ASSERT(metaType == 0); + const QString reason = msgUnmatchedParameterType(arg, i); qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("skipping function '%1::%2', unmatched parameter type '%3'") - .arg(className, functionItem->name(), arg->type().toString()); - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); + << QStringLiteral("skipping function '%1', %2") + .arg(originalQualifiedSignatureWithReturn, reason); + const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn + + QLatin1String(": ") + reason; m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType); - metaFunction->setInvalid(true); - return metaFunction; + delete metaFunction; + return nullptr; } if (metaType == Q_NULLPTR) { + const QString reason = msgVoidParameterType(arg, i); qCWarning(lcShiboken).noquote().nospace() - << QString::fromLatin1("skipping function '%1::%2', 'void' encountered at parameter " - "position %3, but it can only be the the first and only " - "parameter") - .arg(className, functionItem->name()).arg(i); - rejectedFunctionSignature = qualifiedFunctionSignatureWithType(className, functionItem); + << QString::fromLatin1("skipping function '%1': %2") + .arg(originalQualifiedSignatureWithReturn, reason); + const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn + + QLatin1String(": ") + reason; m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType); - metaFunction->setInvalid(true); - return metaFunction; + delete metaFunction; + return nullptr; } AbstractMetaArgument *metaArgument = q->createMetaArgument(); @@ -2200,7 +2350,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel } else { FunctionModificationList mods = TypeDatabase::instance()->functionModifications(metaFunction->minimalSignature()); if (!mods.isEmpty()) { - QList<ArgumentModification> argMods = mods.first().argument_mods; + QVector<ArgumentModification> argMods = mods.first().argument_mods; if (!argMods.isEmpty()) replacedExpression = argMods.first().replacedDefaultExpression; } @@ -2238,26 +2388,22 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel } - fixArgumentNames(metaFunction); + if (!metaArguments.isEmpty()) { + const FunctionModificationList &mods = metaFunction->modifications(m_currentClass); + fixArgumentNames(metaFunction, mods); + for (const FunctionModification &mod : mods) { + for (const ArgumentModification &argMod : mod.argument_mods) { + if (argMod.array) + setArrayArgumentType(metaFunction, functionItem, argMod.index - 1); + } + } + } // Determine class special functions if (m_currentClass && metaFunction->arguments().size() == 1) { const AbstractMetaType *argType = metaFunction->arguments().first()->type(); if (argType->typeEntry() == m_currentClass->typeEntry() && argType->indirections() == 0) { - if (metaFunction->isConstructor()) { - switch (argType->referenceType()) { - case NoReference: - metaFunction->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); - break; - case LValueReference: - if (argType->isConstant()) - metaFunction->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); - break; - case RValueReference: - metaFunction->setFunctionType(AbstractMetaFunction::MoveConstructorFunction); - break; - } - } else if (metaFunction->name() == QLatin1String("operator=")) { + if (metaFunction->name() == QLatin1String("operator=")) { switch (argType->referenceType()) { case NoReference: metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction); @@ -2320,7 +2466,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(double vr, msg += QLatin1String("Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n"); candidates.sort(); - foreach (const QString& candidate, candidates) { + for (const QString& candidate : qAsConst(candidates)) { msg += QLatin1String(" ") + candidate + QLatin1Char('\n'); } qFatal(qPrintable(msg), NULL); @@ -2333,7 +2479,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(double vr, metaType->setReferenceType(LValueReference); metaType->setConstant(typeInfo.isConstant); if (isTemplate) { - foreach (const QString& templateArg, templateArgs) { + for (const QString& templateArg : qAsConst(templateArgs)) { AbstractMetaType* metaArgType = translateType(vr, AddedFunction::TypeInfo::fromSignature(templateArg)); metaType->addInstantiation(metaArgType); } @@ -2403,45 +2549,57 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ return 0; } - // 2. Handle pointers specified as arrays with unspecified size - bool arrayOfUnspecifiedSize = false; - if (typeInfo.arrays.size() > 0) { - arrayOfUnspecifiedSize = true; - for (int i = 0; i < typeInfo.arrays.size(); ++i) - arrayOfUnspecifiedSize = arrayOfUnspecifiedSize && typeInfo.arrays.at(i).isEmpty(); - - if (!arrayOfUnspecifiedSize) { - TypeInfo newInfo; - //newInfo.setArguments(typei.arguments()); - newInfo.setIndirections(typei.indirections()); - newInfo.setConstant(typei.isConstant()); - newInfo.setFunctionPointer(typei.isFunctionPointer()); - newInfo.setQualifiedName(typei.qualifiedName()); - newInfo.setReferenceType(typei.referenceType()); - newInfo.setVolatile(typei.isVolatile()); - - AbstractMetaType* elementType = translateType(newInfo, ok); - if (!(*ok)) - return 0; + // 2. Handle arrays. + // 2.1 Handle char arrays with unspecified size (aka "const char[]") as "const char*" with + // NativePointerPattern usage. + bool oneDimensionalArrayOfUnspecifiedSize = + typeInfo.arrays.size() == 1 + && typeInfo.arrays[0].isEmpty(); + + bool isConstCharStarCase = + oneDimensionalArrayOfUnspecifiedSize + && typeInfo.qualified_name.size() == 1 + && typeInfo.qualified_name[0] == QStringLiteral("char") + && typeInfo.indirections == 0 + && typeInfo.is_constant == 1 + && typeInfo.is_busted == 0 + && typeInfo.referenceType == NoReference + && typeInfo.template_instantiations.size() == 0; + + if (isConstCharStarCase) + typeInfo.indirections += typeInfo.arrays.size(); + + // 2.2 Handle regular arrays. + if (typeInfo.arrays.size() > 0 && !isConstCharStarCase) { + TypeInfo newInfo; + //newInfo.setArguments(typei.arguments()); + newInfo.setIndirections(typei.indirections()); + newInfo.setConstant(typei.isConstant()); + newInfo.setFunctionPointer(typei.isFunctionPointer()); + newInfo.setQualifiedName(typei.qualifiedName()); + newInfo.setReferenceType(typei.referenceType()); + newInfo.setVolatile(typei.isVolatile()); + + AbstractMetaType* elementType = translateType(newInfo, ok); + if (!(*ok)) + return 0; - for (int i = typeInfo.arrays.size() - 1; i >= 0; --i) { - QString s = typeInfo.arrays.at(i); + for (int i = typeInfo.arrays.size() - 1; i >= 0; --i) { + AbstractMetaType *arrayType = q->createMetaType(); + arrayType->setArrayElementType(elementType); + if (!typeInfo.arrays.at(i).isEmpty()) { bool _ok; - int elems = findOutValueFromString(s, _ok); - - AbstractMetaType *arrayType = q->createMetaType(); - arrayType->setArrayElementCount(elems); - arrayType->setArrayElementType(elementType); - arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry() , elementType->typeEntry()->version())); - decideUsagePattern(arrayType); - - elementType = arrayType; + const int elems = findOutValueFromString(typeInfo.arrays.at(i), _ok); + if (_ok) + arrayType->setArrayElementCount(elems); } + arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry() , elementType->typeEntry()->version())); + decideUsagePattern(arrayType); - return elementType; - } else { - typeInfo.indirections += typeInfo.arrays.size(); + elementType = arrayType; } + + return elementType; } QStringList qualifierList = typeInfo.qualified_name; @@ -2472,7 +2630,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ // 5.1.1 - Try using the class parents' scopes if (!type && !m_currentClass->baseClassNames().isEmpty()) { - foreach (const AbstractMetaClass* cls, getBaseClasses(m_currentClass)) { + const AbstractMetaClassList &baseClasses = getBaseClasses(m_currentClass); + for (const AbstractMetaClass *cls : baseClasses) { type = findTypeEntryUsingContext(cls, qualifiedName); if (type) break; @@ -2495,8 +2654,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ // 8. No? Check if the current class is a template and this type is one // of the parameters. if (!type && m_currentClass) { - QList<TypeEntry *> template_args = m_currentClass->templateArguments(); - foreach (TypeEntry *te, template_args) { + const QVector<TypeEntry *> &template_args = m_currentClass->templateArguments(); + for (TypeEntry *te : template_args) { if (te->name() == qualifiedName) type = te; } @@ -2544,7 +2703,7 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ metaType->setConstant(typeInfo.is_constant); metaType->setOriginalTypeDescription(_typei.toString()); - foreach (const TypeParser::Info &ta, typeInfo.template_instantiations) { + for (const TypeParser::Info &ta : qAsConst(typeInfo.template_instantiations)) { TypeInfo info; info.setConstant(ta.is_constant); info.setReferenceType(ta.referenceType); @@ -2585,8 +2744,9 @@ int AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValu // This is a very lame way to handle expression evaluation, // but it is not critical and will do for the time being. - static QRegExp variableNameRegExp(QLatin1String("^[a-zA-Z_][a-zA-Z0-9_]*$")); - if (!variableNameRegExp.exactMatch(stringValue)) { + static const QRegularExpression variableNameRegExp(QStringLiteral("^[a-zA-Z_][a-zA-Z0-9_]*$")); + Q_ASSERT(variableNameRegExp.isValid()); + if (!variableNameRegExp.match(stringValue).hasMatch()) { ok = true; return 0; } @@ -2597,8 +2757,9 @@ int AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValu return enumValue->value(); } - foreach (AbstractMetaEnum* metaEnum, m_globalEnums) { - foreach (AbstractMetaEnumValue* ev, metaEnum->values()) { + for (AbstractMetaEnum *metaEnum : qAsConst(m_globalEnums)) { + const AbstractMetaEnumValueList &values = metaEnum->values(); + for (const AbstractMetaEnumValue *ev : values) { if (ev->name() == stringValue) { ok = true; return ev->value(); @@ -2647,23 +2808,28 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(ArgumentModelItem item, if (!isNumber && expr.indexOf(colonColon()) < 0) { // Add the enum/flag scope to default value, making it usable // from other contexts beside its owner class hierarchy - QRegExp typeRegEx(QLatin1String("[^<]*[<]([^:]*::).*")); - typeRegEx.indexIn(type->minimalSignature()); - expr = typeRegEx.cap(1) + expr; + static const QRegularExpression typeRegEx(QStringLiteral("[^<]*[<]([^:]*::).*")); + Q_ASSERT(typeRegEx.isValid()); + const QRegularExpressionMatch match = typeRegEx.match(type->minimalSignature()); + if (match.hasMatch()) + expr.prepend(match.captured(1)); } } else if (type->isContainer() && expr.contains(QLatin1Char('<'))) { - QRegExp typeRegEx(QLatin1String("[^<]*<(.*)>")); - typeRegEx.indexIn(type->minimalSignature()); - QRegExp defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)")); - defaultRegEx.indexIn(expr); - expr = defaultRegEx.cap(1) + typeRegEx.cap(1) + defaultRegEx.cap(2); + static const QRegularExpression typeRegEx(QStringLiteral("[^<]*<(.*)>")); + Q_ASSERT(typeRegEx.isValid()); + const QRegularExpressionMatch typeMatch = typeRegEx.match(type->minimalSignature()); + static const QRegularExpression defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)")); + Q_ASSERT(defaultRegEx.isValid()); + const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr); + if (typeMatch.hasMatch() && defaultMatch.hasMatch()) + expr = defaultMatch.captured(1) + typeMatch.captured(1) + defaultMatch.captured(2); } else { // Here the default value is supposed to be a constructor, // a class field, or a constructor receiving a class field - QRegExp defaultRegEx(QLatin1String("([^\\(]*\\(|)([^\\)]*)(\\)|)")); - defaultRegEx.indexIn(expr); - - QString defaultValueCtorName = defaultRegEx.cap(1); + static const QRegularExpression defaultRegEx(QStringLiteral("([^\\(]*\\(|)([^\\)]*)(\\)|)")); + Q_ASSERT(defaultRegEx.isValid()); + const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr); + QString defaultValueCtorName = defaultMatch.hasMatch() ? defaultMatch.captured(1) : QString(); if (defaultValueCtorName.endsWith(QLatin1Char('('))) defaultValueCtorName.chop(1); @@ -2671,20 +2837,22 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(ArgumentModelItem item, // resolved argument type as a reference. // The following regular expression extracts any // use of namespaces/scopes from the type string. - QRegExp typeRegEx(QLatin1String("^(?:const[\\s]+|)([\\w:]*::|)([A-Za-z_]\\w*)\\s*[&\\*]?$")); - typeRegEx.indexIn(type->minimalSignature()); + static const QRegularExpression typeRegEx(QLatin1String("^(?:const[\\s]+|)([\\w:]*::|)([A-Za-z_]\\w*)\\s*[&\\*]?$")); + Q_ASSERT(typeRegEx.isValid()); + const QRegularExpressionMatch typeMatch = typeRegEx.match(type->minimalSignature()); - QString typeNamespace = typeRegEx.cap(1); - QString typeCtorName = typeRegEx.cap(2); + QString typeNamespace = typeMatch.hasMatch() ? typeMatch.captured(1) : QString(); + QString typeCtorName = typeMatch.hasMatch() ? typeMatch.captured(2) : QString(); if (!typeNamespace.isEmpty() && defaultValueCtorName == typeCtorName) expr.prepend(typeNamespace); // Fix scope if the parameter is a field of the current class if (implementingClass) { - foreach (const AbstractMetaField* field, implementingClass->fields()) { - if (defaultRegEx.cap(2) == field->name()) { - expr = defaultRegEx.cap(1) + implementingClass->name() - + colonColon() + defaultRegEx.cap(2) + defaultRegEx.cap(3); + const AbstractMetaFieldList &fields = implementingClass->fields(); + for (const AbstractMetaField *field : fields) { + if (defaultMatch.hasMatch() && defaultMatch.captured(2) == field->name()) { + expr = defaultMatch.captured(1) + implementingClass->name() + + colonColon() + defaultMatch.captured(2) + defaultMatch.captured(3); break; } } @@ -2717,19 +2885,19 @@ bool AbstractMetaBuilderPrivate::isQObject(const FileModelItem &dom, const QStri classItem = ns->findClass(names.at(names.size() - 1)); } - bool isqobject = classItem && classItem->extendsClass(QLatin1String("QObject")); + if (classItem == nullptr) + return false; - if (classItem && !isqobject) { - QStringList baseClasses = classItem->baseClasses(); - for (int i = 0; i < baseClasses.count(); ++i) { + if (classItem->extendsClass(QLatin1String("QObject"))) + return true; - isqobject = isQObject(dom, baseClasses.at(i)); - if (isqobject) - break; - } + const QVector<_ClassModelItem::BaseClass> &baseClasses = classItem->baseClasses(); + for (const _ClassModelItem::BaseClass &baseClass : baseClasses) { + if (isQObject(dom, baseClass.name)) + return true; } - return isqobject; + return false; } @@ -2766,7 +2934,7 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString & QString qualifiedName = info->qualified_name.join(colonColon()); AbstractMetaClass* templ = 0; - foreach (AbstractMetaClass *c, m_templates) { + for (AbstractMetaClass *c : qAsConst(m_templates)) { if (c->typeEntry()->name() == qualifiedName) { templ = c; break; @@ -2789,7 +2957,8 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString & AbstractMetaClassList AbstractMetaBuilderPrivate::getBaseClasses(const AbstractMetaClass *metaClass) const { AbstractMetaClassList baseClasses; - foreach (const QString& parent, metaClass->baseClassNames()) { + const QStringList &baseClassNames = metaClass->baseClassNames(); + for (const QString& parent : baseClassNames) { AbstractMetaClass* cls = 0; if (parent.contains(QLatin1Char('<'))) cls = findTemplateClass(parent, metaClass); @@ -2806,14 +2975,15 @@ bool AbstractMetaBuilderPrivate::ancestorHasPrivateCopyConstructor(const Abstrac { if (metaClass->hasPrivateCopyConstructor()) return true; - foreach (const AbstractMetaClass* cls, getBaseClasses(metaClass)) { + const AbstractMetaClassList &baseClasses = getBaseClasses(metaClass); + for (const AbstractMetaClass *cls : baseClasses) { if (ancestorHasPrivateCopyConstructor(cls)) return true; } return false; } -AbstractMetaType* AbstractMetaBuilderPrivate::inheritTemplateType(const QList<AbstractMetaType *> &templateTypes, +AbstractMetaType* AbstractMetaBuilderPrivate::inheritTemplateType(const QVector<AbstractMetaType *> &templateTypes, const AbstractMetaType *metaType, bool *ok) { @@ -2865,8 +3035,8 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, const AbstractMetaClass *templateClass, const TypeParser::Info &info) { - QList<TypeParser::Info> targs = info.template_instantiations; - QList<AbstractMetaType*> templateTypes; + QVector<TypeParser::Info> targs = info.template_instantiations; + QVector<AbstractMetaType *> templateTypes; if (subclass->isTypeDef()) { subclass->setHasCloneOperator(templateClass->hasCloneOperator()); @@ -2878,7 +3048,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, subclass->setHasVirtualDestructor(templateClass->hasVirtualDestructor()); } - foreach (const TypeParser::Info &i, targs) { + for (const TypeParser::Info &i : qAsConst(targs)) { QString typeName = i.qualified_name.join(colonColon()); QStringList possibleNames; possibleNames << subclass->qualifiedCppName() + colonColon() + typeName; @@ -2890,7 +3060,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, TypeDatabase* typeDb = TypeDatabase::instance(); TypeEntry* t = 0; QString templateParamName; - foreach (const QString &possibleName, possibleNames) { + for (const QString &possibleName : qAsConst(possibleNames)) { t = typeDb->findType(possibleName); if (t) { QString templateParamName = possibleName; @@ -2914,7 +3084,8 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, } AbstractMetaFunctionList funcs = subclass->functions(); - foreach (const AbstractMetaFunction* function, templateClass->functions()) { + const AbstractMetaFunctionList &templateClassFunctions = templateClass->functions(); + for (const AbstractMetaFunction *function : templateClassFunctions) { if (function->isModifiedRemoved(TypeSystem::All)) continue; @@ -2929,7 +3100,8 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, continue; } - foreach (AbstractMetaArgument* argument, function->arguments()) { + const AbstractMetaArgumentList &arguments = function->arguments(); + for (AbstractMetaArgument *argument : arguments) { AbstractMetaType* atype = argument->type(); AbstractMetaArgument *arg = argument->copy(); @@ -2980,7 +3152,7 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, FunctionModificationList mods = function->modifications(templateClass); for (int i = 0; i < mods.size(); ++i) { FunctionModification mod = mods.at(i); - mod.signature = f->minimalSignature(); + mod.setSignature(f->minimalSignature()); // If we ever need it... Below is the code to do // substitution of the template instantation type inside @@ -3068,7 +3240,7 @@ static AbstractMetaFunction* findCopyCtor(AbstractMetaClass* cls) AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::Invisible); functions << cls->queryFunctions(AbstractMetaClass::Visible); - foreach (AbstractMetaFunction* f, functions) { + for (AbstractMetaFunction *f : qAsConst(functions)) { const AbstractMetaFunction::FunctionType t = f->functionType(); if (t == AbstractMetaFunction::CopyConstructorFunction || t == AbstractMetaFunction::AssignmentOperatorFunction) return f; @@ -3088,11 +3260,11 @@ void AbstractMetaBuilderPrivate::setupClonable(AbstractMetaClass *cls) QQueue<AbstractMetaClass*> baseClasses; if (cls->baseClass()) baseClasses.enqueue(cls->baseClass()); - baseClasses << cls->interfaces(); + baseClasses << cls->interfaces().toList(); while (!baseClasses.isEmpty()) { AbstractMetaClass* currentClass = baseClasses.dequeue(); - baseClasses << currentClass->interfaces(); + baseClasses << currentClass->interfaces().toList(); if (currentClass->baseClass()) baseClasses.enqueue(currentClass->baseClass()); @@ -3108,8 +3280,8 @@ void AbstractMetaBuilderPrivate::setupClonable(AbstractMetaClass *cls) void AbstractMetaBuilderPrivate::setupExternalConversion(AbstractMetaClass *cls) { - AbstractMetaFunctionList convOps = cls->operatorOverloads(AbstractMetaClass::ConversionOp); - foreach (AbstractMetaFunction* func, convOps) { + const AbstractMetaFunctionList &convOps = cls->operatorOverloads(AbstractMetaClass::ConversionOp); + for (AbstractMetaFunction *func : convOps) { if (func->isModifiedRemoved()) continue; AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, func->type()->typeEntry()); @@ -3117,7 +3289,8 @@ void AbstractMetaBuilderPrivate::setupExternalConversion(AbstractMetaClass *cls) continue; metaClass->addExternalConversionOperator(func); } - foreach (AbstractMetaClass* innerClass, cls->innerClasses()) + const AbstractMetaClassList &innerClasses = cls->innerClasses(); + for (AbstractMetaClass *innerClass : innerClasses) setupExternalConversion(innerClass); } @@ -3197,7 +3370,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const const AbstractMetaClassList& classList = cppClass ? cppClass->innerClasses() : m_metaClasses; int i = 0; - foreach (AbstractMetaClass* clazz, classList) { + for (AbstractMetaClass *clazz : classList) { if (map.contains(clazz->qualifiedCppName())) continue; map[clazz->qualifiedCppName()] = i; @@ -3207,7 +3380,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const Graph graph(map.count()); - foreach (const Dependency &dep, additionalDependencies) { + for (const Dependency &dep : additionalDependencies) { const int parentIndex = map.value(dep.parent, -1); const int childIndex = map.value(dep.child, -1); if (parentIndex >= 0 && childIndex >= 0) { @@ -3220,14 +3393,16 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const } // TODO choose a better name to these regexs - QRegExp regex1(QLatin1String("\\(.*\\)")); - QRegExp regex2(QLatin1String("::.*")); - foreach (AbstractMetaClass* clazz, classList) { + static const QRegularExpression regex1(QStringLiteral("\\(.*\\)")); + Q_ASSERT(regex1.isValid()); + static const QRegularExpression regex2(QStringLiteral("::.*")); + Q_ASSERT(regex2.isValid()); + for (AbstractMetaClass *clazz : classList) { if (clazz->enclosingClass() && map.contains(clazz->enclosingClass()->qualifiedCppName())) graph.addEdge(map[clazz->enclosingClass()->qualifiedCppName()], map[clazz->qualifiedCppName()]); - AbstractMetaClassList bases = getBaseClasses(clazz); - foreach(AbstractMetaClass* baseClass, bases) { + const AbstractMetaClassList &bases = getBaseClasses(clazz); + for (AbstractMetaClass *baseClass : bases) { // Fix polymorphic expression if (clazz->baseClass() == baseClass) clazz->setBaseClass(baseClass); @@ -3236,8 +3411,10 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const graph.addEdge(map[baseClass->qualifiedCppName()], map[clazz->qualifiedCppName()]); } - foreach (AbstractMetaFunction* func, clazz->functions()) { - foreach (AbstractMetaArgument* arg, func->arguments()) { + const AbstractMetaFunctionList &functions = clazz->functions(); + for (AbstractMetaFunction *func : functions) { + const AbstractMetaArgumentList &arguments = func->arguments(); + for (AbstractMetaArgument *arg : arguments) { // check methods with default args QString defaultExpression = arg->originalDefaultValueExpression(); if (!defaultExpression.isEmpty()) { @@ -3251,7 +3428,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const QString exprClassName = clazz->qualifiedCppName() + colonColon() + defaultExpression; if (!map.contains(exprClassName)) { bool found = false; - foreach(AbstractMetaClass* baseClass, bases) { + for (AbstractMetaClass *baseClass : bases) { exprClassName = baseClass->qualifiedCppName() + colonColon() + defaultExpression; if (map.contains(exprClassName)) { found = true; @@ -3287,7 +3464,7 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const << "Cyclic dependency found! Graph can be found at " << QDir::toNativeSeparators(tempFile.fileName()); } else { - foreach (int i, unmappedResult) { + for (int i : qAsConst(unmappedResult)) { Q_ASSERT(reverseMap.contains(i)); if (!reverseMap[i]->isInterface()) result << reverseMap[i]; @@ -3308,7 +3485,7 @@ AbstractMetaArgumentList AbstractMetaBuilderPrivate::reverseList(const AbstractM AbstractMetaArgumentList ret; int index = list.size(); - foreach (AbstractMetaArgument* arg, list) { + for (AbstractMetaArgument *arg : list) { arg->setArgumentIndex(index); ret.prepend(arg); index--; |