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>
17#include <QtCore/qtmocconstants.h>
22#include <private/qmetaobject_p.h>
23#include <private/qplugin_p.h>
27using namespace QtMiscUtils;
34 uint tp = qMetaTypeTypeInternal(name.constData());
35 return tp < uint(QMetaType::User) ? tp : uint(QMetaType::UnknownType);
39
40
43 int id = qMetaTypeTypeInternal(type.constData());
44 if (id == QMetaType::UnknownType)
46 return (id < QMetaType::User);
51#define RETURN_METATYPENAME_STRING(MetaTypeName, MetaTypeId, RealType)
52 case QMetaType::MetaTypeName: return #MetaTypeName;
55QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING)
57#undef RETURN_METATYPENAME_STRING
62 const QHash<QByteArray, QByteArray> &knownQObjectClasses,
63 const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile,
64 bool requireCompleteTypes)
71 requireCompleteTypes(requireCompleteTypes)
73 if (cdef->superclassList.size())
74 purestSuperClass = cdef->superclassList.constFirst().classname;
79 if (s.at(i) !=
'\\' || i >= s.size() - 1)
81 const qsizetype startPos = i;
86 while (i < s.size() && isHexDigit(s.at(i)))
88 }
else if (isOctalDigit(ch)) {
89 while (i < startPos + 4
91 && isOctalDigit(s.at(i))) {
95 i = qMin(i + 1, s.size());
104 static constexpr int ColumnWidth = 72;
105 const qsizetype len = s.size();
109 qsizetype spanLen = qMin(ColumnWidth - 2, len - idx);
111 const qsizetype backSlashPos = s.lastIndexOf(
'\\', idx + spanLen - 1);
112 if (backSlashPos >= idx) {
113 const qsizetype escapeLen = lengthOfEscapeSequence(s, backSlashPos);
114 spanLen = qBound(spanLen, backSlashPos + escapeLen - idx, len - idx);
116 fprintf(out,
"\n \"%.*s\"",
int(spanLen), s.constData() + idx);
121void Generator::strreg(
const QByteArray &s)
123 if (!strings.contains(s))
127int Generator::stridx(
const QByteArray &s)
129 int i =
int(strings.indexOf(s));
130 Q_ASSERT_X(i != -1, Q_FUNC_INFO,
"We forgot to register some strings");
140 for (
const FunctionDef &def : list)
141 sum +=
int(def.arguments.size()) + 1;
145bool Generator::registerableMetaType(
const QByteArray &propertyType)
147 if (metaTypes.contains(propertyType))
150 if (propertyType.endsWith(
'*')) {
151 QByteArray objectPointerType = propertyType;
155 objectPointerType.chop(1);
156 if (knownQObjectClasses.contains(objectPointerType))
160 static const QList<QByteArray> smartPointers = QList<QByteArray>()
161#define STREAM_SMART_POINTER(SMART_POINTER) << #SMART_POINTER
162 QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(STREAM_SMART_POINTER)
163#undef STREAM_SMART_POINTER
166 for (
const QByteArray &smartPointer : smartPointers) {
167 QByteArray ba = smartPointer +
"<";
168 if (propertyType.startsWith(ba) && !propertyType.endsWith(
"&"))
169 return knownQObjectClasses.contains(propertyType.mid(smartPointer.size() + 1, propertyType.size() - smartPointer.size() - 1 - 1));
172 static const QList<QByteArray> oneArgTemplates = QList<QByteArray>()
173#define STREAM_1ARG_TEMPLATE(TEMPLATENAME) << #TEMPLATENAME
174 QT_FOR_EACH_AUTOMATIC_TEMPLATE_1ARG(STREAM_1ARG_TEMPLATE)
175#undef STREAM_1ARG_TEMPLATE
177 for (
const QByteArray &oneArgTemplateType : oneArgTemplates) {
178 const QByteArray ba = oneArgTemplateType +
"<";
179 if (propertyType.startsWith(ba) && propertyType.endsWith(
">")) {
180 const qsizetype argumentSize = propertyType.size() - ba.size()
184 - (propertyType.at(propertyType.size() - 2) ==
' ' ? 1 : 0 );
185 const QByteArray templateArg = propertyType.sliced(ba.size(), argumentSize);
186 return isBuiltinType(templateArg) || registerableMetaType(templateArg);
193
196 if (qualifiedName == name)
198 const qsizetype index = qualifiedName.indexOf(
"::");
201 return qualifiedNameEquals(qualifiedName.mid(index+2), name);
206 QByteArray qualifiedClassNameIdentifier = identifier;
211 qualifiedClassNameIdentifier.replace(
"::",
"SCOPE");
216 qualifiedClassNameIdentifier =
"CLASS" + qualifiedClassNameIdentifier +
"ENDCLASS";
217 return qualifiedClassNameIdentifier;
222 bool isQObject = (cdef->classname ==
"QObject");
223 bool isConstructible = !cdef->constructorList.isEmpty();
228 for (EnumDef def : std::as_const(cdef->enumList)) {
229 if (cdef->enumDeclarations.contains(def.name)) {
232 def.enumName = def.name;
233 QByteArray alias = cdef->flagAliases.value(def.name);
234 if (cdef->enumDeclarations.contains(alias)) {
239 cdef->enumList = enumList;
245 strreg(cdef->qualified);
246 registerClassInfoStrings();
247 registerFunctionStrings(cdef->signalList);
248 registerFunctionStrings(cdef->slotList);
249 registerFunctionStrings(cdef->methodList);
250 registerFunctionStrings(cdef->constructorList);
251 registerByteArrayVector(cdef->nonClassSignalList);
252 registerPropertyStrings();
253 registerEnumStrings();
255 const bool hasStaticMetaCall =
257 || !cdef->propertyList.isEmpty() || !cdef->constructorList.isEmpty());
259 const QByteArray qualifiedClassNameIdentifier = generateQualifiedClassNameIdentifier(cdef->qualified);
262 fprintf(out,
"namespace {\n");
268 fprintf(out,
"\n#ifdef QT_MOC_HAS_STRINGDATA\n"
269 "struct qt_meta_stringdata_%s_t {};\n"
270 "constexpr auto qt_meta_stringdata_%s = QtMocHelpers::stringData(",
271 qualifiedClassNameIdentifier.constData(), qualifiedClassNameIdentifier.constData());
274 for (
const QByteArray &str : strings) {
277 printStringWithIndentation(out, str);
281 fprintf(out,
"\n);\n"
282 "#else // !QT_MOC_HAS_STRINGDATA\n");
283 fprintf(out,
"#error \"qtmochelpers.h not found or too old.\"\n");
284 fprintf(out,
"#endif // !QT_MOC_HAS_STRINGDATA\n");
285 fprintf(out,
"} // unnamed namespace\n\n");
291 int index = MetaObjectPrivateFieldCount;
292 fprintf(out,
"Q_CONSTINIT static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData());
293 fprintf(out,
"\n // content:\n");
295 fprintf(out,
" %4d, // classname\n", stridx(cdef->qualified));
296 fprintf(out,
" %4d, %4d, // classinfo\n",
int(cdef->classInfoList.size()),
int(cdef->classInfoList.size() ? index : 0));
297 index += cdef->classInfoList.size() * 2;
299 qsizetype methodCount = 0;
300 if (qAddOverflow(cdef->signalList.size(), cdef->slotList.size(), &methodCount)
301 || qAddOverflow(cdef->methodList.size(), methodCount, &methodCount)) {
302 parser->error(
"internal limit exceeded: the total number of member functions"
303 " (including signals and slots) is too big.");
306 fprintf(out,
" %4" PRIdQSIZETYPE
", %4d, // methods\n", methodCount, methodCount ? index : 0);
307 index += methodCount * QMetaObjectPrivate::IntsPerMethod;
309 index += methodCount;
310 int paramsIndex = index;
311 int totalParameterCount = aggregateParameterCount(cdef->signalList)
312 + aggregateParameterCount(cdef->slotList)
313 + aggregateParameterCount(cdef->methodList)
314 + aggregateParameterCount(cdef->constructorList);
315 index += totalParameterCount * 2
317 -
int(cdef->constructorList.size());
319 fprintf(out,
" %4d, %4d, // properties\n",
int(cdef->propertyList.size()),
int(cdef->propertyList.size() ? index : 0));
320 index += cdef->propertyList.size() * QMetaObjectPrivate::IntsPerProperty;
321 fprintf(out,
" %4d, %4d, // enums/sets\n",
int(cdef->enumList.size()), cdef->enumList.size() ? index : 0);
323 int enumsIndex = index;
324 for (
const EnumDef &def : std::as_const(cdef->enumList))
325 index += QMetaObjectPrivate::IntsPerEnum + (def.values.size() * 2);
327 fprintf(out,
" %4d, %4d, // constructors\n", isConstructible ?
int(cdef->constructorList.size()) : 0,
328 isConstructible ? index : 0);
334 flags |= PropertyAccessInStaticMetaCall;
336 fprintf(out,
" %4d, // flags\n", flags);
337 fprintf(out,
" %4d, // signalCount\n",
int(cdef->signalList.size()));
343 generateClassInfos();
345 qsizetype propEnumCount = 0;
347 if (qAddOverflow(cdef->propertyList.size(), cdef->enumList.size(), &propEnumCount)
348 || qAddOverflow(propEnumCount, qsizetype(1), &propEnumCount)
349 || propEnumCount >=
std::numeric_limits<
int>::max()) {
350 parser->error(
"internal limit exceeded: number of property and enum metatypes is too big.");
352 int initialMetaTypeOffset =
int(propEnumCount);
357 generateFunctions(cdef->signalList,
"signal", MethodSignal, paramsIndex, initialMetaTypeOffset);
362 generateFunctions(cdef->slotList,
"slot", MethodSlot, paramsIndex, initialMetaTypeOffset);
367 generateFunctions(cdef->methodList,
"method", MethodMethod, paramsIndex, initialMetaTypeOffset);
373 generateFunctionRevisions(cdef->signalList,
"signal");
374 generateFunctionRevisions(cdef->slotList,
"slot");
375 generateFunctionRevisions(cdef->methodList,
"method");
381 generateFunctionParameters(cdef->signalList,
"signal");
382 generateFunctionParameters(cdef->slotList,
"slot");
383 generateFunctionParameters(cdef->methodList,
"method");
385 generateFunctionParameters(cdef->constructorList,
"constructor");
390 generateProperties();
395 generateEnums(enumsIndex);
401 generateFunctions(cdef->constructorList,
"constructor", MethodConstructor, paramsIndex, initialMetaTypeOffset);
406 fprintf(out,
"\n 0 // eod\n};\n\n");
411 QList<QByteArray> extraList;
412 QMultiHash<QByteArray, QByteArray> knownExtraMetaObject(knownGadgets);
413 knownExtraMetaObject.unite(knownQObjectClasses);
415 for (
const PropertyDef &p : std::as_const(cdef->propertyList)) {
416 if (isBuiltinType(p.type))
419 if (p.type.contains(
'*') || p.type.contains(
'<') || p.type.contains(
'>'))
422 const qsizetype s = p.type.lastIndexOf(
"::");
426 QByteArray unqualifiedScope = p.type.left(s);
429 QMultiHash<QByteArray, QByteArray>::ConstIterator scopeIt;
431 QByteArray thisScope = cdef->qualified;
433 const qsizetype s = thisScope.lastIndexOf(
"::");
434 thisScope = thisScope.left(s);
435 QByteArray currentScope = thisScope.isEmpty() ? unqualifiedScope : thisScope +
"::" + unqualifiedScope;
436 scopeIt = knownExtraMetaObject.constFind(currentScope);
437 }
while (!thisScope.isEmpty() && scopeIt == knownExtraMetaObject.constEnd());
439 if (scopeIt == knownExtraMetaObject.constEnd())
442 const QByteArray &scope = *scopeIt;
446 if (qualifiedNameEquals(cdef->qualified, scope))
449 if (!extraList.contains(scope))
456 for (
auto it = cdef->enumDeclarations.keyBegin(),
457 end = cdef->enumDeclarations.keyEnd(); it != end; ++it) {
458 const QByteArray &enumKey = *it;
459 const qsizetype s = enumKey.lastIndexOf(
"::");
461 QByteArray scope = enumKey.left(s);
462 if (scope !=
"Qt" && !qualifiedNameEquals(cdef->qualified, scope) && !extraList.contains(scope))
471 if (!extraList.isEmpty()) {
472 fprintf(out,
"Q_CONSTINIT static const QMetaObject::SuperData qt_meta_extradata_%s[] = {\n",
473 qualifiedClassNameIdentifier.constData());
474 for (
const QByteArray &ba : std::as_const(extraList))
475 fprintf(out,
" QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", ba.constData());
477 fprintf(out,
" nullptr\n};\n\n");
483 fprintf(out,
"Q_CONSTINIT const QMetaObject %s::staticMetaObject = { {\n",
484 cdef->qualified.constData());
487 fprintf(out,
" nullptr,\n");
489 fprintf(out,
" QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData());
490 else if (cdef->superclassList.size())
491 fprintf(out,
" QtPrivate::MetaObjectForType<%s>::value,\n", purestSuperClass.constData());
493 fprintf(out,
" nullptr,\n");
494 fprintf(out,
" qt_meta_stringdata_%s.offsetsAndSizes,\n"
495 " qt_meta_data_%s,\n", qualifiedClassNameIdentifier.constData(),
496 qualifiedClassNameIdentifier.constData());
497 if (hasStaticMetaCall)
498 fprintf(out,
" qt_static_metacall,\n");
500 fprintf(out,
" nullptr,\n");
502 if (extraList.isEmpty())
503 fprintf(out,
" nullptr,\n");
505 fprintf(out,
" qt_meta_extradata_%s,\n", qualifiedClassNameIdentifier.constData());
507 const char *comma =
"";
509 auto stringForType = [requireCompleteness](
const QByteArray &type,
bool forceComplete) -> QByteArray {
510 const char *forceCompleteType = forceComplete ?
", std::true_type>" :
", std::false_type>";
511 if (requireCompleteness)
513 return "QtPrivate::TypeAndForceComplete<" % type % forceCompleteType;
515 if (!requireCompleteness) {
516 fprintf(out,
" qt_incomplete_metaTypeArray<qt_meta_stringdata_%s_t", qualifiedClassNameIdentifier.constData());
519 fprintf(out,
" qt_metaTypeArray<");
522 for (
const PropertyDef &p : std::as_const(cdef->propertyList)) {
523 fprintf(out,
"%s\n // property '%s'\n %s",
524 comma, p.name.constData(), stringForType(p.type,
true).constData());
529 for (
const EnumDef &e : std::as_const(cdef->enumList)) {
530 fprintf(out,
"%s\n // enum '%s'\n %s",
531 comma, e.name.constData(), stringForType(e.qualifiedType(cdef),
true).constData());
537 fprintf(out,
"%s\n // Q_OBJECT / Q_GADGET\n %s",
538 comma, stringForType(ownType,
true).constData());
543 const auto allMethods = {&cdef->signalList, &cdef->slotList, &cdef->methodList};
544 for (
const QList<FunctionDef> *methodContainer : allMethods) {
545 for (
const FunctionDef &fdef : *methodContainer) {
546 fprintf(out,
",\n // method '%s'\n %s",
547 fdef.name.constData(), stringForType(fdef.type.name,
false).constData());
548 for (
const auto &argument: fdef.arguments)
549 fprintf(out,
",\n %s", stringForType(argument.type.name,
false).constData());
554 for (
const FunctionDef &fdef : std::as_const(cdef->constructorList)) {
555 if (fdef.arguments.isEmpty())
558 fprintf(out,
"%s\n // constructor '%s'", comma, fdef.name.constData());
560 for (
const auto &argument: fdef.arguments) {
561 fprintf(out,
"%s\n %s", comma,
562 stringForType(argument.type.name,
false).constData());
566 fprintf(out,
"\n >,\n");
568 fprintf(out,
" nullptr\n} };\n\n");
573 if (hasStaticMetaCall)
574 generateStaticMetacall();
579 fprintf(out,
"\nconst QMetaObject *%s::metaObject() const\n{\n return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;\n}\n",
580 cdef->qualified.constData());
586 fprintf(out,
"\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData());
587 fprintf(out,
" if (!_clname) return nullptr;\n");
588 fprintf(out,
" if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata0))\n"
589 " return static_cast<void*>(this);\n",
590 qualifiedClassNameIdentifier.constData());
593 if (cdef->superclassList.size() > 1) {
594 auto it = cdef->superclassList.cbegin() + 1;
595 const auto end = cdef->superclassList.cend();
596 for (; it != end; ++it) {
599 const char *cname = it->classname.constData();
600 fprintf(out,
" if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(this);\n",
605 for (
const QList<ClassDef::Interface> &iface : std::as_const(cdef->interfaceList)) {
606 for (qsizetype j = 0; j < iface.size(); ++j) {
607 fprintf(out,
" if (!strcmp(_clname, %s))\n return ", iface.at(j).interfaceId.constData());
608 for (qsizetype k = j; k >= 0; --k)
609 fprintf(out,
"static_cast< %s*>(", iface.at(k).className.constData());
610 fprintf(out,
"this%s;\n", QByteArray(j + 1,
')').constData());
613 if (!purestSuperClass.isEmpty() && !isQObject) {
614 QByteArray superClass = purestSuperClass;
615 fprintf(out,
" return %s::qt_metacast(_clname);\n", superClass.constData());
617 fprintf(out,
" return nullptr;\n");
629 for (
int signalindex = 0; signalindex <
int(cdef->signalList.size()); ++signalindex)
630 generateSignal(&cdef->signalList.at(signalindex), signalindex);
635 generatePluginMetaData();
640 if (!cdef->nonClassSignalList.isEmpty()) {
641 fprintf(out,
"namespace CheckNotifySignalValidity_%s {\n", qualifiedClassNameIdentifier.constData());
642 for (
const QByteArray &nonClassSignal : std::as_const(cdef->nonClassSignalList)) {
643 const auto propertyIt = std::find_if(cdef->propertyList.constBegin(),
644 cdef->propertyList.constEnd(),
645 [&nonClassSignal](
const PropertyDef &p) {
646 return nonClassSignal == p.notify;
649 Q_ASSERT(propertyIt != cdef->propertyList.constEnd());
650 fprintf(out,
"template<typename T> using has_nullary_%s = decltype(std::declval<T>().%s());\n",
651 nonClassSignal.constData(),
652 nonClassSignal.constData());
653 const auto &propertyType = propertyIt->type;
654 fprintf(out,
"template<typename T> using has_unary_%s = decltype(std::declval<T>().%s(std::declval<%s>()));\n",
655 nonClassSignal.constData(),
656 nonClassSignal.constData(),
657 propertyType.constData());
658 fprintf(out,
"static_assert(qxp::is_detected_v<has_nullary_%s, %s> || qxp::is_detected_v<has_unary_%s, %s>,\n"
659 " \"NOTIFY signal %s does not exist in class (or is private in its parent)\");\n",
660 nonClassSignal.constData(), cdef->qualified.constData(),
661 nonClassSignal.constData(), cdef->qualified.constData(),
662 nonClassSignal.constData());
669void Generator::registerClassInfoStrings()
671 for (
const ClassInfoDef &c : std::as_const(cdef->classInfoList)) {
679 if (cdef->classInfoList.isEmpty())
682 fprintf(out,
"\n // classinfo: key, value\n");
684 for (
const ClassInfoDef &c : std::as_const(cdef->classInfoList))
685 fprintf(out,
" %4d, %4d,\n", stridx(c.name), stridx(c.value));
690 for (
const FunctionDef &f : list) {
692 if (!isBuiltinType(f.normalizedType))
693 strreg(f.normalizedType);
696 for (
const ArgumentDef &a : f.arguments) {
697 if (!isBuiltinType(a.normalizedType))
698 strreg(a.normalizedType);
704void Generator::registerByteArrayVector(
const QList<QByteArray> &list)
706 for (
const QByteArray &ba : list)
711 int ¶msIndex,
int &initialMetatypeOffset)
715 fprintf(out,
"\n // %ss: name, argc, parameters, tag, flags, initial metatype offsets\n", functype);
717 for (
const FunctionDef &f : list) {
720 if (f.access == FunctionDef::Private) {
721 flags |= AccessPrivate;
722 comment.append(
"Private");
723 }
else if (f.access == FunctionDef::Public) {
724 flags |= AccessPublic;
725 comment.append(
"Public");
726 }
else if (f.access == FunctionDef::Protected) {
727 flags |= AccessProtected;
728 comment.append(
"Protected");
731 flags |= MethodCompatibility;
732 comment.append(
" | MethodCompatibility");
735 flags |= MethodCloned;
736 comment.append(
" | MethodCloned");
738 if (f.isScriptable) {
739 flags |= MethodScriptable;
740 comment.append(
" | isScriptable");
742 if (f.revision > 0) {
743 flags |= MethodRevisioned;
744 comment.append(
" | MethodRevisioned");
748 flags |= MethodIsConst;
749 comment.append(
" | MethodIsConst ");
752 const int argc =
int(f.arguments.size());
753 fprintf(out,
" %4d, %4d, %4d, %4d, 0x%02x, %4d /* %s */,\n",
754 stridx(f.name), argc, paramsIndex, stridx(f.tag), flags, initialMetatypeOffset, comment.constData());
756 paramsIndex += 1 + argc * 2;
758 initialMetatypeOffset += (f.isConstructor ? 0 : 1) + argc;
765 fprintf(out,
"\n // %ss: revision\n", functype);
766 for (
const FunctionDef &f : list)
767 fprintf(out,
" %4d,\n", f.revision);
774 fprintf(out,
"\n // %ss: parameters\n", functype);
775 for (
const FunctionDef &f : list) {
779 const bool allowEmptyName = f.isConstructor;
780 generateTypeInfo(f.normalizedType, allowEmptyName);
782 for (
const ArgumentDef &arg : f.arguments) {
784 generateTypeInfo(arg.normalizedType, allowEmptyName);
789 for (
const ArgumentDef &arg : f.arguments)
790 fprintf(out,
" %4d,", stridx(arg.name));
796void Generator::generateTypeInfo(
const QByteArray &typeName,
bool allowEmptyName)
798 Q_UNUSED(allowEmptyName);
799 if (isBuiltinType(typeName)) {
801 const char *valueString;
802 if (typeName ==
"qreal") {
803 type = QMetaType::UnknownType;
804 valueString =
"QReal";
806 type = nameToBuiltinType(typeName);
810 fprintf(out,
"QMetaType::%s", valueString);
812 Q_ASSERT(type != QMetaType::UnknownType);
813 fprintf(out,
"%4d", type);
816 Q_ASSERT(!typeName.isEmpty() || allowEmptyName);
817 fprintf(out,
"0x%.8x | %d", IsUnresolvedType, stridx(typeName));
823 for (
const PropertyDef &p : std::as_const(cdef->propertyList)) {
825 if (!isBuiltinType(p.type))
836 if (cdef->propertyList.size())
837 fprintf(out,
"\n // properties: name, type, flags, notifyId, revision\n");
838 for (
const PropertyDef &p : std::as_const(cdef->propertyList)) {
839 uint flags = Invalid;
840 if (!isBuiltinType(p.type))
842 if (!p.member.isEmpty() && !p.constant)
844 if (!p.read.isEmpty() || !p.member.isEmpty())
846 if (!p.write.isEmpty()) {
852 if (!p.reset.isEmpty())
855 if (p.designable !=
"false")
858 if (p.scriptable !=
"false")
861 if (p.stored !=
"false")
864 if (p.user !=
"false")
874 if (!p.bind.isEmpty())
877 fprintf(out,
" %4d, ", stridx(p.name));
878 generateTypeInfo(p.type);
879 int notifyId = p.notifyId;
880 if (p.notifyId < -1) {
882 const int indexInStrings =
int(strings.indexOf(p.notify));
883 notifyId = indexInStrings | IsUnresolvedSignal;
885 fprintf(out,
", 0x%.8x, uint(%d), %d,\n", flags, notifyId, p.revision);
891 for (
const EnumDef &e : std::as_const(cdef->enumList)) {
893 if (!e.enumName.isNull())
895 for (
const QByteArray &val : e.values)
902 if (cdef->enumDeclarations.isEmpty())
905 fprintf(out,
"\n // enums: name, alias, flags, count, data\n");
906 index += QMetaObjectPrivate::IntsPerEnum * cdef->enumList.size();
908 for (i = 0; i < cdef->enumList.size(); ++i) {
909 const EnumDef &e = cdef->enumList.at(i);
910 uint flags = e.flags | cdef->enumDeclarations.value(e.name);
911 fprintf(out,
" %4d, %4d, 0x%.1x, %4d, %4d,\n",
913 e.enumName.isNull() ? stridx(e.name) : stridx(e.enumName),
915 int(e.values.size()),
917 index += e.values.size() * 2;
920 fprintf(out,
"\n // enum data: key, value\n");
921 for (
const EnumDef &e : std::as_const(cdef->enumList)) {
922 QByteArray prefix = cdef->qualified;
923 if (e.flags & EnumIsScoped)
924 prefix +=
"::" + (e.enumName.isNull() ? e.name : e.enumName);
925 for (
const QByteArray &val : e.values) {
926 fprintf(out,
" %4d, uint(%s::%s),\n",
927 stridx(val), prefix.constData(), val.constData());
934 bool isQObject = (cdef->classname ==
"QObject");
936 fprintf(out,
"\nint %s::qt_metacall(QMetaObject::Call _c, int _id, void **_a)\n{\n",
937 cdef->qualified.constData());
939 if (!purestSuperClass.isEmpty() && !isQObject) {
940 QByteArray superClass = purestSuperClass;
941 fprintf(out,
" _id = %s::qt_metacall(_c, _id, _a);\n", superClass.constData());
945 bool needElse =
false;
947 methodList += cdef->signalList;
948 methodList += cdef->slotList;
949 methodList += cdef->methodList;
954 if (methodList.size() || cdef->propertyList.size()) {
955 fprintf(out,
" if (_id < 0)\n return _id;\n");
960 if (methodList.size()) {
962 fprintf(out,
"if (_c == QMetaObject::InvokeMetaMethod) {\n");
963 fprintf(out,
" if (_id < %d)\n",
int(methodList.size()));
964 fprintf(out,
" qt_static_metacall(this, _c, _id, _a);\n");
965 fprintf(out,
" _id -= %d;\n }",
int(methodList.size()));
967 fprintf(out,
" else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {\n");
968 fprintf(out,
" if (_id < %d)\n",
int(methodList.size()));
970 if (methodsWithAutomaticTypesHelper(methodList).isEmpty())
971 fprintf(out,
" *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType();\n");
973 fprintf(out,
" qt_static_metacall(this, _c, _id, _a);\n");
974 fprintf(out,
" _id -= %d;\n }",
int(methodList.size()));
978 if (cdef->propertyList.size()) {
980 fprintf(out,
"else ");
982 "if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty\n"
983 " || _c == QMetaObject::ResetProperty || _c == QMetaObject::BindableProperty\n"
984 " || _c == QMetaObject::RegisterPropertyMetaType) {\n"
985 " qt_static_metacall(this, _c, _id, _a);\n"
986 " _id -= %d;\n }",
int(cdef->propertyList.size()));
988 if (methodList.size() || cdef->propertyList.size())
990 fprintf(out,
"return _id;\n}\n");
995QMultiMap<QByteArray,
int>
Generator::automaticPropertyMetaTypesHelper()
997 QMultiMap<QByteArray,
int> automaticPropertyMetaTypes;
998 for (
int i = 0; i <
int(cdef->propertyList.size()); ++i) {
999 const QByteArray propertyType = cdef->propertyList.at(i).type;
1000 if (registerableMetaType(propertyType) && !isBuiltinType(propertyType))
1001 automaticPropertyMetaTypes.insert(propertyType, i);
1003 return automaticPropertyMetaTypes;
1006QMap<
int, QMultiMap<QByteArray,
int>>
1009 QMap<
int, QMultiMap<QByteArray,
int> > methodsWithAutomaticTypes;
1010 for (
int i = 0; i < methodList.size(); ++i) {
1012 for (
int j = 0; j < f.arguments.size(); ++j) {
1013 const QByteArray argType = f.arguments.at(j).normalizedType;
1014 if (registerableMetaType(argType) && !isBuiltinType(argType))
1015 methodsWithAutomaticTypes[i].insert(argType, j);
1018 return methodsWithAutomaticTypes;
1023 fprintf(out,
"void %s::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)\n{\n",
1024 cdef->qualified.constData());
1026 bool needElse =
false;
1027 bool isUsed_a =
false;
1029 const auto generateCtorArguments = [&](
int ctorindex) {
1030 const FunctionDef &f = cdef->constructorList.at(ctorindex);
1034 const auto begin = f.arguments.cbegin();
1035 const auto end = f.arguments.cend();
1036 for (
auto it = begin; it != end; ++it) {
1040 fprintf(out,
"(*reinterpret_cast<%s>(_a[%d]))",
1041 a.typeNameForCast.constData(), offset++);
1045 if (!cdef->constructorList.isEmpty()) {
1046 fprintf(out,
" if (_c == QMetaObject::CreateInstance) {\n");
1047 fprintf(out,
" switch (_id) {\n");
1048 const int ctorend =
int(cdef->constructorList.size());
1049 for (
int ctorindex = 0; ctorindex < ctorend; ++ctorindex) {
1050 fprintf(out,
" case %d: { %s *_r = new %s(", ctorindex,
1051 cdef->classname.constData(), cdef->classname.constData());
1052 generateCtorArguments(ctorindex);
1053 fprintf(out,
");\n");
1054 fprintf(out,
" if (_a[0]) *reinterpret_cast<%s**>(_a[0]) = _r; } break;\n",
1057 fprintf(out,
" default: break;\n");
1058 fprintf(out,
" }\n");
1059 fprintf(out,
" } else if (_c == QMetaObject::ConstructInPlace) {\n");
1060 fprintf(out,
" switch (_id) {\n");
1061 for (
int ctorindex = 0; ctorindex < ctorend; ++ctorindex) {
1062 fprintf(out,
" case %d: { new (_a[0]) %s(",
1063 ctorindex, cdef->classname.constData());
1064 generateCtorArguments(ctorindex);
1065 fprintf(out,
"); } break;\n");
1067 fprintf(out,
" default: break;\n");
1068 fprintf(out,
" }\n");
1075 methodList += cdef->signalList;
1076 methodList += cdef->slotList;
1077 methodList += cdef->methodList;
1079 if (!methodList.isEmpty()) {
1081 fprintf(out,
" else ");
1084 fprintf(out,
"if (_c == QMetaObject::InvokeMetaMethod) {\n");
1087 fprintf(out,
" Q_ASSERT(staticMetaObject.cast(_o));\n");
1089 fprintf(out,
" auto *_t = static_cast<%s *>(_o);\n", cdef->classname.constData());
1091 fprintf(out,
" auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData());
1093 fprintf(out,
" (void)_t;\n");
1094 fprintf(out,
" switch (_id) {\n");
1095 for (
int methodindex = 0; methodindex < methodList.size(); ++methodindex) {
1096 const FunctionDef &f = methodList.at(methodindex);
1097 Q_ASSERT(!f.normalizedType.isEmpty());
1098 fprintf(out,
" case %d: ", methodindex);
1099 if (f.normalizedType !=
"void")
1100 fprintf(out,
"{ %s _r = ", noRef(f.normalizedType).constData());
1101 fprintf(out,
"_t->");
1102 if (f.inPrivateClass.size())
1103 fprintf(out,
"%s->", f.inPrivateClass.constData());
1104 fprintf(out,
"%s(", f.name.constData());
1108 fprintf(out,
"QMethodRawArguments{ _a }");
1110 const auto begin = f.arguments.cbegin();
1111 const auto end = f.arguments.cend();
1112 for (
auto it = begin; it != end; ++it) {
1116 fprintf(out,
"(*reinterpret_cast< %s>(_a[%d]))",a.typeNameForCast.constData(), offset++);
1120 if (!f.arguments.isEmpty())
1122 fprintf(out,
"%s",
"QPrivateSignal()");
1126 if (f.normalizedType !=
"void") {
1127 fprintf(out,
"\n if (_a[0]) *reinterpret_cast< %s*>(_a[0]) = std::move(_r); } ",
1128 noRef(f.normalizedType).constData());
1131 fprintf(out,
" break;\n");
1133 fprintf(out,
" default: ;\n");
1134 fprintf(out,
" }\n");
1138 QMap<
int, QMultiMap<QByteArray,
int> > methodsWithAutomaticTypes = methodsWithAutomaticTypesHelper(methodList);
1140 if (!methodsWithAutomaticTypes.isEmpty()) {
1141 fprintf(out,
" else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {\n");
1142 fprintf(out,
" switch (_id) {\n");
1143 fprintf(out,
" default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;\n");
1144 QMap<
int, QMultiMap<QByteArray,
int> >::const_iterator it = methodsWithAutomaticTypes.constBegin();
1145 const QMap<
int, QMultiMap<QByteArray,
int> >::const_iterator end = methodsWithAutomaticTypes.constEnd();
1146 for ( ; it != end; ++it) {
1147 fprintf(out,
" case %d:\n", it.key());
1148 fprintf(out,
" switch (*reinterpret_cast<int*>(_a[1])) {\n");
1149 fprintf(out,
" default: *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType(); break;\n");
1150 auto jt = it->begin();
1151 const auto jend = it->end();
1152 while (jt != jend) {
1153 fprintf(out,
" case %d:\n", jt.value());
1154 const QByteArray &lastKey = jt.key();
1156 if (jt == jend || jt.key() != lastKey)
1157 fprintf(out,
" *reinterpret_cast<QMetaType *>(_a[0]) = QMetaType::fromType< %s >(); break;\n", lastKey.constData());
1159 fprintf(out,
" }\n");
1160 fprintf(out,
" break;\n");
1162 fprintf(out,
" }\n");
1168 if (!cdef->signalList.isEmpty()) {
1170 fprintf(out,
" else if (_c == QMetaObject::IndexOfMethod) {\n");
1171 fprintf(out,
" int *result = reinterpret_cast<int *>(_a[0]);\n");
1172 bool anythingUsed =
false;
1173 for (
int methodindex = 0; methodindex <
int(cdef->signalList.size()); ++methodindex) {
1174 const FunctionDef &f = cdef->signalList.at(methodindex);
1177 anythingUsed =
true;
1178 fprintf(out,
" {\n");
1179 fprintf(out,
" using _t = %s (%s::*)(",f.type.rawName.constData() , cdef->classname.constData());
1181 const auto begin = f.arguments.cbegin();
1182 const auto end = f.arguments.cend();
1183 for (
auto it = begin; it != end; ++it) {
1187 fprintf(out,
"%s", QByteArray(a.type.name +
' ' + a.rightType).constData());
1190 if (!f.arguments.isEmpty())
1192 fprintf(out,
"%s",
"QPrivateSignal");
1195 fprintf(out,
") const;\n");
1197 fprintf(out,
");\n");
1198 fprintf(out,
" if (_t _q_method = &%s::%s; *reinterpret_cast<_t *>(_a[1]) == _q_method) {\n",
1199 cdef->classname.constData(), f.name.constData());
1200 fprintf(out,
" *result = %d;\n", methodindex);
1201 fprintf(out,
" return;\n");
1202 fprintf(out,
" }\n }\n");
1205 fprintf(out,
" (void)result;\n");
1210 const QMultiMap<QByteArray,
int> automaticPropertyMetaTypes = automaticPropertyMetaTypesHelper();
1212 if (!automaticPropertyMetaTypes.isEmpty()) {
1214 fprintf(out,
" else ");
1217 fprintf(out,
"if (_c == QMetaObject::RegisterPropertyMetaType) {\n");
1218 fprintf(out,
" switch (_id) {\n");
1219 fprintf(out,
" default: *reinterpret_cast<int*>(_a[0]) = -1; break;\n");
1220 auto it = automaticPropertyMetaTypes.begin();
1221 const auto end = automaticPropertyMetaTypes.end();
1223 fprintf(out,
" case %d:\n", it.value());
1224 const QByteArray &lastKey = it.key();
1226 if (it == end || it.key() != lastKey)
1227 fprintf(out,
" *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< %s >(); break;\n", lastKey.constData());
1229 fprintf(out,
" }\n");
1230 fprintf(out,
" } ");
1235 if (!cdef->propertyList.empty()) {
1236 bool needGet =
false;
1237 bool needTempVarForGet =
false;
1238 bool needSet =
false;
1239 bool needReset =
false;
1240 bool hasBindableProperties =
false;
1241 for (
const PropertyDef &p : std::as_const(cdef->propertyList)) {
1242 needGet |= !p.read.isEmpty() || !p.member.isEmpty();
1243 if (!p.read.isEmpty() || !p.member.isEmpty())
1244 needTempVarForGet |= (p.gspec != PropertyDef::PointerSpec
1245 && p.gspec != PropertyDef::ReferenceSpec);
1247 needSet |= !p.write.isEmpty() || (!p.member.isEmpty() && !p.constant);
1248 needReset |= !p.reset.isEmpty();
1249 hasBindableProperties |= !p.bind.isEmpty();
1252 fprintf(out,
" else ");
1253 fprintf(out,
"if (_c == QMetaObject::ReadProperty) {\n");
1255 auto setupMemberAccess = [
this]() {
1258 fprintf(out,
" Q_ASSERT(staticMetaObject.cast(_o));\n");
1260 fprintf(out,
" auto *_t = static_cast<%s *>(_o);\n", cdef->classname.constData());
1262 fprintf(out,
" auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData());
1264 fprintf(out,
" (void)_t;\n");
1268 setupMemberAccess();
1269 if (needTempVarForGet)
1270 fprintf(out,
" void *_v = _a[0];\n");
1271 fprintf(out,
" switch (_id) {\n");
1272 for (
int propindex = 0; propindex <
int(cdef->propertyList.size()); ++propindex) {
1273 const PropertyDef &p = cdef->propertyList.at(propindex);
1274 if (p.read.isEmpty() && p.member.isEmpty())
1276 QByteArray prefix =
"_t->";
1277 if (p.inPrivateClass.size()) {
1278 prefix += p.inPrivateClass +
"->";
1282 fprintf(out,
" case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(%s%s())); break;\n",
1283 propindex, prefix.constData(), p.read.constData());
1285 fprintf(out,
" case %d: _a[0] = const_cast<void*>(reinterpret_cast<const void*>(&%s%s())); break;\n",
1286 propindex, prefix.constData(), p.read.constData());
1287 else if (
auto eflags = cdef->enumDeclarations.value(p.type); eflags & EnumIsFlag)
1288 fprintf(out,
" case %d: *reinterpret_cast<int*>(_v) = QFlag(%s%s()); break;\n",
1289 propindex, prefix.constData(), p.read.constData());
1290 else if (p.read ==
"default")
1291 fprintf(out,
" case %d: *reinterpret_cast< %s*>(_v) = %s%s().value(); break;\n",
1292 propindex, p.type.constData(), prefix.constData(), p.bind.constData());
1293 else if (!p.read.isEmpty())
1294 fprintf(out,
" case %d: *reinterpret_cast< %s*>(_v) = %s%s(); break;\n",
1295 propindex, p.type.constData(), prefix.constData(), p.read.constData());
1297 fprintf(out,
" case %d: *reinterpret_cast< %s*>(_v) = %s%s; break;\n",
1298 propindex, p.type.constData(), prefix.constData(), p.member.constData());
1300 fprintf(out,
" default: break;\n");
1301 fprintf(out,
" }\n");
1306 fprintf(out,
" else ");
1307 fprintf(out,
"if (_c == QMetaObject::WriteProperty) {\n");
1310 setupMemberAccess();
1311 fprintf(out,
" void *_v = _a[0];\n");
1312 fprintf(out,
" switch (_id) {\n");
1313 for (
int propindex = 0; propindex <
int(cdef->propertyList.size()); ++propindex) {
1314 const PropertyDef &p = cdef->propertyList.at(propindex);
1317 if (p.write.isEmpty() && p.member.isEmpty())
1319 QByteArray prefix =
"_t->";
1320 if (p.inPrivateClass.size()) {
1321 prefix += p.inPrivateClass +
"->";
1323 if (
auto eflags = cdef->enumDeclarations.value(p.type); eflags & EnumIsFlag) {
1324 fprintf(out,
" case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
1325 propindex, prefix.constData(), p.write.constData());
1326 }
else if (p.write ==
"default") {
1327 fprintf(out,
" case %d: {\n", propindex);
1328 fprintf(out,
" %s%s().setValue(*reinterpret_cast< %s*>(_v));\n",
1329 prefix.constData(), p.bind.constData(), p.type.constData());
1330 fprintf(out,
" break;\n");
1331 fprintf(out,
" }\n");
1332 }
else if (!p.write.isEmpty()) {
1333 fprintf(out,
" case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n",
1334 propindex, prefix.constData(), p.write.constData(), p.type.constData());
1336 fprintf(out,
" case %d:\n", propindex);
1337 fprintf(out,
" if (%s%s != *reinterpret_cast< %s*>(_v)) {\n",
1338 prefix.constData(), p.member.constData(), p.type.constData());
1339 fprintf(out,
" %s%s = *reinterpret_cast< %s*>(_v);\n",
1340 prefix.constData(), p.member.constData(), p.type.constData());
1341 if (!p.notify.isEmpty() && p
.notifyId > -1) {
1343 if (f.arguments.size() == 0)
1344 fprintf(out,
" Q_EMIT _t->%s();\n", p.notify.constData());
1345 else if (f.arguments.size() == 1 && f.arguments.at(0).normalizedType == p.type)
1346 fprintf(out,
" Q_EMIT _t->%s(%s%s);\n",
1347 p.notify.constData(), prefix.constData(), p.member.constData());
1348 }
else if (!p.notify.isEmpty() && p
.notifyId < -1) {
1349 fprintf(out,
" Q_EMIT _t->%s();\n", p.notify.constData());
1351 fprintf(out,
" }\n");
1352 fprintf(out,
" break;\n");
1355 fprintf(out,
" default: break;\n");
1356 fprintf(out,
" }\n");
1361 fprintf(out,
" else ");
1362 fprintf(out,
"if (_c == QMetaObject::ResetProperty) {\n");
1364 setupMemberAccess();
1365 fprintf(out,
" switch (_id) {\n");
1366 for (
int propindex = 0; propindex <
int(cdef->propertyList.size()); ++propindex) {
1367 const PropertyDef &p = cdef->propertyList.at(propindex);
1368 if (p.reset.isEmpty())
1370 QByteArray prefix =
"_t->";
1371 if (p.inPrivateClass.size()) {
1372 prefix += p.inPrivateClass +
"->";
1374 fprintf(out,
" case %d: %s%s(); break;\n",
1375 propindex, prefix.constData(), p.reset.constData());
1377 fprintf(out,
" default: break;\n");
1378 fprintf(out,
" }\n");
1382 fprintf(out,
" else ");
1383 fprintf(out,
"if (_c == QMetaObject::BindableProperty) {\n");
1384 if (hasBindableProperties) {
1385 setupMemberAccess();
1386 fprintf(out,
" switch (_id) {\n");
1387 for (
int propindex = 0; propindex <
int(cdef->propertyList.size()); ++propindex) {
1388 const PropertyDef &p = cdef->propertyList.at(propindex);
1389 if (p.bind.isEmpty())
1391 QByteArray prefix =
"_t->";
1392 if (p.inPrivateClass.size()) {
1393 prefix += p.inPrivateClass +
"->";
1396 " case %d: *static_cast<QUntypedBindable *>(_a[0]) = %s%s(); "
1398 propindex, prefix.constData(), p.bind.constData());
1400 fprintf(out,
" default: break;\n");
1401 fprintf(out,
" }\n");
1410 if (methodList.isEmpty()) {
1411 fprintf(out,
" (void)_o;\n");
1412 if (cdef->constructorList.isEmpty() && automaticPropertyMetaTypes.isEmpty() && methodsWithAutomaticTypesHelper(methodList).isEmpty()) {
1413 fprintf(out,
" (void)_id;\n");
1414 fprintf(out,
" (void)_c;\n");
1418 fprintf(out,
" (void)_a;\n");
1420 fprintf(out,
"}\n");
1427 fprintf(out,
"\n// SIGNAL %d\n%s %s::%s(",
1428 index, def->type.name.constData(), cdef->qualified.constData(), def->name.constData());
1430 QByteArray thisPtr =
"this";
1431 const char *constQualifier =
"";
1434 thisPtr =
"const_cast< " + cdef->qualified +
" *>(this)";
1435 constQualifier =
"const";
1438 Q_ASSERT(!def->normalizedType.isEmpty());
1439 if (def->arguments.isEmpty() && def->normalizedType ==
"void" && !def
->isPrivateSignal) {
1440 fprintf(out,
")%s\n{\n"
1441 " QMetaObject::activate(%s, &staticMetaObject, %d, nullptr);\n"
1442 "}\n", constQualifier, thisPtr.constData(), index);
1447 const auto begin = def->arguments.cbegin();
1448 const auto end = def->arguments.cend();
1449 for (
auto it = begin; it != end; ++it) {
1453 if (a.type.name.size())
1454 fputs(a.type.name.constData(), out);
1455 fprintf(out,
" _t%d", offset++);
1456 if (a.rightType.size())
1457 fputs(a.rightType.constData(), out);
1460 if (!def->arguments.isEmpty())
1462 fprintf(out,
"QPrivateSignal _t%d", offset++);
1465 fprintf(out,
")%s\n{\n", constQualifier);
1466 if (def->type.name.size() && def->normalizedType !=
"void") {
1467 QByteArray returnType = noRef(def->normalizedType);
1468 fprintf(out,
" %s _t0{};\n", returnType.constData());
1471 fprintf(out,
" void *_a[] = { ");
1472 if (def->normalizedType ==
"void") {
1473 fprintf(out,
"nullptr");
1476 fprintf(out,
"const_cast<void*>(reinterpret_cast<const volatile void*>(std::addressof(_t0)))");
1478 fprintf(out,
"const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t0)))");
1481 for (i = 1; i < offset; ++i)
1482 if (i <= def->arguments.size() && def->arguments.at(i - 1).type.isVolatile)
1483 fprintf(out,
", const_cast<void*>(reinterpret_cast<const volatile void*>(std::addressof(_t%d)))", i);
1485 fprintf(out,
", const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t%d)))", i);
1486 fprintf(out,
" };\n");
1487 fprintf(out,
" QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index);
1488 if (def->normalizedType !=
"void")
1489 fprintf(out,
" return _t0;\n");
1490 fprintf(out,
"}\n");
1496 auto it = o.constBegin();
1497 auto end = o.constEnd();
1499 cbor_encoder_create_map(parent, &map, o.size());
1501 for ( ; it != end; ++it) {
1502 QByteArray key = it.key().toUtf8();
1503 cbor_encode_text_string(&map, key.constData(), key.size());
1504 jsonValueToCbor(&map, it.value());
1506 return cbor_encoder_close_container(parent, &map);
1512 cbor_encoder_create_array(parent, &array, a.size());
1513 for (
const QJsonValue v : a)
1514 jsonValueToCbor(&array, v);
1515 return cbor_encoder_close_container(parent, &array);
1521 case QJsonValue::Null:
1522 case QJsonValue::Undefined:
1523 return cbor_encode_null(parent);
1524 case QJsonValue::Bool:
1525 return cbor_encode_boolean(parent, v.toBool());
1526 case QJsonValue::Array:
1527 return jsonArrayToCbor(parent, v.toArray());
1528 case QJsonValue::Object:
1529 return jsonObjectToCbor(parent, v.toObject());
1530 case QJsonValue::String: {
1531 QByteArray s = v.toString().toUtf8();
1532 return cbor_encode_text_string(parent, s.constData(), s.size());
1534 case QJsonValue::Double: {
1535 double d = v.toDouble();
1536 if (d == floor(d) && fabs(d) <= (Q_INT64_C(1) <<
std::numeric_limits<
double>::digits))
1537 return cbor_encode_int(parent, qint64(d));
1538 return cbor_encode_double(parent, d);
1541 Q_UNREACHABLE_RETURN(CborUnknownError);
1546 if (cdef->pluginData.iid.isEmpty())
1549 auto outputCborData = [
this]() {
1552 cbor_encoder_init_writer(&enc, CborDevice::callback, &dev);
1555 cbor_encoder_create_map(&enc, &map, CborIndefiniteLength);
1558 cbor_encode_int(&map,
int(QtPluginMetaDataKeys::IID));
1559 cbor_encode_text_string(&map, cdef->pluginData.iid.constData(), cdef->pluginData.iid.size());
1562 cbor_encode_int(&map,
int(QtPluginMetaDataKeys::ClassName));
1563 cbor_encode_text_string(&map, cdef->classname.constData(), cdef->classname.size());
1565 QJsonObject o = cdef->pluginData.metaData.object();
1568 cbor_encode_int(&map,
int(QtPluginMetaDataKeys::MetaData));
1569 jsonObjectToCbor(&map, o);
1572 if (!cdef->pluginData.uri.isEmpty()) {
1574 cbor_encode_int(&map,
int(QtPluginMetaDataKeys::URI));
1575 cbor_encode_text_string(&map, cdef->pluginData.uri.constData(), cdef->pluginData.uri.size());
1579 for (
auto it = cdef->pluginData.metaArgs.cbegin(), end = cdef->pluginData.metaArgs.cend(); it != end; ++it) {
1580 const QJsonArray &a = it.value();
1581 QByteArray key = it.key().toUtf8();
1582 dev
.nextItem(QByteArray(
"command-line \"" + key +
"\"").constData()
);
1583 cbor_encode_text_string(&map, key.constData(), key.size());
1584 jsonArrayToCbor(&map, a);
1589 cbor_encoder_close_container(&enc, &map);
1593 qsizetype pos = cdef->qualified.indexOf(
"::");
1594 for ( ; pos != -1 ; pos = cdef->qualified.indexOf(
"::", pos + 2) )
1595 fprintf(out,
"using namespace %s;\n", cdef->qualified.left(pos).constData());
1597 fputs(
"\n#ifdef QT_MOC_EXPORT_PLUGIN_V2", out);
1600 fprintf(out,
"\nstatic constexpr unsigned char qt_pluginMetaDataV2_%s[] = {",
1601 cdef->classname.constData());
1603 fprintf(out,
"\n};\nQT_MOC_EXPORT_PLUGIN_V2(%s, %s, qt_pluginMetaDataV2_%s)\n",
1604 cdef->qualified.constData(), cdef->classname.constData(), cdef->classname.constData());
1607 fprintf(out,
"#else\nQT_PLUGIN_METADATA_SECTION\n"
1608 "Q_CONSTINIT static constexpr unsigned char qt_pluginMetaData_%s[] = {\n"
1609 " 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!',\n"
1610 " // metadata version, Qt version, architectural requirements\n"
1611 " 0, QT_VERSION_MAJOR, QT_VERSION_MINOR, qPluginArchRequirements(),",
1612 cdef->classname.constData());
1614 fprintf(out,
"\n};\nQT_MOC_EXPORT_PLUGIN(%s, %s)\n"
1615 "#endif // QT_MOC_EXPORT_PLUGIN_V2\n",
1616 cdef->qualified.constData(), cdef->classname.constData());
1621QT_WARNING_DISABLE_GCC(
"-Wunused-function")
1622QT_WARNING_DISABLE_CLANG(
"-Wunused-function")
1623QT_WARNING_DISABLE_CLANG(
"-Wundefined-internal")
1624QT_WARNING_DISABLE_MSVC(4334)
1626#define CBOR_ENCODER_WRITER_CONTROL 1
1627#define CBOR_ENCODER_WRITE_FUNCTION CborDevice::callback
1631#include "cborencoder.c"
void nextItem(const char *comment=nullptr)
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)
\inmodule QtCore\reentrant
bool requireCompleteMethodTypes
bool returnTypeIsVolatile