Skip to content

Commit

Permalink
moc: use EnumFlags in EnumDef
Browse files Browse the repository at this point in the history
Change-Id: I8a96935cf6c742259c9dfffd17e950a5230e2465
Reviewed-by: Fabian Kosmale <[email protected]>
Reviewed-by: Ahmad Samir <[email protected]>
  • Loading branch information
thiagomacieira committed Aug 14, 2024
1 parent 0cbc50b commit 1791d88
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 26 deletions.
21 changes: 8 additions & 13 deletions src/tools/moc/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,11 +907,7 @@ void Generator::generateEnums(int index)
int i;
for (i = 0; i < cdef->enumList.size(); ++i) {
const EnumDef &e = cdef->enumList.at(i);
int flags = 0;
if (cdef->enumDeclarations.value(e.name))
flags |= EnumIsFlag;
if (e.isEnumClass)
flags |= EnumIsScoped;
uint flags = e.flags | cdef->enumDeclarations.value(e.name);
fprintf(out, " %4d, %4d, 0x%.1x, %4d, %4d,\n",
stridx(e.name),
e.enumName.isNull() ? stridx(e.name) : stridx(e.enumName),
Expand All @@ -923,13 +919,12 @@ void Generator::generateEnums(int index)

fprintf(out, "\n // enum data: key, value\n");
for (const EnumDef &e : std::as_const(cdef->enumList)) {
QByteArray prefix = cdef->qualified;
if (e.flags & EnumIsScoped)
prefix += "::" + (e.enumName.isNull() ? e.name : e.enumName);
for (const QByteArray &val : e.values) {
QByteArray code = cdef->qualified.constData();
if (e.isEnumClass)
code += "::" + (e.enumName.isNull() ? e.name : e.enumName);
code += "::" + val;
fprintf(out, " %4d, uint(%s),\n",
stridx(val), code.constData());
fprintf(out, " %4d, uint(%s::%s),\n",
stridx(val), prefix.constData(), val.constData());
}
}
}
Expand Down Expand Up @@ -1289,7 +1284,7 @@ void Generator::generateStaticMetacall()
else if (p.gspec == PropertyDef::ReferenceSpec)
fprintf(out, " case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s%s())); break;\n",
propindex, prefix.constData(), p.read.constData());
else if (cdef->enumDeclarations.value(p.type, false))
else if (auto eflags = cdef->enumDeclarations.value(p.type); eflags & EnumIsFlag)
fprintf(out, " case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n",
propindex, prefix.constData(), p.read.constData());
else if (p.read == "default")
Expand Down Expand Up @@ -1325,7 +1320,7 @@ void Generator::generateStaticMetacall()
if (p.inPrivateClass.size()) {
prefix += p.inPrivateClass + "->";
}
if (cdef->enumDeclarations.value(p.type, false)) {
if (auto eflags = cdef->enumDeclarations.value(p.type); eflags & EnumIsFlag) {
fprintf(out, " case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
propindex, prefix.constData(), p.write.constData());
} else if (p.write == "default") {
Expand Down
20 changes: 11 additions & 9 deletions src/tools/moc/moc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <QtCore/qjsondocument.h>

// for normalizeTypeInternal
#include <private/qmetaobject_p.h>
#include <private/qmetaobject_moc_p.h>
#include <private/qduplicatetracker_p.h>

Expand Down Expand Up @@ -242,7 +243,7 @@ bool Moc::parseEnum(EnumDef *def)
bool isTypdefEnum = false; // typedef enum { ... } Foo;

if (test(CLASS) || test(STRUCT))
def->isEnumClass = true;
def->flags |= EnumIsScoped;

if (test(IDENTIFIER)) {
def->name = lexem();
Expand Down Expand Up @@ -741,14 +742,14 @@ void Moc::parse()
break;
case Q_ENUMS_TOKEN:
case Q_ENUM_NS_TOKEN:
parseEnumOrFlag(&def, false);
parseEnumOrFlag(&def, {});
break;
case Q_ENUM_TOKEN:
error("Q_ENUM can't be used in a Q_NAMESPACE, use Q_ENUM_NS instead");
break;
case Q_FLAGS_TOKEN:
case Q_FLAG_NS_TOKEN:
parseEnumOrFlag(&def, true);
parseEnumOrFlag(&def, EnumIsFlag);
break;
case Q_FLAG_TOKEN:
error("Q_FLAG can't be used in a Q_NAMESPACE, use Q_FLAG_NS instead");
Expand Down Expand Up @@ -936,14 +937,14 @@ void Moc::parse()
break;
case Q_ENUMS_TOKEN:
case Q_ENUM_TOKEN:
parseEnumOrFlag(&def, false);
parseEnumOrFlag(&def, {});
break;
case Q_ENUM_NS_TOKEN:
error("Q_ENUM_NS can't be used in a Q_OBJECT/Q_GADGET, use Q_ENUM instead");
break;
case Q_FLAGS_TOKEN:
case Q_FLAG_TOKEN:
parseEnumOrFlag(&def, true);
parseEnumOrFlag(&def, EnumIsFlag);
break;
case Q_FLAG_NS_TOKEN:
error("Q_FLAG_NS can't be used in a Q_OBJECT/Q_GADGET, use Q_FLAG instead");
Expand Down Expand Up @@ -1599,7 +1600,7 @@ void Moc::parsePrivateProperty(ClassDef *def, Moc::PropertyMode mode)
def->propertyList += propDef;
}

void Moc::parseEnumOrFlag(BaseDef *def, bool isFlag)
void Moc::parseEnumOrFlag(BaseDef *def, EnumFlags flags)
{
next(LPAREN);
QByteArray identifier;
Expand All @@ -1609,7 +1610,7 @@ void Moc::parseEnumOrFlag(BaseDef *def, bool isFlag)
identifier += "::";
identifier += lexem();
}
def->enumDeclarations[identifier] = isFlag;
def->enumDeclarations[identifier] = flags;
}
next(RPAREN);
}
Expand Down Expand Up @@ -2177,13 +2178,14 @@ QJsonObject PropertyDef::toJson() const
QJsonObject EnumDef::toJson(const ClassDef &cdef) const
{
QJsonObject def;
uint flags = this->flags | cdef.enumDeclarations.value(name);
def["name"_L1] = QString::fromUtf8(name);
if (!enumName.isEmpty())
def["alias"_L1] = QString::fromUtf8(enumName);
if (!type.isEmpty())
def["type"_L1] = QString::fromUtf8(type);
def["isFlag"_L1] = cdef.enumDeclarations.value(name);
def["isClass"_L1] = isEnumClass;
def["isFlag"_L1] = (flags & EnumIsFlag) != 0;
def["isClass"_L1] = (flags & EnumIsScoped) != 0;

QJsonArray valueArr;
for (const QByteArray &value: values)
Expand Down
8 changes: 4 additions & 4 deletions src/tools/moc/moc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <qjsondocument.h>
#include <qjsonarray.h>
#include <qjsonobject.h>
#include <qtmocconstants.h>
#include <qtyperevision.h>
#include <stdio.h>

Expand Down Expand Up @@ -44,8 +45,7 @@ struct EnumDef
QByteArray enumName;
QByteArray type;
QList<QByteArray> values;
bool isEnumClass; // c++11 enum class
EnumDef() : isEnumClass(false) {}
QFlags<QtMocConstants::EnumFlags> flags = {};
QJsonObject toJson(const ClassDef &cdef) const;
QByteArray qualifiedType(const ClassDef *cdef) const;
};
Expand Down Expand Up @@ -148,7 +148,7 @@ struct BaseDef {
QByteArray classname;
QByteArray qualified;
QList<ClassInfoDef> classInfoList;
QMap<QByteArray, bool> enumDeclarations;
QMap<QByteArray, QFlags<QtMocConstants::EnumFlags>> enumDeclarations;
QList<EnumDef> enumList;
QMap<QByteArray, QByteArray> flagAliases;
qsizetype begin = 0;
Expand Down Expand Up @@ -261,7 +261,7 @@ class Moc : public Parser
void createPropertyDef(PropertyDef &def, int propertyIndex, PropertyMode mode);

void parsePropertyAttributes(PropertyDef &propDef);
void parseEnumOrFlag(BaseDef *def, bool isFlag);
void parseEnumOrFlag(BaseDef *def, QtMocConstants::EnumFlags flags);
void parseFlag(BaseDef *def);
enum class EncounteredQmlMacro {Yes, No};
EncounteredQmlMacro parseClassInfo(BaseDef *def);
Expand Down

0 comments on commit 1791d88

Please sign in to comment.