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
1984
1985
1989 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
1991 result.reserve(256);
1994 QList<QByteArray> argTypes = parameterTypes();
1995 for (
int i = 0; i < argTypes.size(); ++i) {
1998 result += argTypes.at(i);
2004QByteArrayView QMetaMethodPrivate::name()
const noexcept
2006 QByteArrayView name = qualifiedName();
2007 if (qsizetype colon = name.lastIndexOf(
':'); colon > 0)
2008 return name.sliced(colon + 1);
2012QByteArrayView QMetaMethodPrivate::qualifiedName()
const noexcept
2014 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2015 return stringDataView(mobj, data.name());
2018int QMetaMethodPrivate::typesDataIndex()
const
2020 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2021 return data.parameters();
2024const char *QMetaMethodPrivate::rawReturnTypeName()
const
2026 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2027 uint typeInfo = mobj->d.data[typesDataIndex()];
2028 if (typeInfo & IsUnresolvedType)
2029 return rawStringData(mobj, typeInfo & TypeNameIndexMask);
2031 return QMetaType(typeInfo).name();
2034int QMetaMethodPrivate::returnType()
const
2036 return parameterType(-1);
2039int QMetaMethodPrivate::parameterCount()
const
2041 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2049 uint typeInfo = parameterTypeInfo(index);
2052 if ((typeInfo & IsUnresolvedType) == 0)
2053 Q_ASSERT(mt.rawId() ==
int(typeInfo & TypeNameIndexMask));
2054 Q_ASSERT(mt.name());
2060#define ASSERT_NOT_PRIMITIVE_TYPE(TYPE, METATYPEID, NAME)
2061 Q_ASSERT(typeInfo != QMetaType::TYPE);
2063#undef ASSERT_NOT_PRIMITIVE_TYPE
2064 Q_ASSERT(typeInfo != QMetaType::QObjectStar);
2067 if (priv(mobj->d.data)->revision >= 11) {
2068 Q_ASSERT(typeInfo != QMetaType::Void);
2069 Q_ASSERT(typeInfo != QMetaType::VoidStar);
2074int QMetaMethodPrivate::parametersDataIndex()
const
2076 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2077 return typesDataIndex() + 1;
2080uint QMetaMethodPrivate::parameterTypeInfo(
int index)
const
2082 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2083 return mobj->d.data[parametersDataIndex() + index];
2088 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2089 if (methodType() == QMetaMethod::Constructor)
2093 checkMethodMetaTypeConsistency(iface, -1);
2099 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2100 int offset = (methodType() == QMetaMethod::Constructor ? 0 : 1);
2101 const auto ifaces = &mobj->d.metaTypes[data.metaTypeOffset() + offset];
2103 for (
int i = 0; i < parameterCount(); ++i)
2104 checkMethodMetaTypeConsistency(ifaces[i], i);
2109int QMetaMethodPrivate::parameterType(
int index)
const
2111 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2112 return typeFromTypeInfo(mobj, parameterTypeInfo(index));
2115void QMetaMethodPrivate::getParameterTypes(
int *types)
const
2117 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2118 int dataIndex = parametersDataIndex();
2119 int argc = parameterCount();
2120 for (
int i = 0; i < argc; ++i) {
2121 int id = typeFromTypeInfo(mobj, mobj->d.data[dataIndex++]);
2126QByteArrayView QMetaMethodPrivate::parameterTypeName(
int index)
const noexcept
2128 int paramsIndex = parametersDataIndex();
2129 return typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + index]);
2132QList<QByteArray> QMetaMethodPrivate::parameterTypes()
const
2134 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2135 int argc = parameterCount();
2136 QList<QByteArray> list;
2138 int paramsIndex = parametersDataIndex();
2139 for (
int i = 0; i < argc; ++i) {
2140 QByteArrayView name = typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + i]);
2141 list.emplace_back(name.toByteArray());
2146QList<QByteArray> QMetaMethodPrivate::parameterNames()
const
2148 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2149 int argc = parameterCount();
2150 QList<QByteArray> list;
2152 int namesIndex = parametersDataIndex() + argc;
2153 for (
int i = 0; i < argc; ++i)
2154 list += stringData(mobj, mobj->d.data[namesIndex + i]);
2158const char *QMetaMethodPrivate::tag()
const
2160 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2161 return rawStringData(mobj, data.tag());
2164int QMetaMethodPrivate::ownMethodIndex()
const
2167 return ( data.d - mobj->d.data - priv(mobj->d.data)->methodData)/Data::Size;
2170int QMetaMethodPrivate::ownConstructorMethodIndex()
const
2173 Q_ASSERT(methodType() == Constructor);
2174 return ( data.d - mobj->d.data - priv(mobj->d.data)->constructorData)/Data::Size;
2178
2179
2180
2181
2182
2183
2184
2185QByteArray QMetaMethod::methodSignature()
const
2188 return QByteArray();
2189 return QMetaMethodPrivate::get(
this)->signature();
2193
2194
2195
2196
2197
2198
2199QByteArray QMetaMethod::name()
const
2202 return QByteArray();
2204 return stringData(mobj, QMetaMethodPrivate::get(
this)->name());
2208
2209
2210
2211
2212
2213
2214
2215
2216QByteArrayView QMetaMethod::nameView()
const
2218 return QMetaMethodPrivate::get(
this)->name();
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231int QMetaMethod::returnType()
const
2233 return returnMetaType().rawId();
2237
2238
2239
2240
2241
2242QMetaType QMetaMethod::returnMetaType()
const
2244 if (!mobj || methodType() == QMetaMethod::Constructor)
2246 auto mt = QMetaType(mobj->d.metaTypes[data.metaTypeOffset()]);
2248 mt = QMetaType(QMetaMethodPrivate::get(
this)->returnType());
2254
2255
2256
2257
2258
2259
2260int QMetaMethod::parameterCount()
const
2264 return QMetaMethodPrivate::get(
this)->parameterCount();
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277int QMetaMethod::parameterType(
int index)
const
2279 return parameterMetaType(index).rawId();
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292QMetaType QMetaMethod::parameterMetaType(
int index)
const
2294 if (!mobj || index < 0)
2296 auto priv = QMetaMethodPrivate::get(
this);
2297 if (index >= priv->parameterCount())
2300 auto parameterOffset = index + (methodType() == QMetaMethod::Constructor ? 0 : 1);
2301 auto mt = QMetaType(mobj->d.metaTypes[data.metaTypeOffset() + parameterOffset]);
2303 mt = QMetaType(QMetaMethodPrivate::get(
this)->parameterType(index));
2309
2310
2311
2312
2313
2314
2315
2316
2317void QMetaMethod::getParameterTypes(
int *types)
const
2321 QMetaMethodPrivate::get(
this)->getParameterTypes(types);
2325
2326
2327
2328
2329QList<QByteArray> QMetaMethod::parameterTypes()
const
2332 return QList<QByteArray>();
2333 return QMetaMethodPrivate::get(
this)->parameterTypes();
2337
2338
2339
2340
2341
2342
2343QByteArray QMetaMethod::parameterTypeName(
int index)
const
2345 if (!mobj || index < 0 || index >= parameterCount())
2348 return stringData(mobj, QMetaMethodPrivate::get(
this)->parameterTypeName(index));
2352
2353
2354
2355
2356QList<QByteArray> QMetaMethod::parameterNames()
const
2359 return QList<QByteArray>();
2360 return QMetaMethodPrivate::get(
this)->parameterNames();
2365
2366
2367
2368
2369
2370
2371
2372
2373const char *QMetaMethod::typeName()
const
2377#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
2378 if (methodType() == QMetaMethod::Constructor)
2381 return QMetaMethodPrivate::get(
this)->rawReturnTypeName();
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408const char *QMetaMethod::tag()
const
2412 return QMetaMethodPrivate::get(
this)->tag();
2417
2418
2419int QMetaMethod::attributes()
const
2423 return data.flags() >> 4;
2427
2428
2429
2430
2431int QMetaMethod::methodIndex()
const
2435 return QMetaMethodPrivate::get(
this)->ownMethodIndex() + mobj->methodOffset();
2439
2440
2441
2442
2443int QMetaMethod::relativeMethodIndex()
const
2447 return QMetaMethodPrivate::get(
this)->ownMethodIndex();
2452
2453
2454
2455
2456
2457int QMetaMethod::revision()
const
2461 if ((data.flags() & MethodRevisioned) == 0)
2463#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
2464 if (priv(mobj->d.data)->revision < 13) {
2466 int offset = priv(mobj->d.data)->methodData
2467 + priv(mobj->d.data)->methodCount * Data::Size
2468 + QMetaMethodPrivate::get(
this)->ownMethodIndex();
2469 return mobj->d.data[offset];
2473 return mobj->d.data[data.parameters() - 1];
2477
2478
2479
2480
2481
2482
2483
2484bool QMetaMethod::isConst()
const
2488 if (QMetaObjectPrivate::get(mobj)->revision < 10)
2490 return data.flags() & MethodIsConst;
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503QMetaMethod::Access QMetaMethod::access()
const
2505 constexpr int AccessShift = qCountTrailingZeroBits(AccessMask);
2506 static_assert(AccessPrivate >> AccessShift == Private);
2507 static_assert(AccessProtected >> AccessShift == Protected);
2508 static_assert(AccessPublic >> AccessShift == Public);
2511 return Access((data.flags() & AccessMask) >> AccessShift);
2515
2516
2517
2518
2519QMetaMethod::MethodType QMetaMethod::methodType()
const
2521 constexpr int MethodShift = qCountTrailingZeroBits(MethodTypeMask);
2522 static_assert(MethodMethod >> MethodShift == Method);
2523 static_assert(MethodSignal >> MethodShift == Signal);
2524 static_assert(MethodSlot >> MethodShift == Slot);
2525 static_assert(MethodConstructor >> MethodShift == Constructor);
2527 return QMetaMethod::Method;
2528 return MethodType((data.flags() & MethodTypeMask) >> MethodShift);
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2544
2545
2546
2547
2548
2549
2550
2551QMetaMethod QMetaMethod::fromSignalImpl(
const QMetaObject *metaObject,
void **signal)
2554 void *args[] = { &i, signal };
2555 for (
const QMetaObject *m = metaObject; m; m = m->d.superdata) {
2556 m->static_metacall(QMetaObject::IndexOfMethod, 0, args);
2558 return QMetaMethod::fromRelativeMethodIndex(m, i);
2560 return QMetaMethod();
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
2639
2640
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
2673
2674
2675bool QMetaMethod::invoke(QObject *object,
2676 Qt::ConnectionType connectionType,
2677 QGenericReturnArgument returnValue,
2678 QGenericArgument val0,
2679 QGenericArgument val1,
2680 QGenericArgument val2,
2681 QGenericArgument val3,
2682 QGenericArgument val4,
2683 QGenericArgument val5,
2684 QGenericArgument val6,
2685 QGenericArgument val7,
2686 QGenericArgument val8,
2687 QGenericArgument val9)
const
2689 if (!object || !mobj)
2693 const char *typeNames[] = {
2721 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
2722 if (qstrlen(typeNames[paramCount]) <= 0)
2725 return invokeImpl(*
this, object, connectionType, paramCount, param, typeNames,
nullptr);
2728bool QMetaMethod::invokeImpl(QMetaMethod self,
void *target, Qt::ConnectionType connectionType,
2729 qsizetype paramCount,
const void *
const *parameters,
2730 const char *
const *typeNames,
2731 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
2733 if (!target || !self.mobj)
2735 QMetaMethodPrivate::InvokeFailReason r =
2736 QMetaMethodPrivate::invokeImpl(self, target, connectionType, paramCount, parameters,
2737 typeNames, metaTypes);
2738 if (Q_LIKELY(r == QMetaMethodPrivate::InvokeFailReason::None))
2741 if (
int(r) >=
int(QMetaMethodPrivate::InvokeFailReason::FormalParameterMismatch)) {
2742 int n =
int(r) -
int(QMetaMethodPrivate::InvokeFailReason::FormalParameterMismatch);
2743 qWarning(
"QMetaMethod::invoke: cannot convert formal parameter %d from %s in call to %s::%s",
2744 n, typeNames[n + 1] ? typeNames[n + 1] : metaTypes[n + 1]->name,
2745 self.mobj->className(), self.methodSignature().constData());
2747 if (r == QMetaMethodPrivate::InvokeFailReason::TooFewArguments) {
2748 qWarning(
"QMetaMethod::invoke: too few arguments (%d) in call to %s::%s",
2749 int(paramCount), self.mobj->className(), self.methodSignature().constData());
2755 Qt::ConnectionType connectionType,
2756 qsizetype paramCount,
const void *
const *parameters,
2757 const char *
const *typeNames,
2760 auto object =
static_cast<QObject *>(target);
2761 auto priv = QMetaMethodPrivate::get(&self);
2762 constexpr bool MetaTypesAreOptional = QT_VERSION < QT_VERSION_CHECK(7, 0, 0);
2763 auto methodMetaTypes = priv->parameterMetaTypeInterfaces();
2764 auto param =
const_cast<
void **>(parameters);
2766 Q_ASSERT(priv->mobj);
2767 Q_ASSERT(self.methodType() == Constructor || object);
2768 Q_ASSERT(self.methodType() == Constructor || connectionType == Qt::ConnectionType(-1) ||
2769 priv->mobj->cast(object));
2770 Q_ASSERT(paramCount >= 1);
2771 Q_ASSERT(parameters);
2772 Q_ASSERT(typeNames);
2773 Q_ASSERT(MetaTypesAreOptional || metaTypes);
2775 if ((paramCount - 1) < qsizetype(priv->data.argc()))
2779 auto checkTypesAreCompatible = [=](
int idx) {
2780 uint typeInfo = priv->parameterTypeInfo(idx - 1);
2781 QByteArrayView userTypeName(typeNames[idx] ? typeNames[idx] : metaTypes[idx]
->name);
2783 if ((typeInfo & IsUnresolvedType) == 0) {
2785 if (MetaTypesAreOptional && !metaTypes)
2786 return int(typeInfo) == QMetaType::fromName(userTypeName).rawId();
2787 return int(typeInfo) == metaTypes[idx]->typeId;
2790 QByteArrayView methodTypeName = stringDataView(priv->mobj, typeInfo & TypeNameIndexMask);
2791 if ((MetaTypesAreOptional && !metaTypes) || !metaTypes[idx]) {
2793 if (methodTypeName == userTypeName)
2797 QByteArray normalized = normalizeTypeInternal(userTypeName.begin(), userTypeName.end());
2798 return methodTypeName == normalized;
2802 Q_ASSERT(userType.isValid());
2803 if (QMetaType(methodMetaTypes[idx - 1]) == userType)
2808 if (methodMetaTypes[idx - 1])
2812 QMetaType resolved = QMetaType::fromName(methodTypeName);
2813 return resolved == userType;
2817 for (qsizetype i = 0; metaTypes && i < paramCount; ++i)
2821 for (qsizetype i = 1; i < paramCount; ++i) {
2822 if (!checkTypesAreCompatible(i))
2827 if (self.methodType() == Constructor) {
2829 qWarning(
"QMetaMethod::invokeMethod: cannot call constructor %s on object %p",
2830 self.methodSignature().constData(), object);
2834 if (!parameters[0]) {
2835 qWarning(
"QMetaMethod::invokeMethod: constructor call to %s must assign a return type",
2836 self.methodSignature().constData());
2840 if (!MetaTypesAreOptional || metaTypes) {
2841 if (metaTypes[0]->typeId != QMetaType::QObjectStar) {
2842 qWarning(
"QMetaMethod::invokeMethod: cannot convert QObject* to %s on constructor call %s",
2843 metaTypes[0]
->name, self.methodSignature().constData());
2848 int idx = priv->ownConstructorMethodIndex();
2849 if (priv->mobj->static_metacall(QMetaObject::CreateInstance, idx, param) >= 0)
2855 if (parameters[0]) {
2856 if (!checkTypesAreCompatible(0)) {
2857 const char *retType = typeNames[0] ? typeNames[0] : metaTypes[0]
->name;
2858 qWarning(
"QMetaMethod::invokeMethod: return type mismatch for method %s::%s:"
2859 " cannot convert from %s to %s during invocation",
2860 priv->mobj->className(), priv->methodSignature().constData(),
2861 priv->rawReturnTypeName(), retType);
2866 Qt::HANDLE currentThreadId =
nullptr;
2867 QThread *objectThread =
nullptr;
2868 auto receiverInSameThread = [&]() {
2869 if (!currentThreadId) {
2870 currentThreadId = QThread::currentThreadId();
2871 objectThread = object->thread();
2874 return currentThreadId == QThreadData::get2(objectThread)->threadId.loadRelaxed();
2879 if (connectionType == Qt::AutoConnection)
2880 connectionType = receiverInSameThread() ? Qt::DirectConnection : Qt::QueuedConnection;
2881 else if (connectionType == Qt::ConnectionType(-1))
2882 connectionType = Qt::DirectConnection;
2884#if !QT_CONFIG(thread)
2885 if (connectionType == Qt::BlockingQueuedConnection) {
2886 connectionType = Qt::DirectConnection;
2891 int idx_relative = priv->ownMethodIndex();
2892 int idx_offset = priv->mobj->methodOffset();
2893 QObjectPrivate::StaticMetaCallFunction callFunction = priv->mobj->d.static_metacall;
2895 if (connectionType == Qt::DirectConnection) {
2897 callFunction(object, QMetaObject::InvokeMetaMethod, idx_relative, param);
2898 else if (QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, idx_relative + idx_offset, param) >= 0)
2900 }
else if (connectionType == Qt::QueuedConnection) {
2901 if (parameters[0]) {
2902 qWarning(
"QMetaMethod::invoke: Unable to invoke methods with return values in "
2903 "queued connections");
2907 QVarLengthArray<
const QtPrivate::QMetaTypeInterface *, 16> argTypes;
2908 argTypes.reserve(paramCount);
2909 argTypes.emplace_back(
nullptr);
2911 for (
int i = 1; i < paramCount; ++i) {
2912 QMetaType type = QMetaType(methodMetaTypes[i - 1]);
2913 if (!type.iface() && (!MetaTypesAreOptional || metaTypes))
2914 type = QMetaType(metaTypes[i]);
2916 type = priv->parameterMetaType(i - 1);
2917 if (!type.iface() && typeNames[i])
2918 type = QMetaType::fromName(typeNames[i]);
2919 if (!type.iface()) {
2920 qWarning(
"QMetaMethod::invoke: Unable to handle unregistered datatype '%s'",
2924 argTypes.emplace_back(type.iface());
2927 QCoreApplication::postEvent(object,
new QQueuedMetaCallEvent(idx_offset, idx_relative, callFunction,
nullptr,
2928 -1, paramCount, argTypes.data(), parameters));
2930#if QT_CONFIG(thread)
2931 if (receiverInSameThread()) {
2932 qWarning(
"QMetaMethod::invoke: Dead lock detected in BlockingQueuedConnection: "
2933 "Receiver is %s(%p)", priv->mobj->className(), object);
2934 return InvokeFailReason::DeadLockDetected;
2938 QCoreApplication::postEvent(object,
new QMetaCallEvent(idx_offset, idx_relative, callFunction,
2939 nullptr, -1, param, &latch));
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049bool QMetaMethod::invokeOnGadget(
void *gadget,
3050 QGenericReturnArgument returnValue,
3051 QGenericArgument val0,
3052 QGenericArgument val1,
3053 QGenericArgument val2,
3054 QGenericArgument val3,
3055 QGenericArgument val4,
3056 QGenericArgument val5,
3057 QGenericArgument val6,
3058 QGenericArgument val7,
3059 QGenericArgument val8,
3060 QGenericArgument val9)
const
3062 if (!gadget || !mobj)
3066 if (returnValue.data()) {
3067 const char *retType = typeName();
3068 if (qstrcmp(returnValue.name(), retType) != 0) {
3070 QByteArray normalized = QMetaObject::normalizedType(returnValue.name());
3071 if (qstrcmp(normalized.constData(), retType) != 0) {
3073 int t = returnType();
3074 if (t == QMetaType::UnknownType || t != QMetaType::fromName(normalized).rawId())
3081 const char *typeNames[] = {
3095 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
3096 if (qstrlen(typeNames[paramCount]) <= 0)
3099 if (paramCount <= QMetaMethodPrivate::get(
this)->parameterCount())
3116 int idx_relative = QMetaMethodPrivate::get(
this)->ownMethodIndex();
3117 Q_ASSERT(QMetaObjectPrivate::get(mobj)->revision >= 6);
3118 QObjectPrivate::StaticMetaCallFunction callFunction = mobj->d.static_metacall;
3121 callFunction(
reinterpret_cast<QObject*>(gadget), QMetaObject::InvokeMetaMethod, idx_relative, param);
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
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
3178
3179
3182
3183
3184
3185
3186
3187
3188
3191
3192
3193
3197
3198
3199
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212const char *QMetaEnum::name()
const
3216 return rawStringData(mobj, data.name());
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231const char *QMetaEnum::enumName()
const
3235 return rawStringData(mobj, data.alias());
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250QMetaType QMetaEnum::metaType()
const
3255 const QMetaObjectPrivate *p = priv(mobj->d.data);
3256#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
3257 if (p->revision < 12)
3261 QMetaType mt(mobj->d.metaTypes[data.index(mobj) + p->propertyCount]);
3267
3268
3269
3270
3271int QMetaEnum::keyCount()
const
3275 return data.keyCount();
3279
3280
3281
3282
3283const char *QMetaEnum::key(
int index)
const
3287 if (index >= 0 && index <
int(data.keyCount()))
3288 return rawStringData(mobj, mobj->d.data[data.data() + 2*index]);
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302int QMetaEnum::value(
int index)
const
3304 return value64(index).value_or(-1);
3312Q_DECL_PURE_FUNCTION
static inline EnumExtendMode enumExtendMode(
const QMetaEnum &e)
3318 if (e.metaType().flags() & QMetaType::IsUnsignedEnumeration)
3330 return value == uint(value);
3331 return value == quint64(
int(value));
3334template <
typename... Mode>
inline
3335quint64 QMetaEnum::value_helper(uint index, Mode... modes)
const noexcept
3337 static_assert(
sizeof...(Mode) < 2);
3338 if constexpr (
sizeof...(Mode) == 0) {
3339 return value_helper(index, enumExtendMode(*
this));
3340 }
else if constexpr (
sizeof...(Mode) == 1) {
3341 auto mode = (modes, ...);
3342 quint64 value = mobj->d.data[data.data() + 2U * index + 1];
3344 value |= quint64(mobj->d.data[data.data() + 2U * data.keyCount() + index]) << 32;
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373std::optional<quint64> QMetaEnum::value64(
int index)
const
3376 return std::nullopt;
3377 if (index < 0 || index >=
int(data.keyCount()))
3378 return std::nullopt;
3380 return value_helper(index);
3384
3385
3386
3387
3388
3389
3390
3391
3392bool QMetaEnum::isFlag()
const
3396 return data.flags() & EnumIsFlag;
3400
3401
3402
3403
3404
3405bool QMetaEnum::isScoped()
const
3409 return data.flags() & EnumIsScoped;
3413
3414
3415
3416
3417
3418
3419bool QMetaEnum::is64Bit()
const
3423 return data.flags() & EnumIs64Bit;
3427
3428
3429
3430
3431
3432
3433
3434const char *QMetaEnum::scope()
const
3436 return mobj ? mobj->className() :
nullptr;
3441 const QByteArrayView className = e->enclosingMetaObject()->className();
3446 if (scope == className)
3452 QByteArrayView name = e->enumName();
3456 const auto sz = className.size();
3457 if (scope.size() == sz + qsizetype(qstrlen(
"::")) + name.size()
3458 && scope.startsWith(className)
3459 && scope.sliced(sz, 2) ==
"::"
3460 && scope.sliced(sz + 2) == name)
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481int QMetaEnum::keyToValue(
const char *key,
bool *ok)
const
3483 auto value = keyToValue64(key);
3485 *ok = value.has_value();
3486 return int(value.value_or(-1));
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501std::optional<quint64> QMetaEnum::keyToValue64(
const char *key)
const
3504 return std::nullopt;
3505 const auto [scope, enumKey] = parse_scope(QLatin1StringView(key));
3506 for (
int i = 0; i <
int(data.keyCount()); ++i) {
3507 if ((!scope || isScopeMatch(*scope,
this))
3508 && enumKey == stringDataView(mobj, mobj->d.data[data.data() + 2 * i])) {
3509 return value_helper(i);
3512 return std::nullopt;
3516
3517
3518
3519
3520
3521
3522
3523const char *QMetaEnum::valueToKey(quint64 value)
const
3528 EnumExtendMode mode = enumExtendMode(*
this);
3529 if (!isEnumValueSuitable(value, mode))
3532 for (
int i = 0; i <
int(data.keyCount()); ++i) {
3533 if (value == value_helper(i, mode))
3534 return rawStringData(mobj, mobj->d.data[data.data() + 2 * i]);
3539static bool parseEnumFlags(QByteArrayView v, QVarLengthArray<QByteArrayView, 10> &list)
3543 qWarning(
"QMetaEnum::keysToValue: empty keys string.");
3547 qsizetype sep = v.indexOf(
'|', 0);
3549 qWarning(
"QMetaEnum::keysToValue: malformed keys string, starts with '|', \"%s\"",
3559 if (v.endsWith(
'|')) {
3560 qWarning(
"QMetaEnum::keysToValue: malformed keys string, ends with '|', \"%s\"",
3565 const auto begin = v.begin();
3566 const auto end = v.end();
3568 for (; b != end && sep != -1; sep = v.indexOf(
'|', sep)) {
3569 list.push_back({b, begin + sep});
3573 qWarning(
"QMetaEnum::keysToValue: malformed keys string, has two consecutive '|': "
3574 "\"%s\"", v.constData());
3580 list.push_back({b, end});
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598int QMetaEnum::keysToValue(
const char *keys,
bool *ok)
const
3600 auto value = keysToValue64(keys);
3602 *ok = value.has_value();
3603 return int(value.value_or(-1));
3607
3608
3609
3610
3611
3612
3613
3614
3615std::optional<quint64> QMetaEnum::keysToValue64(
const char *keys)
const
3618 return std::nullopt;
3620 EnumExtendMode mode = enumExtendMode(*
this);
3621 auto lookup = [&] (QByteArrayView key) -> std::optional<quint64> {
3622 for (
int i = data.keyCount() - 1; i >= 0; --i) {
3623 if (key == stringDataView(mobj, mobj->d.data[data.data() + 2*i]))
3624 return value_helper(i, mode);
3626 return std::nullopt;
3630 QVarLengthArray<QByteArrayView, 10> list;
3631 const bool r = parseEnumFlags(QByteArrayView{keys}, list);
3633 return std::nullopt;
3634 for (
const auto &untrimmed : list) {
3635 const auto parsed = parse_scope(untrimmed.trimmed());
3636 if (parsed.scope && !isScopeMatch(*parsed.scope,
this))
3637 return std::nullopt;
3638 if (
auto thisValue = lookup(parsed.key))
3639 value |= *thisValue;
3641 return std::nullopt;
3648template <
typename String,
typename Container,
typename Separator>
3649void join_reversed(String &s,
const Container &c, Separator sep)
3653 qsizetype len = qsizetype(c.size()) - 1;
3655 len += qsizetype(e.size());
3658 for (
auto rit = c.rbegin(), rend = c.rend(); rit != rend; ++rit) {
3659 const auto &e = *rit;
3663 s.append(e.data(), e.size());
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678QByteArray QMetaEnum::valueToKeys(quint64 value)
const
3684 EnumExtendMode mode = enumExtendMode(*
this);
3685 if (!isEnumValueSuitable(value, mode))
3688 QVarLengthArray<QByteArrayView,
sizeof(
int) * CHAR_BIT> parts;
3692 for (
int i = data.keyCount() - 1; i >= 0; --i) {
3693 quint64 k = value_helper(i, mode);
3694 if ((k != 0 && (v & k) == k) || (k == value)) {
3696 parts.push_back(stringDataView(mobj, mobj->d.data[data.data() + 2 * i]));
3699 join_reversed(keys, parts,
'|');
3704
3705
3706QMetaEnum::QMetaEnum(
const QMetaObject *mobj,
int index)
3707 : mobj(mobj), data({ mobj->d.data + priv(mobj->d.data)->enumeratorData + index * Data::Size })
3709 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->enumeratorCount);
3712int QMetaEnum::Data::index(
const QMetaObject *mobj)
const
3714#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
3715# warning "Consider changing Size to a power of 2"
3717 return (
unsigned(d - mobj->d.data) - priv(mobj->d.data)->enumeratorData) / Size;
3721
3722
3723
3724
3725
3726
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
3761
3762
3765
3766
3767
3768
3769
3770
3771
3774
3775
3776
3779
3780
3781
3784
3785
3786
3787
3788const char *QMetaProperty::name()
const
3792 return rawStringData(mobj, data.name());
3796
3797
3798
3799
3800const char *QMetaProperty::typeName()
const
3805 if (
const auto mt = metaType(); mt.isValid())
3807 return typeNameFromTypeInfo(mobj, data.type()).constData();
3811
3812
3813
3814
3815
3816
3817
3820
3821
3822
3823
3824
3825
3826
3827
3828
3831
3832
3833
3834
3835
3836
3837
3840
3841
3842
3843
3844
3845
3846QMetaType QMetaProperty::metaType()
const
3850 QMetaType mt(mobj->d.metaTypes[data.index(mobj)]);
3855int QMetaProperty::Data::index(
const QMetaObject *mobj)
const
3857#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
3858# warning "Consider changing Size to a power of 2"
3860 return (
unsigned(d - mobj->d.data) - priv(mobj->d.data)->propertyData) / Size;
3864
3865
3866
3867
3868int QMetaProperty::propertyIndex()
const
3872 return data.index(mobj) + mobj->propertyOffset();
3876
3877
3878
3879
3880int QMetaProperty::relativePropertyIndex()
const
3884 return data.index(mobj);
3888
3889
3890
3891
3892
3893
3894
3895
3897bool QMetaProperty::isFlagType()
const
3899 return isEnumType() && menum.isFlag();
3903
3904
3905
3906
3907
3908bool QMetaProperty::isEnumType()
const
3912 return (data.flags() & EnumOrFlag) && menum.name();
3916
3917
3918
3919
3920
3921
3922
3923
3924bool QMetaProperty::hasStdCppSet()
const
3928 return (data.flags() & StdCppSet);
3932
3933
3934
3935
3936
3937
3938bool QMetaProperty::isAlias()
const
3942 return (data.flags() & Alias);
3945#if QT_DEPRECATED_SINCE(6
, 4
)
3947
3948
3949
3950
3951
3952
3953
3954int QMetaProperty::registerPropertyType()
const
3960QMetaProperty::QMetaProperty(
const QMetaObject *mobj,
int index)
3962 data(getMetaPropertyData(mobj, index))
3964 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->propertyCount);
3966 if (!(data.flags() & EnumOrFlag) || !metaType().flags().testFlag(QMetaType::IsEnumeration))
3968 QByteArrayView enum_name = typeNameFromTypeInfo(mobj, data.type());
3969 menum = mobj->enumerator(QMetaObjectPrivate::indexOfEnumerator(mobj, enum_name));
3970 if (menum.isValid())
3973 QByteArrayView scope_name;
3974 const auto parsed = parse_scope(enum_name);
3976 scope_name = *parsed.scope;
3977 enum_name = parsed.key;
3979 scope_name = objectClassName(mobj);
3982 const QMetaObject *scope =
nullptr;
3983 if (scope_name ==
"Qt")
3984 scope = &Qt::staticMetaObject;
3986 scope = QMetaObject_findMetaObject(mobj, QByteArrayView(scope_name));
3989 menum = scope->enumerator(QMetaObjectPrivate::indexOfEnumerator(scope, enum_name));
3993
3994
3995
3996QMetaProperty::Data QMetaProperty::getMetaPropertyData(
const QMetaObject *mobj,
int index)
3998 return { mobj->d.data + priv(mobj->d.data)->propertyData + index * Data::Size };
4002
4003
4004
4005
4006
4007QMetaEnum QMetaProperty::enumerator()
const
4013
4014
4015
4016
4017
4018QVariant QMetaProperty::read(
const QObject *object)
const
4020 if (!object || !mobj)
4030 void *argv[] = {
nullptr, &value, &status };
4031 QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
4032 if (t == QMetaType::fromType<QVariant>()) {
4035 value = QVariant(t,
nullptr);
4036 argv[0] = value.data();
4038 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) {
4039 mobj->d.static_metacall(
const_cast<QObject*>(object), QMetaObject::ReadProperty, data.index(mobj), argv);
4041 QMetaObject::metacall(
const_cast<QObject*>(object), QMetaObject::ReadProperty,
4042 data.index(mobj) + mobj->propertyOffset(), argv);
4047 if (t != QMetaType::fromType<QVariant>() && argv[0] != value.data())
4049 return QVariant(t, argv[0]);
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067bool QMetaProperty::write(QObject *object,
const QVariant &value)
const
4069 if (!object || !isWritable())
4071 return write(object, QVariant(value));
4075
4076
4077
4078bool QMetaProperty::write(QObject *object, QVariant &&v)
const
4080 if (!object || !isWritable())
4082 QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
4083 if (t != QMetaType::fromType<QVariant>() && t != v.metaType()) {
4084 if (isEnumType() && !t.metaObject() && v.metaType() == QMetaType::fromType<QString>()) {
4088 std::optional value = isFlagType() ? menum.keysToValue64(v.toByteArray())
4089 : menum.keyToValue64(v.toByteArray());
4091 v = QVariant(qlonglong(*value));
4098 return reset(object);
4099 v = QVariant(t,
nullptr);
4100 }
else if (!v.convert(t)) {
4113 void *argv[] = {
nullptr, &v, &status, &flags };
4114 if (t == QMetaType::fromType<QVariant>())
4118 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
4119 mobj->d.static_metacall(object, QMetaObject::WriteProperty, data.index(mobj), argv);
4121 QMetaObject::metacall(object, QMetaObject::WriteProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4127
4128
4129
4130
4131
4132
4133
4134bool QMetaProperty::reset(QObject *object)
const
4136 if (!object || !mobj || !isResettable())
4138 void *argv[] = {
nullptr };
4139 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
4140 mobj->d.static_metacall(object, QMetaObject::ResetProperty, data.index(mobj), argv);
4142 QMetaObject::metacall(object, QMetaObject::ResetProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4147
4148
4149
4150
4151
4152
4153
4154
4155QUntypedBindable QMetaProperty::bindable(QObject *object)
const
4157 QUntypedBindable bindable;
4158 void * argv[1] { &bindable };
4159 mobj->metacall(object, QMetaObject::BindableProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4163
4164
4165
4166
4167
4168
4169
4170QVariant QMetaProperty::readOnGadget(
const void *gadget)
const
4172 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4173 return read(
reinterpret_cast<
const QObject*>(gadget));
4177
4178
4179
4180
4181
4182
4183
4184bool QMetaProperty::writeOnGadget(
void *gadget,
const QVariant &value)
const
4186 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4187 return write(
reinterpret_cast<QObject*>(gadget), value);
4191
4192
4193
4194bool QMetaProperty::writeOnGadget(
void *gadget, QVariant &&value)
const
4196 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4197 return write(
reinterpret_cast<QObject*>(gadget), std::move(value));
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210bool QMetaProperty::resetOnGadget(
void *gadget)
const
4212 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4213 return reset(
reinterpret_cast<QObject*>(gadget));
4217
4218
4219
4220
4221
4222bool QMetaProperty::isResettable()
const
4226 return data.flags() & Resettable;
4230
4231
4232
4233
4234bool QMetaProperty::isReadable()
const
4238 return data.flags() & Readable;
4242
4243
4244
4245
4246
4247bool QMetaProperty::hasNotifySignal()
const
4251 return data.notifyIndex() != uint(-1);
4255
4256
4257
4258
4259
4260
4261
4262QMetaMethod QMetaProperty::notifySignal()
const
4264 int id = notifySignalIndex();
4266 return mobj->method(id);
4268 return QMetaMethod();
4272
4273
4274
4275
4276
4277
4278
4279int QMetaProperty::notifySignalIndex()
const
4281 if (!mobj || data.notifyIndex() == std::numeric_limits<uint>::max())
4283 uint methodIndex = data.notifyIndex();
4284 if (!(methodIndex & IsUnresolvedSignal))
4285 return methodIndex + mobj->methodOffset();
4286 methodIndex &= ~IsUnresolvedSignal;
4287 const QByteArrayView signalName = stringDataView(mobj, methodIndex);
4288 const QMetaObject *m = mobj;
4290 int idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, {}, QMetaMethod::Signal);
4292 return idx + m->methodOffset();
4294 QArgumentType argType[] = {metaType()};
4295 idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, argType, QMetaMethod::Signal);
4297 return idx + m->methodOffset();
4298 qWarning(
"QMetaProperty::notifySignal: cannot find the NOTIFY signal %s in class %s for property '%s'",
4299 signalName.constData(), mobj->className(), name());
4305
4306
4307
4308
4309
4310
4311int QMetaProperty::revision()
const
4315 return data.revision();
4319
4320
4321
4322
4323
4324bool QMetaProperty::isWritable()
const
4328 return data.flags() & Writable;
4332
4333
4334
4335
4336
4337bool QMetaProperty::isDesignable()
const
4341 return data.flags() & Designable;
4345
4346
4347
4348
4349
4350bool QMetaProperty::isScriptable()
const
4354 return data.flags() & Scriptable;
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367bool QMetaProperty::isStored()
const
4371 return data.flags() & Stored;
4375
4376
4377
4378
4379
4380
4381
4382bool QMetaProperty::isUser()
const
4386 return data.flags() & User;
4390
4391
4392
4393
4394
4395
4396bool QMetaProperty::isConstant()
const
4400 return data.flags() & Constant;
4404
4405
4406
4407
4408
4409
4410bool QMetaProperty::isFinal()
const
4414 return data.flags() & Final;
4418
4419
4420
4421
4422
4423
4424bool QMetaProperty::isVirtual()
const
4428 return data.flags() & Virtual;
4432
4433
4434
4435
4436
4437
4438bool QMetaProperty::isOverride()
const
4442 return data.flags() & Override;
4446
4447
4448
4449
4450
4451
4452bool QMetaProperty::isRequired()
const
4456 return data.flags() & Required;
4460
4461
4462
4463
4464
4465
4466
4467
4468bool QMetaProperty::isBindable()
const
4472 return (data.flags() & Bindable);
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4500
4501
4502
4505
4506
4507
4510
4511
4512
4513
4514const char *QMetaClassInfo::name()
const
4518 return rawStringData(mobj, data.name());
4522
4523
4524
4525
4526const char *QMetaClassInfo::value()
const
4530 return rawStringData(mobj, data.value());
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4548
4549
4550
4551
4552
4553
4554
4555
4556
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4584
4585
4586
4587
4590
4591
4592
4593
4596
4597
4598
4599
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4615
4616
4617
4618
4619
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4635 Q_ASSERT(local_method_index < get(mobj)->methodCount);
4636 while (QMetaMethod::fromRelativeMethodIndex(mobj, local_method_index).data.flags() & MethodCloned) {
4637 Q_ASSERT(local_method_index > 0);
4638 --local_method_index;
4640 return local_method_index;
4644
4645
4646
4647
4648
4649
4650
4651
4654 QVarLengthArray<QByteArrayView, 10> &typeNames)
4656 const char *signature =
static_cast<
const char *>(memchr(sig.begin(),
'(', sig.size()));
4659 auto name = QByteArrayView{sig.begin(), signature};
4661 if (!sig.endsWith(
')'))
4663 const char *end = sig.end() - 1;
4664 while (signature != end) {
4665 if (*signature ==
',')
4667 const char *begin = signature;
4669 while (signature != end && (level > 0 || *signature !=
',')) {
4670 if (*signature ==
'<')
4672 else if (*signature ==
'>')
4676 typeNames.append(QByteArrayView{begin, signature - begin});