10#include <QtCore/qmetatype.h>
11#include <QtCore/qjsondocument.h>
12#include <QtCore/qjsonobject.h>
13#include <QtCore/qjsonvalue.h>
14#include <QtCore/qjsonarray.h>
15#include <QtCore/qplugin.h>
16#include <QtCore/qstringview.h>
21#include <private/qmetaobject_p.h>
22#include <private/qplugin_p.h>
50#define RETURN_METATYPENAME_STRING(MetaTypeName, MetaTypeId, RealType) \
51 case QMetaType::MetaTypeName: return #MetaTypeName;
56#undef RETURN_METATYPENAME_STRING
61 const QHash<QByteArray, QByteArray> &knownQObjectClasses,
62 const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile,
63 bool requireCompleteTypes)
68 knownQObjectClasses(knownQObjectClasses),
69 knownGadgets(knownGadgets),
70 requireCompleteTypes(requireCompleteTypes)
78 if (
s.at(
i) !=
'\\' ||
i >=
s.size() - 1)
88 while (
i < startPos + 4
103 static constexpr int ColumnWidth = 72;
110 const qsizetype backSlashPos =
s.lastIndexOf(
'\\', idx + spanLen - 1);
111 if (backSlashPos >= idx) {
113 spanLen =
qBound(spanLen, backSlashPos + escapeLen - idx,
len - idx);
115 fprintf(
out,
"\n \"%.*s\"",
int(spanLen),
s.constData() + idx);
140 sum +=
int(def.arguments.size()) + 1;
144bool Generator::registerableMetaType(
const QByteArray &propertyType)
146 if (metaTypes.
contains(propertyType))
154 objectPointerType.
chop(1);
155 if (knownQObjectClasses.
contains(objectPointerType))
159 static const QList<QByteArray> smartPointers = QList<QByteArray>()
160#define STREAM_SMART_POINTER(SMART_POINTER) << #SMART_POINTER
162#undef STREAM_SMART_POINTER
165 for (
const QByteArray &smartPointer : smartPointers) {
168 return knownQObjectClasses.
contains(propertyType.
mid(smartPointer.size() + 1, propertyType.
size() - smartPointer.size() - 1 - 1));
171 static const QList<QByteArray> oneArgTemplates = QList<QByteArray>()
172#define STREAM_1ARG_TEMPLATE(TEMPLATENAME) << #TEMPLATENAME
174#undef STREAM_1ARG_TEMPLATE
176 for (
const QByteArray &oneArgTemplateType : oneArgTemplates) {
183 - (propertyType.
at(propertyType.
size() - 2) ==
' ' ? 1 : 0 );
195 if (qualifiedName ==
name)
205 QByteArray qualifiedClassNameIdentifier = identifier;
210 qualifiedClassNameIdentifier.
replace(
"::",
"SCOPE");
215 qualifiedClassNameIdentifier =
"CLASS" + qualifiedClassNameIdentifier +
"ENDCLASS";
216 return qualifiedClassNameIdentifier;
221 bool isQObject = (cdef->
classname ==
"QObject");
226 QList<EnumDef> enumList;
231 def.enumName = def.name;
245 registerClassInfoStrings();
247 registerFunctionStrings(cdef->
slotList);
251 registerPropertyStrings();
252 registerEnumStrings();
254 const bool hasStaticMetaCall =
261 fprintf(out,
"namespace {\n");
267 fprintf(out,
"\n#ifdef QT_MOC_HAS_STRINGDATA\n"
268 "struct qt_meta_stringdata_%s_t {};\n"
269 "constexpr auto qt_meta_stringdata_%s = QtMocHelpers::stringData(",
270 qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData());
280 fprintf(out,
"\n);\n"
281 "#else // !QT_MOC_HAS_STRINGDATA\n");
282 fprintf(out,
"#error \"qtmochelpers.h not found or too old.\"\n");
283 fprintf(out,
"#endif // !QT_MOC_HAS_STRINGDATA\n");
284 fprintf(out,
"} // unnamed namespace\n\n");
291 fprintf(out,
"Q_CONSTINIT static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
292 fprintf(out,
"\n // content:\n");
294 fprintf(out,
" %4d, // classname\n", stridx(cdef->
qualified));
301 parser->
error(
"internal limit exceeded: the total number of member functions"
302 " (including signals and slots) is too big.");
305 fprintf(out,
" %4" PRIdQSIZETYPE ", %4d, // methods\n", methodCount, methodCount ?
index : 0);
308 index += methodCount;
309 int paramsIndex =
index;
314 index += totalParameterCount * 2
322 int enumsIndex =
index;
326 fprintf(out,
" %4d, %4d, // constructors\n", isConstructible ?
int(cdef->
constructorList.
size()) : 0,
327 isConstructible ?
index : 0);
335 fprintf(out,
" %4d, // flags\n",
flags);
336 fprintf(out,
" %4d, // signalCount\n",
int(cdef->
signalList.
size()));
342 generateClassInfos();
348 || propEnumCount >= std::numeric_limits<int>::max()) {
349 parser->
error(
"internal limit exceeded: number of property and enum metatypes is too big.");
351 int initialMetaTypeOffset = int(propEnumCount);
361 generateFunctions(cdef->
slotList,
"slot",
MethodSlot, paramsIndex, initialMetaTypeOffset);
372 generateFunctionRevisions(cdef->
signalList,
"signal");
373 generateFunctionRevisions(cdef->
slotList,
"slot");
374 generateFunctionRevisions(cdef->
methodList,
"method");
380 generateFunctionParameters(cdef->
signalList,
"signal");
381 generateFunctionParameters(cdef->
slotList,
"slot");
382 generateFunctionParameters(cdef->
methodList,
"method");
389 generateProperties();
394 generateEnums(enumsIndex);
405 fprintf(out,
"\n 0 // eod\n};\n\n");
410 QList<QByteArray> extraList;
411 QMultiHash<QByteArray, QByteArray> knownExtraMetaObject(knownGadgets);
412 knownExtraMetaObject.unite(knownQObjectClasses);
418 if (
p.type.contains(
'*') ||
p.type.contains(
'<') ||
p.type.contains(
'>'))
433 thisScope = thisScope.left(
s);
434 QByteArray currentScope = thisScope.
isEmpty() ? unqualifiedScope : thisScope +
"::" + unqualifiedScope;
435 scopeIt = knownExtraMetaObject.constFind(currentScope);
436 }
while (!thisScope.isEmpty() && scopeIt == knownExtraMetaObject.constEnd());
438 if (scopeIt == knownExtraMetaObject.constEnd())
448 if (!extraList.contains(scope))
470 if (!extraList.isEmpty()) {
471 fprintf(out,
"Q_CONSTINIT static const QMetaObject::SuperData qt_meta_extradata_%s[] = {\n",
472 qualifiedClassNameIdentifier.constData());
474 fprintf(out,
" QMetaObject::SuperData::link<%s::staticMetaObject>(),\n",
ba.
constData());
476 fprintf(out,
" nullptr\n};\n\n");
482 fprintf(out,
"Q_CONSTINIT const QMetaObject %s::staticMetaObject = { {\n",
486 fprintf(out,
" nullptr,\n");
488 fprintf(out,
" QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.
constData());
490 fprintf(out,
" QtPrivate::MetaObjectForType<%s>::value,\n", purestSuperClass.
constData());
492 fprintf(out,
" nullptr,\n");
493 fprintf(out,
" qt_meta_stringdata_%s.offsetsAndSizes,\n"
494 " qt_meta_data_%s,\n", qualifiedClassNameIdentifier.constData(),
495 qualifiedClassNameIdentifier.constData());
496 if (hasStaticMetaCall)
497 fprintf(out,
" qt_static_metacall,\n");
499 fprintf(out,
" nullptr,\n");
501 if (extraList.isEmpty())
502 fprintf(out,
" nullptr,\n");
504 fprintf(out,
" qt_meta_extradata_%s,\n", qualifiedClassNameIdentifier.constData());
506 const char *comma =
"";
509 const char *forceCompleteType = forceComplete ?
", std::true_type>" :
", std::false_type>";
510 if (requireCompleteness)
512 return "QtPrivate::TypeAndForceComplete<" %
type % forceCompleteType;
514 if (!requireCompleteness) {
515 fprintf(out,
" qt_incomplete_metaTypeArray<qt_meta_stringdata_%s_t", qualifiedClassNameIdentifier.constData());
518 fprintf(out,
" qt_metaTypeArray<");
522 fprintf(out,
"%s\n // property '%s'\n %s",
523 comma,
p.name.constData(), stringForType(
p.type,
true).constData());
529 fprintf(out,
"%s\n // enum '%s'\n %s",
530 comma, e.name.constData(), stringForType(e.qualifiedType(cdef),
true).constData());
536 fprintf(out,
"%s\n // Q_OBJECT / Q_GADGET\n %s",
537 comma, stringForType(ownType,
true).constData());
543 for (
const QList<FunctionDef> *methodContainer : allMethods) {
545 fprintf(out,
",\n // method '%s'\n %s",
546 fdef.name.constData(), stringForType(fdef.type.name,
false).constData());
547 for (
const auto &
argument: fdef.arguments)
548 fprintf(out,
",\n %s", stringForType(
argument.type.name,
false).constData());
554 if (fdef.arguments.isEmpty())
557 fprintf(out,
"%s\n // constructor '%s'", comma, fdef.name.constData());
559 for (
const auto &
argument: fdef.arguments) {
560 fprintf(out,
"%s\n %s", comma,
561 stringForType(
argument.type.name,
false).constData());
565 fprintf(out,
"\n >,\n");
567 fprintf(out,
" nullptr\n} };\n\n");
572 if (hasStaticMetaCall)
573 generateStaticMetacall();
578 fprintf(out,
"\nconst QMetaObject *%s::metaObject() const\n{\n return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;\n}\n",
585 fprintf(out,
"\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->
qualified.
constData());
586 fprintf(out,
" if (!_clname) return nullptr;\n");
587 fprintf(out,
" if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata0))\n"
588 " return static_cast<void*>(this);\n",
589 qualifiedClassNameIdentifier.constData());
598 const char *cname =
it->classname.constData();
599 fprintf(out,
" if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(this);\n",
604 for (
const QList<ClassDef::Interface> &iface : std::as_const(cdef->
interfaceList)) {
606 fprintf(out,
" if (!strcmp(_clname, %s))\n return ", iface.at(
j).interfaceId.constData());
608 fprintf(out,
"static_cast< %s*>(", iface.at(k).className.constData());
609 fprintf(out,
"this%s;\n",
QByteArray(
j + 1,
')').constData());
612 if (!purestSuperClass.
isEmpty() && !isQObject) {
614 fprintf(out,
" return %s::qt_metacast(_clname);\n", superClass.
constData());
616 fprintf(out,
" return nullptr;\n");
628 for (
int signalindex = 0; signalindex < int(cdef->
signalList.
size()); ++signalindex)
629 generateSignal(&cdef->
signalList.
at(signalindex), signalindex);
634 generatePluginMetaData();
640 fprintf(out,
"namespace CheckNotifySignalValidity_%s {\n", qualifiedClassNameIdentifier.constData());
645 return nonClassSignal == p.notify;
649 fprintf(out,
"template<typename T> using has_nullary_%s = decltype(std::declval<T>().%s());\n",
650 nonClassSignal.constData(),
651 nonClassSignal.constData());
652 const auto &propertyType = propertyIt->type;
653 fprintf(out,
"template<typename T> using has_unary_%s = decltype(std::declval<T>().%s(std::declval<%s>()));\n",
654 nonClassSignal.constData(),
655 nonClassSignal.constData(),
657 fprintf(out,
"static_assert(qxp::is_detected_v<has_nullary_%s, %s> || qxp::is_detected_v<has_unary_%s, %s>,\n"
658 " \"NOTIFY signal %s does not exist in class (or is private in its parent)\");\n",
661 nonClassSignal.constData());
668void Generator::registerClassInfoStrings()
676void Generator::generateClassInfos()
681 fprintf(out,
"\n // classinfo: key, value\n");
684 fprintf(out,
" %4d, %4d,\n", stridx(
c.
name), stridx(
c.
value));
687void Generator::registerFunctionStrings(
const QList<FunctionDef> &
list)
692 strreg(
f.normalizedType);
697 strreg(
a.normalizedType);
703void Generator::registerByteArrayVector(
const QList<QByteArray> &
list)
709void Generator::generateFunctions(
const QList<FunctionDef> &
list,
const char *functype,
int type,
710 int ¶msIndex,
int &initialMetatypeOffset)
714 fprintf(out,
"\n // %ss: name, argc, parameters, tag, flags, initial metatype offsets\n", functype);
721 comment.
append(
"Private");
727 comment.
append(
"Protected");
731 comment.
append(
" | MethodCompatibility");
735 comment.
append(
" | MethodCloned");
737 if (
f.isScriptable) {
739 comment.
append(
" | isScriptable");
741 if (
f.revision > 0) {
743 comment.
append(
" | MethodRevisioned");
748 comment.
append(
" | MethodIsConst ");
751 const int argc = int(
f.arguments.size());
752 fprintf(out,
" %4d, %4d, %4d, %4d, 0x%02x, %4d /* %s */,\n",
753 stridx(
f.name), argc, paramsIndex, stridx(
f.tag),
flags, initialMetatypeOffset, comment.
constData());
755 paramsIndex += 1 + argc * 2;
757 initialMetatypeOffset += (
f.isConstructor ? 0 : 1) + argc;
761void Generator::generateFunctionRevisions(
const QList<FunctionDef> &
list,
const char *functype)
764 fprintf(out,
"\n // %ss: revision\n", functype);
766 fprintf(out,
" %4d,\n",
f.revision);
769void Generator::generateFunctionParameters(
const QList<FunctionDef> &
list,
const char *functype)
773 fprintf(out,
"\n // %ss: parameters\n", functype);
778 const bool allowEmptyName =
f.isConstructor;
779 generateTypeInfo(
f.normalizedType, allowEmptyName);
783 generateTypeInfo(
arg.normalizedType, allowEmptyName);
789 fprintf(out,
" %4d,", stridx(
arg.
name));
800 const char *valueString;
803 valueString =
"QReal";
809 fprintf(out,
"QMetaType::%s", valueString);
812 fprintf(out,
"%4d",
type);
820void Generator::registerPropertyStrings()
829void Generator::generateProperties()
836 fprintf(out,
"\n // properties: name, type, flags, notifyId, revision\n");
841 if (!
p.member.isEmpty() && !
p.constant)
843 if (!
p.read.isEmpty() || !
p.member.isEmpty())
845 if (!
p.write.isEmpty()) {
851 if (!
p.reset.isEmpty())
854 if (
p.designable !=
"false")
857 if (
p.scriptable !=
"false")
860 if (
p.stored !=
"false")
863 if (
p.user !=
"false")
873 if (!
p.bind.isEmpty())
876 fprintf(out,
" %4d, ", stridx(
p.name));
877 generateTypeInfo(
p.type);
878 int notifyId =
p.notifyId;
879 if (
p.notifyId < -1) {
881 const int indexInStrings = int(
strings.indexOf(
p.notify));
884 fprintf(out,
", 0x%.8x, uint(%d), %d,\n",
flags, notifyId,
p.revision);
888void Generator::registerEnumStrings()
890 for (
const EnumDef &e :
std::as_const(cdef->enumList)) {
892 if (!e.enumName.isNull())
899void Generator::generateEnums(
int index)
904 fprintf(out,
"\n // enums: name, alias, flags, count, data\n");
914 fprintf(out,
" %4d, %4d, 0x%.1x, %4d, %4d,\n",
923 fprintf(out,
"\n // enum data: key, value\n");
924 for (
const EnumDef &e :
std::as_const(cdef->enumList)) {
930 fprintf(out,
" %4d, uint(%s),\n",
936void Generator::generateMetacall()
938 bool isQObject = (cdef->
classname ==
"QObject");
940 fprintf(out,
"\nint %s::qt_metacall(QMetaObject::Call _c, int _id, void **_a)\n{\n",
943 if (!purestSuperClass.
isEmpty() && !isQObject) {
945 fprintf(out,
" _id = %s::qt_metacall(_c, _id, _a);\n", superClass.
constData());
949 bool needElse =
false;
950 QList<FunctionDef> methodList;
959 fprintf(out,
" if (_id < 0)\n return _id;\n");
964 if (methodList.size()) {
966 fprintf(out,
"if (_c == QMetaObject::InvokeMetaMethod) {\n");
967 fprintf(out,
" if (_id < %d)\n",
int(methodList.size()));
968 fprintf(out,
" qt_static_metacall(this, _c, _id, _a);\n");
969 fprintf(out,
" _id -= %d;\n }",
int(methodList.size()));
971 fprintf(out,
" else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {\n");
972 fprintf(out,
" if (_id < %d)\n",
int(methodList.size()));
974 if (methodsWithAutomaticTypesHelper(methodList).isEmpty())
975 fprintf(out,
" *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType();\n");
977 fprintf(out,
" qt_static_metacall(this, _c, _id, _a);\n");
978 fprintf(out,
" _id -= %d;\n }",
int(methodList.size()));
984 fprintf(out,
"else ");
986 "if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty\n"
987 " || _c == QMetaObject::ResetProperty || _c == QMetaObject::BindableProperty\n"
988 " || _c == QMetaObject::RegisterPropertyMetaType) {\n"
989 " qt_static_metacall(this, _c, _id, _a);\n"
994 fprintf(out,
"return _id;\n}\n");
999QMultiMap<QByteArray, int> Generator::automaticPropertyMetaTypesHelper()
1001 QMultiMap<QByteArray, int> automaticPropertyMetaTypes;
1004 if (registerableMetaType(propertyType) && !
isBuiltinType(propertyType))
1005 automaticPropertyMetaTypes.
insert(propertyType,
i);
1007 return automaticPropertyMetaTypes;
1010QMap<int, QMultiMap<QByteArray, int>>
1011Generator::methodsWithAutomaticTypesHelper(
const QList<FunctionDef> &methodList)
1013 QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypes;
1014 for (
int i = 0;
i < methodList.size(); ++
i) {
1016 for (
int j = 0;
j <
f.arguments.size(); ++
j) {
1018 if (registerableMetaType(argType) && !
isBuiltinType(argType))
1019 methodsWithAutomaticTypes[
i].insert(argType,
j);
1022 return methodsWithAutomaticTypes;
1025void Generator::generateStaticMetacall()
1027 fprintf(out,
"void %s::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)\n{\n",
1030 bool needElse =
false;
1031 bool isUsed_a =
false;
1033 const auto generateCtorArguments = [&](
int ctorindex) {
1038 const auto begin =
f.arguments.cbegin();
1039 const auto end =
f.arguments.cend();
1044 fprintf(out,
"(*reinterpret_cast<%s>(_a[%d]))",
1045 a.typeNameForCast.constData(),
offset++);
1050 fprintf(out,
" if (_c == QMetaObject::CreateInstance) {\n");
1051 fprintf(out,
" switch (_id) {\n");
1053 for (
int ctorindex = 0; ctorindex < ctorend; ++ctorindex) {
1054 fprintf(out,
" case %d: { %s *_r = new %s(", ctorindex,
1056 generateCtorArguments(ctorindex);
1057 fprintf(out,
");\n");
1058 fprintf(out,
" if (_a[0]) *reinterpret_cast<%s**>(_a[0]) = _r; } break;\n",
1061 fprintf(out,
" default: break;\n");
1062 fprintf(out,
" }\n");
1063 fprintf(out,
" } else if (_c == QMetaObject::ConstructInPlace) {\n");
1064 fprintf(out,
" switch (_id) {\n");
1065 for (
int ctorindex = 0; ctorindex < ctorend; ++ctorindex) {
1066 fprintf(out,
" case %d: { new (_a[0]) %s(",
1068 generateCtorArguments(ctorindex);
1069 fprintf(out,
"); } break;\n");
1071 fprintf(out,
" default: break;\n");
1072 fprintf(out,
" }\n");
1078 QList<FunctionDef> methodList;
1083 if (!methodList.isEmpty()) {
1085 fprintf(out,
" else ");
1088 fprintf(out,
"if (_c == QMetaObject::InvokeMetaMethod) {\n");
1091 fprintf(out,
" Q_ASSERT(staticMetaObject.cast(_o));\n");
1095 fprintf(out,
" auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->
classname.
constData());
1097 fprintf(out,
" (void)_t;\n");
1098 fprintf(out,
" switch (_id) {\n");
1099 for (
int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
1102 fprintf(out,
" case %d: ", methodindex);
1103 if (
f.normalizedType !=
"void")
1105 fprintf(out,
"_t->");
1106 if (
f.inPrivateClass.size())
1107 fprintf(out,
"%s->",
f.inPrivateClass.constData());
1108 fprintf(out,
"%s(",
f.name.constData());
1112 fprintf(out,
"QMethodRawArguments{ _a }");
1114 const auto begin =
f.arguments.cbegin();
1115 const auto end =
f.arguments.cend();
1120 fprintf(out,
"(*reinterpret_cast< %s>(_a[%d]))",
a.typeNameForCast.constData(),
offset++);
1123 if (
f.isPrivateSignal) {
1124 if (!
f.arguments.isEmpty())
1126 fprintf(out,
"%s",
"QPrivateSignal()");
1130 if (
f.normalizedType !=
"void") {
1131 fprintf(out,
"\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = std::move(_r); } ",
1135 fprintf(out,
" break;\n");
1137 fprintf(out,
" default: ;\n");
1138 fprintf(out,
" }\n");
1142 QMap<int, QMultiMap<QByteArray, int> > methodsWithAutomaticTypes = methodsWithAutomaticTypesHelper(methodList);
1144 if (!methodsWithAutomaticTypes.isEmpty()) {
1145 fprintf(out,
" else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {\n");
1146 fprintf(out,
" switch (_id) {\n");
1147 fprintf(out,
" default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;\n");
1148 QMap<int, QMultiMap<QByteArray, int> >::const_iterator
it = methodsWithAutomaticTypes.
constBegin();
1149 const QMap<int, QMultiMap<QByteArray, int> >::const_iterator
end = methodsWithAutomaticTypes.constEnd();
1151 fprintf(out,
" case %d:\n",
it.key());
1152 fprintf(out,
" switch (*reinterpret_cast<int*>(_a[1])) {\n");
1153 fprintf(out,
" default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;\n");
1155 const auto jend =
it->
end();
1156 while (jt != jend) {
1157 fprintf(out,
" case %d:\n", jt.value());
1160 if (jt == jend || jt.key() != lastKey)
1161 fprintf(out,
" *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType::fromType< %s >(); break;\n", lastKey.
constData());
1163 fprintf(out,
" }\n");
1164 fprintf(out,
" break;\n");
1166 fprintf(out,
" }\n");
1174 fprintf(out,
" else if (_c == QMetaObject::IndexOfMethod) {\n");
1175 fprintf(out,
" int *result = reinterpret_cast<int *>(_a[0]);\n");
1176 bool anythingUsed =
false;
1177 for (
int methodindex = 0; methodindex < int(cdef->
signalList.
size()); ++methodindex) {
1179 if (
f.wasCloned || !
f.inPrivateClass.isEmpty() ||
f.isStatic)
1181 anythingUsed =
true;
1182 fprintf(out,
" {\n");
1183 fprintf(out,
" using _t = %s (%s::*)(",
f.type.rawName.constData() , cdef->
classname.
constData());
1185 const auto begin =
f.arguments.cbegin();
1186 const auto end =
f.arguments.cend();
1191 fprintf(out,
"%s",
QByteArray(
a.type.name +
' ' +
a.rightType).constData());
1193 if (
f.isPrivateSignal) {
1194 if (!
f.arguments.isEmpty())
1196 fprintf(out,
"%s",
"QPrivateSignal");
1199 fprintf(out,
") const;\n");
1201 fprintf(out,
");\n");
1202 fprintf(out,
" if (_t _q_method = &%s::%s; *reinterpret_cast<_t *>(_a[1]) == _q_method) {\n",
1204 fprintf(out,
" *result = %d;\n", methodindex);
1205 fprintf(out,
" return;\n");
1206 fprintf(out,
" }\n }\n");
1209 fprintf(out,
" (void)result;\n");
1214 const QMultiMap<QByteArray, int> automaticPropertyMetaTypes = automaticPropertyMetaTypesHelper();
1216 if (!automaticPropertyMetaTypes.isEmpty()) {
1218 fprintf(out,
" else ");
1221 fprintf(out,
"if (_c == QMetaObject::RegisterPropertyMetaType) {\n");
1222 fprintf(out,
" switch (_id) {\n");
1223 fprintf(out,
" default: *reinterpret_cast<int*>(_a[0]) = -1; break;\n");
1224 auto it = automaticPropertyMetaTypes.
begin();
1225 const auto end = automaticPropertyMetaTypes.end();
1227 fprintf(out,
" case %d:\n",
it.value());
1230 if (
it ==
end ||
it.key() != lastKey)
1231 fprintf(out,
" *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< %s >(); break;\n", lastKey.
constData());
1233 fprintf(out,
" }\n");
1234 fprintf(out,
" } ");
1240 bool needGet =
false;
1241 bool needTempVarForGet =
false;
1242 bool needSet =
false;
1243 bool needReset =
false;
1244 bool hasBindableProperties =
false;
1246 needGet |= !
p.read.isEmpty() || !
p.member.isEmpty();
1247 if (!
p.read.isEmpty() || !
p.member.isEmpty())
1251 needSet |= !
p.write.isEmpty() || (!
p.member.isEmpty() && !
p.constant);
1252 needReset |= !
p.reset.isEmpty();
1253 hasBindableProperties |= !
p.bind.isEmpty();
1256 fprintf(out,
" else ");
1257 fprintf(out,
"if (_c == QMetaObject::ReadProperty) {\n");
1259 auto setupMemberAccess = [
this]() {
1262 fprintf(out,
" Q_ASSERT(staticMetaObject.cast(_o));\n");
1266 fprintf(out,
" auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->
classname.
constData());
1268 fprintf(out,
" (void)_t;\n");
1272 setupMemberAccess();
1273 if (needTempVarForGet)
1274 fprintf(out,
" void *_v = _a[0];\n");
1275 fprintf(out,
" switch (_id) {\n");
1276 for (
int propindex = 0; propindex < int(cdef->
propertyList.
size()); ++propindex) {
1278 if (
p.read.isEmpty() &&
p.member.isEmpty())
1281 if (
p.inPrivateClass.size()) {
1282 prefix +=
p.inPrivateClass +
"->";
1286 fprintf(out,
" case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s%s())); break;\n",
1287 propindex, prefix.
constData(),
p.read.constData());
1289 fprintf(out,
" case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s%s())); break;\n",
1290 propindex, prefix.
constData(),
p.read.constData());
1292 fprintf(out,
" case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n",
1293 propindex, prefix.
constData(),
p.read.constData());
1294 else if (
p.read ==
"default")
1295 fprintf(out,
" case %d: *reinterpret_cast< %s*>(_v) = %s%s().value(); break;\n",
1296 propindex,
p.type.constData(), prefix.
constData(),
p.bind.constData());
1297 else if (!
p.read.isEmpty())
1298 fprintf(out,
" case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n",
1299 propindex,
p.type.constData(), prefix.
constData(),
p.read.constData());
1301 fprintf(out,
" case %d: *reinterpret_cast< %s*>(_v) = %s%s; break;\n",
1302 propindex,
p.type.constData(), prefix.
constData(),
p.member.constData());
1304 fprintf(out,
" default: break;\n");
1305 fprintf(out,
" }\n");
1310 fprintf(out,
" else ");
1311 fprintf(out,
"if (_c == QMetaObject::WriteProperty) {\n");
1314 setupMemberAccess();
1315 fprintf(out,
" void *_v = _a[0];\n");
1316 fprintf(out,
" switch (_id) {\n");
1317 for (
int propindex = 0; propindex < int(cdef->
propertyList.
size()); ++propindex) {
1321 if (
p.write.isEmpty() &&
p.member.isEmpty())
1324 if (
p.inPrivateClass.size()) {
1325 prefix +=
p.inPrivateClass +
"->";
1328 fprintf(out,
" case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
1329 propindex, prefix.
constData(),
p.write.constData());
1330 }
else if (
p.write ==
"default") {
1331 fprintf(out,
" case %d: {\n", propindex);
1332 fprintf(out,
" %s%s().setValue(*reinterpret_cast< %s*>(_v));\n",
1333 prefix.
constData(),
p.bind.constData(),
p.type.constData());
1334 fprintf(out,
" break;\n");
1335 fprintf(out,
" }\n");
1336 }
else if (!
p.write.isEmpty()) {
1337 fprintf(out,
" case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n",
1338 propindex, prefix.
constData(),
p.write.constData(),
p.type.constData());
1340 fprintf(out,
" case %d:\n", propindex);
1341 fprintf(out,
" if (%s%s != *reinterpret_cast< %s*>(_v)) {\n",
1342 prefix.
constData(),
p.member.constData(),
p.type.constData());
1343 fprintf(out,
" %s%s = *reinterpret_cast< %s*>(_v);\n",
1344 prefix.
constData(),
p.member.constData(),
p.type.constData());
1345 if (!
p.notify.isEmpty() &&
p.notifyId > -1) {
1347 if (
f.arguments.size() == 0)
1348 fprintf(out,
" Q_EMIT _t->%s();\n",
p.notify.constData());
1349 else if (
f.arguments.size() == 1 &&
f.arguments.at(0).normalizedType ==
p.type)
1350 fprintf(out,
" Q_EMIT _t->%s(%s%s);\n",
1351 p.notify.constData(), prefix.
constData(),
p.member.constData());
1352 }
else if (!
p.notify.isEmpty() &&
p.notifyId < -1) {
1353 fprintf(out,
" Q_EMIT _t->%s();\n",
p.notify.constData());
1355 fprintf(out,
" }\n");
1356 fprintf(out,
" break;\n");
1359 fprintf(out,
" default: break;\n");
1360 fprintf(out,
" }\n");
1365 fprintf(out,
" else ");
1366 fprintf(out,
"if (_c == QMetaObject::ResetProperty) {\n");
1368 setupMemberAccess();
1369 fprintf(out,
" switch (_id) {\n");
1370 for (
int propindex = 0; propindex < int(cdef->
propertyList.
size()); ++propindex) {
1372 if (
p.reset.isEmpty())
1375 if (
p.inPrivateClass.size()) {
1376 prefix +=
p.inPrivateClass +
"->";
1378 fprintf(out,
" case %d: %s%s(); break;\n",
1379 propindex, prefix.
constData(),
p.reset.constData());
1381 fprintf(out,
" default: break;\n");
1382 fprintf(out,
" }\n");
1386 fprintf(out,
" else ");
1387 fprintf(out,
"if (_c == QMetaObject::BindableProperty) {\n");
1388 if (hasBindableProperties) {
1389 setupMemberAccess();
1390 fprintf(out,
" switch (_id) {\n");
1391 for (
int propindex = 0; propindex < int(cdef->
propertyList.
size()); ++propindex) {
1393 if (
p.bind.isEmpty())
1396 if (
p.inPrivateClass.size()) {
1397 prefix +=
p.inPrivateClass +
"->";
1400 " case %d: *static_cast<QUntypedBindable *>(_a[0]) = %s%s(); "
1402 propindex, prefix.
constData(),
p.bind.constData());
1404 fprintf(out,
" default: break;\n");
1405 fprintf(out,
" }\n");
1414 if (methodList.isEmpty()) {
1415 fprintf(out,
" (void)_o;\n");
1416 if (cdef->
constructorList.
isEmpty() && automaticPropertyMetaTypes.isEmpty() && methodsWithAutomaticTypesHelper(methodList).isEmpty()) {
1417 fprintf(out,
" (void)_id;\n");
1418 fprintf(out,
" (void)_c;\n");
1422 fprintf(out,
" (void)_a;\n");
1424 fprintf(out,
"}\n");
1431 fprintf(out,
"\n// SIGNAL %d\n%s %s::%s(",
1435 const char *constQualifier =
"";
1438 thisPtr =
"const_cast< " + cdef->
qualified +
" *>(this)";
1439 constQualifier =
"const";
1444 fprintf(out,
")%s\n{\n"
1445 " QMetaObject::activate(%s, &staticMetaObject, %d, nullptr);\n"
1446 "}\n", constQualifier, thisPtr.constData(),
index);
1457 if (
a.type.name.size())
1458 fputs(
a.type.name.constData(), out);
1459 fprintf(out,
" _t%d",
offset++);
1460 if (
a.rightType.size())
1461 fputs(
a.rightType.constData(), out);
1466 fprintf(out,
"QPrivateSignal _t%d",
offset++);
1469 fprintf(out,
")%s\n{\n", constQualifier);
1472 fprintf(out,
" %s _t0{};\n", returnType.
constData());
1475 fprintf(out,
" void *_a[] = { ");
1477 fprintf(out,
"nullptr");
1480 fprintf(out,
"const_cast<void*>(reinterpret_cast<const volatile void*>(std::addressof(_t0)))");
1482 fprintf(out,
"const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t0)))");
1487 fprintf(out,
", const_cast<void*>(reinterpret_cast<const volatile void*>(std::addressof(_t%d)))",
i);
1489 fprintf(out,
", const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t%d)))",
i);
1490 fprintf(out,
" };\n");
1491 fprintf(out,
" QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(),
index);
1493 fprintf(out,
" return _t0;\n");
1494 fprintf(out,
"}\n");
1500 auto it =
o.constBegin();
1501 auto end =
o.constEnd();
1503 cbor_encoder_create_map(parent, &
map,
o.size());
1510 return cbor_encoder_close_container(parent, &
map);
1516 cbor_encoder_create_array(parent, &
array,
a.size());
1519 return cbor_encoder_close_container(parent, &
array);
1527 return cbor_encode_null(parent);
1529 return cbor_encode_boolean(parent,
v.toBool());
1536 return cbor_encode_text_string(parent,
s.constData(),
s.size());
1539 double d =
v.toDouble();
1540 if (
d == floor(
d) && fabs(
d) <= (
Q_INT64_C(1) << std::numeric_limits<double>::digits))
1541 return cbor_encode_int(parent,
qint64(
d));
1542 return cbor_encode_double(parent,
d);
1545 Q_UNREACHABLE_RETURN(CborUnknownError);
1548void Generator::generatePluginMetaData()
1553 auto outputCborData = [
this]() {
1559 cbor_encoder_create_map(&enc, &
map, CborIndefiniteLength);
1561 dev.nextItem(
"\"IID\"");
1565 dev.nextItem(
"\"className\"");
1571 dev.nextItem(
"\"MetaData\"");
1577 dev.nextItem(
"\"URI\"");
1586 dev.nextItem(
QByteArray(
"command-line \"" +
key +
"\"").constData());
1593 cbor_encoder_close_container(&enc, &
map);
1601 fputs(
"\n#ifdef QT_MOC_EXPORT_PLUGIN_V2", out);
1604 fprintf(out,
"\nstatic constexpr unsigned char qt_pluginMetaDataV2_%s[] = {",
1607 fprintf(out,
"\n};\nQT_MOC_EXPORT_PLUGIN_V2(%s, %s, qt_pluginMetaDataV2_%s)\n",
1611 fprintf(out,
"#else\nQT_PLUGIN_METADATA_SECTION\n"
1612 "Q_CONSTINIT static constexpr unsigned char qt_pluginMetaData_%s[] = {\n"
1613 " 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!',\n"
1614 " // metadata version, Qt version, architectural requirements\n"
1615 " 0, QT_VERSION_MAJOR, QT_VERSION_MINOR, qPluginArchRequirements(),",
1618 fprintf(out,
"\n};\nQT_MOC_EXPORT_PLUGIN(%s, %s)\n"
1619 "#endif // QT_MOC_EXPORT_PLUGIN_V2\n",
1630#define CBOR_ENCODER_WRITER_CONTROL 1
1631#define CBOR_ENCODER_WRITE_FUNCTION CborDevice::callback
1635#include "cborencoder.c"
static CborError callback(void *self, const void *ptr, size_t len, CborEncoderAppendType t)
Generator(Moc *moc, ClassDef *classDef, const QList< QByteArray > &metaTypes, const QHash< QByteArray, QByteArray > &knownQObjectClasses, const QHash< QByteArray, QByteArray > &knownGadgets, FILE *outfile=nullptr, bool requireCompleteTypes=false)
Q_NORETURN void error(const Symbol &symbol)
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
bool endsWith(char c) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
QByteArray left(qsizetype n) const &
qsizetype indexOf(char c, qsizetype from=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void chop(qsizetype n)
Removes n bytes from the end of the byte array.
bool startsWith(QByteArrayView bv) const
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
QByteArray & insert(qsizetype i, QByteArrayView data)
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
QByteArray sliced(qsizetype pos) const &
qsizetype lastIndexOf(char c, qsizetype from=-1) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray mid(qsizetype index, qsizetype len=-1) const &
bool isNull() const noexcept
Returns true if this byte array is null; otherwise returns false.
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
qsizetype size() const noexcept
bool isEmpty() const noexcept
bool empty() const noexcept
const_reference at(qsizetype i) const noexcept
const_iterator constBegin() const noexcept
const T & constFirst() const noexcept
const_iterator cend() const noexcept
const_iterator constEnd() const noexcept
const_iterator cbegin() const noexcept
T value(const Key &key, const T &defaultValue=T()) const
bool contains(const Key &key) const
key_iterator keyBegin() const
key_iterator keyEnd() const
const_iterator constBegin() const noexcept
const QChar * constData() const
Returns a pointer to the data stored in the QString.
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
QList< QVariant > arguments
static QByteArray generateQualifiedClassNameIdentifier(const QByteArray &identifier)
static CborError jsonValueToCbor(CborEncoder *parent, const QJsonValue &v)
static bool qualifiedNameEquals(const QByteArray &qualifiedName, const QByteArray &name)
uint nameToBuiltinType(const QByteArray &name)
static int aggregateParameterCount(const QList< FunctionDef > &list)
#define STREAM_1ARG_TEMPLATE(TEMPLATENAME)
static CborError jsonArrayToCbor(CborEncoder *parent, const QJsonArray &a)
bool isBuiltinType(const QByteArray &type)
static const char * metaTypeEnumValueString(int type)
static void printStringWithIndentation(FILE *out, const QByteArray &s)
#define STREAM_SMART_POINTER(SMART_POINTER)
static qsizetype lengthOfEscapeSequence(const QByteArray &s, qsizetype i)
static CborError jsonObjectToCbor(CborEncoder *parent, const QJsonObject &o)
#define RETURN_METATYPENAME_STRING(MetaTypeName, MetaTypeId, RealType)
QByteArray noRef(const QByteArray &type)
Combined button and popup list for selecting options.
constexpr bool isOctalDigit(char32_t c) noexcept
constexpr bool isHexDigit(char32_t c) noexcept
#define QT_WARNING_DISABLE_MSVC(number)
#define QT_WARNING_DISABLE_GCC(text)
#define QT_WARNING_DISABLE_CLANG(text)
static QString moc(const QString &name)
static QString templateArg(const QByteArray &arg)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei const GLchar ** strings
[1]
GLenum GLuint GLintptr offset
#define Q_ASSERT_X(cond, x, msg)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QTextStream out(stdout)
[7]
QMap< QByteArray, QByteArray > flagAliases
QMap< QByteArray, bool > enumDeclarations
QList< ClassInfoDef > classInfoList
QList< EnumDef > enumList
QList< QList< Interface > > interfaceList
QList< FunctionDef > methodList
QList< PropertyDef > propertyList
QList< FunctionDef > constructorList
QList< SuperClass > superclassList
bool requireCompleteMethodTypes
QList< FunctionDef > slotList
QList< FunctionDef > signalList
struct ClassDef::PluginData pluginData
QList< QByteArray > nonClassSignalList
QList< QByteArray > values
QByteArray normalizedType
QList< ArgumentDef > arguments
bool returnTypeIsVolatile
bool contains(const AT &t) const noexcept