diff options
| author | Thiago Macieira <thiago.macieira@intel.com> | 2024-10-07 21:27:42 -0700 |
|---|---|---|
| committer | Thiago Macieira <thiago.macieira@intel.com> | 2024-11-20 21:42:55 -0800 |
| commit | ea3288c9b6687d6ace5fa0fc7fd525f2387b68b5 (patch) | |
| tree | d3d27df5f847e78e701285dd0eadd4f7b381eab0 /src | |
| parent | 8fabcb642f3a156ac5f97aa82ac722df3472dbfb (diff) | |
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>
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/moc/generator.cpp | 55 | ||||
| -rw-r--r-- | src/tools/moc/moc.cpp | 11 | ||||
| -rw-r--r-- | src/tools/moc/moc.h | 11 |
3 files changed, 57 insertions, 20 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 0b8b9c05226..54972ade90e 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -35,6 +35,20 @@ uint nameToBuiltinType(const QByteArray &name) 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. */ @@ -710,8 +724,8 @@ void Generator::addProperties() { for (const PropertyDef &p : std::as_const(cdef->propertyList)) { fprintf(out, " // property '%s'\n" - " QtMocHelpers::PropertyData<%s>(%d, ", - p.name.constData(), p.type.constData(), stridx(p.name)); + " QtMocHelpers::PropertyData<%s%s>(%d, ", + p.name.constData(), cxxTypeTag(p.typeTag), p.type.constData(), stridx(p.name)); generateTypeInfo(p.type); fputc(',', out); @@ -888,9 +902,10 @@ QMultiMap<QByteArray, int> Generator::automaticPropertyMetaTypesHelper() { QMultiMap<QByteArray, int> automaticPropertyMetaTypes; 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)) - automaticPropertyMetaTypes.insert(propertyType, i); + automaticPropertyMetaTypes.insert(cxxTypeTag(p.typeTag) + propertyType, i); } return automaticPropertyMetaTypes; } @@ -1157,14 +1172,17 @@ void Generator::generateStaticMetacall() propindex, p.type.constData(), prefix.constData(), p.read.constData()); #endif else if (p.read == "default") - fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s().value(); break;\n", - propindex, p.type.constData(), prefix.constData(), p.bind.constData()); + fprintf(out, " case %d: *reinterpret_cast<%s%s*>(_v) = %s%s().value(); break;\n", + propindex, cxxTypeTag(p.typeTag), p.type.constData(), + prefix.constData(), p.bind.constData()); else if (!p.read.isEmpty()) - fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n", - propindex, p.type.constData(), prefix.constData(), p.read.constData()); + fprintf(out, " case %d: *reinterpret_cast<%s%s*>(_v) = %s%s(); break;\n", + propindex, cxxTypeTag(p.typeTag), p.type.constData(), + prefix.constData(), p.read.constData()); else - fprintf(out, " case %d: *reinterpret_cast< %s*>(_v) = %s%s; break;\n", - propindex, p.type.constData(), prefix.constData(), p.member.constData()); + fprintf(out, " case %d: *reinterpret_cast<%s%s*>(_v) = %s%s; break;\n", + propindex, cxxTypeTag(p.typeTag), p.type.constData(), + prefix.constData(), p.member.constData()); } fprintf(out, " default: break;\n"); fprintf(out, " }\n"); @@ -1187,21 +1205,22 @@ void Generator::generateStaticMetacall() } if (p.write == "default") { fprintf(out, " case %d: {\n", propindex); - fprintf(out, " %s%s().setValue(*reinterpret_cast< %s*>(_v));\n", - prefix.constData(), p.bind.constData(), p.type.constData()); + fprintf(out, " %s%s().setValue(*reinterpret_cast<%s%s*>(_v));\n", + prefix.constData(), p.bind.constData(), cxxTypeTag(p.typeTag), p.type.constData()); fprintf(out, " break;\n"); fprintf(out, " }\n"); } else if (!p.write.isEmpty()) { - fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n", - propindex, prefix.constData(), p.write.constData(), p.type.constData()); + fprintf(out, " case %d: %s%s(*reinterpret_cast<%s%s*>(_v)); break;\n", + propindex, prefix.constData(), p.write.constData(), + cxxTypeTag(p.typeTag), p.type.constData()); } else { fprintf(out, " case %d:", propindex); if (p.notify.isEmpty()) { - fprintf(out, " QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s*>(_v)); break;\n", - prefix.constData(), p.member.constData(), p.type.constData()); + fprintf(out, " QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s%s*>(_v)); break;\n", + prefix.constData(), p.member.constData(), cxxTypeTag(p.typeTag), p.type.constData()); } else { - fprintf(out, "\n if (QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s*>(_v)))\n", - prefix.constData(), p.member.constData(), p.type.constData()); + fprintf(out, "\n if (QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s%s*>(_v)))\n", + prefix.constData(), p.member.constData(), cxxTypeTag(p.typeTag), p.type.constData()); fprintf(out, " Q_EMIT _t->%s(", p.notify.constData()); if (p.notifyId > -1) { const FunctionDef &f = cdef->signalList.at(p.notifyId); diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index f15109dea26..d4b6286b10c 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -162,7 +162,12 @@ Type Moc::parseType() } 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(;;) { skipCxxAttributes(); switch (next()) { @@ -1326,9 +1331,11 @@ void Moc::createPropertyDef(PropertyDef &propDef, int propertyIndex, Moc::Proper propDef.location = index; propDef.relativeIndex = propertyIndex; - QByteArray type = parseType().name; + Type t = parseType(); + QByteArray type = t.name; if (type.isEmpty()) error(); + propDef.typeTag = t.typeTag; propDef.designable = propDef.scriptable = propDef.stored = "true"; propDef.user = "false"; /* diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index 27caeda953b..549c294867b 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -20,6 +20,15 @@ QT_BEGIN_NAMESPACE 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 { enum ReferenceType { NoReference, Reference, RValueReference, Pointer }; @@ -33,6 +42,7 @@ struct Type QByteArray rawName; uint isVolatile : 1; uint isScoped : 1; + TypeTags typeTag; Token firstToken; ReferenceType referenceType; }; @@ -116,6 +126,7 @@ struct PropertyDef enum Specification { ValueSpec, ReferenceSpec, PointerSpec }; Specification gspec = ValueSpec; int revision = 0; + TypeTags typeTag; bool constant = false; bool final = false; bool required = false; |
