summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2024-10-07 21:27:42 -0700
committerThiago Macieira <thiago.macieira@intel.com>2024-11-20 21:42:55 -0800
commitea3288c9b6687d6ace5fa0fc7fd525f2387b68b5 (patch)
treed3d27df5f847e78e701285dd0eadd4f7b381eab0 /src
parent8fabcb642f3a156ac5f97aa82ac722df3472dbfb (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.cpp55
-rw-r--r--src/tools/moc/moc.cpp11
-rw-r--r--src/tools/moc/moc.h11
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;