Support Q_GADGET QMetaObject super class hierarchies across templates
This patch fixes the QMetaObject::superClass hierarchy for Q_GADGETs that inherit from a template which in turn inherits another Q_GADGET. One common scenario where this is applied is for the CRTP. Without this patch, moc would stop at the template and then sets the superClass QMetaObject to a nullptr. For QObjects this works, since there moc knows that every child must by definition inherit QObject. In order to support this for Q_GADGETs too, we defer the judgment about the availability of a staticMetaObject in the base class to compile time through the existing QtPrivate::MetaObjectForType<Base>::value() helper. [ChangeLog][QtCore][moc] Moc now correctly sets a non-null QMetaObject::superClass for Q_GADGETs that inherit from a template which inherits another Q_GADGET. Change-Id: I103b5efd74ed24172dffce477ca2ed6d0f374d44 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>bb10
parent
83818431e1
commit
656d6f2a9b
|
|
@ -541,8 +541,10 @@ void Generator::generateCode()
|
|||
|
||||
if (isQObject)
|
||||
fprintf(out, " nullptr,\n");
|
||||
else if (cdef->superclassList.size() && (!cdef->hasQGadget || knownGadgets.contains(purestSuperClass)))
|
||||
else if (cdef->superclassList.size() && !cdef->hasQGadget) // for qobject, we know the super class must have a static metaobject
|
||||
fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData());
|
||||
else if (cdef->superclassList.size()) // for gadgets we need to query at compile time for it
|
||||
fprintf(out, " QtPrivate::MetaObjectForType<%s>::value(),\n", purestSuperClass.constData());
|
||||
else
|
||||
fprintf(out, " nullptr,\n");
|
||||
fprintf(out, " qt_meta_stringdata_%s.data,\n"
|
||||
|
|
|
|||
|
|
@ -2061,6 +2061,17 @@
|
|||
"name": "Derived"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"className": "CRTPDerivedGadget",
|
||||
"gadget": true,
|
||||
"qualifiedClassName": "GrandParentGadget::CRTPDerivedGadget",
|
||||
"superClasses": [
|
||||
{
|
||||
"access": "public",
|
||||
"name": "CRTP<CRTPDerivedGadget>"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"inputFile": "grand-parent-gadget-class.h",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ namespace GrandParentGadget {
|
|||
struct BaseGadget { Q_GADGET };
|
||||
struct Derived : BaseGadget {};
|
||||
struct DerivedGadget : Derived { Q_GADGET };
|
||||
|
||||
template<typename T> struct CRTP : BaseGadget {};
|
||||
struct CRTPDerivedGadget : CRTP<CRTPDerivedGadget> { Q_GADGET };
|
||||
}
|
||||
|
||||
#endif // GRANDPARENTGADGETCLASS_H
|
||||
|
|
|
|||
|
|
@ -3836,6 +3836,7 @@ void tst_Moc::gadgetHierarchy()
|
|||
{
|
||||
QCOMPARE(NonGadgetParent::Derived::staticMetaObject.superClass(), static_cast<const QMetaObject*>(nullptr));
|
||||
QCOMPARE(GrandParentGadget::DerivedGadget::staticMetaObject.superClass(), &GrandParentGadget::BaseGadget::staticMetaObject);
|
||||
QCOMPARE(GrandParentGadget::CRTPDerivedGadget::staticMetaObject.superClass(), &GrandParentGadget::BaseGadget::staticMetaObject);
|
||||
}
|
||||
|
||||
void tst_Moc::optionsFileError_data()
|
||||
|
|
|
|||
Loading…
Reference in New Issue