aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp')
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp799
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 &param = 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--;