13#include <qcoreapplication.h>
14#include <QtCore/qspan.h>
20#include "private/qthread_p.h"
22#include "private/qlatch_p.h"
26#include "private/qmetaobject_moc_p.h"
35using namespace Qt::StringLiterals;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
115
116
117
118
119
120
121
122
129 Q_ASSERT(priv(mo->d.data)->revision >= 7);
130 uint offset = mo->d.stringdata[2*index];
131 return reinterpret_cast<
const char *>(mo->d.stringdata) + offset;
136 Q_ASSERT(priv(mo->d.data)->revision >= 7);
137 uint offset = mo->d.stringdata[2*index];
138 uint length = mo->d.stringdata[2*index + 1];
139 const char *string =
reinterpret_cast<
const char *>(mo->d.stringdata) + offset;
140 return {string, qsizetype(length)};
145 if (QMetaObjectPrivate::get(mo)->flags & AllocatedMetaObject) {
147 return view.toByteArray();
152 return QByteArray::fromRawData(view.data(), view.size());
157 return stringData(mo, stringDataView(mo, index));
162 if (typeInfo & IsUnresolvedType)
163 return stringDataView(mo, typeInfo & TypeNameIndexMask);
165 return QByteArrayView(QMetaType(typeInfo).name());
170 if (!(typeInfo & IsUnresolvedType))
172 return qMetaTypeTypeInternal(stringDataView(mo, typeInfo & TypeNameIndexMask));
178 std::optional<QByteArrayView> scope;
181 if (qualifiedKey.startsWith(
"QFlags<") && qualifiedKey.endsWith(
'>'))
182 qualifiedKey.slice(7, qualifiedKey.length() - 8);
183 const auto scopePos = qualifiedKey.lastIndexOf(
"::"_L1);
185 return R{
std::nullopt, qualifiedKey};
187 return R{qualifiedKey.first(scopePos), qualifiedKey.sliced(scopePos + 2)};
194 static const QMetaMethodPrivate *get(
const QMetaMethod *q)
195 {
return static_cast<
const QMetaMethodPrivate *>(q); }
198 inline QByteArrayView qualifiedName()
const noexcept;
199 inline QByteArrayView name()
const noexcept;
200 inline int typesDataIndex()
const;
201 inline const char *rawReturnTypeName()
const;
202 inline int returnType()
const;
203 inline int parameterCount()
const;
204 inline int parametersDataIndex()
const;
205 inline uint parameterTypeInfo(
int index)
const;
206 inline int parameterType(
int index)
const;
207 inline void getParameterTypes(
int *types)
const;
210 inline QByteArrayView parameterTypeName(
int index)
const noexcept;
211 inline QList<QByteArray> parameterTypes()
const;
212 inline QList<QByteArray> parameterNames()
const;
213 inline const char *tag()
const;
214 inline int ownMethodIndex()
const;
215 inline int ownConstructorMethodIndex()
const;
219 QMetaMethodPrivate();
225#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
227
228
229
230
231
232
233
234
235
236
237
238
239
240QObject *QMetaObject::newInstance(QGenericArgument val0,
241 QGenericArgument val1,
242 QGenericArgument val2,
243 QGenericArgument val3,
244 QGenericArgument val4,
245 QGenericArgument val5,
246 QGenericArgument val6,
247 QGenericArgument val7,
248 QGenericArgument val8,
249 QGenericArgument val9)
const
251 const char *typeNames[] = {
253 val0.name(), val1.name(), val2.name(), val3.name(), val4.name(),
254 val5.name(), val6.name(), val7.name(), val8.name(), val9.name()
256 const void *parameters[] = {
258 val0.data(), val1.data(), val2.data(), val3.data(), val4.data(),
259 val5.data(), val6.data(), val7.data(), val8.data(), val9.data()
263 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
264 int len =
int(qstrlen(typeNames[paramCount]));
269 return newInstanceImpl(
this, paramCount, parameters, typeNames,
nullptr);
274
275
276
277
278
279
280
281
282
283
284
285
286
288QObject *QMetaObject::newInstanceImpl(
const QMetaObject *mobj, qsizetype paramCount,
289 const void **parameters,
const char **typeNames,
290 const QtPrivate::QMetaTypeInterface **metaTypes)
292 if (!mobj->inherits(&QObject::staticMetaObject)) {
293 qWarning(
"QMetaObject::newInstance: type %s does not inherit QObject", mobj->className());
299QT_WARNING_DISABLE_GCC(
"-Wdangling-pointer")
303 QObject *returnValue =
nullptr;
304 QMetaType returnValueMetaType = QMetaType::fromType<
decltype(returnValue)>();
305 parameters[0] = &returnValue;
306 typeNames[0] = returnValueMetaType.name();
308 metaTypes[0] = returnValueMetaType.iface();
313 auto priv = QMetaObjectPrivate::get(mobj);
314 for (
int i = 0; i < priv->constructorCount; ++i) {
315 QMetaMethod m = QMetaMethod::fromRelativeConstructorIndex(mobj, i);
316 if (m.parameterCount() != (paramCount - 1))
320 QMetaMethodPrivate::InvokeFailReason r =
321 QMetaMethodPrivate::invokeImpl(m,
nullptr, Qt::DirectConnection, paramCount,
322 parameters, typeNames, metaTypes);
323 if (r == QMetaMethodPrivate::InvokeFailReason::None)
333
334
335int QMetaObject::static_metacall(Call cl,
int idx,
void **argv)
const
337 Q_ASSERT(priv(d.data)->revision >= 6);
338 if (!d.static_metacall)
340 d.static_metacall(
nullptr, cl, idx, argv);
345
346
347int QMetaObject::metacall(QObject *object, Call cl,
int idx,
void **argv)
349 if (object->d_ptr->metaObject)
350 return object->d_ptr->metaObject->metaCall(object, cl, idx, argv);
352 return object->qt_metacall(cl, idx, argv);
357 return stringDataView(m, priv(m->d.data)->className);
361
362
363
364
365const char *QMetaObject::className()
const
367 return objectClassName(
this).constData();
371
372
373
374
375
376
377
380
381
382
383
384
385
386
387bool QMetaObject::inherits(
const QMetaObject *metaObject)
const noexcept
389 const QMetaObject *m =
this;
393 }
while ((m = m->d.superdata));
398
399
400
401
402
403
406
407
408
409
410
411const QObject *QMetaObject::cast(
const QObject *obj)
const
413 return (obj && obj->metaObject()->inherits(
this)) ? obj :
nullptr;
416#ifndef QT_NO_TRANSLATION
418
419
420QString QMetaObject::tr(
const char *s,
const char *c,
int n)
const
422 return QCoreApplication::translate(className(), s, c, n);
427
428
429
430
431QMetaType QMetaObject::metaType()
const
434 const QMetaObjectPrivate *d = priv(
this->d.data);
435 if (d->revision < 10) {
437 return QMetaType::fromName(className());
440
441
442
443
444
445
446
447
448
449
450
451
452#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
456 const qsizetype offset = d->revision < 12
458 : d->propertyCount + d->enumeratorCount;
460 const qsizetype offset = d->propertyCount + d->enumeratorCount;
463 auto iface =
this->d.metaTypes[offset];
464 if (iface && QtMetaTypePrivate::isInterfaceFor<
void>(iface))
467 return QMetaType(iface);
469 return QMetaType::fromName(className());
474
475
476
477
478
479
480
481
482
483int QMetaObject::methodOffset()
const
486 const QMetaObject *m = d.superdata;
488 offset += priv(m->d.data)->methodCount;
496
497
498
499
500
501
502
503
504
505int QMetaObject::enumeratorOffset()
const
508 const QMetaObject *m = d.superdata;
510 offset += priv(m->d.data)->enumeratorCount;
517
518
519
520
521
522
523
524
525
526int QMetaObject::propertyOffset()
const
529 const QMetaObject *m = d.superdata;
531 offset += priv(m->d.data)->propertyCount;
538
539
540
541
542
543
544
545
546
547int QMetaObject::classInfoOffset()
const
550 const QMetaObject *m = d.superdata;
552 offset += priv(m->d.data)->classInfoCount;
559
560
561
562
563
564
565int QMetaObject::constructorCount()
const
567 Q_ASSERT(priv(d.data)->revision >= 2);
568 return priv(d.data)->constructorCount;
572
573
574
575
576
577
578
579
580
581
582
583int QMetaObject::methodCount()
const
585 int n = priv(d.data)->methodCount;
586 const QMetaObject *m = d.superdata;
588 n += priv(m->d.data)->methodCount;
595
596
597
598
599int QMetaObject::enumeratorCount()
const
601 int n = priv(d.data)->enumeratorCount;
602 const QMetaObject *m = d.superdata;
604 n += priv(m->d.data)->enumeratorCount;
611
612
613
614
615
616
617
618
619
620
621int QMetaObject::propertyCount()
const
623 int n = priv(d.data)->propertyCount;
624 const QMetaObject *m = d.superdata;
626 n += priv(m->d.data)->propertyCount;
633
634
635
636
637int QMetaObject::classInfoCount()
const
639 int n = priv(d.data)->classInfoCount;
640 const QMetaObject *m = d.superdata;
642 n += priv(m->d.data)->classInfoCount;
653 QSpan<
const QArgumentType> types)
655 const qsizetype argc = types.size();
656 const QMetaMethod::Data &data = method.data;
657 auto priv = QMetaMethodPrivate::get(&method);
658 if (priv->parameterCount() != argc)
663 if (
const auto qname = priv->qualifiedName(); !qname.endsWith(name))
665 else if (
const auto n = qname.chopped(name.size()); !n.isEmpty() && !n.endsWith(
':'))
669 int paramsIndex = data.parameters() + 1;
670 for (qsizetype i = 0; i < argc; ++i) {
671 uint typeInfo = m->d.data[paramsIndex + i];
674 if (mt == QMetaType(ifaces[i]))
676 if ((typeInfo & IsUnresolvedType) == 0 && mt.rawId() !=
int(typeInfo))
678 if (mt.id() != typeFromTypeInfo(m, typeInfo))
681 if (types[i].name() == QMetaType(ifaces[i]).name())
683 if (types[i].name() != typeNameFromTypeInfo(m, typeInfo))
692
693
694
697 for (
const QMetaObject *currentObject = baseObject; currentObject; currentObject = currentObject->superClass()) {
698 const int start = priv(currentObject->d.data)->methodCount - 1;
700 for (
int i = start; i >= end; --i) {
701 auto candidate = QMetaMethod::fromRelativeMethodIndex(currentObject, i);
702 if (name == candidate.name())
706 return QMetaMethod{};
710
711
712
713
714
715
716
719 QSpan<
const QArgumentType> types,
720 QMetaMethod::MethodType what)
722 for (
const QMetaObject *m = *baseObject; m; m = m->d.superdata) {
723 Q_ASSERT(priv(m->d.data)->revision >= 7);
727 case QMetaMethod::Signal:
728 i = priv(m->d.data)->signalCount - 1;
730 case QMetaMethod::Slot:
731 i = priv(m->d.data)->methodCount - 1;
732 end = priv(m->d.data)->signalCount;
734 case QMetaMethod::Method:
735 i = priv(m->d.data)->methodCount - 1;
737 case QMetaMethod::Constructor:
738 Q_UNREACHABLE_RETURN(-1);
742 for (; i >= end; --i) {
743 auto data = QMetaMethod::fromRelativeMethodIndex(m, i);
744 if (methodMatch(m, data, name, types)) {
745 if (QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
746 && what == QMetaMethod::Slot && data.methodType() != QMetaMethod::Slot) {
759
760
761
762
763
764
765
766
767
768
770#if QT_DEPRECATED_SINCE(6
, 10
)
772static int compat_indexOf(
const char *what,
const char *sig,
const QMetaObject *mo,
773 int (*indexOf)(
const QMetaObject *,
const char *))
775 const QByteArray normalized = QByteArray(sig).replace(
"QVector<",
"QList<");
776 const int i = indexOf(mo, normalized.data());
778 qWarning(R"(QMetaObject::indexOf%s: argument "%s" is not normalized, because it contains "QVector<". )"
779 R"(Earlier versions of Qt 6 incorrectly normalized QVector< to QList<, silently. )"
780 R"(This behavior is deprecated as of 6.10, and will be removed in a future version of Qt.)",
786#define INDEXOF_COMPAT(what, arg)
788 if (i < 0
&& Q_UNLIKELY(std::strstr(arg, "QVector<")))
789 i = compat_indexOf(#what, arg, this, &indexOf ## what ## _helper);
792#define INDEXOF_COMPAT(what, arg)
798 QByteArrayView name = QMetaObjectPrivate::decodeMethodSignature(constructor, types);
799 return QMetaObjectPrivate::indexOfConstructor(mo, name, types);
802int QMetaObject::indexOfConstructor(
const char *constructor)
const
804 Q_ASSERT(priv(d.data)->revision >= 7);
805 int i = indexOfConstructor_helper(
this, constructor);
811
812
813
814
815
816
817
818
819
823 Q_ASSERT(priv(m->d.data)->revision >= 7);
825 QByteArrayView name = QMetaObjectPrivate::decodeMethodSignature(method, types);
826 return QMetaObjectPrivate::indexOfMethod(m, name, types);
829int QMetaObject::indexOfMethod(
const char *method)
const
831 int i = indexOfMethod_helper(
this, method);
837
838
839
840
841
842
846 Q_ASSERT(types.isEmpty());
847 QVarLengthArray<QByteArrayView, 10> typeNames;
848 QByteArrayView name = parameterTypeNamesFromSignature(signature, typeNames);
849 for (
auto type : typeNames)
850 types.emplace_back(type);
855
856
857
858
859
860
861
862
863
864
865
866
870 Q_ASSERT(priv(m->d.data)->revision >= 7);
872 QByteArrayView name = QMetaObjectPrivate::decodeMethodSignature(signal, types);
873 return QMetaObjectPrivate::indexOfSignal(m, name, types);
876int QMetaObject::indexOfSignal(
const char *signal)
const
878 int i = indexOfSignal_helper(
this, signal);
884
885
886
887
888
891 QSpan<
const QArgumentType> types)
893 int i = indexOfMethodRelative(baseObject, name, types, QMetaMethod::Signal);
895 const QMetaObject *m = *baseObject;
896 if (i >= 0 && m && m->d.superdata) {
897 int conflict = indexOfMethod(m->d.superdata, name, types);
899 QMetaMethod conflictMethod = m->d.superdata->method(conflict);
900 qWarning(
"QMetaObject::indexOfSignal: signal %s from %s redefined in %s",
901 conflictMethod.methodSignature().constData(),
902 m->d.superdata->className(), m->className());
910
911
912
913
914
915
916
917
918
922 Q_ASSERT(priv(m->d.data)->revision >= 7);
924 QByteArrayView name = QMetaObjectPrivate::decodeMethodSignature(slot, types);
925 return QMetaObjectPrivate::indexOfSlot(m, name, types);
928int QMetaObject::indexOfSlot(
const char *slot)
const
930 int i = indexOfSlot_helper(
this, slot);
940 QSpan<
const QArgumentType> types)
942 return indexOfMethodRelative(m, name, types, QMetaMethod::Slot);
946 QSpan<
const QArgumentType> types)
948 int i = indexOfSignalRelative(&m, name, types);
950 i += m->methodOffset();
955 QSpan<
const QArgumentType> types)
957 int i = indexOfSlotRelative(&m, name, types);
959 i += m->methodOffset();
964 QSpan<
const QArgumentType> types)
966 int i = indexOfMethodRelative(&m, name, types, QMetaMethod::Method);
968 i += m->methodOffset();
973 QSpan<
const QArgumentType> types)
975 for (
int i = priv(m->d.data)->constructorCount-1; i >= 0; --i) {
976 const QMetaMethod method = QMetaMethod::fromRelativeConstructorIndex(m, i);
977 if (methodMatch(m, method, name, types))
984
985
986
987
988
989
990
991
992
993
996
997
998
999
1000
1001
1002
1003
1004
1007 Q_ASSERT(m !=
nullptr);
1008 int n = priv(m->d.data)->signalCount;
1009 for (m = m->d.superdata; m; m = m->d.superdata)
1010 n += priv(m->d.data)->signalCount;
1015
1016
1017
1018
1019
1020
1021
1022
1027 return QMetaMethodPrivate::get(&m)->ownMethodIndex() + signalOffset(m.mobj);
1031
1032
1033
1034
1035
1036
1037
1038
1041 if (signal_index < 0)
1042 return QMetaMethod();
1044 Q_ASSERT(m !=
nullptr);
1045 int i = signal_index;
1046 i -= signalOffset(m);
1047 if (i < 0 && m->d.superdata)
1048 return signal(m->d.superdata, signal_index);
1051 if (i >= 0 && i < priv(m->d.data)->signalCount)
1052 return QMetaMethod::fromRelativeMethodIndex(m, i);
1053 return QMetaMethod();
1057
1058
1059
1060
1061
1063 QSpan<
const QArgumentType> methodTypes)
1065 const qsizetype methodArgc = methodTypes.size();
1066 if (signalTypes.size() >= methodArgc) {
1067 signalTypes = signalTypes.first(methodArgc);
1068 return std::equal(signalTypes.begin(), signalTypes.end(),
1069 methodTypes.begin(), methodTypes.end());
1075
1076
1077
1078
1079
1081 const QMetaMethodPrivate *method)
1083 if (signal->methodType() != QMetaMethod::Signal)
1085 if (signal->parameterCount() < method->parameterCount())
1087 const QMetaObject *smeta = signal->enclosingMetaObject();
1088 const QMetaObject *rmeta = method->enclosingMetaObject();
1089 for (
int i = 0; i < method->parameterCount(); ++i) {
1090 uint sourceTypeInfo = signal->parameterTypeInfo(i);
1091 uint targetTypeInfo = method->parameterTypeInfo(i);
1092 if ((sourceTypeInfo & IsUnresolvedType)
1093 || (targetTypeInfo & IsUnresolvedType)) {
1094 QByteArrayView sourceName = typeNameFromTypeInfo(smeta, sourceTypeInfo);
1095 QByteArrayView targetName = typeNameFromTypeInfo(rmeta, targetTypeInfo);
1096 if (sourceName != targetName)
1101 if (sourceType != targetType)
1113 if (self->d.relatedMetaObjects) {
1114 Q_ASSERT(priv(self->d.data)->revision >= 2);
1115 const auto *e = self->d.relatedMetaObjects;
1118 if (
const QMetaObject *m =QMetaObject_findMetaObject((*e), name))
1124 self = self->d.superdata;
1130
1131
1132
1133
1134
1135int QMetaObject::indexOfEnumerator(
const char *name)
const
1137 return QMetaObjectPrivate::indexOfEnumerator(
this, name);
1143 for (
auto which : { W::Name, W::Alias }) {
1144 if (
int index = indexOfEnumerator(m, name, which); index != -1)
1155 const QMetaEnum e(m, i);
1156 const quint32 id = which ==
Which::Name ? e.data.name() : e.data.alias();
1157 QByteArrayView prop = stringDataView(m, id);
1159 i += m->enumeratorOffset();
1169
1170
1171
1172
1173
1174int QMetaObject::indexOfProperty(
const char *name)
const
1176 const QMetaObject *m =
this;
1178 const QMetaObjectPrivate *d = priv(m->d.data);
1179 for (
int i = 0; i < d->propertyCount; ++i) {
1180 const QMetaProperty::Data data = QMetaProperty::getMetaPropertyData(m, i);
1181 const char *prop = rawStringData(m, data.name());
1182 if (strcmp(name, prop) == 0) {
1183 i += m->propertyOffset();
1190 if (priv(
this->d.data)->flags & DynamicMetaObject) {
1191 QAbstractDynamicMetaObject *me =
1192 const_cast<QAbstractDynamicMetaObject *>(
static_cast<
const QAbstractDynamicMetaObject *>(
this));
1194 return me->createProperty(name,
nullptr);
1201
1202
1203
1204
1205
1206int QMetaObject::indexOfClassInfo(
const char *name)
const
1209 const QMetaObject *m =
this;
1210 while (m && i < 0) {
1211 for (i = priv(m->d.data)->classInfoCount-1; i >= 0; --i)
1212 if (strcmp(name, rawStringData(m, m->d.data[priv(m->d.data)->classInfoData + 2*i])) == 0) {
1213 i += m->classInfoOffset();
1222
1223
1224
1225
1226
1227
1228QMetaMethod QMetaObject::constructor(
int index)
const
1231 if (i >= 0 && i < priv(d.data)->constructorCount)
1232 return QMetaMethod::fromRelativeConstructorIndex(
this, i);
1233 return QMetaMethod();
1237
1238
1239
1240
1241QMetaMethod QMetaObject::method(
int index)
const
1244 i -= methodOffset();
1245 if (i < 0 && d.superdata)
1246 return d.superdata->method(index);
1248 if (i >= 0 && i < priv(d.data)->methodCount)
1249 return QMetaMethod::fromRelativeMethodIndex(
this, i);
1250 return QMetaMethod();
1254
1255
1256
1257
1258QMetaEnum QMetaObject::enumerator(
int index)
const
1261 i -= enumeratorOffset();
1262 if (i < 0 && d.superdata)
1263 return d.superdata->enumerator(index);
1265 if (i >= 0 && i < priv(d.data)->enumeratorCount)
1266 return QMetaEnum(
this, i);
1271
1272
1273
1274
1275
1276QMetaProperty QMetaObject::property(
int index)
const
1279 i -= propertyOffset();
1280 if (i < 0 && d.superdata)
1281 return d.superdata->property(index);
1283 if (i >= 0 && i < priv(d.data)->propertyCount)
1284 return QMetaProperty(
this, i);
1285 return QMetaProperty();
1289
1290
1291
1292
1293
1294
1295QMetaProperty QMetaObject::userProperty()
const
1297 const int propCount = propertyCount();
1298 for (
int i = propCount - 1; i >= 0; --i) {
1299 const QMetaProperty prop = property(i);
1303 return QMetaProperty();
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316QMetaClassInfo QMetaObject::classInfo(
int index)
const
1319 i -= classInfoOffset();
1320 if (i < 0 && d.superdata)
1321 return d.superdata->classInfo(index);
1323 QMetaClassInfo result;
1324 if (i >= 0 && i < priv(d.data)->classInfoCount) {
1326 result.data = { d.data + priv(d.data)->classInfoData + i * QMetaClassInfo::Data::Size };
1332
1333
1334
1335
1336
1337
1338
1339bool QMetaObject::checkConnectArgs(
const char *signal,
const char *method)
1341 const char *s1 = signal;
1342 const char *s2 = method;
1343 while (*s1++ !=
'(') { }
1344 while (*s2++ !=
'(') { }
1345 if (*s2 ==
')' || qstrcmp(s1,s2) == 0)
1347 const auto s1len = qstrlen(s1);
1348 const auto s2len = qstrlen(s2);
1349 if (s2len < s1len && strncmp(s1,s2,s2len-1)==0 && s1[s2len-1]==
',')
1355
1356
1357
1358
1359
1360
1361bool QMetaObject::checkConnectArgs(
const QMetaMethod &signal,
1362 const QMetaMethod &method)
1364 return QMetaObjectPrivate::checkConnectArgs(
1365 QMetaMethodPrivate::get(&signal),
1366 QMetaMethodPrivate::get(&method));
1371 return std::find_if_not(in.begin(), in.end(), is_space);
1376 auto rit = std::find_if_not(in.rbegin(), in.rend(), is_space);
1377 in = in.first(rit.base() - in.begin());
1383 const char *d = in.begin();
1385 const char *end = in.end();
1389 while (d != end && (templdepth
1390 || (*d !=
',' && *d !=
')'))) {
1399 auto type = QByteArrayView{t, d - t};
1400 type = trimSpacesFromRight(type);
1401 if (type ==
"void") {
1402 const char *next = trimSpacesFromLeft(QByteArrayView{d, end});
1403 if (next != end && *next ==
')')
1407 normalizeTypeInternal(QByteArrayView{t, d}, result);
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427QByteArray QMetaObject::normalizedType(
const char *type)
1429 return normalizeTypeInternal(type, type + qstrlen(type));
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1447 method = trimSpacesFromRight(method);
1448 if (method.isEmpty())
1451 const char *d = method.begin();
1452 const char *end = method.end();
1453 d = trimSpacesFromLeft({d, end});
1456 result.reserve(method.size());
1462 Q_ASSERT(!result.isEmpty());
1464 d = trimSpacesFromLeft({d, end});
1475 if (argdepth == 1) {
1476 d = qNormalizeType(QByteArrayView{d, end}, templdepth, result);
1490QByteArray QMetaObject::normalizedSignature(
const char *method)
1492 return QMetaObjectPrivate::normalizedSignature(method);
1497 const char *
const *names,
1502 for (
int i = 0; i < meta->methodCount(); ++i) {
1503 const QMetaMethod method = meta->method(i);
1504 if (method.name() == name)
1505 candidateMessage +=
" " + method.methodSignature() +
'\n';
1507 if (!candidateMessage.isEmpty()) {
1508 candidateMessage.prepend(
"\nCandidates are:\n");
1509 candidateMessage.chop(1);
1512 QVarLengthArray<
char, 512> sig;
1513 for (qsizetype i = 1; i < paramCount; ++i) {
1515 sig.append(names[i], qstrlen(names[i]));
1517 sig.append(metaTypes[i]->name, qstrlen(metaTypes[i]->name));
1520 if (paramCount != 1)
1521 sig.resize(sig.size() - 1);
1523 qWarning(
"QMetaObject::invokeMethod: No such method %s::%.*s(%.*s)%.*s",
1524 meta->className(),
int(name.size()), name.constData(),
1525 int(sig.size()), sig.constData(),
1526 int(candidateMessage.size()), candidateMessage.constData());
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645bool QMetaObject::invokeMethod(QObject *obj,
1647 Qt::ConnectionType type,
1648 QGenericReturnArgument ret,
1649 QGenericArgument val0,
1650 QGenericArgument val1,
1651 QGenericArgument val2,
1652 QGenericArgument val3,
1653 QGenericArgument val4,
1654 QGenericArgument val5,
1655 QGenericArgument val6,
1656 QGenericArgument val7,
1657 QGenericArgument val8,
1658 QGenericArgument val9)
1663 const char *typeNames[] = {ret.name(), val0.name(), val1.name(), val2.name(), val3.name(),
1664 val4.name(), val5.name(), val6.name(), val7.name(), val8.name(),
1666 const void *parameters[] = {ret.data(), val0.data(), val1.data(), val2.data(), val3.data(),
1667 val4.data(), val5.data(), val6.data(), val7.data(), val8.data(),
1670 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
1671 if (qstrlen(typeNames[paramCount]) <= 0)
1674 return invokeMethodImpl(obj, member, type, paramCount, parameters, typeNames,
nullptr);
1677bool QMetaObject::invokeMethodImpl(QObject *obj,
const char *member, Qt::ConnectionType type,
1678 qsizetype paramCount,
const void *
const *parameters,
1679 const char *
const *typeNames,
1680 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
1685 Q_ASSERT(paramCount >= 1);
1686 Q_ASSERT(parameters);
1687 Q_ASSERT(typeNames);
1690 QByteArrayView name(member);
1694 const QMetaObject *meta = obj->metaObject();
1695 for ( ; meta; meta = meta->superClass()) {
1696 auto priv = QMetaObjectPrivate::get(meta);
1697 for (
int i = 0; i < priv->methodCount; ++i) {
1698 QMetaMethod m = QMetaMethod::fromRelativeMethodIndex(meta, i);
1699 if (m.parameterCount() != (paramCount - 1))
1701 if (name != stringDataView(meta, m.data.name()))
1705 QMetaMethodPrivate::InvokeFailReason r =
1706 QMetaMethodPrivate::invokeImpl(m, obj, type, paramCount, parameters,
1707 typeNames, metaTypes);
1709 return r == QMetaMethodPrivate::InvokeFailReason::None;
1714 return printMethodNotFoundWarning(obj->metaObject(), name, paramCount, typeNames, metaTypes);
1717bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
1718 qsizetype parameterCount,
const void *
const *params,
const char *
const *names,
1719 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
1724 auto slot = QtPrivate::SlotObjUniquePtr(slotObj);
1729 Qt::HANDLE currentThreadId = QThread::currentThreadId();
1730 QThread *objectThread = object->thread();
1731 bool receiverInSameThread =
false;
1733 receiverInSameThread = currentThreadId == QThreadData::get2(objectThread)->threadId.loadRelaxed();
1735 if (type == Qt::AutoConnection)
1736 type = receiverInSameThread ? Qt::DirectConnection : Qt::QueuedConnection;
1738 void **argv =
const_cast<
void **>(params);
1739 if (type == Qt::DirectConnection) {
1740 slot->call(object, argv);
1741 }
else if (type == Qt::QueuedConnection) {
1743 qWarning(
"QMetaObject::invokeMethod: Unable to invoke methods with return values in "
1744 "queued connections");
1747 QCoreApplication::postEvent(object,
new QQueuedMetaCallEvent(std::move(slot),
nullptr, -1,
1748 parameterCount, metaTypes, params));
1749 }
else if (type == Qt::BlockingQueuedConnection) {
1750#if QT_CONFIG(thread)
1751 if (receiverInSameThread)
1752 qWarning(
"QMetaObject::invokeMethod: Dead lock detected");
1755 QCoreApplication::postEvent(object,
new QMetaCallEvent(std::move(slot),
nullptr, -1, argv, &latch));
1759 qWarning(
"QMetaObject::invokeMethod: Unknown connection type");
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1867
1868
1869
1870
1872
1873
1874
1875
1876
1879
1880
1881
1882
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1903
1904
1905
1906
1907
1908
1909
1910
1913
1914
1915
1916
1917
1918
1921
1922
1923
1924
1925
1926
1929
1930
1931
1932
1933
1934
1937
1938
1939
1942
1943
1944
1945
1946
1947
1948
1951
1952
1953
1956
1957
1958QMetaMethod QMetaMethod::fromRelativeMethodIndex(
const QMetaObject *mobj,
int index)
1960 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->methodCount);
1963 m.data = { mobj->d.data + priv(mobj->d.data)->methodData + index * Data::Size };
1967QMetaMethod QMetaMethod::fromRelativeConstructorIndex(
const QMetaObject *mobj,
int index)
1969 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->constructorCount);
1972 m.data = { mobj->d.data + priv(mobj->d.data)->constructorData + index * Data::Size };
1977
1978
1979
1980
1981
1982
1986 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1988 result.reserve(256);
1991 QList<QByteArray> argTypes = parameterTypes();
1992 for (
int i = 0; i < argTypes.size(); ++i) {
1995 result += argTypes.at(i);
2001QByteArrayView QMetaMethodPrivate::name()
const noexcept
2003 QByteArrayView name = qualifiedName();
2004 if (qsizetype colon = name.lastIndexOf(
':'); colon > 0)
2005 return name.sliced(colon + 1);
2009QByteArrayView QMetaMethodPrivate::qualifiedName()
const noexcept
2011 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2012 return stringDataView(mobj, data.name());
2015int QMetaMethodPrivate::typesDataIndex()
const
2017 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2018 return data.parameters();
2021const char *QMetaMethodPrivate::rawReturnTypeName()
const
2023 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2024 uint typeInfo = mobj->d.data[typesDataIndex()];
2025 if (typeInfo & IsUnresolvedType)
2026 return rawStringData(mobj, typeInfo & TypeNameIndexMask);
2028 return QMetaType(typeInfo).name();
2031int QMetaMethodPrivate::returnType()
const
2033 return parameterType(-1);
2036int QMetaMethodPrivate::parameterCount()
const
2038 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2046 uint typeInfo = parameterTypeInfo(index);
2049 if ((typeInfo & IsUnresolvedType) == 0)
2050 Q_ASSERT(mt.rawId() ==
int(typeInfo & TypeNameIndexMask));
2051 Q_ASSERT(mt.name());
2057#define ASSERT_NOT_PRIMITIVE_TYPE(TYPE, METATYPEID, NAME)
2058 Q_ASSERT(typeInfo != QMetaType::TYPE);
2060#undef ASSERT_NOT_PRIMITIVE_TYPE
2061 Q_ASSERT(typeInfo != QMetaType::QObjectStar);
2064 if (priv(mobj->d.data)->revision >= 11) {
2065 Q_ASSERT(typeInfo != QMetaType::Void);
2066 Q_ASSERT(typeInfo != QMetaType::VoidStar);
2071int QMetaMethodPrivate::parametersDataIndex()
const
2073 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2074 return typesDataIndex() + 1;
2077uint QMetaMethodPrivate::parameterTypeInfo(
int index)
const
2079 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2080 return mobj->d.data[parametersDataIndex() + index];
2085 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2086 if (methodType() == QMetaMethod::Constructor)
2090 checkMethodMetaTypeConsistency(iface, -1);
2096 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2097 int offset = (methodType() == QMetaMethod::Constructor ? 0 : 1);
2098 const auto ifaces = &mobj->d.metaTypes[data.metaTypeOffset() + offset];
2100 for (
int i = 0; i < parameterCount(); ++i)
2101 checkMethodMetaTypeConsistency(ifaces[i], i);
2106int QMetaMethodPrivate::parameterType(
int index)
const
2108 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2109 return typeFromTypeInfo(mobj, parameterTypeInfo(index));
2112void QMetaMethodPrivate::getParameterTypes(
int *types)
const
2114 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2115 int dataIndex = parametersDataIndex();
2116 int argc = parameterCount();
2117 for (
int i = 0; i < argc; ++i) {
2118 int id = typeFromTypeInfo(mobj, mobj->d.data[dataIndex++]);
2123QByteArrayView QMetaMethodPrivate::parameterTypeName(
int index)
const noexcept
2125 int paramsIndex = parametersDataIndex();
2126 return typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + index]);
2129QList<QByteArray> QMetaMethodPrivate::parameterTypes()
const
2131 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2132 int argc = parameterCount();
2133 QList<QByteArray> list;
2135 int paramsIndex = parametersDataIndex();
2136 for (
int i = 0; i < argc; ++i) {
2137 QByteArrayView name = typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + i]);
2138 list.emplace_back(name.toByteArray());
2143QList<QByteArray> QMetaMethodPrivate::parameterNames()
const
2145 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2146 int argc = parameterCount();
2147 QList<QByteArray> list;
2149 int namesIndex = parametersDataIndex() + argc;
2150 for (
int i = 0; i < argc; ++i)
2151 list += stringData(mobj, mobj->d.data[namesIndex + i]);
2155const char *QMetaMethodPrivate::tag()
const
2157 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2158 return rawStringData(mobj, data.tag());
2161int QMetaMethodPrivate::ownMethodIndex()
const
2164 return ( data.d - mobj->d.data - priv(mobj->d.data)->methodData)/Data::Size;
2167int QMetaMethodPrivate::ownConstructorMethodIndex()
const
2170 Q_ASSERT(methodType() == Constructor);
2171 return ( data.d - mobj->d.data - priv(mobj->d.data)->constructorData)/Data::Size;
2175
2176
2177
2178
2179
2180
2181
2182QByteArray QMetaMethod::methodSignature()
const
2185 return QByteArray();
2186 return QMetaMethodPrivate::get(
this)->signature();
2190
2191
2192
2193
2194
2195
2196QByteArray QMetaMethod::name()
const
2199 return QByteArray();
2201 return stringData(mobj, QMetaMethodPrivate::get(
this)->name());
2205
2206
2207
2208
2209
2210
2211
2212
2213QByteArrayView QMetaMethod::nameView()
const
2215 return QMetaMethodPrivate::get(
this)->name();
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228int QMetaMethod::returnType()
const
2230 return returnMetaType().rawId();
2234
2235
2236
2237
2238
2239QMetaType QMetaMethod::returnMetaType()
const
2241 if (!mobj || methodType() == QMetaMethod::Constructor)
2243 auto mt = QMetaType(mobj->d.metaTypes[data.metaTypeOffset()]);
2245 mt = QMetaType(QMetaMethodPrivate::get(
this)->returnType());
2251
2252
2253
2254
2255
2256
2257int QMetaMethod::parameterCount()
const
2261 return QMetaMethodPrivate::get(
this)->parameterCount();
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274int QMetaMethod::parameterType(
int index)
const
2276 return parameterMetaType(index).rawId();
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289QMetaType QMetaMethod::parameterMetaType(
int index)
const
2291 if (!mobj || index < 0)
2293 auto priv = QMetaMethodPrivate::get(
this);
2294 if (index >= priv->parameterCount())
2297 auto parameterOffset = index + (methodType() == QMetaMethod::Constructor ? 0 : 1);
2298 auto mt = QMetaType(mobj->d.metaTypes[data.metaTypeOffset() + parameterOffset]);
2300 mt = QMetaType(QMetaMethodPrivate::get(
this)->parameterType(index));
2306
2307
2308
2309
2310
2311
2312
2313
2314void QMetaMethod::getParameterTypes(
int *types)
const
2318 QMetaMethodPrivate::get(
this)->getParameterTypes(types);
2322
2323
2324
2325
2326QList<QByteArray> QMetaMethod::parameterTypes()
const
2329 return QList<QByteArray>();
2330 return QMetaMethodPrivate::get(
this)->parameterTypes();
2334
2335
2336
2337
2338
2339
2340QByteArray QMetaMethod::parameterTypeName(
int index)
const
2342 if (!mobj || index < 0 || index >= parameterCount())
2345 return stringData(mobj, QMetaMethodPrivate::get(
this)->parameterTypeName(index));
2349
2350
2351
2352
2353QList<QByteArray> QMetaMethod::parameterNames()
const
2356 return QList<QByteArray>();
2357 return QMetaMethodPrivate::get(
this)->parameterNames();
2362
2363
2364
2365
2366
2367
2368
2369
2370const char *QMetaMethod::typeName()
const
2374#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
2375 if (methodType() == QMetaMethod::Constructor)
2378 return QMetaMethodPrivate::get(
this)->rawReturnTypeName();
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405const char *QMetaMethod::tag()
const
2409 return QMetaMethodPrivate::get(
this)->tag();
2414
2415
2416int QMetaMethod::attributes()
const
2420 return data.flags() >> 4;
2424
2425
2426
2427
2428int QMetaMethod::methodIndex()
const
2432 return QMetaMethodPrivate::get(
this)->ownMethodIndex() + mobj->methodOffset();
2436
2437
2438
2439
2440int QMetaMethod::relativeMethodIndex()
const
2444 return QMetaMethodPrivate::get(
this)->ownMethodIndex();
2449
2450
2451
2452
2453
2454int QMetaMethod::revision()
const
2458 if ((data.flags() & MethodRevisioned) == 0)
2460#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
2461 if (priv(mobj->d.data)->revision < 13) {
2463 int offset = priv(mobj->d.data)->methodData
2464 + priv(mobj->d.data)->methodCount * Data::Size
2465 + QMetaMethodPrivate::get(
this)->ownMethodIndex();
2466 return mobj->d.data[offset];
2470 return mobj->d.data[data.parameters() - 1];
2474
2475
2476
2477
2478
2479
2480
2481bool QMetaMethod::isConst()
const
2485 if (QMetaObjectPrivate::get(mobj)->revision < 10)
2487 return data.flags() & MethodIsConst;
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500QMetaMethod::Access QMetaMethod::access()
const
2502 constexpr int AccessShift = qCountTrailingZeroBits(AccessMask);
2503 static_assert(AccessPrivate >> AccessShift == Private);
2504 static_assert(AccessProtected >> AccessShift == Protected);
2505 static_assert(AccessPublic >> AccessShift == Public);
2508 return Access((data.flags() & AccessMask) >> AccessShift);
2512
2513
2514
2515
2516QMetaMethod::MethodType QMetaMethod::methodType()
const
2518 constexpr int MethodShift = qCountTrailingZeroBits(MethodTypeMask);
2519 static_assert(MethodMethod >> MethodShift == Method);
2520 static_assert(MethodSignal >> MethodShift == Signal);
2521 static_assert(MethodSlot >> MethodShift == Slot);
2522 static_assert(MethodConstructor >> MethodShift == Constructor);
2524 return QMetaMethod::Method;
2525 return MethodType((data.flags() & MethodTypeMask) >> MethodShift);
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2541
2542
2543
2544
2545
2546
2547
2548QMetaMethod QMetaMethod::fromSignalImpl(
const QMetaObject *metaObject,
void **signal)
2551 void *args[] = { &i, signal };
2552 for (
const QMetaObject *m = metaObject; m; m = m->d.superdata) {
2553 m->static_metacall(QMetaObject::IndexOfMethod, 0, args);
2555 return QMetaMethod::fromRelativeMethodIndex(m, i);
2557 return QMetaMethod();
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672bool QMetaMethod::invoke(QObject *object,
2673 Qt::ConnectionType connectionType,
2674 QGenericReturnArgument returnValue,
2675 QGenericArgument val0,
2676 QGenericArgument val1,
2677 QGenericArgument val2,
2678 QGenericArgument val3,
2679 QGenericArgument val4,
2680 QGenericArgument val5,
2681 QGenericArgument val6,
2682 QGenericArgument val7,
2683 QGenericArgument val8,
2684 QGenericArgument val9)
const
2686 if (!object || !mobj)
2690 const char *typeNames[] = {
2718 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
2719 if (qstrlen(typeNames[paramCount]) <= 0)
2722 return invokeImpl(*
this, object, connectionType, paramCount, param, typeNames,
nullptr);
2725bool QMetaMethod::invokeImpl(QMetaMethod self,
void *target, Qt::ConnectionType connectionType,
2726 qsizetype paramCount,
const void *
const *parameters,
2727 const char *
const *typeNames,
2728 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
2730 if (!target || !self.mobj)
2732 QMetaMethodPrivate::InvokeFailReason r =
2733 QMetaMethodPrivate::invokeImpl(self, target, connectionType, paramCount, parameters,
2734 typeNames, metaTypes);
2735 if (Q_LIKELY(r == QMetaMethodPrivate::InvokeFailReason::None))
2738 if (
int(r) >=
int(QMetaMethodPrivate::InvokeFailReason::FormalParameterMismatch)) {
2739 int n =
int(r) -
int(QMetaMethodPrivate::InvokeFailReason::FormalParameterMismatch);
2740 qWarning(
"QMetaMethod::invoke: cannot convert formal parameter %d from %s in call to %s::%s",
2741 n, typeNames[n + 1] ? typeNames[n + 1] : metaTypes[n + 1]->name,
2742 self.mobj->className(), self.methodSignature().constData());
2744 if (r == QMetaMethodPrivate::InvokeFailReason::TooFewArguments) {
2745 qWarning(
"QMetaMethod::invoke: too few arguments (%d) in call to %s::%s",
2746 int(paramCount), self.mobj->className(), self.methodSignature().constData());
2752 Qt::ConnectionType connectionType,
2753 qsizetype paramCount,
const void *
const *parameters,
2754 const char *
const *typeNames,
2757 auto object =
static_cast<QObject *>(target);
2758 auto priv = QMetaMethodPrivate::get(&self);
2759 constexpr bool MetaTypesAreOptional = QT_VERSION < QT_VERSION_CHECK(7, 0, 0);
2760 auto methodMetaTypes = priv->parameterMetaTypeInterfaces();
2761 auto param =
const_cast<
void **>(parameters);
2763 Q_ASSERT(priv->mobj);
2764 Q_ASSERT(self.methodType() == Constructor || object);
2765 Q_ASSERT(self.methodType() == Constructor || connectionType == Qt::ConnectionType(-1) ||
2766 priv->mobj->cast(object));
2767 Q_ASSERT(paramCount >= 1);
2768 Q_ASSERT(parameters);
2769 Q_ASSERT(typeNames);
2770 Q_ASSERT(MetaTypesAreOptional || metaTypes);
2772 if ((paramCount - 1) < qsizetype(priv->data.argc()))
2776 auto checkTypesAreCompatible = [=](
int idx) {
2777 uint typeInfo = priv->parameterTypeInfo(idx - 1);
2778 QByteArrayView userTypeName(typeNames[idx] ? typeNames[idx] : metaTypes[idx]
->name);
2780 if ((typeInfo & IsUnresolvedType) == 0) {
2782 if (MetaTypesAreOptional && !metaTypes)
2783 return int(typeInfo) == QMetaType::fromName(userTypeName).rawId();
2784 return int(typeInfo) == metaTypes[idx]->typeId;
2787 QByteArrayView methodTypeName = stringDataView(priv->mobj, typeInfo & TypeNameIndexMask);
2788 if ((MetaTypesAreOptional && !metaTypes) || !metaTypes[idx]) {
2790 if (methodTypeName == userTypeName)
2794 QByteArray normalized = normalizeTypeInternal(userTypeName.begin(), userTypeName.end());
2795 return methodTypeName == normalized;
2799 Q_ASSERT(userType.isValid());
2800 if (QMetaType(methodMetaTypes[idx - 1]) == userType)
2805 if (methodMetaTypes[idx - 1])
2809 QMetaType resolved = QMetaType::fromName(methodTypeName);
2810 return resolved == userType;
2814 for (qsizetype i = 0; metaTypes && i < paramCount; ++i)
2818 for (qsizetype i = 1; i < paramCount; ++i) {
2819 if (!checkTypesAreCompatible(i))
2824 if (self.methodType() == Constructor) {
2826 qWarning(
"QMetaMethod::invokeMethod: cannot call constructor %s on object %p",
2827 self.methodSignature().constData(), object);
2831 if (!parameters[0]) {
2832 qWarning(
"QMetaMethod::invokeMethod: constructor call to %s must assign a return type",
2833 self.methodSignature().constData());
2837 if (!MetaTypesAreOptional || metaTypes) {
2838 if (metaTypes[0]->typeId != QMetaType::QObjectStar) {
2839 qWarning(
"QMetaMethod::invokeMethod: cannot convert QObject* to %s on constructor call %s",
2840 metaTypes[0]
->name, self.methodSignature().constData());
2845 int idx = priv->ownConstructorMethodIndex();
2846 if (priv->mobj->static_metacall(QMetaObject::CreateInstance, idx, param) >= 0)
2852 if (parameters[0]) {
2853 if (!checkTypesAreCompatible(0)) {
2854 const char *retType = typeNames[0] ? typeNames[0] : metaTypes[0]
->name;
2855 qWarning(
"QMetaMethod::invokeMethod: return type mismatch for method %s::%s:"
2856 " cannot convert from %s to %s during invocation",
2857 priv->mobj->className(), priv->methodSignature().constData(),
2858 priv->rawReturnTypeName(), retType);
2863 Qt::HANDLE currentThreadId =
nullptr;
2864 QThread *objectThread =
nullptr;
2865 auto receiverInSameThread = [&]() {
2866 if (!currentThreadId) {
2867 currentThreadId = QThread::currentThreadId();
2868 objectThread = object->thread();
2871 return currentThreadId == QThreadData::get2(objectThread)->threadId.loadRelaxed();
2876 if (connectionType == Qt::AutoConnection)
2877 connectionType = receiverInSameThread() ? Qt::DirectConnection : Qt::QueuedConnection;
2878 else if (connectionType == Qt::ConnectionType(-1))
2879 connectionType = Qt::DirectConnection;
2881#if !QT_CONFIG(thread)
2882 if (connectionType == Qt::BlockingQueuedConnection) {
2883 connectionType = Qt::DirectConnection;
2888 int idx_relative = priv->ownMethodIndex();
2889 int idx_offset = priv->mobj->methodOffset();
2890 QObjectPrivate::StaticMetaCallFunction callFunction = priv->mobj->d.static_metacall;
2892 if (connectionType == Qt::DirectConnection) {
2894 callFunction(object, QMetaObject::InvokeMetaMethod, idx_relative, param);
2895 else if (QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, idx_relative + idx_offset, param) >= 0)
2897 }
else if (connectionType == Qt::QueuedConnection) {
2898 if (parameters[0]) {
2899 qWarning(
"QMetaMethod::invoke: Unable to invoke methods with return values in "
2900 "queued connections");
2904 QVarLengthArray<
const QtPrivate::QMetaTypeInterface *, 16> argTypes;
2905 argTypes.reserve(paramCount);
2906 argTypes.emplace_back(
nullptr);
2908 for (
int i = 1; i < paramCount; ++i) {
2909 QMetaType type = QMetaType(methodMetaTypes[i - 1]);
2910 if (!type.iface() && (!MetaTypesAreOptional || metaTypes))
2911 type = QMetaType(metaTypes[i]);
2913 type = priv->parameterMetaType(i - 1);
2914 if (!type.iface() && typeNames[i])
2915 type = QMetaType::fromName(typeNames[i]);
2916 if (!type.iface()) {
2917 qWarning(
"QMetaMethod::invoke: Unable to handle unregistered datatype '%s'",
2921 argTypes.emplace_back(type.iface());
2924 QCoreApplication::postEvent(object,
new QQueuedMetaCallEvent(idx_offset, idx_relative, callFunction,
nullptr,
2925 -1, paramCount, argTypes.data(), parameters));
2927#if QT_CONFIG(thread)
2928 if (receiverInSameThread()) {
2929 qWarning(
"QMetaMethod::invoke: Dead lock detected in BlockingQueuedConnection: "
2930 "Receiver is %s(%p)", priv->mobj->className(), object);
2931 return InvokeFailReason::DeadLockDetected;
2935 QCoreApplication::postEvent(object,
new QMetaCallEvent(idx_offset, idx_relative, callFunction,
2936 nullptr, -1, param, &latch));
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046bool QMetaMethod::invokeOnGadget(
void *gadget,
3047 QGenericReturnArgument returnValue,
3048 QGenericArgument val0,
3049 QGenericArgument val1,
3050 QGenericArgument val2,
3051 QGenericArgument val3,
3052 QGenericArgument val4,
3053 QGenericArgument val5,
3054 QGenericArgument val6,
3055 QGenericArgument val7,
3056 QGenericArgument val8,
3057 QGenericArgument val9)
const
3059 if (!gadget || !mobj)
3063 if (returnValue.data()) {
3064 const char *retType = typeName();
3065 if (qstrcmp(returnValue.name(), retType) != 0) {
3067 QByteArray normalized = QMetaObject::normalizedType(returnValue.name());
3068 if (qstrcmp(normalized.constData(), retType) != 0) {
3070 int t = returnType();
3071 if (t == QMetaType::UnknownType || t != QMetaType::fromName(normalized).rawId())
3078 const char *typeNames[] = {
3092 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
3093 if (qstrlen(typeNames[paramCount]) <= 0)
3096 if (paramCount <= QMetaMethodPrivate::get(
this)->parameterCount())
3113 int idx_relative = QMetaMethodPrivate::get(
this)->ownMethodIndex();
3114 Q_ASSERT(QMetaObjectPrivate::get(mobj)->revision >= 6);
3115 QObjectPrivate::StaticMetaCallFunction callFunction = mobj->d.static_metacall;
3118 callFunction(
reinterpret_cast<QObject*>(gadget), QMetaObject::InvokeMetaMethod, idx_relative, param);
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3179
3180
3181
3182
3183
3184
3185
3188
3189
3190
3194
3195
3196
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209const char *QMetaEnum::name()
const
3213 return rawStringData(mobj, data.name());
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228const char *QMetaEnum::enumName()
const
3232 return rawStringData(mobj, data.alias());
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247QMetaType QMetaEnum::metaType()
const
3252 const QMetaObjectPrivate *p = priv(mobj->d.data);
3253#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
3254 if (p->revision < 12)
3258 QMetaType mt(mobj->d.metaTypes[data.index(mobj) + p->propertyCount]);
3264
3265
3266
3267
3268int QMetaEnum::keyCount()
const
3272 return data.keyCount();
3276
3277
3278
3279
3280const char *QMetaEnum::key(
int index)
const
3284 if (index >= 0 && index <
int(data.keyCount()))
3285 return rawStringData(mobj, mobj->d.data[data.data() + 2*index]);
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299int QMetaEnum::value(
int index)
const
3301 return value64(index).value_or(-1);
3309Q_DECL_PURE_FUNCTION
static inline EnumExtendMode enumExtendMode(
const QMetaEnum &e)
3315 if (e.metaType().flags() & QMetaType::IsUnsignedEnumeration)
3327 return value == uint(value);
3328 return value == quint64(
int(value));
3331template <
typename... Mode>
inline
3332quint64 QMetaEnum::value_helper(uint index, Mode... modes)
const noexcept
3334 static_assert(
sizeof...(Mode) < 2);
3335 if constexpr (
sizeof...(Mode) == 0) {
3336 return value_helper(index, enumExtendMode(*
this));
3337 }
else if constexpr (
sizeof...(Mode) == 1) {
3338 auto mode = (modes, ...);
3339 quint64 value = mobj->d.data[data.data() + 2U * index + 1];
3341 value |= quint64(mobj->d.data[data.data() + 2U * data.keyCount() + index]) << 32;
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370std::optional<quint64> QMetaEnum::value64(
int index)
const
3373 return std::nullopt;
3374 if (index < 0 || index >=
int(data.keyCount()))
3375 return std::nullopt;
3377 return value_helper(index);
3381
3382
3383
3384
3385
3386
3387
3388
3389bool QMetaEnum::isFlag()
const
3393 return data.flags() & EnumIsFlag;
3397
3398
3399
3400
3401
3402bool QMetaEnum::isScoped()
const
3406 return data.flags() & EnumIsScoped;
3410
3411
3412
3413
3414
3415
3416bool QMetaEnum::is64Bit()
const
3420 return data.flags() & EnumIs64Bit;
3424
3425
3426
3427
3428
3429
3430
3431const char *QMetaEnum::scope()
const
3433 return mobj ? mobj->className() :
nullptr;
3438 const QByteArrayView className = e->enclosingMetaObject()->className();
3443 if (scope == className)
3449 QByteArrayView name = e->enumName();
3453 const auto sz = className.size();
3454 if (scope.size() == sz + qsizetype(qstrlen(
"::")) + name.size()
3455 && scope.startsWith(className)
3456 && scope.sliced(sz, 2) ==
"::"
3457 && scope.sliced(sz + 2) == name)
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478int QMetaEnum::keyToValue(
const char *key,
bool *ok)
const
3480 auto value = keyToValue64(key);
3482 *ok = value.has_value();
3483 return int(value.value_or(-1));
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498std::optional<quint64> QMetaEnum::keyToValue64(
const char *key)
const
3501 return std::nullopt;
3502 const auto [scope, enumKey] = parse_scope(QLatin1StringView(key));
3503 for (
int i = 0; i <
int(data.keyCount()); ++i) {
3504 if ((!scope || isScopeMatch(*scope,
this))
3505 && enumKey == stringDataView(mobj, mobj->d.data[data.data() + 2 * i])) {
3506 return value_helper(i);
3509 return std::nullopt;
3513
3514
3515
3516
3517
3518
3519
3520const char *QMetaEnum::valueToKey(quint64 value)
const
3525 EnumExtendMode mode = enumExtendMode(*
this);
3526 if (!isEnumValueSuitable(value, mode))
3529 for (
int i = 0; i <
int(data.keyCount()); ++i) {
3530 if (value == value_helper(i, mode))
3531 return rawStringData(mobj, mobj->d.data[data.data() + 2 * i]);
3536static bool parseEnumFlags(QByteArrayView v, QVarLengthArray<QByteArrayView, 10> &list)
3540 qWarning(
"QMetaEnum::keysToValue: empty keys string.");
3544 qsizetype sep = v.indexOf(
'|', 0);
3546 qWarning(
"QMetaEnum::keysToValue: malformed keys string, starts with '|', \"%s\"",
3556 if (v.endsWith(
'|')) {
3557 qWarning(
"QMetaEnum::keysToValue: malformed keys string, ends with '|', \"%s\"",
3562 const auto begin = v.begin();
3563 const auto end = v.end();
3565 for (; b != end && sep != -1; sep = v.indexOf(
'|', sep)) {
3566 list.push_back({b, begin + sep});
3570 qWarning(
"QMetaEnum::keysToValue: malformed keys string, has two consecutive '|': "
3571 "\"%s\"", v.constData());
3577 list.push_back({b, end});
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595int QMetaEnum::keysToValue(
const char *keys,
bool *ok)
const
3597 auto value = keysToValue64(keys);
3599 *ok = value.has_value();
3600 return int(value.value_or(-1));
3604
3605
3606
3607
3608
3609
3610
3611
3612std::optional<quint64> QMetaEnum::keysToValue64(
const char *keys)
const
3615 return std::nullopt;
3617 EnumExtendMode mode = enumExtendMode(*
this);
3618 auto lookup = [&] (QByteArrayView key) -> std::optional<quint64> {
3619 for (
int i = data.keyCount() - 1; i >= 0; --i) {
3620 if (key == stringDataView(mobj, mobj->d.data[data.data() + 2*i]))
3621 return value_helper(i, mode);
3623 return std::nullopt;
3627 QVarLengthArray<QByteArrayView, 10> list;
3628 const bool r = parseEnumFlags(QByteArrayView{keys}, list);
3630 return std::nullopt;
3631 for (
const auto &untrimmed : list) {
3632 const auto parsed = parse_scope(untrimmed.trimmed());
3633 if (parsed.scope && !isScopeMatch(*parsed.scope,
this))
3634 return std::nullopt;
3635 if (
auto thisValue = lookup(parsed.key))
3636 value |= *thisValue;
3638 return std::nullopt;
3645template <
typename String,
typename Container,
typename Separator>
3646void join_reversed(String &s,
const Container &c, Separator sep)
3650 qsizetype len = qsizetype(c.size()) - 1;
3652 len += qsizetype(e.size());
3655 for (
auto rit = c.rbegin(), rend = c.rend(); rit != rend; ++rit) {
3656 const auto &e = *rit;
3660 s.append(e.data(), e.size());
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675QByteArray QMetaEnum::valueToKeys(quint64 value)
const
3681 EnumExtendMode mode = enumExtendMode(*
this);
3682 if (!isEnumValueSuitable(value, mode))
3685 QVarLengthArray<QByteArrayView,
sizeof(
int) * CHAR_BIT> parts;
3689 for (
int i = data.keyCount() - 1; i >= 0; --i) {
3690 quint64 k = value_helper(i, mode);
3691 if ((k != 0 && (v & k) == k) || (k == value)) {
3693 parts.push_back(stringDataView(mobj, mobj->d.data[data.data() + 2 * i]));
3696 join_reversed(keys, parts,
'|');
3701
3702
3703QMetaEnum::QMetaEnum(
const QMetaObject *mobj,
int index)
3704 : mobj(mobj), data({ mobj->d.data + priv(mobj->d.data)->enumeratorData + index * Data::Size })
3706 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->enumeratorCount);
3709int QMetaEnum::Data::index(
const QMetaObject *mobj)
const
3711#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
3712# warning "Consider changing Size to a power of 2"
3714 return (
unsigned(d - mobj->d.data) - priv(mobj->d.data)->enumeratorData) / Size;
3718
3719
3720
3721
3722
3723
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3762
3763
3764
3765
3766
3767
3768
3771
3772
3773
3776
3777
3778
3781
3782
3783
3784
3785const char *QMetaProperty::name()
const
3789 return rawStringData(mobj, data.name());
3793
3794
3795
3796
3797const char *QMetaProperty::typeName()
const
3802 if (
const auto mt = metaType(); mt.isValid())
3804 return typeNameFromTypeInfo(mobj, data.type()).constData();
3808
3809
3810
3811
3812
3813
3814
3817
3818
3819
3820
3821
3822
3823
3824
3825
3828
3829
3830
3831
3832
3833
3834
3837
3838
3839
3840
3841
3842
3843QMetaType QMetaProperty::metaType()
const
3847 QMetaType mt(mobj->d.metaTypes[data.index(mobj)]);
3852int QMetaProperty::Data::index(
const QMetaObject *mobj)
const
3854#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
3855# warning "Consider changing Size to a power of 2"
3857 return (
unsigned(d - mobj->d.data) - priv(mobj->d.data)->propertyData) / Size;
3861
3862
3863
3864
3865int QMetaProperty::propertyIndex()
const
3869 return data.index(mobj) + mobj->propertyOffset();
3873
3874
3875
3876
3877int QMetaProperty::relativePropertyIndex()
const
3881 return data.index(mobj);
3885
3886
3887
3888
3889
3890
3891
3892
3894bool QMetaProperty::isFlagType()
const
3896 return isEnumType() && menum.isFlag();
3900
3901
3902
3903
3904
3905bool QMetaProperty::isEnumType()
const
3909 return (data.flags() & EnumOrFlag) && menum.name();
3913
3914
3915
3916
3917
3918
3919
3920
3921bool QMetaProperty::hasStdCppSet()
const
3925 return (data.flags() & StdCppSet);
3929
3930
3931
3932
3933
3934
3935bool QMetaProperty::isAlias()
const
3939 return (data.flags() & Alias);
3942#if QT_DEPRECATED_SINCE(6
, 4
)
3944
3945
3946
3947
3948
3949
3950
3951int QMetaProperty::registerPropertyType()
const
3957QMetaProperty::QMetaProperty(
const QMetaObject *mobj,
int index)
3959 data(getMetaPropertyData(mobj, index))
3961 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->propertyCount);
3963 if (!(data.flags() & EnumOrFlag) || !metaType().flags().testFlag(QMetaType::IsEnumeration))
3965 QByteArrayView enum_name = typeNameFromTypeInfo(mobj, data.type());
3966 menum = mobj->enumerator(QMetaObjectPrivate::indexOfEnumerator(mobj, enum_name));
3967 if (menum.isValid())
3970 QByteArrayView scope_name;
3971 const auto parsed = parse_scope(enum_name);
3973 scope_name = *parsed.scope;
3974 enum_name = parsed.key;
3976 scope_name = objectClassName(mobj);
3979 const QMetaObject *scope =
nullptr;
3980 if (scope_name ==
"Qt")
3981 scope = &Qt::staticMetaObject;
3983 scope = QMetaObject_findMetaObject(mobj, QByteArrayView(scope_name));
3986 menum = scope->enumerator(QMetaObjectPrivate::indexOfEnumerator(scope, enum_name));
3990
3991
3992
3993QMetaProperty::Data QMetaProperty::getMetaPropertyData(
const QMetaObject *mobj,
int index)
3995 return { mobj->d.data + priv(mobj->d.data)->propertyData + index * Data::Size };
3999
4000
4001
4002
4003
4004QMetaEnum QMetaProperty::enumerator()
const
4010
4011
4012
4013
4014
4015QVariant QMetaProperty::read(
const QObject *object)
const
4017 if (!object || !mobj)
4027 void *argv[] = {
nullptr, &value, &status };
4028 QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
4029 if (t == QMetaType::fromType<QVariant>()) {
4032 value = QVariant(t,
nullptr);
4033 argv[0] = value.data();
4035 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) {
4036 mobj->d.static_metacall(
const_cast<QObject*>(object), QMetaObject::ReadProperty, data.index(mobj), argv);
4038 QMetaObject::metacall(
const_cast<QObject*>(object), QMetaObject::ReadProperty,
4039 data.index(mobj) + mobj->propertyOffset(), argv);
4044 if (t != QMetaType::fromType<QVariant>() && argv[0] != value.data())
4046 return QVariant(t, argv[0]);
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064bool QMetaProperty::write(QObject *object,
const QVariant &value)
const
4066 if (!object || !isWritable())
4068 return write(object, QVariant(value));
4072
4073
4074
4075bool QMetaProperty::write(QObject *object, QVariant &&v)
const
4077 if (!object || !isWritable())
4079 QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
4080 if (t != QMetaType::fromType<QVariant>() && t != v.metaType()) {
4081 if (isEnumType() && !t.metaObject() && v.metaType() == QMetaType::fromType<QString>()) {
4085 std::optional value = isFlagType() ? menum.keysToValue64(v.toByteArray())
4086 : menum.keyToValue64(v.toByteArray());
4088 v = QVariant(qlonglong(*value));
4095 return reset(object);
4096 v = QVariant(t,
nullptr);
4097 }
else if (!v.convert(t)) {
4110 void *argv[] = {
nullptr, &v, &status, &flags };
4111 if (t == QMetaType::fromType<QVariant>())
4115 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
4116 mobj->d.static_metacall(object, QMetaObject::WriteProperty, data.index(mobj), argv);
4118 QMetaObject::metacall(object, QMetaObject::WriteProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4124
4125
4126
4127
4128
4129
4130
4131bool QMetaProperty::reset(QObject *object)
const
4133 if (!object || !mobj || !isResettable())
4135 void *argv[] = {
nullptr };
4136 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
4137 mobj->d.static_metacall(object, QMetaObject::ResetProperty, data.index(mobj), argv);
4139 QMetaObject::metacall(object, QMetaObject::ResetProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4144
4145
4146
4147
4148
4149
4150
4151
4152QUntypedBindable QMetaProperty::bindable(QObject *object)
const
4154 QUntypedBindable bindable;
4155 void * argv[1] { &bindable };
4156 mobj->metacall(object, QMetaObject::BindableProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4160
4161
4162
4163
4164
4165
4166
4167QVariant QMetaProperty::readOnGadget(
const void *gadget)
const
4169 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4170 return read(
reinterpret_cast<
const QObject*>(gadget));
4174
4175
4176
4177
4178
4179
4180
4181bool QMetaProperty::writeOnGadget(
void *gadget,
const QVariant &value)
const
4183 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4184 return write(
reinterpret_cast<QObject*>(gadget), value);
4188
4189
4190
4191bool QMetaProperty::writeOnGadget(
void *gadget, QVariant &&value)
const
4193 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4194 return write(
reinterpret_cast<QObject*>(gadget), std::move(value));
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207bool QMetaProperty::resetOnGadget(
void *gadget)
const
4209 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4210 return reset(
reinterpret_cast<QObject*>(gadget));
4214
4215
4216
4217
4218
4219bool QMetaProperty::isResettable()
const
4223 return data.flags() & Resettable;
4227
4228
4229
4230
4231bool QMetaProperty::isReadable()
const
4235 return data.flags() & Readable;
4239
4240
4241
4242
4243
4244bool QMetaProperty::hasNotifySignal()
const
4248 return data.notifyIndex() != uint(-1);
4252
4253
4254
4255
4256
4257
4258
4259QMetaMethod QMetaProperty::notifySignal()
const
4261 int id = notifySignalIndex();
4263 return mobj->method(id);
4265 return QMetaMethod();
4269
4270
4271
4272
4273
4274
4275
4276int QMetaProperty::notifySignalIndex()
const
4278 if (!mobj || data.notifyIndex() == std::numeric_limits<uint>::max())
4280 uint methodIndex = data.notifyIndex();
4281 if (!(methodIndex & IsUnresolvedSignal))
4282 return methodIndex + mobj->methodOffset();
4283 methodIndex &= ~IsUnresolvedSignal;
4284 const QByteArrayView signalName = stringDataView(mobj, methodIndex);
4285 const QMetaObject *m = mobj;
4287 int idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, {}, QMetaMethod::Signal);
4289 return idx + m->methodOffset();
4291 QArgumentType argType[] = {metaType()};
4292 idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, argType, QMetaMethod::Signal);
4294 return idx + m->methodOffset();
4295 qWarning(
"QMetaProperty::notifySignal: cannot find the NOTIFY signal %s in class %s for property '%s'",
4296 signalName.constData(), mobj->className(), name());
4302
4303
4304
4305
4306
4307
4308int QMetaProperty::revision()
const
4312 return data.revision();
4316
4317
4318
4319
4320
4321bool QMetaProperty::isWritable()
const
4325 return data.flags() & Writable;
4329
4330
4331
4332
4333
4334bool QMetaProperty::isDesignable()
const
4338 return data.flags() & Designable;
4342
4343
4344
4345
4346
4347bool QMetaProperty::isScriptable()
const
4351 return data.flags() & Scriptable;
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364bool QMetaProperty::isStored()
const
4368 return data.flags() & Stored;
4372
4373
4374
4375
4376
4377
4378
4379bool QMetaProperty::isUser()
const
4383 return data.flags() & User;
4387
4388
4389
4390
4391
4392
4393bool QMetaProperty::isConstant()
const
4397 return data.flags() & Constant;
4401
4402
4403
4404
4405
4406
4407bool QMetaProperty::isFinal()
const
4411 return data.flags() & Final;
4415
4416
4417
4418
4419
4420
4421bool QMetaProperty::isVirtual()
const
4425 return data.flags() & Virtual;
4429
4430
4431
4432
4433
4434
4435bool QMetaProperty::isOverride()
const
4439 return data.flags() & Override;
4443
4444
4445
4446
4447
4448
4449bool QMetaProperty::isRequired()
const
4453 return data.flags() & Required;
4457
4458
4459
4460
4461
4462
4463
4464
4465bool QMetaProperty::isBindable()
const
4469 return (data.flags() & Bindable);
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4497
4498
4499
4502
4503
4504
4507
4508
4509
4510
4511const char *QMetaClassInfo::name()
const
4515 return rawStringData(mobj, data.name());
4519
4520
4521
4522
4523const char *QMetaClassInfo::value()
const
4527 return rawStringData(mobj, data.value());
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4545
4546
4547
4548
4549
4550
4551
4552
4553
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4581
4582
4583
4584
4587
4588
4589
4590
4593
4594
4595
4596
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4612
4613
4614
4615
4616
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4632 Q_ASSERT(local_method_index < get(mobj)->methodCount);
4633 while (QMetaMethod::fromRelativeMethodIndex(mobj, local_method_index).data.flags() & MethodCloned) {
4634 Q_ASSERT(local_method_index > 0);
4635 --local_method_index;
4637 return local_method_index;
4641
4642
4643
4644
4645
4646
4647
4648
4651 QVarLengthArray<QByteArrayView, 10> &typeNames)
4653 const char *signature =
static_cast<
const char *>(memchr(sig.begin(),
'(', sig.size()));
4656 auto name = QByteArrayView{sig.begin(), signature};
4658 if (!sig.endsWith(
')'))
4660 const char *end = sig.end() - 1;
4661 while (signature != end) {
4662 if (*signature ==
',')
4664 const char *begin = signature;
4666 while (signature != end && (level > 0 || *signature !=
',')) {
4667 if (*signature ==
'<')
4669 else if (*signature ==
'>')
4673 typeNames.append(QByteArrayView{begin, signature - begin});