diff options
Diffstat (limited to 'src/tools/moc/generator.cpp')
-rw-r--r-- | src/tools/moc/generator.cpp | 138 |
1 files changed, 88 insertions, 50 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 7264b5bf66..c0e1dca748 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -194,7 +194,6 @@ static bool qualifiedNameEquals(const QByteArray &qualifiedName, const QByteArra void Generator::generateCode() { - bool isQt = (cdef->classname == "Qt"); bool isQObject = (cdef->classname == "QObject"); bool isConstructible = !cdef->constructorList.isEmpty(); @@ -237,7 +236,7 @@ void Generator::generateCode() // const int constCharArraySizeLimit = 65535; fprintf(out, "struct qt_meta_stringdata_%s_t {\n", qualifiedClassNameIdentifier.constData()); - fprintf(out, " QByteArrayData data[%d];\n", strings.size()); + fprintf(out, " const uint offsetsAndSize[%d];\n", strings.size()*2); { int stringDataLength = 0; int stringDataCounter = 0; @@ -260,11 +259,8 @@ void Generator::generateCode() // stringdata.stringdata member, and 2) the stringdata.data index of the // QByteArrayData being defined. This calculation relies on the // QByteArrayData::data() implementation returning simply "this + offset". - fprintf(out, "#define QT_MOC_LITERAL(idx, ofs, len) \\\n" - " Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \\\n" - " qptrdiff(offsetof(qt_meta_stringdata_%s_t, stringdata0) + ofs \\\n" - " - idx * sizeof(QByteArrayData)) \\\n" - " )\n", + fprintf(out, "#define QT_MOC_LITERAL(ofs, len) \\\n" + " uint(offsetof(qt_meta_stringdata_%s_t, stringdata0) + ofs), len \n", qualifiedClassNameIdentifier.constData()); fprintf(out, "static const qt_meta_stringdata_%s_t qt_meta_stringdata_%s = {\n", @@ -274,7 +270,7 @@ void Generator::generateCode() int idx = 0; for (int i = 0; i < strings.size(); ++i) { const QByteArray &str = strings.at(i); - fprintf(out, "QT_MOC_LITERAL(%d, %d, %d)", i, idx, str.length()); + fprintf(out, "QT_MOC_LITERAL(%d, %d)", idx, str.length()); if (i != strings.size() - 1) fputc(',', out); const QByteArray comment = str.length() > 32 ? str.left(29) + "..." : str; @@ -452,7 +448,7 @@ void Generator::generateCode() // // Generate internal qt_static_metacall() function // - const bool hasStaticMetaCall = !isQt && + const bool hasStaticMetaCall = (cdef->hasQObject || !cdef->methodList.isEmpty() || !cdef->propertyList.isEmpty() || !cdef->constructorList.isEmpty()); if (hasStaticMetaCall) @@ -480,7 +476,7 @@ void Generator::generateCode() QByteArray unqualifiedScope = p.type.left(s); // The scope may be a namespace for example, so it's only safe to include scopes that are known QObjects (QTBUG-2151) - QHash<QByteArray, QByteArray>::ConstIterator scopeIt; + QMultiHash<QByteArray, QByteArray>::ConstIterator scopeIt; QByteArray thisScope = cdef->qualified; do { @@ -534,10 +530,7 @@ void Generator::generateCode() // // Finally create and initialize the static meta object // - if (isQt) - fprintf(out, "QT_INIT_METAOBJECT const QMetaObject QObject::staticQtMetaObject = { {\n"); - else - fprintf(out, "QT_INIT_METAOBJECT const QMetaObject %s::staticMetaObject = { {\n", cdef->qualified.constData()); + fprintf(out, "QT_INIT_METAOBJECT const QMetaObject %s::staticMetaObject = { {\n", cdef->qualified.constData()); if (isQObject) fprintf(out, " nullptr,\n"); @@ -547,7 +540,7 @@ void Generator::generateCode() fprintf(out, " QtPrivate::MetaObjectForType<%s>::value(),\n", purestSuperClass.constData()); else fprintf(out, " nullptr,\n"); - fprintf(out, " qt_meta_stringdata_%s.data,\n" + fprintf(out, " qt_meta_stringdata_%s.offsetsAndSize,\n" " qt_meta_data_%s,\n", qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData()); if (hasStaticMetaCall) @@ -559,10 +552,19 @@ void Generator::generateCode() fprintf(out, " nullptr,\n"); else fprintf(out, " qt_meta_extradata_%s,\n", qualifiedClassNameIdentifier.constData()); - fprintf(out, " nullptr\n} };\n\n"); - if(isQt) - return; + if (cdef->propertyList.isEmpty()) { + fprintf(out, " nullptr,\n"); + } else { + fprintf(out, "qt_metaTypeArray<\n"); + for (int i = 0; i < cdef->propertyList.count(); ++i) { + const PropertyDef &p = cdef->propertyList.at(i); + fprintf(out, "%s%s", i == 0 ? "" : ", ", p.type.data()); + } + fprintf(out, ">,\n"); + } + + fprintf(out, " nullptr\n} };\n\n"); if (!cdef->hasQObject) return; @@ -867,6 +869,9 @@ void Generator::generateProperties() if (p.required) flags |= Required; + if (p.isQProperty) + flags |= IsQProperty; + fprintf(out, " %4d, ", stridx(p.name)); generateTypeInfo(p.type); fprintf(out, ", 0x%.8x,\n", flags); @@ -1015,7 +1020,9 @@ void Generator::generateMetacall() fprintf(out, "else "); fprintf(out, "if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty\n" - " || _c == QMetaObject::ResetProperty || _c == QMetaObject::RegisterPropertyMetaType) {\n" + " || _c == QMetaObject::ResetProperty || _c == QMetaObject::RegisterPropertyMetaType\n" + " || _c == QMetaObject::RegisterQPropertyObserver\n" + " || _c == QMetaObject::SetQPropertyBinding) {\n" " qt_static_metacall(this, _c, _id, _a);\n" " _id -= %d;\n }", cdef->propertyList.count()); @@ -1221,18 +1228,22 @@ void Generator::generateStaticMetacall() fprintf(out, "%s(", f.name.constData()); int offset = 1; - int argsCount = f.arguments.count(); - for (int j = 0; j < argsCount; ++j) { - const ArgumentDef &a = f.arguments.at(j); - if (j) - fprintf(out, ","); - fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++); - isUsed_a = true; - } - if (f.isPrivateSignal) { - if (argsCount > 0) - fprintf(out, ", "); - fprintf(out, "%s", "QPrivateSignal()"); + if (f.isRawSlot) { + fprintf(out, "QMethodRawArguments{ _a }"); + } else { + int argsCount = f.arguments.count(); + for (int j = 0; j < argsCount; ++j) { + const ArgumentDef &a = f.arguments.at(j); + if (j) + fprintf(out, ","); + fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++); + isUsed_a = true; + } + if (f.isPrivateSignal) { + if (argsCount > 0) + fprintf(out, ", "); + fprintf(out, "%s", "QPrivateSignal()"); + } } fprintf(out, ");"); if (f.normalizedType != "void") { @@ -1348,6 +1359,7 @@ void Generator::generateStaticMetacall() bool needTempVarForGet = false; bool needSet = false; bool needReset = false; + bool haveQProperties = false; for (int i = 0; i < cdef->propertyList.size(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); needGet |= !p.read.isEmpty() || !p.member.isEmpty(); @@ -1357,13 +1369,15 @@ void Generator::generateStaticMetacall() needSet |= !p.write.isEmpty() || (!p.member.isEmpty() && !p.constant); needReset |= !p.reset.isEmpty(); + haveQProperties |= p.isQProperty; } fprintf(out, "\n#ifndef QT_NO_PROPERTIES\n "); if (needElse) fprintf(out, "else "); fprintf(out, "if (_c == QMetaObject::ReadProperty) {\n"); - if (needGet) { + + auto setupMemberAccess = [this]() { if (cdef->hasQObject) { #ifndef QT_NO_DEBUG fprintf(out, " Q_ASSERT(staticMetaObject.cast(_o));\n"); @@ -1373,6 +1387,10 @@ void Generator::generateStaticMetacall() fprintf(out, " auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData()); } fprintf(out, " Q_UNUSED(_t)\n"); + }; + + if (needGet) { + setupMemberAccess(); if (needTempVarForGet) fprintf(out, " void *_v = _a[0];\n"); fprintf(out, " switch (_id) {\n"); @@ -1410,15 +1428,7 @@ void Generator::generateStaticMetacall() fprintf(out, "if (_c == QMetaObject::WriteProperty) {\n"); if (needSet) { - if (cdef->hasQObject) { -#ifndef QT_NO_DEBUG - fprintf(out, " Q_ASSERT(staticMetaObject.cast(_o));\n"); -#endif - fprintf(out, " auto *_t = static_cast<%s *>(_o);\n", cdef->classname.constData()); - } else { - fprintf(out, " auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData()); - } - fprintf(out, " Q_UNUSED(_t)\n"); + setupMemberAccess(); fprintf(out, " void *_v = _a[0];\n"); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { @@ -1466,15 +1476,7 @@ void Generator::generateStaticMetacall() fprintf(out, " else "); fprintf(out, "if (_c == QMetaObject::ResetProperty) {\n"); if (needReset) { - if (cdef->hasQObject) { -#ifndef QT_NO_DEBUG - fprintf(out, " Q_ASSERT(staticMetaObject.cast(_o));\n"); -#endif - fprintf(out, " %s *_t = static_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData()); - } else { - fprintf(out, " %s *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData()); - } - fprintf(out, " Q_UNUSED(_t)\n"); + setupMemberAccess(); fprintf(out, " switch (_id) {\n"); for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { const PropertyDef &p = cdef->propertyList.at(propindex); @@ -1491,6 +1493,42 @@ void Generator::generateStaticMetacall() fprintf(out, " }\n"); } fprintf(out, " }"); + + fprintf(out, " else "); + fprintf(out, "if (_c == QMetaObject::RegisterQPropertyObserver) {\n"); + if (haveQProperties) { + setupMemberAccess(); + fprintf(out, " QPropertyObserver *observer = reinterpret_cast<QPropertyObserver *>(_a[0]);\n"); + fprintf(out, " switch (_id) {\n"); + for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { + const PropertyDef &p = cdef->propertyList.at(propindex); + if (!p.isQProperty) + continue; + fprintf(out, " case %d: observer->setSource(_t->%s); break;\n", + propindex, p.name.constData()); + } + fprintf(out, " default: break;\n"); + fprintf(out, " }\n"); + } + fprintf(out, " }"); + + fprintf(out, " else "); + fprintf(out, "if (_c == QMetaObject::SetQPropertyBinding) {\n"); + if (haveQProperties) { + setupMemberAccess(); + fprintf(out, " switch (_id) {\n"); + for (int propindex = 0; propindex < cdef->propertyList.size(); ++propindex) { + const PropertyDef &p = cdef->propertyList.at(propindex); + if (!p.isQProperty) + continue; + fprintf(out, " case %d: _t->%s.setBinding(*reinterpret_cast<QPropertyBinding<%s> *>(_a[0])); break;\n", + propindex, p.name.constData(), p.type.constData()); + } + fprintf(out, " default: break;\n"); + fprintf(out, " }\n"); + } + fprintf(out, " }"); + fprintf(out, "\n#endif // QT_NO_PROPERTIES"); needElse = true; } |