moc: keep the enum/class/struct C++ type tag in properties
ActiveQt dumpcpp could use this so Q_PROPERTY(class Accounts *Accounts READ Accounts) can compile. moc will now generate: QtMocHelpers::UintData qt_properties { // property 'Accounts' QtMocHelpers::PropertyData<class Accounts*>(1, 0x80000000 | 2, QMC::DefaultPropertyFlags | QMC::EnumOrFlag), }; if (_c == QMetaObject::RegisterPropertyMetaType) { switch (_id) { default: *reinterpret_cast<int*>(_a[0]) = -1; break; case 0: *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< class Accounts* >(); break; } } if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast<class Accounts**>(_v) = _t->Accounts(); break; default: break; } } Change-Id: Ibb85c3a067054d017b05fffdbd500f302f655bd9 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
8fabcb642f
commit
ea3288c9b6
@ -35,6 +35,20 @@ uint nameToBuiltinType(const QByteArray &name)
|
|||||||
return tp < uint(QMetaType::User) ? tp : uint(QMetaType::UnknownType);
|
return tp < uint(QMetaType::User) ? tp : uint(QMetaType::UnknownType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr const char *cxxTypeTag(TypeTags t)
|
||||||
|
{
|
||||||
|
if (t & TypeTag::HasEnum) {
|
||||||
|
if (t & TypeTag::HasClass)
|
||||||
|
return "enum class ";
|
||||||
|
if (t & TypeTag::HasStruct)
|
||||||
|
return "enum struct ";
|
||||||
|
return "enum ";
|
||||||
|
}
|
||||||
|
if (t & TypeTag::HasClass) return "class ";
|
||||||
|
if (t & TypeTag::HasStruct) return "struct ";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns \c true if the type is a built-in type.
|
Returns \c true if the type is a built-in type.
|
||||||
*/
|
*/
|
||||||
@ -710,8 +724,8 @@ void Generator::addProperties()
|
|||||||
{
|
{
|
||||||
for (const PropertyDef &p : std::as_const(cdef->propertyList)) {
|
for (const PropertyDef &p : std::as_const(cdef->propertyList)) {
|
||||||
fprintf(out, " // property '%s'\n"
|
fprintf(out, " // property '%s'\n"
|
||||||
" QtMocHelpers::PropertyData<%s>(%d, ",
|
" QtMocHelpers::PropertyData<%s%s>(%d, ",
|
||||||
p.name.constData(), p.type.constData(), stridx(p.name));
|
p.name.constData(), cxxTypeTag(p.typeTag), p.type.constData(), stridx(p.name));
|
||||||
generateTypeInfo(p.type);
|
generateTypeInfo(p.type);
|
||||||
fputc(',', out);
|
fputc(',', out);
|
||||||
|
|
||||||
@ -888,9 +902,10 @@ QMultiMap<QByteArray, int> Generator::automaticPropertyMetaTypesHelper()
|
|||||||
{
|
{
|
||||||
QMultiMap<QByteArray, int> automaticPropertyMetaTypes;
|
QMultiMap<QByteArray, int> automaticPropertyMetaTypes;
|
||||||
for (int i = 0; i < int(cdef->propertyList.size()); ++i) {
|
for (int i = 0; i < int(cdef->propertyList.size()); ++i) {
|
||||||
const QByteArray propertyType = cdef->propertyList.at(i).type;
|
const PropertyDef &p = cdef->propertyList.at(i);
|
||||||
|
const QByteArray propertyType = p.type;
|
||||||
if (registerableMetaType(propertyType) && !isBuiltinType(propertyType))
|
if (registerableMetaType(propertyType) && !isBuiltinType(propertyType))
|
||||||
automaticPropertyMetaTypes.insert(propertyType, i);
|
automaticPropertyMetaTypes.insert(cxxTypeTag(p.typeTag) + propertyType, i);
|
||||||
}
|
}
|
||||||
return automaticPropertyMetaTypes;
|
return automaticPropertyMetaTypes;
|
||||||
}
|
}
|
||||||
@ -1157,14 +1172,17 @@ void Generator::generateStaticMetacall()
|
|||||||
propindex, p.type.constData(), prefix.constData(), p.read.constData());
|
propindex, p.type.constData(), prefix.constData(), p.read.constData());
|
||||||
#endif
|
#endif
|
||||||
else if (p.read == "default")
|
else if (p.read == "default")
|
||||||
fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s().value(); break;\n",
|
fprintf(out, " case %d: *reinterpret_cast<%s%s*>(_v) = %s%s().value(); break;\n",
|
||||||
propindex, p.type.constData(), prefix.constData(), p.bind.constData());
|
propindex, cxxTypeTag(p.typeTag), p.type.constData(),
|
||||||
|
prefix.constData(), p.bind.constData());
|
||||||
else if (!p.read.isEmpty())
|
else if (!p.read.isEmpty())
|
||||||
fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n",
|
fprintf(out, " case %d: *reinterpret_cast<%s%s*>(_v) = %s%s(); break;\n",
|
||||||
propindex, p.type.constData(), prefix.constData(), p.read.constData());
|
propindex, cxxTypeTag(p.typeTag), p.type.constData(),
|
||||||
|
prefix.constData(), p.read.constData());
|
||||||
else
|
else
|
||||||
fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s; break;\n",
|
fprintf(out, " case %d: *reinterpret_cast<%s%s*>(_v) = %s%s; break;\n",
|
||||||
propindex, p.type.constData(), prefix.constData(), p.member.constData());
|
propindex, cxxTypeTag(p.typeTag), p.type.constData(),
|
||||||
|
prefix.constData(), p.member.constData());
|
||||||
}
|
}
|
||||||
fprintf(out, " default: break;\n");
|
fprintf(out, " default: break;\n");
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
@ -1187,21 +1205,22 @@ void Generator::generateStaticMetacall()
|
|||||||
}
|
}
|
||||||
if (p.write == "default") {
|
if (p.write == "default") {
|
||||||
fprintf(out, " case %d: {\n", propindex);
|
fprintf(out, " case %d: {\n", propindex);
|
||||||
fprintf(out, " %s%s().setValue(*reinterpret_cast< %s*>(_v));\n",
|
fprintf(out, " %s%s().setValue(*reinterpret_cast<%s%s*>(_v));\n",
|
||||||
prefix.constData(), p.bind.constData(), p.type.constData());
|
prefix.constData(), p.bind.constData(), cxxTypeTag(p.typeTag), p.type.constData());
|
||||||
fprintf(out, " break;\n");
|
fprintf(out, " break;\n");
|
||||||
fprintf(out, " }\n");
|
fprintf(out, " }\n");
|
||||||
} else if (!p.write.isEmpty()) {
|
} else if (!p.write.isEmpty()) {
|
||||||
fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n",
|
fprintf(out, " case %d: %s%s(*reinterpret_cast<%s%s*>(_v)); break;\n",
|
||||||
propindex, prefix.constData(), p.write.constData(), p.type.constData());
|
propindex, prefix.constData(), p.write.constData(),
|
||||||
|
cxxTypeTag(p.typeTag), p.type.constData());
|
||||||
} else {
|
} else {
|
||||||
fprintf(out, " case %d:", propindex);
|
fprintf(out, " case %d:", propindex);
|
||||||
if (p.notify.isEmpty()) {
|
if (p.notify.isEmpty()) {
|
||||||
fprintf(out, " QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s*>(_v)); break;\n",
|
fprintf(out, " QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s%s*>(_v)); break;\n",
|
||||||
prefix.constData(), p.member.constData(), p.type.constData());
|
prefix.constData(), p.member.constData(), cxxTypeTag(p.typeTag), p.type.constData());
|
||||||
} else {
|
} else {
|
||||||
fprintf(out, "\n if (QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s*>(_v)))\n",
|
fprintf(out, "\n if (QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s%s*>(_v)))\n",
|
||||||
prefix.constData(), p.member.constData(), p.type.constData());
|
prefix.constData(), p.member.constData(), cxxTypeTag(p.typeTag), p.type.constData());
|
||||||
fprintf(out, " Q_EMIT _t->%s(", p.notify.constData());
|
fprintf(out, " Q_EMIT _t->%s(", p.notify.constData());
|
||||||
if (p.notifyId > -1) {
|
if (p.notifyId > -1) {
|
||||||
const FunctionDef &f = cdef->signalList.at(p.notifyId);
|
const FunctionDef &f = cdef->signalList.at(p.notifyId);
|
||||||
|
@ -162,7 +162,12 @@ Type Moc::parseType()
|
|||||||
}
|
}
|
||||||
|
|
||||||
skipCxxAttributes();
|
skipCxxAttributes();
|
||||||
test(ENUM) || test(CLASS) || test(STRUCT);
|
if (test(ENUM))
|
||||||
|
type.typeTag = TypeTag::HasEnum;
|
||||||
|
if (test(CLASS))
|
||||||
|
type.typeTag |= TypeTag::HasClass;
|
||||||
|
if (test(STRUCT))
|
||||||
|
type.typeTag |= TypeTag::HasStruct;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
skipCxxAttributes();
|
skipCxxAttributes();
|
||||||
switch (next()) {
|
switch (next()) {
|
||||||
@ -1326,9 +1331,11 @@ void Moc::createPropertyDef(PropertyDef &propDef, int propertyIndex, Moc::Proper
|
|||||||
propDef.location = index;
|
propDef.location = index;
|
||||||
propDef.relativeIndex = propertyIndex;
|
propDef.relativeIndex = propertyIndex;
|
||||||
|
|
||||||
QByteArray type = parseType().name;
|
Type t = parseType();
|
||||||
|
QByteArray type = t.name;
|
||||||
if (type.isEmpty())
|
if (type.isEmpty())
|
||||||
error();
|
error();
|
||||||
|
propDef.typeTag = t.typeTag;
|
||||||
propDef.designable = propDef.scriptable = propDef.stored = "true";
|
propDef.designable = propDef.scriptable = propDef.stored = "true";
|
||||||
propDef.user = "false";
|
propDef.user = "false";
|
||||||
/*
|
/*
|
||||||
|
@ -20,6 +20,15 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
struct QMetaObject;
|
struct QMetaObject;
|
||||||
|
|
||||||
|
enum class TypeTag : uchar {
|
||||||
|
None,
|
||||||
|
HasStruct = 0x01,
|
||||||
|
HasClass = 0x02,
|
||||||
|
HasEnum = 0x04,
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(TypeTags, TypeTag)
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(TypeTags)
|
||||||
|
|
||||||
struct Type
|
struct Type
|
||||||
{
|
{
|
||||||
enum ReferenceType { NoReference, Reference, RValueReference, Pointer };
|
enum ReferenceType { NoReference, Reference, RValueReference, Pointer };
|
||||||
@ -33,6 +42,7 @@ struct Type
|
|||||||
QByteArray rawName;
|
QByteArray rawName;
|
||||||
uint isVolatile : 1;
|
uint isVolatile : 1;
|
||||||
uint isScoped : 1;
|
uint isScoped : 1;
|
||||||
|
TypeTags typeTag;
|
||||||
Token firstToken;
|
Token firstToken;
|
||||||
ReferenceType referenceType;
|
ReferenceType referenceType;
|
||||||
};
|
};
|
||||||
@ -116,6 +126,7 @@ struct PropertyDef
|
|||||||
enum Specification { ValueSpec, ReferenceSpec, PointerSpec };
|
enum Specification { ValueSpec, ReferenceSpec, PointerSpec };
|
||||||
Specification gspec = ValueSpec;
|
Specification gspec = ValueSpec;
|
||||||
int revision = 0;
|
int revision = 0;
|
||||||
|
TypeTags typeTag;
|
||||||
bool constant = false;
|
bool constant = false;
|
||||||
bool final = false;
|
bool final = false;
|
||||||
bool required = false;
|
bool required = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user