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
1612
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
1645
1646bool QMetaObject::invokeMethod(QObject *obj,
1648 Qt::ConnectionType type,
1649 QGenericReturnArgument ret,
1650 QGenericArgument val0,
1651 QGenericArgument val1,
1652 QGenericArgument val2,
1653 QGenericArgument val3,
1654 QGenericArgument val4,
1655 QGenericArgument val5,
1656 QGenericArgument val6,
1657 QGenericArgument val7,
1658 QGenericArgument val8,
1659 QGenericArgument val9)
1664 const char *typeNames[] = {ret.name(), val0.name(), val1.name(), val2.name(), val3.name(),
1665 val4.name(), val5.name(), val6.name(), val7.name(), val8.name(),
1667 const void *parameters[] = {ret.data(), val0.data(), val1.data(), val2.data(), val3.data(),
1668 val4.data(), val5.data(), val6.data(), val7.data(), val8.data(),
1671 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
1672 if (qstrlen(typeNames[paramCount]) <= 0)
1675 return invokeMethodImpl(obj, member, type, paramCount, parameters, typeNames,
nullptr);
1678bool QMetaObject::invokeMethodImpl(QObject *obj,
const char *member, Qt::ConnectionType type,
1679 qsizetype paramCount,
const void *
const *parameters,
1680 const char *
const *typeNames,
1681 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
1686 Q_ASSERT(paramCount >= 1);
1687 Q_ASSERT(parameters);
1688 Q_ASSERT(typeNames);
1691 QByteArrayView name(member);
1695 const QMetaObject *meta = obj->metaObject();
1696 for ( ; meta; meta = meta->superClass()) {
1697 auto priv = QMetaObjectPrivate::get(meta);
1698 for (
int i = 0; i < priv->methodCount; ++i) {
1699 QMetaMethod m = QMetaMethod::fromRelativeMethodIndex(meta, i);
1700 if (m.parameterCount() != (paramCount - 1))
1702 if (name != stringDataView(meta, m.data.name()))
1706 QMetaMethodPrivate::InvokeFailReason r =
1707 QMetaMethodPrivate::invokeImpl(m, obj, type, paramCount, parameters,
1708 typeNames, metaTypes);
1710 return r == QMetaMethodPrivate::InvokeFailReason::None;
1715 return printMethodNotFoundWarning(obj->metaObject(), name, paramCount, typeNames, metaTypes);
1718bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
1719 qsizetype parameterCount,
const void *
const *params,
const char *
const *names,
1720 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
1725 auto slot = QtPrivate::SlotObjUniquePtr(slotObj);
1730 Qt::HANDLE currentThreadId = QThread::currentThreadId();
1731 QThread *objectThread = object->thread();
1732 bool receiverInSameThread =
false;
1734 receiverInSameThread = currentThreadId == QThreadData::get2(objectThread)->threadId.loadRelaxed();
1736 if (type == Qt::AutoConnection)
1737 type = receiverInSameThread ? Qt::DirectConnection : Qt::QueuedConnection;
1739 void **argv =
const_cast<
void **>(params);
1740 if (type == Qt::DirectConnection) {
1741 slot->call(object, argv);
1742 }
else if (type == Qt::QueuedConnection) {
1744 qWarning(
"QMetaObject::invokeMethod: Unable to invoke methods with return values in "
1745 "queued connections");
1748 QCoreApplication::postEvent(object,
new QQueuedMetaCallEvent(std::move(slot),
nullptr, -1,
1749 parameterCount, metaTypes, params));
1750 }
else if (type == Qt::BlockingQueuedConnection) {
1751#if QT_CONFIG(thread)
1752 if (receiverInSameThread)
1753 qWarning(
"QMetaObject::invokeMethod: Dead lock detected");
1756 QCoreApplication::postEvent(object,
new QMetaCallEvent(std::move(slot),
nullptr, -1, argv, &latch));
1760 qWarning(
"QMetaObject::invokeMethod: Unknown connection type");
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1868
1869
1870
1871
1873
1874
1875
1876
1877
1880
1881
1882
1883
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1904
1905
1906
1907
1908
1909
1910
1911
1914
1915
1916
1917
1918
1919
1922
1923
1924
1925
1926
1927
1930
1931
1932
1933
1934
1935
1938
1939
1940
1943
1944
1945
1946
1947
1948
1949
1952
1953
1954
1957
1958
1959QMetaMethod QMetaMethod::fromRelativeMethodIndex(
const QMetaObject *mobj,
int index)
1961 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->methodCount);
1964 m.data = { mobj->d.data + priv(mobj->d.data)->methodData + index * Data::Size };
1968QMetaMethod QMetaMethod::fromRelativeConstructorIndex(
const QMetaObject *mobj,
int index)
1970 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->constructorCount);
1973 m.data = { mobj->d.data + priv(mobj->d.data)->constructorData + index * Data::Size };
1978
1979
1980
1981
1982
1983
1987 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1989 result.reserve(256);
1992 QList<QByteArray> argTypes = parameterTypes();
1993 for (
int i = 0; i < argTypes.size(); ++i) {
1996 result += argTypes.at(i);
2002QByteArrayView QMetaMethodPrivate::name()
const noexcept
2004 QByteArrayView name = qualifiedName();
2005 if (qsizetype colon = name.lastIndexOf(
':'); colon > 0)
2006 return name.sliced(colon + 1);
2010QByteArrayView QMetaMethodPrivate::qualifiedName()
const noexcept
2012 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2013 return stringDataView(mobj, data.name());
2016int QMetaMethodPrivate::typesDataIndex()
const
2018 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2019 return data.parameters();
2022const char *QMetaMethodPrivate::rawReturnTypeName()
const
2024 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2025 uint typeInfo = mobj->d.data[typesDataIndex()];
2026 if (typeInfo & IsUnresolvedType)
2027 return rawStringData(mobj, typeInfo & TypeNameIndexMask);
2029 return QMetaType(typeInfo).name();
2032int QMetaMethodPrivate::returnType()
const
2034 return parameterType(-1);
2037int QMetaMethodPrivate::parameterCount()
const
2039 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2047 uint typeInfo = parameterTypeInfo(index);
2050 if ((typeInfo & IsUnresolvedType) == 0)
2051 Q_ASSERT(mt.rawId() ==
int(typeInfo & TypeNameIndexMask));
2052 Q_ASSERT(mt.name());
2058#define ASSERT_NOT_PRIMITIVE_TYPE(TYPE, METATYPEID, NAME)
2059 Q_ASSERT(typeInfo != QMetaType::TYPE);
2061#undef ASSERT_NOT_PRIMITIVE_TYPE
2062 Q_ASSERT(typeInfo != QMetaType::QObjectStar);
2065 if (priv(mobj->d.data)->revision >= 11) {
2066 Q_ASSERT(typeInfo != QMetaType::Void);
2067 Q_ASSERT(typeInfo != QMetaType::VoidStar);
2072int QMetaMethodPrivate::parametersDataIndex()
const
2074 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2075 return typesDataIndex() + 1;
2078uint QMetaMethodPrivate::parameterTypeInfo(
int index)
const
2080 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2081 return mobj->d.data[parametersDataIndex() + index];
2086 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2087 if (methodType() == QMetaMethod::Constructor)
2091 checkMethodMetaTypeConsistency(iface, -1);
2097 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2098 int offset = (methodType() == QMetaMethod::Constructor ? 0 : 1);
2099 const auto ifaces = &mobj->d.metaTypes[data.metaTypeOffset() + offset];
2101 for (
int i = 0; i < parameterCount(); ++i)
2102 checkMethodMetaTypeConsistency(ifaces[i], i);
2107int QMetaMethodPrivate::parameterType(
int index)
const
2109 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2110 return typeFromTypeInfo(mobj, parameterTypeInfo(index));
2113void QMetaMethodPrivate::getParameterTypes(
int *types)
const
2115 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2116 int dataIndex = parametersDataIndex();
2117 int argc = parameterCount();
2118 for (
int i = 0; i < argc; ++i) {
2119 int id = typeFromTypeInfo(mobj, mobj->d.data[dataIndex++]);
2124QByteArrayView QMetaMethodPrivate::parameterTypeName(
int index)
const noexcept
2126 int paramsIndex = parametersDataIndex();
2127 return typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + index]);
2130QList<QByteArray> QMetaMethodPrivate::parameterTypes()
const
2132 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2133 int argc = parameterCount();
2134 QList<QByteArray> list;
2136 int paramsIndex = parametersDataIndex();
2137 for (
int i = 0; i < argc; ++i) {
2138 QByteArrayView name = typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + i]);
2139 list.emplace_back(name.toByteArray());
2144QList<QByteArray> QMetaMethodPrivate::parameterNames()
const
2146 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2147 int argc = parameterCount();
2148 QList<QByteArray> list;
2150 int namesIndex = parametersDataIndex() + argc;
2151 for (
int i = 0; i < argc; ++i)
2152 list += stringData(mobj, mobj->d.data[namesIndex + i]);
2156const char *QMetaMethodPrivate::tag()
const
2158 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2159 return rawStringData(mobj, data.tag());
2162int QMetaMethodPrivate::ownMethodIndex()
const
2165 return ( data.d - mobj->d.data - priv(mobj->d.data)->methodData)/Data::Size;
2168int QMetaMethodPrivate::ownConstructorMethodIndex()
const
2171 Q_ASSERT(methodType() == Constructor);
2172 return ( data.d - mobj->d.data - priv(mobj->d.data)->constructorData)/Data::Size;
2176
2177
2178
2179
2180
2181
2182
2183QByteArray QMetaMethod::methodSignature()
const
2186 return QByteArray();
2187 return QMetaMethodPrivate::get(
this)->signature();
2191
2192
2193
2194
2195
2196
2197QByteArray QMetaMethod::name()
const
2200 return QByteArray();
2202 return stringData(mobj, QMetaMethodPrivate::get(
this)->name());
2206
2207
2208
2209
2210
2211
2212
2213
2214QByteArrayView QMetaMethod::nameView()
const
2216 return QMetaMethodPrivate::get(
this)->name();
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229int QMetaMethod::returnType()
const
2231 return returnMetaType().rawId();
2235
2236
2237
2238
2239
2240QMetaType QMetaMethod::returnMetaType()
const
2242 if (!mobj || methodType() == QMetaMethod::Constructor)
2244 auto mt = QMetaType(mobj->d.metaTypes[data.metaTypeOffset()]);
2246 mt = QMetaType(QMetaMethodPrivate::get(
this)->returnType());
2252
2253
2254
2255
2256
2257
2258int QMetaMethod::parameterCount()
const
2262 return QMetaMethodPrivate::get(
this)->parameterCount();
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275int QMetaMethod::parameterType(
int index)
const
2277 return parameterMetaType(index).rawId();
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290QMetaType QMetaMethod::parameterMetaType(
int index)
const
2292 if (!mobj || index < 0)
2294 auto priv = QMetaMethodPrivate::get(
this);
2295 if (index >= priv->parameterCount())
2298 auto parameterOffset = index + (methodType() == QMetaMethod::Constructor ? 0 : 1);
2299 auto mt = QMetaType(mobj->d.metaTypes[data.metaTypeOffset() + parameterOffset]);
2301 mt = QMetaType(QMetaMethodPrivate::get(
this)->parameterType(index));
2307
2308
2309
2310
2311
2312
2313
2314
2315void QMetaMethod::getParameterTypes(
int *types)
const
2319 QMetaMethodPrivate::get(
this)->getParameterTypes(types);
2323
2324
2325
2326
2327QList<QByteArray> QMetaMethod::parameterTypes()
const
2330 return QList<QByteArray>();
2331 return QMetaMethodPrivate::get(
this)->parameterTypes();
2335
2336
2337
2338
2339
2340
2341QByteArray QMetaMethod::parameterTypeName(
int index)
const
2343 if (!mobj || index < 0 || index >= parameterCount())
2346 return stringData(mobj, QMetaMethodPrivate::get(
this)->parameterTypeName(index));
2350
2351
2352
2353
2354QList<QByteArray> QMetaMethod::parameterNames()
const
2357 return QList<QByteArray>();
2358 return QMetaMethodPrivate::get(
this)->parameterNames();
2363
2364
2365
2366
2367
2368
2369
2370
2371const char *QMetaMethod::typeName()
const
2375#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
2376 if (methodType() == QMetaMethod::Constructor)
2379 return QMetaMethodPrivate::get(
this)->rawReturnTypeName();
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406const char *QMetaMethod::tag()
const
2410 return QMetaMethodPrivate::get(
this)->tag();
2415
2416
2417int QMetaMethod::attributes()
const
2421 return data.flags() >> 4;
2425
2426
2427
2428
2429int QMetaMethod::methodIndex()
const
2433 return QMetaMethodPrivate::get(
this)->ownMethodIndex() + mobj->methodOffset();
2437
2438
2439
2440
2441int QMetaMethod::relativeMethodIndex()
const
2445 return QMetaMethodPrivate::get(
this)->ownMethodIndex();
2450
2451
2452
2453
2454
2455int QMetaMethod::revision()
const
2459 if ((data.flags() & MethodRevisioned) == 0)
2461#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
2462 if (priv(mobj->d.data)->revision < 13) {
2464 int offset = priv(mobj->d.data)->methodData
2465 + priv(mobj->d.data)->methodCount * Data::Size
2466 + QMetaMethodPrivate::get(
this)->ownMethodIndex();
2467 return mobj->d.data[offset];
2471 return mobj->d.data[data.parameters() - 1];
2475
2476
2477
2478
2479
2480
2481
2482bool QMetaMethod::isConst()
const
2486 if (QMetaObjectPrivate::get(mobj)->revision < 10)
2488 return data.flags() & MethodIsConst;
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501QMetaMethod::Access QMetaMethod::access()
const
2503 constexpr int AccessShift = qCountTrailingZeroBits(AccessMask);
2504 static_assert(AccessPrivate >> AccessShift == Private);
2505 static_assert(AccessProtected >> AccessShift == Protected);
2506 static_assert(AccessPublic >> AccessShift == Public);
2509 return Access((data.flags() & AccessMask) >> AccessShift);
2513
2514
2515
2516
2517QMetaMethod::MethodType QMetaMethod::methodType()
const
2519 constexpr int MethodShift = qCountTrailingZeroBits(MethodTypeMask);
2520 static_assert(MethodMethod >> MethodShift == Method);
2521 static_assert(MethodSignal >> MethodShift == Signal);
2522 static_assert(MethodSlot >> MethodShift == Slot);
2523 static_assert(MethodConstructor >> MethodShift == Constructor);
2525 return QMetaMethod::Method;
2526 return MethodType((data.flags() & MethodTypeMask) >> MethodShift);
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2542
2543
2544
2545
2546
2547
2548
2549QMetaMethod QMetaMethod::fromSignalImpl(
const QMetaObject *metaObject,
void **signal)
2552 void *args[] = { &i, signal };
2553 for (
const QMetaObject *m = metaObject; m; m = m->d.superdata) {
2554 m->static_metacall(QMetaObject::IndexOfMethod, 0, args);
2556 return QMetaMethod::fromRelativeMethodIndex(m, i);
2558 return QMetaMethod();
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
2638
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
2672
2673bool QMetaMethod::invoke(QObject *object,
2674 Qt::ConnectionType connectionType,
2675 QGenericReturnArgument returnValue,
2676 QGenericArgument val0,
2677 QGenericArgument val1,
2678 QGenericArgument val2,
2679 QGenericArgument val3,
2680 QGenericArgument val4,
2681 QGenericArgument val5,
2682 QGenericArgument val6,
2683 QGenericArgument val7,
2684 QGenericArgument val8,
2685 QGenericArgument val9)
const
2687 if (!object || !mobj)
2691 const char *typeNames[] = {
2719 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
2720 if (qstrlen(typeNames[paramCount]) <= 0)
2723 return invokeImpl(*
this, object, connectionType, paramCount, param, typeNames,
nullptr);
2726bool QMetaMethod::invokeImpl(QMetaMethod self,
void *target, Qt::ConnectionType connectionType,
2727 qsizetype paramCount,
const void *
const *parameters,
2728 const char *
const *typeNames,
2729 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
2731 if (!target || !self.mobj)
2733 QMetaMethodPrivate::InvokeFailReason r =
2734 QMetaMethodPrivate::invokeImpl(self, target, connectionType, paramCount, parameters,
2735 typeNames, metaTypes);
2736 if (Q_LIKELY(r == QMetaMethodPrivate::InvokeFailReason::None))
2739 if (
int(r) >=
int(QMetaMethodPrivate::InvokeFailReason::FormalParameterMismatch)) {
2740 int n =
int(r) -
int(QMetaMethodPrivate::InvokeFailReason::FormalParameterMismatch);
2741 qWarning(
"QMetaMethod::invoke: cannot convert formal parameter %d from %s in call to %s::%s",
2742 n, typeNames[n + 1] ? typeNames[n + 1] : metaTypes[n + 1]->name,
2743 self.mobj->className(), self.methodSignature().constData());
2745 if (r == QMetaMethodPrivate::InvokeFailReason::TooFewArguments) {
2746 qWarning(
"QMetaMethod::invoke: too few arguments (%d) in call to %s::%s",
2747 int(paramCount), self.mobj->className(), self.methodSignature().constData());
2753 Qt::ConnectionType connectionType,
2754 qsizetype paramCount,
const void *
const *parameters,
2755 const char *
const *typeNames,
2758 auto object =
static_cast<QObject *>(target);
2759 auto priv = QMetaMethodPrivate::get(&self);
2760 constexpr bool MetaTypesAreOptional = QT_VERSION < QT_VERSION_CHECK(7, 0, 0);
2761 auto methodMetaTypes = priv->parameterMetaTypeInterfaces();
2762 auto param =
const_cast<
void **>(parameters);
2764 Q_ASSERT(priv->mobj);
2765 Q_ASSERT(self.methodType() == Constructor || object);
2766 Q_ASSERT(self.methodType() == Constructor || connectionType == Qt::ConnectionType(-1) ||
2767 priv->mobj->cast(object));
2768 Q_ASSERT(paramCount >= 1);
2769 Q_ASSERT(parameters);
2770 Q_ASSERT(typeNames);
2771 Q_ASSERT(MetaTypesAreOptional || metaTypes);
2773 if ((paramCount - 1) < qsizetype(priv->data.argc()))
2777 auto checkTypesAreCompatible = [=](
int idx) {
2778 uint typeInfo = priv->parameterTypeInfo(idx - 1);
2779 QByteArrayView userTypeName(typeNames[idx] ? typeNames[idx] : metaTypes[idx]
->name);
2781 if ((typeInfo & IsUnresolvedType) == 0) {
2783 if (MetaTypesAreOptional && !metaTypes)
2784 return int(typeInfo) == QMetaType::fromName(userTypeName).rawId();
2785 return int(typeInfo) == metaTypes[idx]->typeId;
2788 QByteArrayView methodTypeName = stringDataView(priv->mobj, typeInfo & TypeNameIndexMask);
2789 if ((MetaTypesAreOptional && !metaTypes) || !metaTypes[idx]) {
2791 if (methodTypeName == userTypeName)
2795 QByteArray normalized = normalizeTypeInternal(userTypeName.begin(), userTypeName.end());
2796 return methodTypeName == normalized;
2800 Q_ASSERT(userType.isValid());
2801 if (QMetaType(methodMetaTypes[idx - 1]) == userType)
2806 if (methodMetaTypes[idx - 1])
2810 QMetaType resolved = QMetaType::fromName(methodTypeName);
2811 return resolved == userType;
2815 for (qsizetype i = 0; metaTypes && i < paramCount; ++i)
2819 for (qsizetype i = 1; i < paramCount; ++i) {
2820 if (!checkTypesAreCompatible(i))
2825 if (self.methodType() == Constructor) {
2827 qWarning(
"QMetaMethod::invokeMethod: cannot call constructor %s on object %p",
2828 self.methodSignature().constData(), object);
2832 if (!parameters[0]) {
2833 qWarning(
"QMetaMethod::invokeMethod: constructor call to %s must assign a return type",
2834 self.methodSignature().constData());
2838 if (!MetaTypesAreOptional || metaTypes) {
2839 if (metaTypes[0]->typeId != QMetaType::QObjectStar) {
2840 qWarning(
"QMetaMethod::invokeMethod: cannot convert QObject* to %s on constructor call %s",
2841 metaTypes[0]
->name, self.methodSignature().constData());
2846 int idx = priv->ownConstructorMethodIndex();
2847 if (priv->mobj->static_metacall(QMetaObject::CreateInstance, idx, param) >= 0)
2853 if (parameters[0]) {
2854 if (!checkTypesAreCompatible(0)) {
2855 const char *retType = typeNames[0] ? typeNames[0] : metaTypes[0]
->name;
2856 qWarning(
"QMetaMethod::invokeMethod: return type mismatch for method %s::%s:"
2857 " cannot convert from %s to %s during invocation",
2858 priv->mobj->className(), priv->methodSignature().constData(),
2859 priv->rawReturnTypeName(), retType);
2864 Qt::HANDLE currentThreadId =
nullptr;
2865 QThread *objectThread =
nullptr;
2866 auto receiverInSameThread = [&]() {
2867 if (!currentThreadId) {
2868 currentThreadId = QThread::currentThreadId();
2869 objectThread = object->thread();
2872 return currentThreadId == QThreadData::get2(objectThread)->threadId.loadRelaxed();
2877 if (connectionType == Qt::AutoConnection)
2878 connectionType = receiverInSameThread() ? Qt::DirectConnection : Qt::QueuedConnection;
2879 else if (connectionType == Qt::ConnectionType(-1))
2880 connectionType = Qt::DirectConnection;
2882#if !QT_CONFIG(thread)
2883 if (connectionType == Qt::BlockingQueuedConnection) {
2884 connectionType = Qt::DirectConnection;
2889 int idx_relative = priv->ownMethodIndex();
2890 int idx_offset = priv->mobj->methodOffset();
2891 QObjectPrivate::StaticMetaCallFunction callFunction = priv->mobj->d.static_metacall;
2893 if (connectionType == Qt::DirectConnection) {
2895 callFunction(object, QMetaObject::InvokeMetaMethod, idx_relative, param);
2896 else if (QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, idx_relative + idx_offset, param) >= 0)
2898 }
else if (connectionType == Qt::QueuedConnection) {
2899 if (parameters[0]) {
2900 qWarning(
"QMetaMethod::invoke: Unable to invoke methods with return values in "
2901 "queued connections");
2905 QVarLengthArray<
const QtPrivate::QMetaTypeInterface *, 16> argTypes;
2906 argTypes.reserve(paramCount);
2907 argTypes.emplace_back(
nullptr);
2909 for (
int i = 1; i < paramCount; ++i) {
2910 QMetaType type = QMetaType(methodMetaTypes[i - 1]);
2911 if (!type.iface() && (!MetaTypesAreOptional || metaTypes))
2912 type = QMetaType(metaTypes[i]);
2914 type = priv->parameterMetaType(i - 1);
2915 if (!type.iface() && typeNames[i])
2916 type = QMetaType::fromName(typeNames[i]);
2917 if (!type.iface()) {
2918 qWarning(
"QMetaMethod::invoke: Unable to handle unregistered datatype '%s'",
2922 argTypes.emplace_back(type.iface());
2925 QCoreApplication::postEvent(object,
new QQueuedMetaCallEvent(idx_offset, idx_relative, callFunction,
nullptr,
2926 -1, paramCount, argTypes.data(), parameters));
2928#if QT_CONFIG(thread)
2929 if (receiverInSameThread()) {
2930 qWarning(
"QMetaMethod::invoke: Dead lock detected in BlockingQueuedConnection: "
2931 "Receiver is %s(%p)", priv->mobj->className(), object);
2932 return InvokeFailReason::DeadLockDetected;
2936 QCoreApplication::postEvent(object,
new QMetaCallEvent(idx_offset, idx_relative, callFunction,
2937 nullptr, -1, param, &latch));
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047bool QMetaMethod::invokeOnGadget(
void *gadget,
3048 QGenericReturnArgument returnValue,
3049 QGenericArgument val0,
3050 QGenericArgument val1,
3051 QGenericArgument val2,
3052 QGenericArgument val3,
3053 QGenericArgument val4,
3054 QGenericArgument val5,
3055 QGenericArgument val6,
3056 QGenericArgument val7,
3057 QGenericArgument val8,
3058 QGenericArgument val9)
const
3060 if (!gadget || !mobj)
3064 if (returnValue.data()) {
3065 const char *retType = typeName();
3066 if (qstrcmp(returnValue.name(), retType) != 0) {
3068 QByteArray normalized = QMetaObject::normalizedType(returnValue.name());
3069 if (qstrcmp(normalized.constData(), retType) != 0) {
3071 int t = returnType();
3072 if (t == QMetaType::UnknownType || t != QMetaType::fromName(normalized).rawId())
3079 const char *typeNames[] = {
3093 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
3094 if (qstrlen(typeNames[paramCount]) <= 0)
3097 if (paramCount <= QMetaMethodPrivate::get(
this)->parameterCount())
3114 int idx_relative = QMetaMethodPrivate::get(
this)->ownMethodIndex();
3115 Q_ASSERT(QMetaObjectPrivate::get(mobj)->revision >= 6);
3116 QObjectPrivate::StaticMetaCallFunction callFunction = mobj->d.static_metacall;
3119 callFunction(
reinterpret_cast<QObject*>(gadget), QMetaObject::InvokeMetaMethod, idx_relative, param);
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
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
3177
3180
3181
3182
3183
3184
3185
3186
3189
3190
3191
3195
3196
3197
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210const char *QMetaEnum::name()
const
3214 return rawStringData(mobj, data.name());
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229const char *QMetaEnum::enumName()
const
3233 return rawStringData(mobj, data.alias());
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248QMetaType QMetaEnum::metaType()
const
3253 const QMetaObjectPrivate *p = priv(mobj->d.data);
3254#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
3255 if (p->revision < 12)
3259 QMetaType mt(mobj->d.metaTypes[data.index(mobj) + p->propertyCount]);
3265
3266
3267
3268
3269int QMetaEnum::keyCount()
const
3273 return data.keyCount();
3277
3278
3279
3280
3281const char *QMetaEnum::key(
int index)
const
3285 if (index >= 0 && index <
int(data.keyCount()))
3286 return rawStringData(mobj, mobj->d.data[data.data() + 2*index]);
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300int QMetaEnum::value(
int index)
const
3302 return value64(index).value_or(-1);
3310Q_DECL_PURE_FUNCTION
static inline EnumExtendMode enumExtendMode(
const QMetaEnum &e)
3316 if (e.metaType().flags() & QMetaType::IsUnsignedEnumeration)
3328 return value == uint(value);
3329 return value == quint64(
int(value));
3332template <
typename... Mode>
inline
3333quint64 QMetaEnum::value_helper(uint index, Mode... modes)
const noexcept
3335 static_assert(
sizeof...(Mode) < 2);
3336 if constexpr (
sizeof...(Mode) == 0) {
3337 return value_helper(index, enumExtendMode(*
this));
3338 }
else if constexpr (
sizeof...(Mode) == 1) {
3339 auto mode = (modes, ...);
3340 quint64 value = mobj->d.data[data.data() + 2U * index + 1];
3342 value |= quint64(mobj->d.data[data.data() + 2U * data.keyCount() + index]) << 32;
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371std::optional<quint64> QMetaEnum::value64(
int index)
const
3374 return std::nullopt;
3375 if (index < 0 || index >=
int(data.keyCount()))
3376 return std::nullopt;
3378 return value_helper(index);
3382
3383
3384
3385
3386
3387
3388
3389
3390bool QMetaEnum::isFlag()
const
3394 return data.flags() & EnumIsFlag;
3398
3399
3400
3401
3402
3403bool QMetaEnum::isScoped()
const
3407 return data.flags() & EnumIsScoped;
3411
3412
3413
3414
3415
3416
3417bool QMetaEnum::is64Bit()
const
3421 return data.flags() & EnumIs64Bit;
3425
3426
3427
3428
3429
3430
3431
3432const char *QMetaEnum::scope()
const
3434 return mobj ? mobj->className() :
nullptr;
3439 const QByteArrayView className = e->enclosingMetaObject()->className();
3444 if (scope == className)
3450 QByteArrayView name = e->enumName();
3454 const auto sz = className.size();
3455 if (scope.size() == sz + qsizetype(qstrlen(
"::")) + name.size()
3456 && scope.startsWith(className)
3457 && scope.sliced(sz, 2) ==
"::"
3458 && scope.sliced(sz + 2) == name)
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479int QMetaEnum::keyToValue(
const char *key,
bool *ok)
const
3481 auto value = keyToValue64(key);
3483 *ok = value.has_value();
3484 return int(value.value_or(-1));
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499std::optional<quint64> QMetaEnum::keyToValue64(
const char *key)
const
3502 return std::nullopt;
3503 const auto [scope, enumKey] = parse_scope(QLatin1StringView(key));
3504 for (
int i = 0; i <
int(data.keyCount()); ++i) {
3505 if ((!scope || isScopeMatch(*scope,
this))
3506 && enumKey == stringDataView(mobj, mobj->d.data[data.data() + 2 * i])) {
3507 return value_helper(i);
3510 return std::nullopt;
3514
3515
3516
3517
3518
3519
3520
3521const char *QMetaEnum::valueToKey(quint64 value)
const
3526 EnumExtendMode mode = enumExtendMode(*
this);
3527 if (!isEnumValueSuitable(value, mode))
3530 for (
int i = 0; i <
int(data.keyCount()); ++i) {
3531 if (value == value_helper(i, mode))
3532 return rawStringData(mobj, mobj->d.data[data.data() + 2 * i]);
3537static bool parseEnumFlags(QByteArrayView v, QVarLengthArray<QByteArrayView, 10> &list)
3541 qWarning(
"QMetaEnum::keysToValue: empty keys string.");
3545 qsizetype sep = v.indexOf(
'|', 0);
3547 qWarning(
"QMetaEnum::keysToValue: malformed keys string, starts with '|', \"%s\"",
3557 if (v.endsWith(
'|')) {
3558 qWarning(
"QMetaEnum::keysToValue: malformed keys string, ends with '|', \"%s\"",
3563 const auto begin = v.begin();
3564 const auto end = v.end();
3566 for (; b != end && sep != -1; sep = v.indexOf(
'|', sep)) {
3567 list.push_back({b, begin + sep});
3571 qWarning(
"QMetaEnum::keysToValue: malformed keys string, has two consecutive '|': "
3572 "\"%s\"", v.constData());
3578 list.push_back({b, end});
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596int QMetaEnum::keysToValue(
const char *keys,
bool *ok)
const
3598 auto value = keysToValue64(keys);
3600 *ok = value.has_value();
3601 return int(value.value_or(-1));
3605
3606
3607
3608
3609
3610
3611
3612
3613std::optional<quint64> QMetaEnum::keysToValue64(
const char *keys)
const
3616 return std::nullopt;
3618 EnumExtendMode mode = enumExtendMode(*
this);
3619 auto lookup = [&] (QByteArrayView key) -> std::optional<quint64> {
3620 for (
int i = data.keyCount() - 1; i >= 0; --i) {
3621 if (key == stringDataView(mobj, mobj->d.data[data.data() + 2*i]))
3622 return value_helper(i, mode);
3624 return std::nullopt;
3628 QVarLengthArray<QByteArrayView, 10> list;
3629 const bool r = parseEnumFlags(QByteArrayView{keys}, list);
3631 return std::nullopt;
3632 for (
const auto &untrimmed : list) {
3633 const auto parsed = parse_scope(untrimmed.trimmed());
3634 if (parsed.scope && !isScopeMatch(*parsed.scope,
this))
3635 return std::nullopt;
3636 if (
auto thisValue = lookup(parsed.key))
3637 value |= *thisValue;
3639 return std::nullopt;
3646template <
typename String,
typename Container,
typename Separator>
3647void join_reversed(String &s,
const Container &c, Separator sep)
3651 qsizetype len = qsizetype(c.size()) - 1;
3653 len += qsizetype(e.size());
3656 for (
auto rit = c.rbegin(), rend = c.rend(); rit != rend; ++rit) {
3657 const auto &e = *rit;
3661 s.append(e.data(), e.size());
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676QByteArray QMetaEnum::valueToKeys(quint64 value)
const
3682 EnumExtendMode mode = enumExtendMode(*
this);
3683 if (!isEnumValueSuitable(value, mode))
3686 QVarLengthArray<QByteArrayView,
sizeof(
int) * CHAR_BIT> parts;
3690 for (
int i = data.keyCount() - 1; i >= 0; --i) {
3691 quint64 k = value_helper(i, mode);
3692 if ((k != 0 && (v & k) == k) || (k == value)) {
3694 parts.push_back(stringDataView(mobj, mobj->d.data[data.data() + 2 * i]));
3697 join_reversed(keys, parts,
'|');
3702
3703
3704QMetaEnum::QMetaEnum(
const QMetaObject *mobj,
int index)
3705 : mobj(mobj), data({ mobj->d.data + priv(mobj->d.data)->enumeratorData + index * Data::Size })
3707 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->enumeratorCount);
3710int QMetaEnum::Data::index(
const QMetaObject *mobj)
const
3712#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
3713# warning "Consider changing Size to a power of 2"
3715 return (
unsigned(d - mobj->d.data) - priv(mobj->d.data)->enumeratorData) / Size;
3719
3720
3721
3722
3723
3724
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
3760
3763
3764
3765
3766
3767
3768
3769
3772
3773
3774
3777
3778
3779
3782
3783
3784
3785
3786const char *QMetaProperty::name()
const
3790 return rawStringData(mobj, data.name());
3794
3795
3796
3797
3798const char *QMetaProperty::typeName()
const
3803 if (
const auto mt = metaType(); mt.isValid())
3805 return typeNameFromTypeInfo(mobj, data.type()).constData();
3809
3810
3811
3812
3813
3814
3815
3818
3819
3820
3821
3822
3823
3824
3825
3826
3829
3830
3831
3832
3833
3834
3835
3838
3839
3840
3841
3842
3843
3844QMetaType QMetaProperty::metaType()
const
3848 QMetaType mt(mobj->d.metaTypes[data.index(mobj)]);
3853int QMetaProperty::Data::index(
const QMetaObject *mobj)
const
3855#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
3856# warning "Consider changing Size to a power of 2"
3858 return (
unsigned(d - mobj->d.data) - priv(mobj->d.data)->propertyData) / Size;
3862
3863
3864
3865
3866int QMetaProperty::propertyIndex()
const
3870 return data.index(mobj) + mobj->propertyOffset();
3874
3875
3876
3877
3878int QMetaProperty::relativePropertyIndex()
const
3882 return data.index(mobj);
3886
3887
3888
3889
3890
3891
3892
3893
3895bool QMetaProperty::isFlagType()
const
3897 return isEnumType() && menum.isFlag();
3901
3902
3903
3904
3905
3906bool QMetaProperty::isEnumType()
const
3910 return (data.flags() & EnumOrFlag) && menum.name();
3914
3915
3916
3917
3918
3919
3920
3921
3922bool QMetaProperty::hasStdCppSet()
const
3926 return (data.flags() & StdCppSet);
3930
3931
3932
3933
3934
3935
3936bool QMetaProperty::isAlias()
const
3940 return (data.flags() & Alias);
3943#if QT_DEPRECATED_SINCE(6
, 4
)
3945
3946
3947
3948
3949
3950
3951
3952int QMetaProperty::registerPropertyType()
const
3958QMetaProperty::QMetaProperty(
const QMetaObject *mobj,
int index)
3960 data(getMetaPropertyData(mobj, index))
3962 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->propertyCount);
3964 if (!(data.flags() & EnumOrFlag) || !metaType().flags().testFlag(QMetaType::IsEnumeration))
3966 QByteArrayView enum_name = typeNameFromTypeInfo(mobj, data.type());
3967 menum = mobj->enumerator(QMetaObjectPrivate::indexOfEnumerator(mobj, enum_name));
3968 if (menum.isValid())
3971 QByteArrayView scope_name;
3972 const auto parsed = parse_scope(enum_name);
3974 scope_name = *parsed.scope;
3975 enum_name = parsed.key;
3977 scope_name = objectClassName(mobj);
3980 const QMetaObject *scope =
nullptr;
3981 if (scope_name ==
"Qt")
3982 scope = &Qt::staticMetaObject;
3984 scope = QMetaObject_findMetaObject(mobj, QByteArrayView(scope_name));
3987 menum = scope->enumerator(QMetaObjectPrivate::indexOfEnumerator(scope, enum_name));
3991
3992
3993
3994QMetaProperty::Data QMetaProperty::getMetaPropertyData(
const QMetaObject *mobj,
int index)
3996 return { mobj->d.data + priv(mobj->d.data)->propertyData + index * Data::Size };
4000
4001
4002
4003
4004
4005QMetaEnum QMetaProperty::enumerator()
const
4011
4012
4013
4014
4015
4016QVariant QMetaProperty::read(
const QObject *object)
const
4018 if (!object || !mobj)
4028 void *argv[] = {
nullptr, &value, &status };
4029 QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
4030 if (t == QMetaType::fromType<QVariant>()) {
4033 value = QVariant(t,
nullptr);
4034 argv[0] = value.data();
4036 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) {
4037 mobj->d.static_metacall(
const_cast<QObject*>(object), QMetaObject::ReadProperty, data.index(mobj), argv);
4039 QMetaObject::metacall(
const_cast<QObject*>(object), QMetaObject::ReadProperty,
4040 data.index(mobj) + mobj->propertyOffset(), argv);
4045 if (t != QMetaType::fromType<QVariant>() && argv[0] != value.data())
4047 return QVariant(t, argv[0]);
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065bool QMetaProperty::write(QObject *object,
const QVariant &value)
const
4067 if (!object || !isWritable())
4069 return write(object, QVariant(value));
4073
4074
4075
4076bool QMetaProperty::write(QObject *object, QVariant &&v)
const
4078 if (!object || !isWritable())
4080 QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
4081 if (t != QMetaType::fromType<QVariant>() && t != v.metaType()) {
4082 if (isEnumType() && !t.metaObject() && v.metaType() == QMetaType::fromType<QString>()) {
4086 std::optional value = isFlagType() ? menum.keysToValue64(v.toByteArray())
4087 : menum.keyToValue64(v.toByteArray());
4089 v = QVariant(qlonglong(*value));
4096 return reset(object);
4097 v = QVariant(t,
nullptr);
4098 }
else if (!v.convert(t)) {
4111 void *argv[] = {
nullptr, &v, &status, &flags };
4112 if (t == QMetaType::fromType<QVariant>())
4116 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
4117 mobj->d.static_metacall(object, QMetaObject::WriteProperty, data.index(mobj), argv);
4119 QMetaObject::metacall(object, QMetaObject::WriteProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4125
4126
4127
4128
4129
4130
4131
4132bool QMetaProperty::reset(QObject *object)
const
4134 if (!object || !mobj || !isResettable())
4136 void *argv[] = {
nullptr };
4137 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
4138 mobj->d.static_metacall(object, QMetaObject::ResetProperty, data.index(mobj), argv);
4140 QMetaObject::metacall(object, QMetaObject::ResetProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4145
4146
4147
4148
4149
4150
4151
4152
4153QUntypedBindable QMetaProperty::bindable(QObject *object)
const
4155 QUntypedBindable bindable;
4156 void * argv[1] { &bindable };
4157 mobj->metacall(object, QMetaObject::BindableProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4161
4162
4163
4164
4165
4166
4167
4168QVariant QMetaProperty::readOnGadget(
const void *gadget)
const
4170 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4171 return read(
reinterpret_cast<
const QObject*>(gadget));
4175
4176
4177
4178
4179
4180
4181
4182bool QMetaProperty::writeOnGadget(
void *gadget,
const QVariant &value)
const
4184 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4185 return write(
reinterpret_cast<QObject*>(gadget), value);
4189
4190
4191
4192bool QMetaProperty::writeOnGadget(
void *gadget, QVariant &&value)
const
4194 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4195 return write(
reinterpret_cast<QObject*>(gadget), std::move(value));
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208bool QMetaProperty::resetOnGadget(
void *gadget)
const
4210 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4211 return reset(
reinterpret_cast<QObject*>(gadget));
4215
4216
4217
4218
4219
4220bool QMetaProperty::isResettable()
const
4224 return data.flags() & Resettable;
4228
4229
4230
4231
4232bool QMetaProperty::isReadable()
const
4236 return data.flags() & Readable;
4240
4241
4242
4243
4244
4245bool QMetaProperty::hasNotifySignal()
const
4249 return data.notifyIndex() != uint(-1);
4253
4254
4255
4256
4257
4258
4259
4260QMetaMethod QMetaProperty::notifySignal()
const
4262 int id = notifySignalIndex();
4264 return mobj->method(id);
4266 return QMetaMethod();
4270
4271
4272
4273
4274
4275
4276
4277int QMetaProperty::notifySignalIndex()
const
4279 if (!mobj || data.notifyIndex() == std::numeric_limits<uint>::max())
4281 uint methodIndex = data.notifyIndex();
4282 if (!(methodIndex & IsUnresolvedSignal))
4283 return methodIndex + mobj->methodOffset();
4284 methodIndex &= ~IsUnresolvedSignal;
4285 const QByteArrayView signalName = stringDataView(mobj, methodIndex);
4286 const QMetaObject *m = mobj;
4288 int idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, {}, QMetaMethod::Signal);
4290 return idx + m->methodOffset();
4292 QArgumentType argType[] = {metaType()};
4293 idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, argType, QMetaMethod::Signal);
4295 return idx + m->methodOffset();
4296 qWarning(
"QMetaProperty::notifySignal: cannot find the NOTIFY signal %s in class %s for property '%s'",
4297 signalName.constData(), mobj->className(), name());
4303
4304
4305
4306
4307
4308
4309int QMetaProperty::revision()
const
4313 return data.revision();
4317
4318
4319
4320
4321
4322bool QMetaProperty::isWritable()
const
4326 return data.flags() & Writable;
4330
4331
4332
4333
4334
4335bool QMetaProperty::isDesignable()
const
4339 return data.flags() & Designable;
4343
4344
4345
4346
4347
4348bool QMetaProperty::isScriptable()
const
4352 return data.flags() & Scriptable;
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365bool QMetaProperty::isStored()
const
4369 return data.flags() & Stored;
4373
4374
4375
4376
4377
4378
4379
4380bool QMetaProperty::isUser()
const
4384 return data.flags() & User;
4388
4389
4390
4391
4392
4393
4394bool QMetaProperty::isConstant()
const
4398 return data.flags() & Constant;
4402
4403
4404
4405
4406
4407
4408bool QMetaProperty::isFinal()
const
4412 return data.flags() & Final;
4416
4417
4418
4419
4420
4421
4422bool QMetaProperty::isVirtual()
const
4426 return data.flags() & Virtual;
4430
4431
4432
4433
4434
4435
4436bool QMetaProperty::isOverride()
const
4440 return data.flags() & Override;
4444
4445
4446
4447
4448
4449
4450bool QMetaProperty::isRequired()
const
4454 return data.flags() & Required;
4458
4459
4460
4461
4462
4463
4464
4465
4466bool QMetaProperty::isBindable()
const
4470 return (data.flags() & Bindable);
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4498
4499
4500
4503
4504
4505
4508
4509
4510
4511
4512const char *QMetaClassInfo::name()
const
4516 return rawStringData(mobj, data.name());
4520
4521
4522
4523
4524const char *QMetaClassInfo::value()
const
4528 return rawStringData(mobj, data.value());
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4546
4547
4548
4549
4550
4551
4552
4553
4554
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4582
4583
4584
4585
4588
4589
4590
4591
4594
4595
4596
4597
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4613
4614
4615
4616
4617
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4633 Q_ASSERT(local_method_index < get(mobj)->methodCount);
4634 while (QMetaMethod::fromRelativeMethodIndex(mobj, local_method_index).data.flags() & MethodCloned) {
4635 Q_ASSERT(local_method_index > 0);
4636 --local_method_index;
4638 return local_method_index;
4642
4643
4644
4645
4646
4647
4648
4649
4652 QVarLengthArray<QByteArrayView, 10> &typeNames)
4654 const char *signature =
static_cast<
const char *>(memchr(sig.begin(),
'(', sig.size()));
4657 auto name = QByteArrayView{sig.begin(), signature};
4659 if (!sig.endsWith(
')'))
4661 const char *end = sig.end() - 1;
4662 while (signature != end) {
4663 if (*signature ==
',')
4665 const char *begin = signature;
4667 while (signature != end && (level > 0 || *signature !=
',')) {
4668 if (*signature ==
'<')
4670 else if (*signature ==
'>')
4674 typeNames.append(QByteArrayView{begin, signature - begin});