summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetaobject.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QObject: warn about using SLOT macro with non-slot functionsAhmad Samir2025-10-021-0/+5
| | | | | | | | | | | | And make it no-op in Qt7. [ChangeLog][QtCore][Important Behavior Change] A warning will be shown if the SLOT() macro is used with a function not marked as a slot, but it'll continue to work to keep backwards-compatibility. However in Qt7 the SLOT() macro will be no-op for non-slot functions. Change-Id: I9ea112b7a72a26fcc5548ebc3c0220eab19d0455 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObjectPrivate: refactor indexOfMethodRelative()Ahmad Samir2025-10-021-15/+29
| | | | | | | | | | | | | | As requested in code review, use QMetaMethod::MethodType enum instead of QMocConstants::MethodFlags, to specify which type to search for; MethodFlags has many more irrelevant enumerators wrt. this function. Make it a regular function instead of a template; take the type to search for as a parameter. Use a switch-statement instead of ternaries, for better readability. Change-Id: I699b2a146019b9f4cd4fb5441de6cae151ecce78 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObject: document what a "cloned" function is wrt. the meta-objectAhmad Samir2025-09-301-3/+9
| | | | | | | | This is copied, with some modifications, from the comment in handleDefaultArguments() in moc.cpp. Change-Id: Idef95f3873ae3e7447ee4065adbc14ca5e34a57f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObject: de-duplicate codeAhmad Samir2025-09-081-15/+3
| | | | | | Pick-to: 6.10 Change-Id: Ib6261e92512fb6b085604830f02afdff423349e5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObjectPrivate: use QSpan instead of passing a length and pointerAhmad Samir2025-09-081-36/+38
| | | | | | | | | | | This is easier to read specially because the QArgumentTypeArray parameter is passed on to other methods down the line. Use std::equal to compare the signal's args with the slot's args, instead of hand-rolled for-loop. Change-Id: I38ad0aa02f08dbe86f4f24ed040ec36f3a147b49 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObjectPrivate: calculate the length of a `const char *` onceAhmad Samir2025-09-081-3/+8
| | | | | | | | | | | Port QMetaObjectPrivate::decodeMethodSignature() to QByteArrayView. Add QMetaObjectPrivate::normalizedSignature() that takes a QBAV, QObject::connect() can use that until the QMetaObject public API methods are ported. Change-Id: I180e84f499faad4a200333128c9e0971d8c4ff98 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObjectPrivate: assert empty out-param container in decodeMetodSignature()Ahmad Samir2025-09-031-0/+1
| | | | | | | | | Some code in QObject reuses the same QArgumentTypeArray, so the assert is there to ensure we don't forget to clear() the container before reuse. Change-Id: I103b4a6cde3eee73d164a078a194d57ae357079d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QtAlgorithms: rewrite the functions using q20bit.hThiago Macieira2025-08-281-2/+2
| | | | | | | Which is constexpr on all platforms. Change-Id: I0680e712c96bc3131515fffd2fa97f2f76e0b253 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QMetaObject::access: statically assert that the constants matchThiago Macieira2025-08-211-1/+5
| | | | | | | | | | | The MethodFlags constants used to be in a private header, but we still don't require either header to include the other, so asserting somewhere that uses them both suffices. Drive-by add shifting, which currently is by zero. Change-Id: I5fbf353571fe8df98e95fffd1e031ef9de0b81db Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QMetaObject: make QMetaMethod::{Signal,Slot} == Q{SIGNAL,SLOT}_CODEThiago Macieira2025-08-211-1/+6
| | | | | | | | | | For Qt 7, because it would be binary-incompatible before then. Drive-by statically assert that the constants in the two headers match and clean up old code. Change-Id: Ia4a794faf748baacebcefffd9b8e70f863bb0e05 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add normalizeTypeInternal() overload with an out QBA parameterAhmad Samir2025-08-191-1/+1
| | | | | | | | | | Useful when called in a loop from QMetaObject::normalizedSignature(); avoids allocating a QByteArray for each type in a method's signature. Drive by, add missing include. Change-Id: I423a618f79df2db2be859d41e5df1150b6da9b79 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObject: refactor normalizedSignature()Ahmad Samir2025-08-131-34/+52
| | | | | | | | | Skip spaces during iteration instead of removing them beforehand, so that we scan the string once. Pick-to: 6.10 Change-Id: I02dc9041811df2aee0099e705fdc46dd30bc55fc Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaProperty implementation: replace QByteArray with a QBAViewVolker Hilsheimer2025-08-041-1/+1
| | | | | | | | | | | | | | When looking up the unresolved notify signal of a property, use QBAV to find the index of the property using indexOfMethodRelative, which already takes a QBAV. This code path gets frequently hit when starting a Qt Quick UI, so this might save a few cycles during startup. Pick-to: 6.10 Change-Id: If542ac5086078f10befc86d8387abd2268546ab7 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
* QMetaObjectPrivate: de-duplicate method signature parsing codeAhmad Samir2025-07-301-38/+22
| | | | | | Pick-to: 6.10 Change-Id: I3a6b98c3f6d3f56e54ef9184945c27ccf0f23bed Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Fix files under src_corelib_kernel prefixOleksii Zbykovskyi2025-07-241-1/+1
| | | | | | | | Fixed each file and added to the build system. Also updated docs. Task-number: QTBUG-137566 Change-Id: I8e75b9b089167c427bab236c4792fd1056432be9 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Reduce QVarLengthArray preallocation in queued meta callAurélien Brooke2025-07-211-1/+2
| | | | | | | | | | | | The default prealloc size of 256 is excessive for typical argument counts. Reduce the prealloc to 16 and add a reserve() in case more is needed. Amends f6211c079fa000c0d46b7912341f014669fa628a. Change-Id: I69a0d46636c41ba88cd233b2d243a6e31eb39b0e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObject: cut out the `m` middle-man in indexOf*() methodsMarc Mutz2025-07-121-6/+3
| | | | | | | | | | | It's the same as `this`. Amends e4f86012360b20938be8f34e6966a577dae6c049. Reported-by: Ahmad Samir <a.samir78@gmail.com> Pick-to: 6.10 6.9 6.8 6.5 Change-Id: I43fb23f8995c300b7982ffbb03ea1ed3ff55a122 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaCallEvent: avoid heap allocations for small argumentsAurélien Brooke2025-07-111-27/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, all arguments for queued connections were heap-allocated via QMetaType::create(), even for small types like int or QObject*. This incurred many micro-allocations and led to inefficient cross-thread memory ownership. Additionally, argument copying was the responsibility of the caller after constructing the QMetaCallEvent, leading to code duplication and potential misuse. To fix this, this patch introduces QQueuedMetaCallEvent as a specialized subclass of QMetaCallEvent, used exclusively for queued signal-slot delivery. It supports in-place argument storage by preallocating space for up to 3 argument values (plus 5 pointers and types), enabling copy- construction directly within the event object for types that fit within a 3 × sizeof(void*) buffer and are suitably aligned. Heap allocation via QMetaType::create() is still used as a fallback for larger types. Legacy QMetaCallEvent constructors and the args() and types() accessors are marked deprecated and will be removed once the corresponding qtdeclarative patch eliminates their usage. The prealloc_ member, currently shared for transitional reasons, will also be moved into QQueuedMetaCallEvent as part of that cleanup. Amends b7d073e9905bf9812ba96cecdcf6871a95517d30. Change-Id: Icb6c1544de193b3fe6311fe76eaf00cf501d8977 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Doc: Add QMetaEnum usage snippet to detailed descriptionDheerendra Purohit2025-07-091-0/+14
| | | | | | | | | | The QMetaEnum documentation lacked a code snippet showing how to convert enum values to strings using QMetaEnum::fromType() and Q_ENUM. Pick-to: 6.10 6.9 Fixes: QTBUG-60355 Change-Id: I9581625d4889ebad8c5741aa35a30acafb4ce14c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Doc: silence warning, QMetaType::type() is overloadedVolker Hilsheimer2025-07-021-1/+1
| | | | | | | | | | Instead of linking from QMetaMethod::typeName() to the deprecated and overloaded static QMetaMethod::type() function, link to QMetaType::name() which is neither, and a more relevant reference. Pick-to: 6.10 6.9 6.8 Change-Id: I2a4451d92d9dd36adf6a55a8069230333358fe63 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Replace one-shot uses of QSemaphore with QLatchThiago Macieira2025-06-301-7/+7
| | | | | | | | | | | | | | | This commit replaces one-shot synchronization of threads that were using QSemaphore with QLatch. QSemaphore is efficient on Linux and Windows, but allocates memory elsewhere. Even on those platforms where we have futex-like OS support, QSemaphore is heavier than what we really need here. All but one uses of QSemaphore in qtbase libraries (I didn't change examples or tests) were replaced. The remaining use of QSemaphore in qnetworkproxy_libproxy.cpp is a proper producer-consumer. Change-Id: Ib5ce7a497e034ebabb2cfffd1761a4fcb2be9a6c Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* tst_QMetaObject: add some more signature normalization testsAhmad Samir2025-06-231-0/+3
| | | | | | | | | | | | | | | | Add tests with nested template args. Add tests for empty and null signatures, requested in code review. Add a test for `char * const *` to verify that QTypeNormalizer::normalizeType() normalizes it as expected. Add a test for explicit void argument inside a template, suggested by Fabian in code review. Pick-to: 6.10 Change-Id: I040135355702e9c11d00a8685c274894dc46d848 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QMetaObjectPrivate: simplify parameterTypeNamesFromSignature()Ahmad Samir2025-06-231-5/+12
| | | | | | | | | | | Take by QByteArrayView instead of `const char *`, this method is only called on a QByteArray so the size is already known. Use the length to check for the end of iteration instead of checking for the closing ')' in multiple places in the while-loops' conditions. Pick-to: 6.10 Change-Id: I272231293d07ae699083d2a38898ea2d3cf0e7a0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObject: port QArgumentType to QByteArrayViewMarc Mutz2025-06-121-2/+1
| | | | | | | | | | | | | | | | | | | | Now that argumentTypesFromString() actually doesn't normalize types anymore, all type names are substrings of the signature, and so QByteArrayView suffices (was: QByteArray) to hold the result. QArgumentType in only used transitively, during QMetaObject member function or QObject::connect() calls, so the source string will also never go out of scope before the QArgumentType object that references it. As a drive-by, make the QArgumentType ctor explicit and port from QVLA::op+=() to emplace_back(). No discernable impact on tst_bench_qobject's connect_disconnect. Task-number: QTBUG-135572 Change-Id: If6544917b9df8191a256dc2a67e31c6b7e5a38cb Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObject: deprecate the Qt 6 QVector -> QList porting kludgeMarc Mutz2025-06-121-1/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The argumentTypesFromString() function is clearly documented not to perform any normalization, yet in typical Qt 6.0 porting rush, it did, and this kludge was never removed. Do it now; it's in the way of porting QArgumentType from QBA to QBAV, and it's causing correct code to incorrectly fail. This, however, changes the behavior of QMetaObject::indexOf*(), because they don't fall back to normalization (indeed, these functions are used as isNormalized checks, e.g. in connect()). So we can't remove the kludge just yet, but we can drag it out of the fast path and re-try with QVector replaced by QList when nothing was found using the original signature. This way, we only pessimize unported users (and calls that would have failed for other reasons, by scanning for "QVector<" in the signature). Add a qWarning() that we'll remove this behavior going forward. It does, however, fix the bug that signals and slots that contain types that match, but are not, "QVector<", fail to be found by the machinery: [ChangeLog][QtCore][QMetaObject/QObject] Fixed a bug that caused signals and slots with argument types matching "QVector<" (e.g. "MyQVector<int>" or "NotQt::QVector<int>") to not be found in QObject::connect() or QMetaObject::indexOfMethod(). [ChangeLog][Deprecation Notices][QMetaObject] The indexOf{Constructor,Slot,Signal,Method}() functions are documented to require input according to QMetaObject::normalizedSignature(), but accepted a QList declared as QVector. This was an internal porting aid and is being deprecated now. Watch out for runtime warnings about this. QObject::connect() and QMetaObject::invokeMethod() are unaffected, as they fall back to normalizeSignature() automatically. No change in tst_bench_qobject connect performance, which is unsurprising, as the benchmark doesn't use a QVector alias. Amends 03326a2fec416405b437089874f6439e937bbada. Task-number: QTBUG-135572 Pick-to: 6.10 Change-Id: I7fd9293bba5d2b57b4452e55499ffbf360bc6123 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QMetaObject: extract helpers from indexOf*() methodsMarc Mutz2025-05-301-9/+44
| | | | | | | | | | | | This makes the different functions more similar to each other, thus facilitating adding a warning about non-normalized arguments to them in the next step. Task-number: QTBUG-135572 Pick-to: 6.9 6.8 6.5 Change-Id: Ia2b82928e9a24fb9d43b43933b9a9c5308fa2835 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObject: port qRemoveWhitespace() to QByteArrayViewAhmad Samir2025-05-251-7/+9
| | | | | Change-Id: Ib5754708f25bdb3ac9d6546deaf3182dbb7ed8a8 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QMetaObject: don't use QMetaType::fromName() in typeFromTypeInfo()Marc Mutz2025-04-111-1/+1
| | | | | | | | | | | | | | | | | | | | The former will try to normalize the type name, but everything stored in a QMetaObject is already in normalized form. So, if the first lookup fails, the normalized one won't succeed either. Use qMetaTypeTypeInternal(), which doesn't normalize. At a minimum, this will fail faster. If we're lucky, the missing round-trip via QMetaType(int).id() will help the positive case, too. But if it does, it's lost in the statistical noise of the benchmark. IOW: no measurable performance impact. Pick-to: 6.9 Task-number: QTBUG-135572 Change-Id: I23834c201fbcd1780c50e85cf8a15ea5e4a94c74 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QMetaObject: save a strlen() in typeFromTypeInfo()Marc Mutz2025-04-111-1/+1
| | | | | | | | | | | | | | QMetaType::fromName() takes a QBAV, so don't feed it rawStringData() (a const char*, causing the QBAV ctor to run strlen() on it), but stringDataView() (a QBAV already, whose length is determined by offset difference in the string offset table and not by strlen()). No measurable difference in runtime speed. Pick-to: 6.9 6.8 6.5 Change-Id: I583bea9d818deeaac6f62803f7ac5ab4766cb8a5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaObject: fix performance regression in methodMatch()Marc Mutz2025-04-111-3/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Amends 22ce92f8040183faf9e1ba53c59c6b0b9172fb26, which apparently changed the method name stored in the moc data from unqualified to a qualified name. The original commit message doesn't mention it, but the change in QMetaMethodPrivate::name() suggests as much. Unfortunately, the search for the colon causes the name() call to increase to 25% of the total methodMatch() runtime, up from 6.85% before the change. Since name() now always strips a possible prefix, re-add the original name() as qualifiedName() and use that in methodMatch(). This is faster because we don't need to perform an a-priori search for colons; instead, we can first check for endsWith(), and only if we have a match, can we a-posteriori check that the match was preceded by an (optional) colon. Results on my machine: ********* Start testing of tst_QObject ********* Config: Using QtTest library 6.10.0, Qt 6.10.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by Clang 15.0.3 (github.com:llvm/llvm-project.git 48b23aa469b8cfdb6cde1c55bf3361cabcdef6bc)), ubuntu 20.04 PASS : tst_QObject::initTestCase() PASS : tst_QObject::connect_disconnect_benchmark(normalized signature) RESULT : tst_QObject::connect_disconnect_benchmark():"normalized signature": - 923.542494 nsecs per iteration (total: 461,771,247, iterations: 500000) + 880.558792 nsecs per iteration (total: 440,279,396, iterations: 500000) - 4,340.832532 CPU cycles per iteration, 4,7 GHz (total: 2,170,416,266, iterations: 500000) + 4,093.487614 CPU cycles per iteration, 4,65 GHz (total: 2,046,743,807, iterations: 500000) - 13,706.07561 instructions per iteration, 3,157 instr/cycle (total: 6,853,037,807, iterations: 500000) + 12,779.02463 instructions per iteration, 3,122 instr/cycle (total: 6,389,512,318, iterations: 500000) - 2,201.185595 branch instructions per iteration, 2,38 G/sec (total: 1,100,592,798, iterations: 500000) + 2,208.176500 branch instructions per iteration, 2,51 G/sec (total: 1,104,088,250, iterations: 500000) For a ~5% overall speedup in both ns/iter and instr/iter, keeping in mind that this data contains the disconnect() call, too. As a drive-by, remove a second call of QMetaObjectPrivate::get() on the same object, and reuse the previous call's result. Pick-to: 6.9 Task-number: QTBUG-135572 Change-Id: Ide253b323e7b826f8fa09d2f5f57496861c12f75 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QMetaObjectPrivate: make decodeMethodSignature() return QByteArrayViewMarc Mutz2025-04-101-16/+16
| | | | | | | | | | | | | | | | | | | | ... instead of QByteArray. This is part of a quest to improve string-based connect() performance. Needed to port a few consumers of decodeMethodSignature()'s result from QByteArray to QByteArrayView, too. All private API, so doesn't affect users. This doesn't change anything in tst_bench_qobject's connect_disconnect_benchmark:normalized signature, yet. Task-nunber: QTBUG-135572 Pick-to: 6.9 Change-Id: I1cd5b410ee090ab9c6f3aa8095a4d9efae516ac0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* doc: Fix broken links and incorrect informationDavid Boddie2025-02-101-2/+2
| | | | | | | | ReadOnly was used in places where ReadWrite was the correct value. Pick-to: 6.8 6.9 Change-Id: I26a2f0de55665ac015fe269e8e5f0d23a2f00e5f Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Doc: QMetaProperty documentation references deprecated "type()" functionJaishree Vyas2024-11-281-1/+1
| | | | | | | | | | Documentation of QMetaProperty mentions deprecated members, which includes type(). Added link to the metaType() to avoid confusion. Fixes: QTBUG-131446 Pick-to: 6.8 Change-Id: I8d96bcf712c78ca2b9ce609e511d275053cf6cbf Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Create qdoc macros for C++ class docs 1.2: member-swap(), simplified phrasingMarc Mutz2024-11-081-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We have some patterns for how to document certain functions, but we also vary the sentences a lot, and you have to look up one documentation piece and copy it, essentially. If we ever want to change them, we end up with shotgun surgery. So apply DRY to the documentation and start a collection of macros to help with repetitive C++ class documentation tasks. The first macro is for member-swap(), and this second patch is for documentation that used the simplified phrasing ("Swaps this X with \a other."), which this patch adopts as the text for \memberswap, too, because it doesn't repeat the macro argument, making it easier to find a grammatically-fitting argument than in the traditional phrasing. This doesn't change the documentation, except as follows: * standardizes on simpified instead of traditional phrasing for docs that already use the \memberswap macro * adds the "very fast and never fails" blurb, if it was missing * changes the function's argument name to `other`, as required by the macro. Task-number: QTBUG-129573 Pick-to: 6.8 6.7 6.5 6.2 Change-Id: I1123e783ce0da76c5997ff74007d77504ac5b334 Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* moc: remove always-known parameters to (Revisioned)ConstructorDataThiago Macieira2024-11-071-2/+10
| | | | | | | | | | | | | | | | | | | | | | | | It's a meta method so it must have a name and a return type, even though constructors have neither. The method name of a constructor QMetaMethod is the name of the class and the name is already required to be stored at index 0. We just have to be careful when the class is not directly in the global namespace, because then the first string contains the full scope. Prior to this change, it stored an empty string as the method return type, but QMetaMethod::returnMetaType() already protects against reading it, with: if (!mobj || methodType() == QMetaMethod::Constructor) return QMetaType{}; which was added in commit fa987d44417528856d5e80ed7b48ba99e19fa307 ("MetaObject: Store the QMetaType of the methods") because there is no metatype stored for this non-existent return type. This commit repeats some of that to QMetaMethod::typeName(). Change-Id: Ia903287c2c07b1d588a9fffdaf22fff0b0d6ce9f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* moc: add support for calculating the meta type array at constexpr timeThiago Macieira2024-11-071-1/+4
| | | | | | | | We now need to pass the meta type of the gadget (if it is one) and the unique type for disambiguation into our generator. Change-Id: I8a96935cf6c742259c9dfffd17ea937d8beed1ec Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Fix QFlag properties built by QMetaObjectBuilderPhil Thompson2024-10-291-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | When Q_PROPERTY is used to define a property with type (for example) Qt::Alignment the name of the type stored in the meta-object is "Qt::Alignment". When QMetaObjectBuilder.addProperty() is used it will instead use the name of the meta-type (ie. "QFlags<Qt::AlignmentFlag>") which it has obtained from QMetaType::fromName("Qt::Alignment").name(). In the QMetaProperty ctor it tries to resolve the QMetaEnum for the property and uses the internal parse_scope() to extract the scope and qualified key from the name. However it does not handle template names and so fails with dynamically created properties. This change to parse_scope() removes the "QFlags<>" so that the template type can then be parsed. Another solution would be for addProperty() to always use the type name it was given rather than use QMetaType::fromName(). That has the advantage that the layout of the dynamic meta-object would match that generated by moc. Pick-to: 6.8 Change-Id: Iac9e2db2f134029709158b4e500286922396501d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMeta{Property,Method}: document that revision() is encoded since 6.0Thiago Macieira2024-10-141-4/+6
| | | | | | | | | Amends f64694647a9a3d54fa5ecdaf2570e8c7404271a6. Pick-to: 6.8 6.5 Fixes: QTBUG-129920 Change-Id: Ic42789eb08fc264bdce7fffdc6dcfbc8794070bf Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QMetaMethod: Introduce nameViewFabian Kosmale2024-10-081-0/+14
| | | | | | | | | | The QBAView returning variant of name. It can avoid the check whether the meta-object is dynamic, as it doesn't promise to keep the data valid when the meta-object is gone. Change-Id: Id1fcf1827a30c5d35ea1f40c8a519b88be43c23b Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* moc/QMetaProperty: add support for reading and writing 64-bit QFlagsThiago Macieira2024-10-041-7/+7
| | | | | | | | | | QMetaType::convert() already knows how to convert from integers to enumerations of 64-bit, so this is only necessary for properties that are also declared Q_FLAG(). Task-number: QTBUG-111926 Change-Id: I8a96935cf6c742259c9dfffd17e977ef4b1b9dd9 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QMetaEnum: add support for reading 64-bit flags and enumsThiago Macieira2024-10-041-30/+173
| | | | | | | | | | | | The previous commit added support for storing them in the meta object. This complements by adding support for reading the stored values. Task-number: QTBUG-111926 Fixes: QTBUG-27451 Change-Id: I8a96935cf6c742259c9dfffd17e958aa8ed66086 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QMetaMethod: make some QByteArray-returning methods slightly fasterThiago Macieira2024-10-031-14/+27
| | | | | | | | | | | | | | | | | | | QByteArray::fromRawData() allocates no memory. Since we know that the data range is valid, there's no precondition violation either. But we can only use it for static-lifetime meta objects: those constructed by QMetaObjectBuilder or QtDBus may get deallocated, causing the strings obtained from them to crash on use if they do outlive (unlikely, but not impossible). To differentiate, this commit introduces a new flag to the QMetaObject header and makes use of it in those two places. Come Qt 7, we should change these functions to return QByteArrayView, making the retention of the data in a QByteArray the responsibility of the user. Making the change right now with #if or QTx_ONLY() is ugly, so this commit just leaves a comment. Change-Id: I5aaddbc7ce3fc7a70e15fffd29e276c79d5ef6e4 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QMetaProperty: fix type-punning of QFlags in write() from QStringThiago Macieira2024-10-011-2/+5
| | | | | | | | | | | | | | | | | | | | Amends commit 46f407126ef3e94d59254012cdc34d6a4ad2faf2 ("MetaObject: store the QMetaType of the properties"), from 6.0 cycle, which made QMetaProperty::{read,write}() use the actual enum type in the QVariant. But it missed the case where the input QVariant contained a string with the enum's values. Note this is *not* a type-punning in all cases: if the type of the property was marked as a Q_FLAG, moc generates code to access it as int. That is fixed in the next commit. Drive-by compare QMetaTypes instead of their IDs, which avoids generating a call to register them. Pick-to: 6.8 6.5 See-also: https://lists.qt-project.org/pipermail/development/2024-September/045636.html Change-Id: I1cfce869090c96bb41b6fffdc20855cfa7cb2a18 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QArgumentType: store a QMetaType instead of an idThiago Macieira2024-09-301-4/+5
| | | | | | | | | | This would avoid an indirection through the QMetaType constructor. But I'm also making it so effectively we either have valid QMetaTypes or we don't. If it can be looked up in the constructor, then string comparisons aren't necessary at all. Change-Id: I9a3b2a1a781c27c7271afffd3e5acbca06632476 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* moc & QMetaObject: move the QMetaMethod revision informationThiago Macieira2024-09-211-2/+8
| | | | | | | | | | | | | | | | | | | | | Instead of storing them as an array for every single method (some of which may not have revisions) at a different location in the uint array, store the revision after the parameter type and name lists, in the usual place. This is not implemented for the old integer table in moc, because it's going away. [ChangeLog][Important Behavior Changes] With Qt 6.9, the layout of the meta object data table changed incompatibly for classes containing meta methods (signals, slots) marked with Q_REVISION. This is marked by the presence of revision 13 or later. Code that reads or writes the meta object's raw data directly instead of using QMetaMethod must detect the new layout. Change-Id: I8a96935cf6c742259c9dfffd17e97a2530b52b3e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QMeta{Enum,Property}::metaType(): perform unsigned 32-bit divisionsThiago Macieira2024-09-171-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Instead of signed 64-bit ones. Divisions by 5 (or 20 bytes) aren't efficient in hardware, leading the compilers to implement a multiplication by 2^n / 20 and shifting instead. For Qt 7.0, we should consider either: * store the index to the metatype in the enum/property data block * increase the enum/property data block to 8 integers * decrease the enum/property data block to 4 integers Before: 16d1b8: sub %rcx,%rax # d - mobj->d.data 16d1bb: sar $0x2,%rax 16d1bf: movslq 0x24(%rcx),%rdx # sign-extended enumeratorData 16d1c3: sub %rdx,%rax 16d1c6: movabs $0x6666666666666667,%rdx 16d1d0: imul %rdx # 64-bit mul w/ 128-bit result 16d1d3: mov %rdx,%rax 16d1d6: shr $0x3f,%rax 16d1da: shr $1,%rdx 16d1dd: add %eax,%edx 16d1df: movslq 0x18(%rcx),%rax 16d1e3: movslq %edx,%rcx 16d1e6: add %rax,%rcx After: 18def8: sub %rcx,%rdx # d - mobj->d.data 18defb: shr $0x2,%rdx 18deff: sub 0x24(%rcx),%edx # 32-bit sub of enumeratorData 18df02: mov $0xcccccccd,%esi 18df07: imul %rdx,%rsi # 64-bit mul w/ 64-bit result 18df0b: shr $0x22,%rsi 18df0f: movslq 0x18(%rcx),%rcx 18df13: add %rsi,%rcx The IMUL with 128-bit results[1] needs 4 cycles to calculate the upper part in current Intel P-cores and AMD cores, and 6 cycles on Intel E- cores, which is one cycle more in all cases than the 64-bit IMUL[2]. The old code has two SHR (1 cycle, execute in parallel), an ADD (1 cycle), one sign-extension (1 cycle) before the final ADD, whereas the new code has just one SHR. As a result, the new code should require 3 cycles fewer in all x86 processors. This is what it could look like with Size == 8: 18def8: sub %rcx,%rdx 18defb: shr $0x2,%rdx 18deff: sub 0x24(%rcx),%edx 18df02: shr $0x3,%edx 18df05: movslq 0x18(%rcx),%rcx 18df09: add %rcx,%rdx [1] https://uops.info/html-instr/IMUL_R64.html [2] https://uops.info/html-instr/IMUL_R64_R64.html Change-Id: Ife2dfbd4c341cae4c6cdfffd580455ecf3e99704 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QMetaProperty: limit QMetaEnum resolution to enums known to QMetaTypeMårten Nordheim2024-05-061-2/+2
| | | | | | | | | | | | | | | | | | Since we don't know ahead of time if a property's type is an enum or a flag we have to resolve it at runtime. In a QMetaProperty-heavy application this overhead can be quite dramatic given that we mark anything that is not a built-in as a potential flag/enum. However, QMetaType already knows if it's an enum, so we can use that to return early if it's not known to the meta-type system. To add to this - Q_PROPERTY requires that a type is fully defined, so there are no issues with forward declarations for the enums. Change-Id: Ifecc7f1e6cdef416e3ce72ee705eb26e682071cc Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QMetaMethod: use new comparison helper macrosTatiana Borisova2024-04-301-4/+5
| | | | | | | | | | Replace public friend operators operator==(), operator!=() of QMetaMethod to friend method comparesEqual() and Q_DECLARE_EQUALITY_COMPARABLE macro. Task-number: QTBUG-120304 Change-Id: Idb3f880a1db4850d73a58ed37f8cbd3454dd5ea2 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QMetaMethod: document that fromSignal(nullptr) is okMarc Mutz2024-03-211-1/+1
| | | | | | | | | ... and add a test. Pick-to: 6.7 6.6 6.5 6.2 5.15 Change-Id: I907899d7c54349d2fc23ea5ab58a1e67826b622b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QMetaObject: consistently use QByteArray(View) in the implementationIvan Solovev2024-02-161-9/+9
| | | | | | | | | | | | | The implementation was inconsistent. The `stringData()` method was returning QByteArray, while the `stringDataView()` method was returning QLatin1StringView. Update the second method to return QByteArrayView instead, and fix all related places. Found while trying to resolve ambiguities in QL1SV <-> QBAV comparison. Change-Id: I94f10a5eeeb80a6e512c1f7623becf5e7f543fd9 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>