<feed xmlns='http://www.w3.org/2005/Atom'>
<title>qt/qtdeclarative.git/src/qmlintegration, branch dev</title>
<subtitle>Qt Declarative (Quick 2)
</subtitle>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/'/>
<entry>
<title>QQmlIntegration: reimplement the detectors for the QML_ macros</title>
<updated>2026-02-26T11:28:41+00:00</updated>
<author>
<name>Giuseppe D'Angelo</name>
<email>giuseppe.dangelo@kdab.com</email>
</author>
<published>2026-02-24T16:13:07+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=7e02a743f40417172df682e929282c6abbcf45fa'/>
<id>7e02a743f40417172df682e929282c6abbcf45fa</id>
<content type='text'>
There's a number of detectors in the QQmlPrivate namespace, each one
meant to detect the presence of a specific QML_ macro (e.g. QML_FOREIGN,
QML_EXTENDED, and so on). The detectors work by detecting the presence
of some enumeration value, function, etc. injected by the expansion of
those macros in a class.

Since the macros may generally expand in a private: section of a class,
the macros also befriend the detector classes; otherwise the detection
would fail due to the detector being unable to access the
enumeration/etc.

This should work in principle, but there's a problem with the specific
implementation: it uses SFINAE on the detector class itself via
(a small variation of) the usual pattern:

  template &lt;typename T, typename Enable = void&gt;
  struct Detector : std::false_type {}; /* primary */

  template &lt;typename T&gt;
  struct Detector&lt;T, std::void_t&lt;/* checks */&gt;&gt; : std::true_type {};

The problem here is that the checks are not necessarily carried with
Detector's own access priviliges. In particular it has been observed
that GCC &lt; 12 and MSVC fail the detection; it seems that the SFINAE is
getting evaluated with the privileges of whoever _uses_ the Detector
class, not of the class itself, making the befriending useless.

Therefore, the code employs a further workaround: the macros also
befriend the (only) usage point of the detectors, that is, the
qmlRegisterTypesAndRevisions function.

This approach seems to work, but it makes the detectors crippled /
creates technical debt. Indeed, an upcoming feature (uncreatable
singletons) attempted to use the detectors directly from some other
code, and the detectors (mysteriously) failed on those compilers.

This commit fixes the detectors so that they always work.
To do so, we're moving to "old school" SFINAE, where the detector
becomes

  template &lt;typename T&gt;
  struct Detector {
    template &lt;typename U&gt;
    static auto test(int) -&gt; /* some expression SFINAE yielding true_type */;

    template &lt;typename U&gt;
    static auto test(...) -&gt; false_type;

    static constexpr bool value = decltype(test&lt;U&gt;(0))::value;
  };

The whole point of this approach is to be well within Detector's scope
and therefore establish friendship, making the detection code work
reliably.

The friendship to qmlRegisterTypesAndRevisions can therefore be removed.

I've tried to minimize the refactorings necessary. The "old style"
SFINAE is indeed clumsier, and it shows. I don't quite understand
why the checks are slightly different between each other (instead of
e.g. just checking the presence of a inner type or constant), or why
some QML macros introduce unused declarations (e.g.
qt_qmlMarker_sequence), so I left them alone.

Change-Id: I618e8b7b4ad47dc22f9d61cce6addac00bf29dc6
Reviewed-by: Ulf Hermann &lt;ulf.hermann@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There's a number of detectors in the QQmlPrivate namespace, each one
meant to detect the presence of a specific QML_ macro (e.g. QML_FOREIGN,
QML_EXTENDED, and so on). The detectors work by detecting the presence
of some enumeration value, function, etc. injected by the expansion of
those macros in a class.

Since the macros may generally expand in a private: section of a class,
the macros also befriend the detector classes; otherwise the detection
would fail due to the detector being unable to access the
enumeration/etc.

This should work in principle, but there's a problem with the specific
implementation: it uses SFINAE on the detector class itself via
(a small variation of) the usual pattern:

  template &lt;typename T, typename Enable = void&gt;
  struct Detector : std::false_type {}; /* primary */

  template &lt;typename T&gt;
  struct Detector&lt;T, std::void_t&lt;/* checks */&gt;&gt; : std::true_type {};

The problem here is that the checks are not necessarily carried with
Detector's own access priviliges. In particular it has been observed
that GCC &lt; 12 and MSVC fail the detection; it seems that the SFINAE is
getting evaluated with the privileges of whoever _uses_ the Detector
class, not of the class itself, making the befriending useless.

Therefore, the code employs a further workaround: the macros also
befriend the (only) usage point of the detectors, that is, the
qmlRegisterTypesAndRevisions function.

This approach seems to work, but it makes the detectors crippled /
creates technical debt. Indeed, an upcoming feature (uncreatable
singletons) attempted to use the detectors directly from some other
code, and the detectors (mysteriously) failed on those compilers.

This commit fixes the detectors so that they always work.
To do so, we're moving to "old school" SFINAE, where the detector
becomes

  template &lt;typename T&gt;
  struct Detector {
    template &lt;typename U&gt;
    static auto test(int) -&gt; /* some expression SFINAE yielding true_type */;

    template &lt;typename U&gt;
    static auto test(...) -&gt; false_type;

    static constexpr bool value = decltype(test&lt;U&gt;(0))::value;
  };

The whole point of this approach is to be well within Detector's scope
and therefore establish friendship, making the detection code work
reliably.

The friendship to qmlRegisterTypesAndRevisions can therefore be removed.

I've tried to minimize the refactorings necessary. The "old style"
SFINAE is indeed clumsier, and it shows. I don't quite understand
why the checks are slightly different between each other (instead of
e.g. just checking the presence of a inner type or constant), or why
some QML macros introduce unused declarations (e.g.
qt_qmlMarker_sequence), so I left them alone.

Change-Id: I618e8b7b4ad47dc22f9d61cce6addac00bf29dc6
Reviewed-by: Ulf Hermann &lt;ulf.hermann@qt.io&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>CRA review: Mark qmlintegration as insignificant</title>
<updated>2025-09-16T13:17:49+00:00</updated>
<author>
<name>Fabian Kosmale</name>
<email>fabian.kosmale@qt.io</email>
</author>
<published>2025-08-26T09:53:59+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=4bab3e2c7ad61df97aa962d2b513bddaca3a3798'/>
<id>4bab3e2c7ad61df97aa962d2b513bddaca3a3798</id>
<content type='text'>
The header is only used to add meta-data to source files.

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-136199
Change-Id: Ib2a5c55b68613b9d2c3d7bd619841358201b9341
Reviewed-by: Ulf Hermann &lt;ulf.hermann@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The header is only used to add meta-data to source files.

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-136199
Change-Id: Ib2a5c55b68613b9d2c3d7bd619841358201b9341
Reviewed-by: Ulf Hermann &lt;ulf.hermann@qt.io&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>CMake: Prevent creation of private modules without private headers</title>
<updated>2025-03-13T14:07:01+00:00</updated>
<author>
<name>Joerg Bornemann</name>
<email>joerg.bornemann@qt.io</email>
</author>
<published>2025-03-12T16:10:25+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=e053cefe0894ef253764ce4a0771a9058c693e7b'/>
<id>e053cefe0894ef253764ce4a0771a9058c693e7b</id>
<content type='text'>
Add NO_PRIVATE_MODULE to the creation flags of module that don't have
any private headers. There's no point in creating private modules for
them.

Task-number: QTBUG-132526
Change-Id: I76b820f3348a5066b0aac740d4e0be8ddeadc4dd
Reviewed-by: Alexey Edelev &lt;alexey.edelev@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Add NO_PRIVATE_MODULE to the creation flags of module that don't have
any private headers. There's no point in creating private modules for
them.

Task-number: QTBUG-132526
Change-Id: I76b820f3348a5066b0aac740d4e0be8ddeadc4dd
Reviewed-by: Alexey Edelev &lt;alexey.edelev@qt.io&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>QtQml: Allow "using" declarations in QML type registrations</title>
<updated>2024-05-23T14:29:16+00:00</updated>
<author>
<name>Ulf Hermann</name>
<email>ulf.hermann@qt.io</email>
</author>
<published>2024-05-17T18:21:34+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=5430aeadd88b35c81c08ec96e91206e07346866c'/>
<id>5430aeadd88b35c81c08ec96e91206e07346866c</id>
<content type='text'>
This makes qmltyperegistrar lexically replace occurrences of the alias
with the original type. It therefore assumes that the types are actually
the same. It cannot check whether this assumption holds, and you can
actually provide "using" declarations for types that are not the same if
you have the respective conversion operators in place.

Obviously this is quite dangerous. Therefore it remains internal for
now.

Task-number: QTBUG-125240
Change-Id: Idb54cb42fd1289cbd9438272ae3e9e01a30869eb
Reviewed-by: Fabian Kosmale &lt;fabian.kosmale@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This makes qmltyperegistrar lexically replace occurrences of the alias
with the original type. It therefore assumes that the types are actually
the same. It cannot check whether this assumption holds, and you can
actually provide "using" declarations for types that are not the same if
you have the respective conversion operators in place.

Obviously this is quite dangerous. Therefore it remains internal for
now.

Task-number: QTBUG-125240
Change-Id: Idb54cb42fd1289cbd9438272ae3e9e01a30869eb
Reviewed-by: Fabian Kosmale &lt;fabian.kosmale@qt.io&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>QML macros: suppress Wredundant-decls</title>
<updated>2024-05-06T11:15:47+00:00</updated>
<author>
<name>Fabian Kosmale</name>
<email>fabian.kosmale@qt.io</email>
</author>
<published>2024-05-06T09:27:53+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=df3c82f6af0bf7b857ba7a5110643eb7abe84182'/>
<id>df3c82f6af0bf7b857ba7a5110643eb7abe84182</id>
<content type='text'>
When using multiple QML type registration macros, one might end up with
duplicated friend declarations. This is fine as far as C++ is concerned,
but triggers gcc's redundant-decls warning.

Given that we require the friend declaration, and would like to keep it
in the macros that actually need them (instead of putting them into the
macros which are used in all types exposed to QML), we opt for
suppressing the warning.

Pick-to: 6.5 6.7
Fixes: QTBUG-124934
Change-Id: I4f43afddfefb6e546ddddbdc01435222398a06be
Reviewed-by: Volker Hilsheimer &lt;volker.hilsheimer@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When using multiple QML type registration macros, one might end up with
duplicated friend declarations. This is fine as far as C++ is concerned,
but triggers gcc's redundant-decls warning.

Given that we require the friend declaration, and would like to keep it
in the macros that actually need them (instead of putting them into the
macros which are used in all types exposed to QML), we opt for
suppressing the warning.

Pick-to: 6.5 6.7
Fixes: QTBUG-124934
Change-Id: I4f43afddfefb6e546ddddbdc01435222398a06be
Reviewed-by: Volker Hilsheimer &lt;volker.hilsheimer@qt.io&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Use NO_GENERATE_CPP_EXPORTS explicitly</title>
<updated>2024-03-20T11:40:43+00:00</updated>
<author>
<name>Alexey Edelev</name>
<email>alexey.edelev@qt.io</email>
</author>
<published>2023-11-28T13:24:37+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=276c13441fae123c2adbed86604f658d4c9ccc2d'/>
<id>276c13441fae123c2adbed86604f658d4c9ccc2d</id>
<content type='text'>
Use NO_GENERATE_CPP_EXPORTS explicitly for modules that don't need
the autogenerated exports header file.

Task-number: QTBUG-90492
Change-Id: I6b2b9949f4592de399517dc5e8c7bd96dc7120d6
Reviewed-by: Ulf Hermann &lt;ulf.hermann@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Use NO_GENERATE_CPP_EXPORTS explicitly for modules that don't need
the autogenerated exports header file.

Task-number: QTBUG-90492
Change-Id: I6b2b9949f4592de399517dc5e8c7bd96dc7120d6
Reviewed-by: Ulf Hermann &lt;ulf.hermann@qt.io&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Make builtins an actual module</title>
<updated>2023-11-24T03:26:56+00:00</updated>
<author>
<name>Ulf Hermann</name>
<email>ulf.hermann@qt.io</email>
</author>
<published>2023-11-08T13:20:17+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=a021bd427328c495cf9969be820a3cfbd41996c6'/>
<id>a021bd427328c495cf9969be820a3cfbd41996c6</id>
<content type='text'>
This way we can eventually use the metatypes generated by the builtins
to validate other module using qmltyperegistrar, and throw informed
warnings if types are missing.

qmltyperegistrar automatically picks up the metatypes of any library
linked into a target. This means it always picks up the builtins
metatypes now when QtQml is linked in.

We now have to check more closely whether an object binding is actually
a group property. QVariant now has a value type metaobject and does not
pass as "unknown thing" anymore.

We also have to move the QML_FOREIGN macros to QQmlIntegration since we
want QML_FOREIGN to declare the builtins but we don't want to depend on
QtQml.

Task-number: QTBUG-101143
Change-Id: I9f1a2713797291b6624aef0ade599d19e0766907
Reviewed-by: Alexey Edelev &lt;alexey.edelev@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This way we can eventually use the metatypes generated by the builtins
to validate other module using qmltyperegistrar, and throw informed
warnings if types are missing.

qmltyperegistrar automatically picks up the metatypes of any library
linked into a target. This means it always picks up the builtins
metatypes now when QtQml is linked in.

We now have to check more closely whether an object binding is actually
a group property. QVariant now has a value type metaobject and does not
pass as "unknown thing" anymore.

We also have to move the QML_FOREIGN macros to QQmlIntegration since we
want QML_FOREIGN to declare the builtins but we don't want to depend on
QtQml.

Task-number: QTBUG-101143
Change-Id: I9f1a2713797291b6624aef0ade599d19e0766907
Reviewed-by: Alexey Edelev &lt;alexey.edelev@qt.io&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>QML: Fix conflicts between QML_ANONYMOUS, QML_UNCREATABLE and namespaces</title>
<updated>2023-02-28T20:06:06+00:00</updated>
<author>
<name>Ulf Hermann</name>
<email>ulf.hermann@qt.io</email>
</author>
<published>2023-02-27T13:19:23+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=a60968283b9ca0f5711b8d5b28550b81b61403f2'/>
<id>a60968283b9ca0f5711b8d5b28550b81b61403f2</id>
<content type='text'>
Even though it makes no sense, we have to allow QML_ANONYMOUS and
QML_UNCREATABLE in the same class since we've documented it. You
cannot trigger the custom message because you'd need a name to attempt
to create an instance of the type. Therefore, the documentation
suggesting this is nonsensical.

In theory you could indeed provide a custom message for namespaces, but
in order to continue supporting this, we would either have to drop the
QmlIsUncreatable mechanism, or we would need a different macro. So,
let's drop this for now. If we really need it, we can introduce a
different macro later.

[ChangeLog][QtQml][Important Behavior Changes] You can no longer
override the "uncreatable" message for QML-exposed namespaces using
QML_UNCREATABLE. This would be incompatible with making the
QML_UNCREATABLE macro safe from unintended inheritance. The latter is
much more important.

Pick-to: 6.5
Fixes: QTBUG-111470
Change-Id: Ib736a2411128d58d939fa2a57d28a0b31c0777e6
Reviewed-by: Robert Griebl &lt;robert.griebl@qt.io&gt;
Reviewed-by: Fabian Kosmale &lt;fabian.kosmale@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Even though it makes no sense, we have to allow QML_ANONYMOUS and
QML_UNCREATABLE in the same class since we've documented it. You
cannot trigger the custom message because you'd need a name to attempt
to create an instance of the type. Therefore, the documentation
suggesting this is nonsensical.

In theory you could indeed provide a custom message for namespaces, but
in order to continue supporting this, we would either have to drop the
QmlIsUncreatable mechanism, or we would need a different macro. So,
let's drop this for now. If we really need it, we can introduce a
different macro later.

[ChangeLog][QtQml][Important Behavior Changes] You can no longer
override the "uncreatable" message for QML-exposed namespaces using
QML_UNCREATABLE. This would be incompatible with making the
QML_UNCREATABLE macro safe from unintended inheritance. The latter is
much more important.

Pick-to: 6.5
Fixes: QTBUG-111470
Change-Id: Ib736a2411128d58d939fa2a57d28a0b31c0777e6
Reviewed-by: Robert Griebl &lt;robert.griebl@qt.io&gt;
Reviewed-by: Fabian Kosmale &lt;fabian.kosmale@qt.io&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>QML: Output a warning for creatable object types without default ctor</title>
<updated>2023-01-23T21:27:38+00:00</updated>
<author>
<name>Ulf Hermann</name>
<email>ulf.hermann@qt.io</email>
</author>
<published>2023-01-16T14:00:46+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=6bdeafcad69aeb6b615129c1a3399e4c2bce2d28'/>
<id>6bdeafcad69aeb6b615129c1a3399e4c2bce2d28</id>
<content type='text'>
Pick-to: 6.5
Fixes: QTBUG-104899
Change-Id: I237ddb68968b26c1ce41051ab3bd3c66fb1712f1
Reviewed-by: Fabian Kosmale &lt;fabian.kosmale@qt.io&gt;
Reviewed-by: Qt CI Bot &lt;qt_ci_bot@qt-project.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Pick-to: 6.5
Fixes: QTBUG-104899
Change-Id: I237ddb68968b26c1ce41051ab3bd3c66fb1712f1
Reviewed-by: Fabian Kosmale &lt;fabian.kosmale@qt.io&gt;
Reviewed-by: Qt CI Bot &lt;qt_ci_bot@qt-project.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Allow more options for creating value types from JS objects</title>
<updated>2022-09-24T07:54:29+00:00</updated>
<author>
<name>Ulf Hermann</name>
<email>ulf.hermann@qt.io</email>
</author>
<published>2022-09-08T12:41:42+00:00</published>
<link rel='alternate' type='text/html' href='https://code.qt.io/cgit/qt/qtdeclarative.git/commit/?id=3195b44e1c9678584c05ed823aab2eb32518d868'/>
<id>3195b44e1c9678584c05ed823aab2eb32518d868</id>
<content type='text'>
We allow value types to be created
1. by calling Q_INVOKABLE constructors
2. by setting their values from properties of a JS object

Both have to be opted into by setting a class info. If opted into, these
options override the existing methods. When a a type can be created by
setting its properties, that implies you can also initialize it using an
invokable constructor. However, when given a JS object, the properties
method is used.

We keep this internal and undocumented for now. As the last try (the
create(QJSValue) methods and QJSValue ctors) was not that stellar, let's
first wait a bit and see if we're getting it right this time around.

Fixes: QTBUG-106480
Change-Id: I767230924afcba032d501846cc3263dad57b7bf0
Reviewed-by: Volker Hilsheimer &lt;volker.hilsheimer@qt.io&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We allow value types to be created
1. by calling Q_INVOKABLE constructors
2. by setting their values from properties of a JS object

Both have to be opted into by setting a class info. If opted into, these
options override the existing methods. When a a type can be created by
setting its properties, that implies you can also initialize it using an
invokable constructor. However, when given a JS object, the properties
method is used.

We keep this internal and undocumented for now. As the last try (the
create(QJSValue) methods and QJSValue ctors) was not that stellar, let's
first wait a bit and see if we're getting it right this time around.

Fixes: QTBUG-106480
Change-Id: I767230924afcba032d501846cc3263dad57b7bf0
Reviewed-by: Volker Hilsheimer &lt;volker.hilsheimer@qt.io&gt;
</pre>
</div>
</content>
</entry>
</feed>
