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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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";
|
||||
/*
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user