No idea if this is helpful, but it seems that what was later renamed
QFlag was introduced as QFlagInternal in this commit:
commit dc289baeeb131bddbe6cff5c5620f76f5fac90de
Author: Paul Olav Tvete <p...@trolltech.com>
Date: Thu Aug 7 17:44:28 2003 +0100
Also work with more pedantic compilers.
[git-p4: depot-paths = "//depot/qt/main/": change = 109613]
diff --git a/src/moc/moc.y b/src/moc/moc.y
index 977e875f3b4..818c9d7adb8 100644
--- a/src/moc/moc.y
+++ b/src/moc/moc.y
@@ -2427,10 +2427,14 @@ void generateMetacall()
fprintf(out, " case %d: _o[0] =
(void*)&%s(); break;\n",
propindex,
(const char *)p->read);
- else
+ else if (isVariantType(p->type))
fprintf(out, " case %d: *(%s*)_v = %s();
break;\n",
propindex,
- !isVariantType(p->type) ? "int" : (const
char *)p->type,
+ (const char *)p->type,
+ (const char *)p->read);
+ else
+ fprintf(out, " case %d: *(int*)_v =
(QFlagInternal)%s(); break;\n",
+ propindex,
(const char *)p->read);
}
fprintf(out,
@@ -2448,7 +2452,13 @@ void generateMetacall()
int propindex = -1;
for (p = g->props.first(); p; p = g->props.next()) {
++propindex;
- if (!p->write.isEmpty()) {
+ if (p->write.isEmpty())
+ continue;
+ if (isSetType(p->type)) {
+ fprintf(out, " case %d:
%s(QFlagInternal(*(int*)_v)); break;\n",
+ propindex,
+ (const char *)p->write );
+ } else {
fprintf(out, " case %d: %s(*(%s*)_v); break;\n",
propindex,
(const char *)p->write,
diff --git a/src/tools/qglobal.h b/src/tools/qglobal.h
index 5e124d6c286..08ab4ef761e 100644
--- a/src/tools/qglobal.h
+++ b/src/tools/qglobal.h
@@ -1186,6 +1186,15 @@ inline T qt_cast(const QObject *object)
template <> inline IFace *qt_cast<IFace *>(const QObject *object) \
{ return (IFace *)(object ? object->qt_metacast(#IFace) : 0); }
+class QFlagInternal
+{
+public:
+ QFlagInternal(int i) : i(i) {}
+ operator int() const { return i; }
+private:
+ int i;
+};
+
template<typename Enum>
class QFlags
{
@@ -1194,14 +1203,24 @@ public:
inline QFlags(const QFlags &f) : u(f.u) {}
inline QFlags(Enum f) : u(f) {}
inline QFlags(Zero * = 0) : u(0) {}
+ inline QFlags(QFlagInternal i) : u(i) {}
+ inline operator QFlagInternal() const { return u; }
inline QFlags &operator=(const QFlags &f) { u = f.u; return *this; }
- inline operator int() const { return u; }
+ inline operator Zero*() const { return reinterpret_cast<Zero*>(u ?
0x1:0x0); }
+ inline bool operator!() const { return !u; }
inline QFlags operator|(QFlags f) const { QFlags wf; wf.u = u|f.u;
return wf; }
inline QFlags operator|(Enum f) const { QFlags wf; wf.u = u|f;
return wf; }
- inline QFlags operator&(int mask) const { QFlags wf; wf.u = u&mask;
return wf; }
+// inline QFlags operator&(int mask) const { QFlags wf; wf.u =
u&mask; return wf; }
+ inline QFlags operator&(uint mask) const { QFlags wf; wf.u =
u&mask; return wf; }
+ inline QFlags operator&(QFlags f) const { QFlags wf; wf.u = u&f.u;
return wf; }
+ inline QFlags operator&(Enum f) const { QFlags wf; wf.u = u&f;
return wf; }
+ inline QFlags operator~() const { QFlags wf; wf.u = ~u; return wf; }
+
inline QFlags &operator&=(int mask) { u &= mask; return *this; }
+ inline QFlags &operator&=(QFlags f) { u &= f.u; return *this; }
+ inline QFlags &operator&=(Enum f) { u &= f; return *this; }
inline QFlags &operator|=(QFlags f) { u |= f.u; return *this; }
inline QFlags &operator|=(Enum f) { u |= f; return *this; }
On 9/10/24 02:18, Thiago Macieira wrote:
Can someone look up the history of ths class in qflags.h? That or its use in
src/tools/moc/generator.cpp (it's used in one line)
moc uses this class to generate code for Q_PROPERTYs whose type was seen to be
be the result of a Q_DECLARE_FLAGS. Then, instead of emitting the property
getter/setter on the actual QFlags<E> type, it emits something based on an
integer, such as in moc_qlibrary.cpp:
case 1:
*reinterpret_cast<LoadHints::Int *>(_v) = _t->loadHints().toInt(); break;
case 1:
_t->setLoadHints(QFlag(*reinterpret_cast<LoadHints::Int*>(_v))); break;
I do not understand why it is using integers here in the first place and I
don't think this is implemented correctly either. Before I even attempt to fix
this, I need to understand why it emits code like above. Specifically:
Why is it using QFlag instead of LoadHints::enum_type?
The only reason I can think of is that this allows the setter function to take
an integer instead of the QFlags type, because QFlag can be implicitly
converted to any QFlags and to int. But I am not confident that this was the
goal, as opposed to a side-effect.
This code is NOT matched by QMetaProperty;:read and write. Those create a
QVariant of the actual property type (the QFlags), so the reinterpret_casts to
Int above are type punning.
Also note this does not apply if the QFlags type was not seen to be a
Q_DECLARE_FLAGS, such as when it is not from that class, as in
(moc_qwindow.cpp):
case 2: *reinterpret_cast< Qt::WindowFlags*>(_v) = _t->flags(); break;
case 2: _t->setFlags(*reinterpret_cast< Qt::WindowFlags*>(_v)); break;
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development