12#include <qcoreapplication.h>
13#include <QtCore/qspan.h>
19#include "private/qthread_p.h"
21#include "private/qlatch_p.h"
25#include "private/qmetaobject_moc_p.h"
34using namespace Qt::StringLiterals;
37
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
114
115
116
117
118
119
120
121
128 Q_ASSERT(priv(mo->d.data)->revision >= 7);
129 uint offset = mo->d.stringdata[2*index];
130 return reinterpret_cast<
const char *>(mo->d.stringdata) + offset;
135 Q_ASSERT(priv(mo->d.data)->revision >= 7);
136 uint offset = mo->d.stringdata[2*index];
137 uint length = mo->d.stringdata[2*index + 1];
138 const char *string =
reinterpret_cast<
const char *>(mo->d.stringdata) + offset;
139 return {string, qsizetype(length)};
144 if (QMetaObjectPrivate::get(mo)->flags & AllocatedMetaObject) {
146 return view.toByteArray();
151 return QByteArray::fromRawData(view.data(), view.size());
156 return stringData(mo, stringDataView(mo, index));
161 if (typeInfo & IsUnresolvedType)
162 return stringDataView(mo, typeInfo & TypeNameIndexMask);
164 return QByteArrayView(QMetaType(typeInfo).name());
169 if (!(typeInfo & IsUnresolvedType))
171 return qMetaTypeTypeInternal(stringDataView(mo, typeInfo & TypeNameIndexMask));
177 std::optional<QByteArrayView> scope;
180 if (qualifiedKey.startsWith(
"QFlags<") && qualifiedKey.endsWith(
'>'))
181 qualifiedKey.slice(7, qualifiedKey.length() - 8);
182 const auto scopePos = qualifiedKey.lastIndexOf(
"::"_L1);
184 return R{
std::nullopt, qualifiedKey};
186 return R{qualifiedKey.first(scopePos), qualifiedKey.sliced(scopePos + 2)};
193 static const QMetaMethodPrivate *get(
const QMetaMethod *q)
194 {
return static_cast<
const QMetaMethodPrivate *>(q); }
197 inline QByteArrayView qualifiedName()
const noexcept;
198 inline QByteArrayView name()
const noexcept;
199 inline int typesDataIndex()
const;
200 inline const char *rawReturnTypeName()
const;
201 inline int returnType()
const;
202 inline int parameterCount()
const;
203 inline int parametersDataIndex()
const;
204 inline uint parameterTypeInfo(
int index)
const;
205 inline int parameterType(
int index)
const;
206 inline void getParameterTypes(
int *types)
const;
209 inline QByteArrayView parameterTypeName(
int index)
const noexcept;
210 inline QList<QByteArray> parameterTypes()
const;
211 inline QList<QByteArray> parameterNames()
const;
212 inline const char *tag()
const;
213 inline int ownMethodIndex()
const;
214 inline int ownConstructorMethodIndex()
const;
218 QMetaMethodPrivate();
224#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
226
227
228
229
230
231
232
233
234
235
236
237
238
239QObject *QMetaObject::newInstance(QGenericArgument val0,
240 QGenericArgument val1,
241 QGenericArgument val2,
242 QGenericArgument val3,
243 QGenericArgument val4,
244 QGenericArgument val5,
245 QGenericArgument val6,
246 QGenericArgument val7,
247 QGenericArgument val8,
248 QGenericArgument val9)
const
250 const char *typeNames[] = {
252 val0.name(), val1.name(), val2.name(), val3.name(), val4.name(),
253 val5.name(), val6.name(), val7.name(), val8.name(), val9.name()
255 const void *parameters[] = {
257 val0.data(), val1.data(), val2.data(), val3.data(), val4.data(),
258 val5.data(), val6.data(), val7.data(), val8.data(), val9.data()
262 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
263 int len =
int(qstrlen(typeNames[paramCount]));
268 return newInstanceImpl(
this, paramCount, parameters, typeNames,
nullptr);
273
274
275
276
277
278
279
280
281
282
283
284
285
287QObject *QMetaObject::newInstanceImpl(
const QMetaObject *mobj, qsizetype paramCount,
288 const void **parameters,
const char **typeNames,
289 const QtPrivate::QMetaTypeInterface **metaTypes)
291 if (!mobj->inherits(&QObject::staticMetaObject)) {
292 qWarning(
"QMetaObject::newInstance: type %s does not inherit QObject", mobj->className());
298QT_WARNING_DISABLE_GCC(
"-Wdangling-pointer")
302 QObject *returnValue =
nullptr;
303 QMetaType returnValueMetaType = QMetaType::fromType<
decltype(returnValue)>();
304 parameters[0] = &returnValue;
305 typeNames[0] = returnValueMetaType.name();
307 metaTypes[0] = returnValueMetaType.iface();
312 auto priv = QMetaObjectPrivate::get(mobj);
313 for (
int i = 0; i < priv->constructorCount; ++i) {
314 QMetaMethod m = QMetaMethod::fromRelativeConstructorIndex(mobj, i);
315 if (m.parameterCount() != (paramCount - 1))
319 QMetaMethodPrivate::InvokeFailReason r =
320 QMetaMethodPrivate::invokeImpl(m,
nullptr, Qt::DirectConnection, paramCount,
321 parameters, typeNames, metaTypes);
322 if (r == QMetaMethodPrivate::InvokeFailReason::None)
332
333
334int QMetaObject::static_metacall(Call cl,
int idx,
void **argv)
const
336 Q_ASSERT(priv(d.data)->revision >= 6);
337 if (!d.static_metacall)
339 d.static_metacall(
nullptr, cl, idx, argv);
344
345
346int QMetaObject::metacall(QObject *object, Call cl,
int idx,
void **argv)
348 if (object->d_ptr->metaObject)
349 return object->d_ptr->metaObject->metaCall(object, cl, idx, argv);
351 return object->qt_metacall(cl, idx, argv);
356 return stringDataView(m, priv(m->d.data)->className);
360
361
362
363
364const char *QMetaObject::className()
const
366 return objectClassName(
this).constData();
370
371
372
373
374
375
376
379
380
381
382
383
384
385
386bool QMetaObject::inherits(
const QMetaObject *metaObject)
const noexcept
388 const QMetaObject *m =
this;
392 }
while ((m = m->d.superdata));
397
398
399
400
401
402
405
406
407
408
409
410const QObject *QMetaObject::cast(
const QObject *obj)
const
412 return (obj && obj->metaObject()->inherits(
this)) ? obj :
nullptr;
415#ifndef QT_NO_TRANSLATION
417
418
419QString QMetaObject::tr(
const char *s,
const char *c,
int n)
const
421 return QCoreApplication::translate(className(), s, c, n);
426
427
428
429
430QMetaType QMetaObject::metaType()
const
433 const QMetaObjectPrivate *d = priv(
this->d.data);
434 if (d->revision < 10) {
436 return QMetaType::fromName(className());
439
440
441
442
443
444
445
446
447
448
449
450
451#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
455 const qsizetype offset = d->revision < 12
457 : d->propertyCount + d->enumeratorCount;
459 const qsizetype offset = d->propertyCount + d->enumeratorCount;
462 auto iface =
this->d.metaTypes[offset];
463 if (iface && QtMetaTypePrivate::isInterfaceFor<
void>(iface))
466 return QMetaType(iface);
468 return QMetaType::fromName(className());
475 if (QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && priv(m->d.data)->revision < 14)
477 const auto index = priv(m->d.data)->metaObjectHashIndex;
480 return stringDataView(m, index);
484
485
486
487
488
489
490
491
492
493
494const char *QMetaObject::metaObjectHash()
const
496 return objectMetaObjectHash(
this).constData();
500
501
502
503
504
505
506
507
508
509int QMetaObject::methodOffset()
const
512 const QMetaObject *m = d.superdata;
514 offset += priv(m->d.data)->methodCount;
522
523
524
525
526
527
528
529
530
531int QMetaObject::enumeratorOffset()
const
534 const QMetaObject *m = d.superdata;
536 offset += priv(m->d.data)->enumeratorCount;
543
544
545
546
547
548
549
550
551
552int QMetaObject::propertyOffset()
const
555 const QMetaObject *m = d.superdata;
557 offset += priv(m->d.data)->propertyCount;
564
565
566
567
568
569
570
571
572
573int QMetaObject::classInfoOffset()
const
576 const QMetaObject *m = d.superdata;
578 offset += priv(m->d.data)->classInfoCount;
585
586
587
588
589
590
591int QMetaObject::constructorCount()
const
593 Q_ASSERT(priv(d.data)->revision >= 2);
594 return priv(d.data)->constructorCount;
598
599
600
601
602
603
604
605
606
607
608
609int QMetaObject::methodCount()
const
611 int n = priv(d.data)->methodCount;
612 const QMetaObject *m = d.superdata;
614 n += priv(m->d.data)->methodCount;
621
622
623
624
625int QMetaObject::enumeratorCount()
const
627 int n = priv(d.data)->enumeratorCount;
628 const QMetaObject *m = d.superdata;
630 n += priv(m->d.data)->enumeratorCount;
637
638
639
640
641
642
643
644
645
646
647int QMetaObject::propertyCount()
const
649 int n = priv(d.data)->propertyCount;
650 const QMetaObject *m = d.superdata;
652 n += priv(m->d.data)->propertyCount;
659
660
661
662
663int QMetaObject::classInfoCount()
const
665 int n = priv(d.data)->classInfoCount;
666 const QMetaObject *m = d.superdata;
668 n += priv(m->d.data)->classInfoCount;
679 QSpan<
const QArgumentType> types)
681 const qsizetype argc = types.size();
682 const QMetaMethod::Data &data = method.data;
683 auto priv = QMetaMethodPrivate::get(&method);
684 if (priv->parameterCount() != argc)
689 if (
const auto qname = priv->qualifiedName(); !qname.endsWith(name))
691 else if (
const auto n = qname.chopped(name.size()); !n.isEmpty() && !n.endsWith(
':'))
695 int paramsIndex = data.parameters() + 1;
696 for (qsizetype i = 0; i < argc; ++i) {
697 uint typeInfo = m->d.data[paramsIndex + i];
700 if (mt == QMetaType(ifaces[i]))
702 if (mt.id() != typeFromTypeInfo(m, typeInfo))
705 if (types[i].name() == QMetaType(ifaces[i]).name())
707 if (types[i].name() != typeNameFromTypeInfo(m, typeInfo))
716
717
718
721 for (
const QMetaObject *currentObject = baseObject; currentObject; currentObject = currentObject->superClass()) {
722 const int start = priv(currentObject->d.data)->methodCount - 1;
724 for (
int i = start; i >= end; --i) {
725 auto candidate = QMetaMethod::fromRelativeMethodIndex(currentObject, i);
726 if (name == candidate.name())
730 return QMetaMethod{};
734
735
736
737
738
739
740
743 QSpan<
const QArgumentType> types,
744 QMetaMethod::MethodType what)
746 for (
const QMetaObject *m = *baseObject; m; m = m->d.superdata) {
747 Q_ASSERT(priv(m->d.data)->revision >= 7);
751 case QMetaMethod::Signal:
752 i = priv(m->d.data)->signalCount - 1;
754 case QMetaMethod::Slot:
755 i = priv(m->d.data)->methodCount - 1;
756 end = priv(m->d.data)->signalCount;
758 case QMetaMethod::Method:
759 i = priv(m->d.data)->methodCount - 1;
761 case QMetaMethod::Constructor:
762 Q_UNREACHABLE_RETURN(-1);
766 for (; i >= end; --i) {
767 auto data = QMetaMethod::fromRelativeMethodIndex(m, i);
768 if (methodMatch(m, data, name, types)) {
769 if (QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
770 && what == QMetaMethod::Slot && data.methodType() != QMetaMethod::Slot) {
783
784
785
786
787
788
789
790
791
792
794#if QT_DEPRECATED_SINCE(6
, 10
)
796static int compat_indexOf(
const char *what,
const char *sig,
const QMetaObject *mo,
797 int (*indexOf)(
const QMetaObject *,
const char *))
799 const QByteArray normalized = QByteArray(sig).replace(
"QVector<",
"QList<");
800 const int i = indexOf(mo, normalized.data());
802 qWarning(R"(QMetaObject::indexOf%s: argument "%s" is not normalized, because it contains "QVector<". )"
803 R"(Earlier versions of Qt 6 incorrectly normalized QVector< to QList<, silently. )"
804 R"(This behavior is deprecated as of 6.10, and will be removed in a future version of Qt.)",
810#define INDEXOF_COMPAT(what, arg)
812 if (i < 0
&& Q_UNLIKELY(std::strstr(arg, "QVector<")))
813 i = compat_indexOf(#what, arg, this, &indexOf ## what ## _helper);
816#define INDEXOF_COMPAT(what, arg)
822 QByteArrayView name = QMetaObjectPrivate::decodeMethodSignature(constructor, types);
823 return QMetaObjectPrivate::indexOfConstructor(mo, name, types);
826int QMetaObject::indexOfConstructor(
const char *constructor)
const
828 Q_ASSERT(priv(d.data)->revision >= 7);
829 int i = indexOfConstructor_helper(
this, constructor);
835
836
837
838
839
840
841
842
843
847 Q_ASSERT(priv(m->d.data)->revision >= 7);
849 QByteArrayView name = QMetaObjectPrivate::decodeMethodSignature(method, types);
850 return QMetaObjectPrivate::indexOfMethod(m, name, types);
853int QMetaObject::indexOfMethod(
const char *method)
const
855 int i = indexOfMethod_helper(
this, method);
861
862
863
864
865
866
870 Q_ASSERT(types.isEmpty());
871 QVarLengthArray<QByteArrayView, 10> typeNames;
872 QByteArrayView name = parameterTypeNamesFromSignature(signature, typeNames);
873 for (
auto type : typeNames)
874 types.emplace_back(type);
879
880
881
882
883
884
885
886
887
888
889
890
894 Q_ASSERT(priv(m->d.data)->revision >= 7);
896 QByteArrayView name = QMetaObjectPrivate::decodeMethodSignature(signal, types);
897 return QMetaObjectPrivate::indexOfSignal(m, name, types);
900int QMetaObject::indexOfSignal(
const char *signal)
const
902 int i = indexOfSignal_helper(
this, signal);
908
909
910
911
912
915 QSpan<
const QArgumentType> types)
917 int i = indexOfMethodRelative(baseObject, name, types, QMetaMethod::Signal);
919 const QMetaObject *m = *baseObject;
920 if (i >= 0 && m && m->d.superdata) {
921 int conflict = indexOfMethod(m->d.superdata, name, types);
923 QMetaMethod conflictMethod = m->d.superdata->method(conflict);
924 qWarning(
"QMetaObject::indexOfSignal: signal %s from %s redefined in %s",
925 conflictMethod.methodSignature().constData(),
926 m->d.superdata->className(), m->className());
934
935
936
937
938
939
940
941
942
946 Q_ASSERT(priv(m->d.data)->revision >= 7);
948 QByteArrayView name = QMetaObjectPrivate::decodeMethodSignature(slot, types);
949 return QMetaObjectPrivate::indexOfSlot(m, name, types);
952int QMetaObject::indexOfSlot(
const char *slot)
const
954 int i = indexOfSlot_helper(
this, slot);
964 QSpan<
const QArgumentType> types)
966 return indexOfMethodRelative(m, name, types, QMetaMethod::Slot);
970 QSpan<
const QArgumentType> types)
972 int i = indexOfSignalRelative(&m, name, types);
974 i += m->methodOffset();
979 QSpan<
const QArgumentType> types)
981 int i = indexOfSlotRelative(&m, name, types);
983 i += m->methodOffset();
988 QSpan<
const QArgumentType> types)
990 int i = indexOfMethodRelative(&m, name, types, QMetaMethod::Method);
992 i += m->methodOffset();
997 QSpan<
const QArgumentType> types)
999 for (
int i = priv(m->d.data)->constructorCount-1; i >= 0; --i) {
1000 const QMetaMethod method = QMetaMethod::fromRelativeConstructorIndex(m, i);
1001 if (methodMatch(m, method, name, types))
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1020
1021
1022
1023
1024
1025
1026
1027
1028
1031 Q_ASSERT(m !=
nullptr);
1032 int n = priv(m->d.data)->signalCount;
1033 for (m = m->d.superdata; m; m = m->d.superdata)
1034 n += priv(m->d.data)->signalCount;
1039
1040
1041
1042
1043
1044
1045
1046
1051 return QMetaMethodPrivate::get(&m)->ownMethodIndex() + signalOffset(m.mobj);
1055
1056
1057
1058
1059
1060
1061
1062
1065 if (signal_index < 0)
1066 return QMetaMethod();
1068 Q_ASSERT(m !=
nullptr);
1069 int i = signal_index;
1070 i -= signalOffset(m);
1071 if (i < 0 && m->d.superdata)
1072 return signal(m->d.superdata, signal_index);
1075 if (i >= 0 && i < priv(m->d.data)->signalCount)
1076 return QMetaMethod::fromRelativeMethodIndex(m, i);
1077 return QMetaMethod();
1081
1082
1083
1084
1085
1087 QSpan<
const QArgumentType> methodTypes)
1089 const qsizetype methodArgc = methodTypes.size();
1090 if (signalTypes.size() >= methodArgc) {
1091 signalTypes = signalTypes.first(methodArgc);
1092 return std::equal(signalTypes.begin(), signalTypes.end(),
1093 methodTypes.begin(), methodTypes.end());
1099
1100
1101
1102
1103
1105 const QMetaMethodPrivate *method)
1107 if (signal->methodType() != QMetaMethod::Signal)
1109 if (signal->parameterCount() < method->parameterCount())
1111 const QMetaObject *smeta = signal->enclosingMetaObject();
1112 const QMetaObject *rmeta = method->enclosingMetaObject();
1113 for (
int i = 0; i < method->parameterCount(); ++i) {
1114 uint sourceTypeInfo = signal->parameterTypeInfo(i);
1115 uint targetTypeInfo = method->parameterTypeInfo(i);
1116 if ((sourceTypeInfo & IsUnresolvedType)
1117 || (targetTypeInfo & IsUnresolvedType)) {
1118 QByteArrayView sourceName = typeNameFromTypeInfo(smeta, sourceTypeInfo);
1119 QByteArrayView targetName = typeNameFromTypeInfo(rmeta, targetTypeInfo);
1120 if (sourceName != targetName)
1125 if (sourceType != targetType)
1137 if (self->d.relatedMetaObjects) {
1138 Q_ASSERT(priv(self->d.data)->revision >= 2);
1139 const auto *e = self->d.relatedMetaObjects;
1142 if (
const QMetaObject *m =QMetaObject_findMetaObject((*e), name))
1148 self = self->d.superdata;
1154
1155
1156
1157
1158
1159int QMetaObject::indexOfEnumerator(
const char *name)
const
1161 return QMetaObjectPrivate::indexOfEnumerator(
this, name);
1167 for (
auto which : { W::Name, W::Alias }) {
1168 if (
int index = indexOfEnumerator(m, name, which); index != -1)
1179 const QMetaEnum e(m, i);
1180 const quint32 id = which ==
Which::Name ? e.data.name() : e.data.alias();
1181 QByteArrayView prop = stringDataView(m, id);
1183 i += m->enumeratorOffset();
1193
1194
1195
1196
1197
1198int QMetaObject::indexOfProperty(
const char *name)
const
1200 const QMetaObject *m =
this;
1202 const QMetaObjectPrivate *d = priv(m->d.data);
1203 for (
int i = 0; i < d->propertyCount; ++i) {
1204 const QMetaProperty::Data data = QMetaProperty::getMetaPropertyData(m, i);
1205 const char *prop = rawStringData(m, data.name());
1206 if (strcmp(name, prop) == 0) {
1207 i += m->propertyOffset();
1214 if (priv(
this->d.data)->flags & DynamicMetaObject) {
1215 QAbstractDynamicMetaObject *me =
1216 const_cast<QAbstractDynamicMetaObject *>(
static_cast<
const QAbstractDynamicMetaObject *>(
this));
1218 return me->createProperty(name,
nullptr);
1225
1226
1227
1228
1229
1230int QMetaObject::indexOfClassInfo(
const char *name)
const
1233 const QMetaObject *m =
this;
1234 while (m && i < 0) {
1235 for (i = priv(m->d.data)->classInfoCount-1; i >= 0; --i)
1236 if (strcmp(name, rawStringData(m, m->d.data[priv(m->d.data)->classInfoData + 2*i])) == 0) {
1237 i += m->classInfoOffset();
1246
1247
1248
1249
1250
1251
1252QMetaMethod QMetaObject::constructor(
int index)
const
1255 if (i >= 0 && i < priv(d.data)->constructorCount)
1256 return QMetaMethod::fromRelativeConstructorIndex(
this, i);
1257 return QMetaMethod();
1261
1262
1263
1264
1265QMetaMethod QMetaObject::method(
int index)
const
1268 i -= methodOffset();
1269 if (i < 0 && d.superdata)
1270 return d.superdata->method(index);
1272 if (i >= 0 && i < priv(d.data)->methodCount)
1273 return QMetaMethod::fromRelativeMethodIndex(
this, i);
1274 return QMetaMethod();
1278
1279
1280
1281
1282QMetaEnum QMetaObject::enumerator(
int index)
const
1285 i -= enumeratorOffset();
1286 if (i < 0 && d.superdata)
1287 return d.superdata->enumerator(index);
1289 if (i >= 0 && i < priv(d.data)->enumeratorCount)
1290 return QMetaEnum(
this, i);
1295
1296
1297
1298
1299
1300QMetaProperty QMetaObject::property(
int index)
const
1303 i -= propertyOffset();
1304 if (i < 0 && d.superdata)
1305 return d.superdata->property(index);
1307 if (i >= 0 && i < priv(d.data)->propertyCount)
1308 return QMetaProperty(
this, i);
1309 return QMetaProperty();
1313
1314
1315
1316
1317
1318
1319QMetaProperty QMetaObject::userProperty()
const
1321 const int propCount = propertyCount();
1322 for (
int i = propCount - 1; i >= 0; --i) {
1323 const QMetaProperty prop = property(i);
1327 return QMetaProperty();
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340QMetaClassInfo QMetaObject::classInfo(
int index)
const
1343 i -= classInfoOffset();
1344 if (i < 0 && d.superdata)
1345 return d.superdata->classInfo(index);
1347 QMetaClassInfo result;
1348 if (i >= 0 && i < priv(d.data)->classInfoCount) {
1350 result.data = { d.data + priv(d.data)->classInfoData + i * QMetaClassInfo::Data::Size };
1356
1357
1358
1359
1360
1361
1362
1363bool QMetaObject::checkConnectArgs(
const char *signal,
const char *method)
1365 const char *s1 = signal;
1366 const char *s2 = method;
1367 while (*s1++ !=
'(') { }
1368 while (*s2++ !=
'(') { }
1369 if (*s2 ==
')' || qstrcmp(s1,s2) == 0)
1371 const auto s1len = qstrlen(s1);
1372 const auto s2len = qstrlen(s2);
1373 if (s2len < s1len && strncmp(s1,s2,s2len-1)==0 && s1[s2len-1]==
',')
1379
1380
1381
1382
1383
1384
1385bool QMetaObject::checkConnectArgs(
const QMetaMethod &signal,
1386 const QMetaMethod &method)
1388 return QMetaObjectPrivate::checkConnectArgs(
1389 QMetaMethodPrivate::get(&signal),
1390 QMetaMethodPrivate::get(&method));
1395 return std::find_if_not(in.begin(), in.end(), is_space);
1400 auto rit = std::find_if_not(in.rbegin(), in.rend(), is_space);
1401 in = in.first(rit.base() - in.begin());
1407 const char *d = in.begin();
1409 const char *end = in.end();
1413 while (d != end && (templdepth
1414 || (*d !=
',' && *d !=
')'))) {
1423 auto type = QByteArrayView{t, d - t};
1424 type = trimSpacesFromRight(type);
1425 if (type ==
"void") {
1426 const char *next = trimSpacesFromLeft(QByteArrayView{d, end});
1427 if (next != end && *next ==
')')
1431 normalizeTypeInternal(QByteArrayView{t, d}, result);
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451QByteArray QMetaObject::normalizedType(
const char *type)
1453 return normalizeTypeInternal(type, type + qstrlen(type));
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1471 method = trimSpacesFromRight(method);
1472 if (method.isEmpty())
1475 const char *d = method.begin();
1476 const char *end = method.end();
1477 d = trimSpacesFromLeft({d, end});
1480 result.reserve(method.size());
1486 Q_ASSERT(!result.isEmpty());
1488 d = trimSpacesFromLeft({d, end});
1499 if (argdepth == 1) {
1500 d = qNormalizeType(QByteArrayView{d, end}, templdepth, result);
1514QByteArray QMetaObject::normalizedSignature(
const char *method)
1516 return QMetaObjectPrivate::normalizedSignature(method);
1521 const char *
const *names,
1526 for (
int i = 0; i < meta->methodCount(); ++i) {
1527 const QMetaMethod method = meta->method(i);
1528 if (method.name() == name)
1529 candidateMessage +=
" " + method.methodSignature() +
'\n';
1531 if (!candidateMessage.isEmpty()) {
1532 candidateMessage.prepend(
"\nCandidates are:\n");
1533 candidateMessage.chop(1);
1536 QVarLengthArray<
char, 512> sig;
1537 for (qsizetype i = 1; i < paramCount; ++i) {
1539 sig.append(names[i], qstrlen(names[i]));
1541 sig.append(metaTypes[i]->name, qstrlen(metaTypes[i]->name));
1544 if (paramCount != 1)
1545 sig.resize(sig.size() - 1);
1547 qWarning(
"QMetaObject::invokeMethod: No such method %s::%.*s(%.*s)%.*s",
1548 meta->className(),
int(name.size()), name.constData(),
1549 int(sig.size()), sig.constData(),
1550 int(candidateMessage.size()), candidateMessage.constData());
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
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669bool QMetaObject::invokeMethod(QObject *obj,
1671 Qt::ConnectionType type,
1672 QGenericReturnArgument ret,
1673 QGenericArgument val0,
1674 QGenericArgument val1,
1675 QGenericArgument val2,
1676 QGenericArgument val3,
1677 QGenericArgument val4,
1678 QGenericArgument val5,
1679 QGenericArgument val6,
1680 QGenericArgument val7,
1681 QGenericArgument val8,
1682 QGenericArgument val9)
1687 const char *typeNames[] = {ret.name(), val0.name(), val1.name(), val2.name(), val3.name(),
1688 val4.name(), val5.name(), val6.name(), val7.name(), val8.name(),
1690 const void *parameters[] = {ret.data(), val0.data(), val1.data(), val2.data(), val3.data(),
1691 val4.data(), val5.data(), val6.data(), val7.data(), val8.data(),
1694 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
1695 if (qstrlen(typeNames[paramCount]) <= 0)
1698 return invokeMethodImpl(obj, member, type, paramCount, parameters, typeNames,
nullptr);
1701bool QMetaObject::invokeMethodImpl(QObject *obj,
const char *member, Qt::ConnectionType type,
1702 qsizetype paramCount,
const void *
const *parameters,
1703 const char *
const *typeNames,
1704 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
1709 Q_ASSERT(paramCount >= 1);
1710 Q_ASSERT(parameters);
1711 Q_ASSERT(typeNames);
1714 QByteArrayView name(member);
1718 const QMetaObject *meta = obj->metaObject();
1719 for ( ; meta; meta = meta->superClass()) {
1720 auto priv = QMetaObjectPrivate::get(meta);
1721 for (
int i = 0; i < priv->methodCount; ++i) {
1722 QMetaMethod m = QMetaMethod::fromRelativeMethodIndex(meta, i);
1723 if (m.parameterCount() != (paramCount - 1))
1725 if (name != stringDataView(meta, m.data.name()))
1729 QMetaMethodPrivate::InvokeFailReason r =
1730 QMetaMethodPrivate::invokeImpl(m, obj, type, paramCount, parameters,
1731 typeNames, metaTypes);
1733 return r == QMetaMethodPrivate::InvokeFailReason::None;
1738 return printMethodNotFoundWarning(obj->metaObject(), name, paramCount, typeNames, metaTypes);
1741bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
1742 qsizetype parameterCount,
const void *
const *params,
const char *
const *names,
1743 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
1748 auto slot = QtPrivate::SlotObjUniquePtr(slotObj);
1753 Qt::HANDLE currentThreadId = QThread::currentThreadId();
1754 QThread *objectThread = object->thread();
1755 bool receiverInSameThread =
false;
1757 receiverInSameThread = currentThreadId == QThreadData::get2(objectThread)->threadId.loadRelaxed();
1759 if (type == Qt::AutoConnection)
1760 type = receiverInSameThread ? Qt::DirectConnection : Qt::QueuedConnection;
1762 void **argv =
const_cast<
void **>(params);
1763 if (type == Qt::DirectConnection) {
1764 slot->call(object, argv);
1765 }
else if (type == Qt::QueuedConnection) {
1767 qWarning(
"QMetaObject::invokeMethod: Unable to invoke methods with return values in "
1768 "queued connections");
1771 QCoreApplication::postEvent(object,
new QQueuedMetaCallEvent(std::move(slot),
nullptr, -1,
1772 parameterCount, metaTypes, params));
1773 }
else if (type == Qt::BlockingQueuedConnection) {
1774#if QT_CONFIG(thread)
1775 if (receiverInSameThread)
1776 qWarning(
"QMetaObject::invokeMethod: Dead lock detected");
1779 QCoreApplication::postEvent(object,
new QMetaCallEvent(std::move(slot),
nullptr, -1, argv, &latch));
1783 qWarning(
"QMetaObject::invokeMethod: Unknown connection type");
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1891
1892
1893
1894
1896
1897
1898
1899
1900
1903
1904
1905
1906
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1927
1928
1929
1930
1931
1932
1933
1934
1937
1938
1939
1940
1941
1942
1945
1946
1947
1948
1949
1950
1953
1954
1955
1956
1957
1958
1961
1962
1963
1966
1967
1968
1969
1970
1971
1972
1975
1976
1977
1980
1981
1982QMetaMethod QMetaMethod::fromRelativeMethodIndex(
const QMetaObject *mobj,
int index)
1984 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->methodCount);
1987 m.data = { mobj->d.data + priv(mobj->d.data)->methodData + index * Data::Size };
1991QMetaMethod QMetaMethod::fromRelativeConstructorIndex(
const QMetaObject *mobj,
int index)
1993 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->constructorCount);
1996 m.data = { mobj->d.data + priv(mobj->d.data)->constructorData + index * Data::Size };
2001
2002
2003
2004
2005
2006
2010 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2012 result.reserve(256);
2015 QList<QByteArray> argTypes = parameterTypes();
2016 for (
int i = 0; i < argTypes.size(); ++i) {
2019 result += argTypes.at(i);
2025QByteArrayView QMetaMethodPrivate::name()
const noexcept
2027 QByteArrayView name = qualifiedName();
2028 if (qsizetype colon = name.lastIndexOf(
':'); colon > 0)
2029 return name.sliced(colon + 1);
2033QByteArrayView QMetaMethodPrivate::qualifiedName()
const noexcept
2035 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2036 return stringDataView(mobj, data.name());
2039int QMetaMethodPrivate::typesDataIndex()
const
2041 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2042 return data.parameters();
2045const char *QMetaMethodPrivate::rawReturnTypeName()
const
2047 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2048 uint typeInfo = mobj->d.data[typesDataIndex()];
2049 if (typeInfo & IsUnresolvedType)
2050 return rawStringData(mobj, typeInfo & TypeNameIndexMask);
2052 return QMetaType(typeInfo).name();
2055int QMetaMethodPrivate::returnType()
const
2057 return parameterType(-1);
2060int QMetaMethodPrivate::parameterCount()
const
2062 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2070 uint typeInfo = parameterTypeInfo(index);
2073 if ((typeInfo & IsUnresolvedType) == 0)
2074 Q_ASSERT(mt.id() ==
int(typeInfo & TypeNameIndexMask));
2075 Q_ASSERT(mt.name());
2081#define ASSERT_NOT_PRIMITIVE_TYPE(TYPE, METATYPEID, NAME)
2082 Q_ASSERT(typeInfo != QMetaType::TYPE);
2084#undef ASSERT_NOT_PRIMITIVE_TYPE
2085 Q_ASSERT(typeInfo != QMetaType::QObjectStar);
2088 if (priv(mobj->d.data)->revision >= 11) {
2089 Q_ASSERT(typeInfo != QMetaType::Void);
2090 Q_ASSERT(typeInfo != QMetaType::VoidStar);
2095int QMetaMethodPrivate::parametersDataIndex()
const
2097 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2098 return typesDataIndex() + 1;
2101uint QMetaMethodPrivate::parameterTypeInfo(
int index)
const
2103 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2104 return mobj->d.data[parametersDataIndex() + index];
2109 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2110 if (methodType() == QMetaMethod::Constructor)
2114 checkMethodMetaTypeConsistency(iface, -1);
2120 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2121 int offset = (methodType() == QMetaMethod::Constructor ? 0 : 1);
2122 const auto ifaces = &mobj->d.metaTypes[data.metaTypeOffset() + offset];
2124 for (
int i = 0; i < parameterCount(); ++i)
2125 checkMethodMetaTypeConsistency(ifaces[i], i);
2130int QMetaMethodPrivate::parameterType(
int index)
const
2132 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2133 return typeFromTypeInfo(mobj, parameterTypeInfo(index));
2136void QMetaMethodPrivate::getParameterTypes(
int *types)
const
2138 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2139 int dataIndex = parametersDataIndex();
2140 int argc = parameterCount();
2141 for (
int i = 0; i < argc; ++i) {
2142 int id = typeFromTypeInfo(mobj, mobj->d.data[dataIndex++]);
2147QByteArrayView QMetaMethodPrivate::parameterTypeName(
int index)
const noexcept
2149 int paramsIndex = parametersDataIndex();
2150 return typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + index]);
2153QList<QByteArray> QMetaMethodPrivate::parameterTypes()
const
2155 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2156 int argc = parameterCount();
2157 QList<QByteArray> list;
2159 int paramsIndex = parametersDataIndex();
2160 for (
int i = 0; i < argc; ++i) {
2161 QByteArrayView name = typeNameFromTypeInfo(mobj, mobj->d.data[paramsIndex + i]);
2162 list.emplace_back(name.toByteArray());
2167QList<QByteArray> QMetaMethodPrivate::parameterNames()
const
2169 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2170 int argc = parameterCount();
2171 QList<QByteArray> list;
2173 int namesIndex = parametersDataIndex() + argc;
2174 for (
int i = 0; i < argc; ++i)
2175 list += stringData(mobj, mobj->d.data[namesIndex + i]);
2179const char *QMetaMethodPrivate::tag()
const
2181 Q_ASSERT(priv(mobj->d.data)->revision >= 7);
2182 return rawStringData(mobj, data.tag());
2185int QMetaMethodPrivate::ownMethodIndex()
const
2188 return ( data.d - mobj->d.data - priv(mobj->d.data)->methodData)/Data::Size;
2191int QMetaMethodPrivate::ownConstructorMethodIndex()
const
2194 Q_ASSERT(methodType() == Constructor);
2195 return ( data.d - mobj->d.data - priv(mobj->d.data)->constructorData)/Data::Size;
2199
2200
2201
2202
2203
2204
2205
2206QByteArray QMetaMethod::methodSignature()
const
2209 return QByteArray();
2210 return QMetaMethodPrivate::get(
this)->signature();
2214
2215
2216
2217
2218
2219
2220QByteArray QMetaMethod::name()
const
2223 return QByteArray();
2225 return stringData(mobj, QMetaMethodPrivate::get(
this)->name());
2229
2230
2231
2232
2233
2234
2235
2236
2237QByteArrayView QMetaMethod::nameView()
const
2239 return QMetaMethodPrivate::get(
this)->name();
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252int QMetaMethod::returnType()
const
2254 return returnMetaType().id();
2258
2259
2260
2261
2262
2263QMetaType QMetaMethod::returnMetaType()
const
2265 if (!mobj || methodType() == QMetaMethod::Constructor)
2267 auto mt = QMetaType(mobj->d.metaTypes[data.metaTypeOffset()]);
2268 if (mt.id() == QMetaType::UnknownType)
2269 return QMetaType(QMetaMethodPrivate::get(
this)->returnType());
2275
2276
2277
2278
2279
2280
2281int QMetaMethod::parameterCount()
const
2285 return QMetaMethodPrivate::get(
this)->parameterCount();
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298int QMetaMethod::parameterType(
int index)
const
2300 return parameterMetaType(index).id();
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313QMetaType QMetaMethod::parameterMetaType(
int index)
const
2315 if (!mobj || index < 0)
2317 auto priv = QMetaMethodPrivate::get(
this);
2318 if (index >= priv->parameterCount())
2321 auto parameterOffset = index + (methodType() == QMetaMethod::Constructor ? 0 : 1);
2322 auto mt = QMetaType(mobj->d.metaTypes[data.metaTypeOffset() + parameterOffset]);
2323 if (mt.id() == QMetaType::UnknownType)
2324 return QMetaType(QMetaMethodPrivate::get(
this)->parameterType(index));
2330
2331
2332
2333
2334
2335
2336
2337
2338void QMetaMethod::getParameterTypes(
int *types)
const
2342 QMetaMethodPrivate::get(
this)->getParameterTypes(types);
2346
2347
2348
2349
2350QList<QByteArray> QMetaMethod::parameterTypes()
const
2353 return QList<QByteArray>();
2354 return QMetaMethodPrivate::get(
this)->parameterTypes();
2358
2359
2360
2361
2362
2363
2364QByteArray QMetaMethod::parameterTypeName(
int index)
const
2366 if (!mobj || index < 0 || index >= parameterCount())
2369 return stringData(mobj, QMetaMethodPrivate::get(
this)->parameterTypeName(index));
2373
2374
2375
2376
2377QList<QByteArray> QMetaMethod::parameterNames()
const
2380 return QList<QByteArray>();
2381 return QMetaMethodPrivate::get(
this)->parameterNames();
2386
2387
2388
2389
2390
2391
2392
2393
2394const char *QMetaMethod::typeName()
const
2398#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
2399 if (methodType() == QMetaMethod::Constructor)
2402 return QMetaMethodPrivate::get(
this)->rawReturnTypeName();
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429const char *QMetaMethod::tag()
const
2433 return QMetaMethodPrivate::get(
this)->tag();
2438
2439
2440int QMetaMethod::attributes()
const
2444 return data.flags() >> 4;
2448
2449
2450
2451
2452int QMetaMethod::methodIndex()
const
2456 return QMetaMethodPrivate::get(
this)->ownMethodIndex() + mobj->methodOffset();
2460
2461
2462
2463
2464int QMetaMethod::relativeMethodIndex()
const
2468 return QMetaMethodPrivate::get(
this)->ownMethodIndex();
2473
2474
2475
2476
2477
2478int QMetaMethod::revision()
const
2482 if ((data.flags() & MethodRevisioned) == 0)
2484#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
2485 if (priv(mobj->d.data)->revision < 13) {
2487 int offset = priv(mobj->d.data)->methodData
2488 + priv(mobj->d.data)->methodCount * Data::Size
2489 + QMetaMethodPrivate::get(
this)->ownMethodIndex();
2490 return mobj->d.data[offset];
2494 return mobj->d.data[data.parameters() - 1];
2498
2499
2500
2501
2502
2503
2504
2505bool QMetaMethod::isConst()
const
2509 if (QMetaObjectPrivate::get(mobj)->revision < 10)
2511 return data.flags() & MethodIsConst;
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524QMetaMethod::Access QMetaMethod::access()
const
2526 constexpr int AccessShift = qCountTrailingZeroBits(AccessMask);
2527 static_assert(AccessPrivate >> AccessShift == Private);
2528 static_assert(AccessProtected >> AccessShift == Protected);
2529 static_assert(AccessPublic >> AccessShift == Public);
2532 return Access((data.flags() & AccessMask) >> AccessShift);
2536
2537
2538
2539
2540QMetaMethod::MethodType QMetaMethod::methodType()
const
2542 constexpr int MethodShift = qCountTrailingZeroBits(MethodTypeMask);
2543 static_assert(MethodMethod >> MethodShift == Method);
2544 static_assert(MethodSignal >> MethodShift == Signal);
2545 static_assert(MethodSlot >> MethodShift == Slot);
2546 static_assert(MethodConstructor >> MethodShift == Constructor);
2548 return QMetaMethod::Method;
2549 return MethodType((data.flags() & MethodTypeMask) >> MethodShift);
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2565
2566
2567
2568
2569
2570
2571
2572QMetaMethod QMetaMethod::fromSignalImpl(
const QMetaObject *metaObject,
void **signal)
2575 void *args[] = { &i, signal };
2576 for (
const QMetaObject *m = metaObject; m; m = m->d.superdata) {
2577 m->static_metacall(QMetaObject::IndexOfMethod, 0, args);
2579 return QMetaMethod::fromRelativeMethodIndex(m, i);
2581 return QMetaMethod();
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
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696bool QMetaMethod::invoke(QObject *object,
2697 Qt::ConnectionType connectionType,
2698 QGenericReturnArgument returnValue,
2699 QGenericArgument val0,
2700 QGenericArgument val1,
2701 QGenericArgument val2,
2702 QGenericArgument val3,
2703 QGenericArgument val4,
2704 QGenericArgument val5,
2705 QGenericArgument val6,
2706 QGenericArgument val7,
2707 QGenericArgument val8,
2708 QGenericArgument val9)
const
2710 if (!object || !mobj)
2714 const char *typeNames[] = {
2742 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
2743 if (qstrlen(typeNames[paramCount]) <= 0)
2746 return invokeImpl(*
this, object, connectionType, paramCount, param, typeNames,
nullptr);
2749bool QMetaMethod::invokeImpl(QMetaMethod self,
void *target, Qt::ConnectionType connectionType,
2750 qsizetype paramCount,
const void *
const *parameters,
2751 const char *
const *typeNames,
2752 const QtPrivate::QMetaTypeInterface *
const *metaTypes)
2754 if (!target || !self.mobj)
2756 QMetaMethodPrivate::InvokeFailReason r =
2757 QMetaMethodPrivate::invokeImpl(self, target, connectionType, paramCount, parameters,
2758 typeNames, metaTypes);
2759 if (Q_LIKELY(r == QMetaMethodPrivate::InvokeFailReason::None))
2762 if (
int(r) >=
int(QMetaMethodPrivate::InvokeFailReason::FormalParameterMismatch)) {
2763 int n =
int(r) -
int(QMetaMethodPrivate::InvokeFailReason::FormalParameterMismatch);
2764 qWarning(
"QMetaMethod::invoke: cannot convert formal parameter %d from %s in call to %s::%s",
2765 n, typeNames[n + 1] ? typeNames[n + 1] : metaTypes[n + 1]->name,
2766 self.mobj->className(), self.methodSignature().constData());
2768 if (r == QMetaMethodPrivate::InvokeFailReason::TooFewArguments) {
2769 qWarning(
"QMetaMethod::invoke: too few arguments (%d) in call to %s::%s",
2770 int(paramCount), self.mobj->className(), self.methodSignature().constData());
2776 Qt::ConnectionType connectionType,
2777 qsizetype paramCount,
const void *
const *parameters,
2778 const char *
const *typeNames,
2781 auto object =
static_cast<QObject *>(target);
2782 auto priv = QMetaMethodPrivate::get(&self);
2783 constexpr bool MetaTypesAreOptional = QT_VERSION < QT_VERSION_CHECK(7, 0, 0);
2784 auto methodMetaTypes = priv->parameterMetaTypeInterfaces();
2785 auto param =
const_cast<
void **>(parameters);
2787 Q_ASSERT(priv->mobj);
2788 Q_ASSERT(self.methodType() == Constructor || object);
2789 Q_ASSERT(self.methodType() == Constructor || connectionType == Qt::ConnectionType(-1) ||
2790 priv->mobj->cast(object));
2791 Q_ASSERT(paramCount >= 1);
2792 Q_ASSERT(parameters);
2793 Q_ASSERT(typeNames);
2794 Q_ASSERT(MetaTypesAreOptional || metaTypes);
2796 if ((paramCount - 1) < qsizetype(priv->data.argc()))
2800 auto checkTypesAreCompatible = [=](
int idx) {
2801 uint typeInfo = priv->parameterTypeInfo(idx - 1);
2802 QByteArrayView userTypeName(typeNames[idx] ? typeNames[idx] : metaTypes[idx]
->name);
2804 if ((typeInfo & IsUnresolvedType) == 0) {
2806 if (MetaTypesAreOptional && !metaTypes)
2807 return int(typeInfo) == QMetaType::fromName(userTypeName).id();
2808 return int(typeInfo) == metaTypes[idx]->typeId;
2811 QByteArrayView methodTypeName = stringDataView(priv->mobj, typeInfo & TypeNameIndexMask);
2812 if ((MetaTypesAreOptional && !metaTypes) || !metaTypes[idx]) {
2814 if (methodTypeName == userTypeName)
2818 QByteArray normalized = normalizeTypeInternal(userTypeName.begin(), userTypeName.end());
2819 return methodTypeName == normalized;
2823 Q_ASSERT(userType.isValid());
2824 if (QMetaType(methodMetaTypes[idx - 1]) == userType)
2829 if (methodMetaTypes[idx - 1])
2833 QMetaType resolved = QMetaType::fromName(methodTypeName);
2834 return resolved == userType;
2838 for (qsizetype i = 0; metaTypes && i < paramCount; ++i)
2842 for (qsizetype i = 1; i < paramCount; ++i) {
2843 if (!checkTypesAreCompatible(i))
2848 if (self.methodType() == Constructor) {
2850 qWarning(
"QMetaMethod::invokeMethod: cannot call constructor %s on object %p",
2851 self.methodSignature().constData(), object);
2855 if (!parameters[0]) {
2856 qWarning(
"QMetaMethod::invokeMethod: constructor call to %s must assign a return type",
2857 self.methodSignature().constData());
2861 if (!MetaTypesAreOptional || metaTypes) {
2862 if (metaTypes[0]->typeId != QMetaType::QObjectStar) {
2863 qWarning(
"QMetaMethod::invokeMethod: cannot convert QObject* to %s on constructor call %s",
2864 metaTypes[0]
->name, self.methodSignature().constData());
2869 int idx = priv->ownConstructorMethodIndex();
2870 if (priv->mobj->static_metacall(QMetaObject::CreateInstance, idx, param) >= 0)
2876 if (parameters[0]) {
2877 if (!checkTypesAreCompatible(0)) {
2878 const char *retType = typeNames[0] ? typeNames[0] : metaTypes[0]
->name;
2879 qWarning(
"QMetaMethod::invokeMethod: return type mismatch for method %s::%s:"
2880 " cannot convert from %s to %s during invocation",
2881 priv->mobj->className(), priv->methodSignature().constData(),
2882 priv->rawReturnTypeName(), retType);
2887 Qt::HANDLE currentThreadId =
nullptr;
2888 QThread *objectThread =
nullptr;
2889 auto receiverInSameThread = [&]() {
2890 if (!currentThreadId) {
2891 currentThreadId = QThread::currentThreadId();
2892 objectThread = object->thread();
2895 return currentThreadId == QThreadData::get2(objectThread)->threadId.loadRelaxed();
2900 if (connectionType == Qt::AutoConnection)
2901 connectionType = receiverInSameThread() ? Qt::DirectConnection : Qt::QueuedConnection;
2902 else if (connectionType == Qt::ConnectionType(-1))
2903 connectionType = Qt::DirectConnection;
2905#if !QT_CONFIG(thread)
2906 if (connectionType == Qt::BlockingQueuedConnection) {
2907 connectionType = Qt::DirectConnection;
2912 int idx_relative = priv->ownMethodIndex();
2913 int idx_offset = priv->mobj->methodOffset();
2914 QObjectPrivate::StaticMetaCallFunction callFunction = priv->mobj->d.static_metacall;
2916 if (connectionType == Qt::DirectConnection) {
2918 callFunction(object, QMetaObject::InvokeMetaMethod, idx_relative, param);
2919 else if (QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, idx_relative + idx_offset, param) >= 0)
2921 }
else if (connectionType == Qt::QueuedConnection) {
2922 if (parameters[0]) {
2923 qWarning(
"QMetaMethod::invoke: Unable to invoke methods with return values in "
2924 "queued connections");
2928 QVarLengthArray<
const QtPrivate::QMetaTypeInterface *, 16> argTypes;
2929 argTypes.reserve(paramCount);
2930 argTypes.emplace_back(
nullptr);
2932 for (
int i = 1; i < paramCount; ++i) {
2933 QMetaType type = QMetaType(methodMetaTypes[i - 1]);
2934 if (!type.iface() && (!MetaTypesAreOptional || metaTypes))
2935 type = QMetaType(metaTypes[i]);
2937 type = priv->parameterMetaType(i - 1);
2938 if (!type.iface() && typeNames[i])
2939 type = QMetaType::fromName(typeNames[i]);
2940 if (!type.iface()) {
2941 qWarning(
"QMetaMethod::invoke: Unable to handle unregistered datatype '%s'",
2945 argTypes.emplace_back(type.iface());
2948 QCoreApplication::postEvent(object,
new QQueuedMetaCallEvent(idx_offset, idx_relative, callFunction,
nullptr,
2949 -1, paramCount, argTypes.data(), parameters));
2951#if QT_CONFIG(thread)
2952 if (receiverInSameThread()) {
2953 qWarning(
"QMetaMethod::invoke: Dead lock detected in BlockingQueuedConnection: "
2954 "Receiver is %s(%p)", priv->mobj->className(), object);
2955 return InvokeFailReason::DeadLockDetected;
2959 QCoreApplication::postEvent(object,
new QMetaCallEvent(idx_offset, idx_relative, callFunction,
2960 nullptr, -1, param, &latch));
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070bool QMetaMethod::invokeOnGadget(
void *gadget,
3071 QGenericReturnArgument returnValue,
3072 QGenericArgument val0,
3073 QGenericArgument val1,
3074 QGenericArgument val2,
3075 QGenericArgument val3,
3076 QGenericArgument val4,
3077 QGenericArgument val5,
3078 QGenericArgument val6,
3079 QGenericArgument val7,
3080 QGenericArgument val8,
3081 QGenericArgument val9)
const
3083 if (!gadget || !mobj)
3087 if (returnValue.data()) {
3088 const char *retType = typeName();
3089 if (qstrcmp(returnValue.name(), retType) != 0) {
3091 QByteArray normalized = QMetaObject::normalizedType(returnValue.name());
3092 if (qstrcmp(normalized.constData(), retType) != 0) {
3094 int t = returnType();
3095 if (t == QMetaType::UnknownType || t != QMetaType::fromName(normalized).id())
3102 const char *typeNames[] = {
3116 for (paramCount = 1; paramCount < MaximumParamCount; ++paramCount) {
3117 if (qstrlen(typeNames[paramCount]) <= 0)
3120 if (paramCount <= QMetaMethodPrivate::get(
this)->parameterCount())
3137 int idx_relative = QMetaMethodPrivate::get(
this)->ownMethodIndex();
3138 Q_ASSERT(QMetaObjectPrivate::get(mobj)->revision >= 6);
3139 QObjectPrivate::StaticMetaCallFunction callFunction = mobj->d.static_metacall;
3142 callFunction(
reinterpret_cast<QObject*>(gadget), QMetaObject::InvokeMetaMethod, idx_relative, param);
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3203
3204
3205
3206
3207
3208
3209
3212
3213
3214
3218
3219
3220
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233const char *QMetaEnum::name()
const
3237 return rawStringData(mobj, data.name());
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252const char *QMetaEnum::enumName()
const
3256 return rawStringData(mobj, data.alias());
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271QMetaType QMetaEnum::metaType()
const
3276 const QMetaObjectPrivate *p = priv(mobj->d.data);
3277#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
3278 if (p->revision < 12)
3282 return QMetaType(mobj->d.metaTypes[data.index(mobj) + p->propertyCount]);
3286
3287
3288
3289
3290int QMetaEnum::keyCount()
const
3294 return data.keyCount();
3298
3299
3300
3301
3302const char *QMetaEnum::key(
int index)
const
3306 if (index >= 0 && index <
int(data.keyCount()))
3307 return rawStringData(mobj, mobj->d.data[data.data() + 2*index]);
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321int QMetaEnum::value(
int index)
const
3323 return value64(index).value_or(-1);
3331Q_DECL_PURE_FUNCTION
static inline EnumExtendMode enumExtendMode(
const QMetaEnum &e)
3337 if (e.metaType().flags() & QMetaType::IsUnsignedEnumeration)
3349 return value == uint(value);
3350 return value == quint64(
int(value));
3353template <
typename... Mode>
inline
3354quint64 QMetaEnum::value_helper(uint index, Mode... modes)
const noexcept
3356 static_assert(
sizeof...(Mode) < 2);
3357 if constexpr (
sizeof...(Mode) == 0) {
3358 return value_helper(index, enumExtendMode(*
this));
3359 }
else if constexpr (
sizeof...(Mode) == 1) {
3360 auto mode = (modes, ...);
3361 quint64 value = mobj->d.data[data.data() + 2U * index + 1];
3363 value |= quint64(mobj->d.data[data.data() + 2U * data.keyCount() + index]) << 32;
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392std::optional<quint64> QMetaEnum::value64(
int index)
const
3395 return std::nullopt;
3396 if (index < 0 || index >=
int(data.keyCount()))
3397 return std::nullopt;
3399 return value_helper(index);
3403
3404
3405
3406
3407
3408
3409
3410
3411bool QMetaEnum::isFlag()
const
3415 return data.flags() & EnumIsFlag;
3419
3420
3421
3422
3423
3424bool QMetaEnum::isScoped()
const
3428 return data.flags() & EnumIsScoped;
3432
3433
3434
3435
3436
3437
3438bool QMetaEnum::is64Bit()
const
3442 return data.flags() & EnumIs64Bit;
3446
3447
3448
3449
3450
3451
3452
3453const char *QMetaEnum::scope()
const
3455 return mobj ? mobj->className() :
nullptr;
3460 const QByteArrayView className = e->enclosingMetaObject()->className();
3465 if (scope == className)
3471 QByteArrayView name = e->enumName();
3475 const auto sz = className.size();
3476 if (scope.size() == sz + qsizetype(qstrlen(
"::")) + name.size()
3477 && scope.startsWith(className)
3478 && scope.sliced(sz, 2) ==
"::"
3479 && scope.sliced(sz + 2) == name)
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500int QMetaEnum::keyToValue(
const char *key,
bool *ok)
const
3502 auto value = keyToValue64(key);
3504 *ok = value.has_value();
3505 return int(value.value_or(-1));
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520std::optional<quint64> QMetaEnum::keyToValue64(
const char *key)
const
3523 return std::nullopt;
3524 const auto [scope, enumKey] = parse_scope(QLatin1StringView(key));
3525 for (
int i = 0; i <
int(data.keyCount()); ++i) {
3526 if ((!scope || isScopeMatch(*scope,
this))
3527 && enumKey == stringDataView(mobj, mobj->d.data[data.data() + 2 * i])) {
3528 return value_helper(i);
3531 return std::nullopt;
3535
3536
3537
3538
3539
3540
3541
3542const char *QMetaEnum::valueToKey(quint64 value)
const
3547 EnumExtendMode mode = enumExtendMode(*
this);
3548 if (!isEnumValueSuitable(value, mode))
3551 for (
int i = 0; i <
int(data.keyCount()); ++i) {
3552 if (value == value_helper(i, mode))
3553 return rawStringData(mobj, mobj->d.data[data.data() + 2 * i]);
3558static bool parseEnumFlags(QByteArrayView v, QVarLengthArray<QByteArrayView, 10> &list)
3562 qWarning(
"QMetaEnum::keysToValue: empty keys string.");
3566 qsizetype sep = v.indexOf(
'|', 0);
3568 qWarning(
"QMetaEnum::keysToValue: malformed keys string, starts with '|', \"%s\"",
3578 if (v.endsWith(
'|')) {
3579 qWarning(
"QMetaEnum::keysToValue: malformed keys string, ends with '|', \"%s\"",
3584 const auto begin = v.begin();
3585 const auto end = v.end();
3587 for (; b != end && sep != -1; sep = v.indexOf(
'|', sep)) {
3588 list.push_back({b, begin + sep});
3592 qWarning(
"QMetaEnum::keysToValue: malformed keys string, has two consecutive '|': "
3593 "\"%s\"", v.constData());
3599 list.push_back({b, end});
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617int QMetaEnum::keysToValue(
const char *keys,
bool *ok)
const
3619 auto value = keysToValue64(keys);
3621 *ok = value.has_value();
3622 return int(value.value_or(-1));
3626
3627
3628
3629
3630
3631
3632
3633
3634std::optional<quint64> QMetaEnum::keysToValue64(
const char *keys)
const
3637 return std::nullopt;
3639 EnumExtendMode mode = enumExtendMode(*
this);
3640 auto lookup = [&] (QByteArrayView key) -> std::optional<quint64> {
3641 for (
int i = data.keyCount() - 1; i >= 0; --i) {
3642 if (key == stringDataView(mobj, mobj->d.data[data.data() + 2*i]))
3643 return value_helper(i, mode);
3645 return std::nullopt;
3649 QVarLengthArray<QByteArrayView, 10> list;
3650 const bool r = parseEnumFlags(QByteArrayView{keys}, list);
3652 return std::nullopt;
3653 for (
const auto &untrimmed : list) {
3654 const auto parsed = parse_scope(untrimmed.trimmed());
3655 if (parsed.scope && !isScopeMatch(*parsed.scope,
this))
3656 return std::nullopt;
3657 if (
auto thisValue = lookup(parsed.key))
3658 value |= *thisValue;
3660 return std::nullopt;
3667template <
typename String,
typename Container,
typename Separator>
3668void join_reversed(String &s,
const Container &c, Separator sep)
3672 qsizetype len = qsizetype(c.size()) - 1;
3674 len += qsizetype(e.size());
3677 for (
auto rit = c.rbegin(), rend = c.rend(); rit != rend; ++rit) {
3678 const auto &e = *rit;
3682 s.append(e.data(), e.size());
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697QByteArray QMetaEnum::valueToKeys(quint64 value)
const
3703 EnumExtendMode mode = enumExtendMode(*
this);
3704 if (!isEnumValueSuitable(value, mode))
3707 QVarLengthArray<QByteArrayView,
sizeof(
int) * CHAR_BIT> parts;
3711 for (
int i = data.keyCount() - 1; i >= 0; --i) {
3712 quint64 k = value_helper(i, mode);
3713 if ((k != 0 && (v & k) == k) || (k == value)) {
3715 parts.push_back(stringDataView(mobj, mobj->d.data[data.data() + 2 * i]));
3718 join_reversed(keys, parts,
'|');
3723
3724
3725QMetaEnum::QMetaEnum(
const QMetaObject *mobj,
int index)
3726 : mobj(mobj), data({ mobj->d.data + priv(mobj->d.data)->enumeratorData + index * Data::Size })
3728 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->enumeratorCount);
3731int QMetaEnum::Data::index(
const QMetaObject *mobj)
const
3733#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
3734# warning "Consider changing Size to a power of 2"
3736 return (
unsigned(d - mobj->d.data) - priv(mobj->d.data)->enumeratorData) / Size;
3740
3741
3742
3743
3744
3745
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3784
3785
3786
3787
3788
3789
3790
3793
3794
3795
3798
3799
3800
3803
3804
3805
3806
3807const char *QMetaProperty::name()
const
3811 return rawStringData(mobj, data.name());
3815
3816
3817
3818
3819const char *QMetaProperty::typeName()
const
3824 if (
const auto mt = metaType(); mt.isValid())
3826 return typeNameFromTypeInfo(mobj, data.type()).constData();
3830
3831
3832
3833
3834
3835
3836
3839
3840
3841
3842
3843
3844
3845
3846
3847
3850
3851
3852
3853
3854
3855
3856
3859
3860
3861
3862
3863
3864
3865QMetaType QMetaProperty::metaType()
const
3869 return QMetaType(mobj->d.metaTypes[data.index(mobj)]);
3872int QMetaProperty::Data::index(
const QMetaObject *mobj)
const
3874#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
3875# warning "Consider changing Size to a power of 2"
3877 return (
unsigned(d - mobj->d.data) - priv(mobj->d.data)->propertyData) / Size;
3881
3882
3883
3884
3885int QMetaProperty::propertyIndex()
const
3889 return data.index(mobj) + mobj->propertyOffset();
3893
3894
3895
3896
3897int QMetaProperty::relativePropertyIndex()
const
3901 return data.index(mobj);
3905
3906
3907
3908
3909
3910
3911
3912
3914bool QMetaProperty::isFlagType()
const
3916 return isEnumType() && menum.isFlag();
3920
3921
3922
3923
3924
3925bool QMetaProperty::isEnumType()
const
3929 return (data.flags() & EnumOrFlag) && menum.name();
3933
3934
3935
3936
3937
3938
3939
3940
3941bool QMetaProperty::hasStdCppSet()
const
3945 return (data.flags() & StdCppSet);
3949
3950
3951
3952
3953
3954
3955bool QMetaProperty::isAlias()
const
3959 return (data.flags() & Alias);
3962#if QT_DEPRECATED_SINCE(6
, 4
)
3964
3965
3966
3967
3968
3969
3970
3971int QMetaProperty::registerPropertyType()
const
3977QMetaProperty::QMetaProperty(
const QMetaObject *mobj,
int index)
3979 data(getMetaPropertyData(mobj, index))
3981 Q_ASSERT(index >= 0 && index < priv(mobj->d.data)->propertyCount);
3983 if (!(data.flags() & EnumOrFlag) || !metaType().flags().testFlag(QMetaType::IsEnumeration))
3985 QByteArrayView enum_name = typeNameFromTypeInfo(mobj, data.type());
3986 menum = mobj->enumerator(QMetaObjectPrivate::indexOfEnumerator(mobj, enum_name));
3987 if (menum.isValid())
3990 QByteArrayView scope_name;
3991 const auto parsed = parse_scope(enum_name);
3993 scope_name = *parsed.scope;
3994 enum_name = parsed.key;
3996 scope_name = objectClassName(mobj);
3999 const QMetaObject *scope =
nullptr;
4000 if (scope_name ==
"Qt")
4001 scope = &Qt::staticMetaObject;
4003 scope = QMetaObject_findMetaObject(mobj, QByteArrayView(scope_name));
4006 menum = scope->enumerator(QMetaObjectPrivate::indexOfEnumerator(scope, enum_name));
4010
4011
4012
4013QMetaProperty::Data QMetaProperty::getMetaPropertyData(
const QMetaObject *mobj,
int index)
4015 return { mobj->d.data + priv(mobj->d.data)->propertyData + index * Data::Size };
4019
4020
4021
4022
4023
4024QMetaEnum QMetaProperty::enumerator()
const
4030
4031
4032
4033
4034
4035QVariant QMetaProperty::read(
const QObject *object)
const
4037 if (!object || !mobj)
4047 void *argv[] = {
nullptr, &value, &status };
4048 QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
4049 if (t == QMetaType::fromType<QVariant>()) {
4052 value = QVariant(t,
nullptr);
4053 argv[0] = value.data();
4055 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall) {
4056 mobj->d.static_metacall(
const_cast<QObject*>(object), QMetaObject::ReadProperty, data.index(mobj), argv);
4058 QMetaObject::metacall(
const_cast<QObject*>(object), QMetaObject::ReadProperty,
4059 data.index(mobj) + mobj->propertyOffset(), argv);
4064 if (t != QMetaType::fromType<QVariant>() && argv[0] != value.data())
4066 return QVariant(t, argv[0]);
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084bool QMetaProperty::write(QObject *object,
const QVariant &value)
const
4086 if (!object || !isWritable())
4088 return write(object, QVariant(value));
4092
4093
4094
4095bool QMetaProperty::write(QObject *object, QVariant &&v)
const
4097 if (!object || !isWritable())
4099 QMetaType t(mobj->d.metaTypes[data.index(mobj)]);
4100 if (t != QMetaType::fromType<QVariant>() && t != v.metaType()) {
4101 if (isEnumType() && !t.metaObject() && v.metaType() == QMetaType::fromType<QString>()) {
4105 std::optional value = isFlagType() ? menum.keysToValue64(v.toByteArray())
4106 : menum.keyToValue64(v.toByteArray());
4108 v = QVariant(qlonglong(*value));
4115 return reset(object);
4116 v = QVariant(t,
nullptr);
4117 }
else if (!v.convert(t)) {
4130 void *argv[] = {
nullptr, &v, &status, &flags };
4131 if (t == QMetaType::fromType<QVariant>())
4135 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
4136 mobj->d.static_metacall(object, QMetaObject::WriteProperty, data.index(mobj), argv);
4138 QMetaObject::metacall(object, QMetaObject::WriteProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4144
4145
4146
4147
4148
4149
4150
4151bool QMetaProperty::reset(QObject *object)
const
4153 if (!object || !mobj || !isResettable())
4155 void *argv[] = {
nullptr };
4156 if (priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall)
4157 mobj->d.static_metacall(object, QMetaObject::ResetProperty, data.index(mobj), argv);
4159 QMetaObject::metacall(object, QMetaObject::ResetProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4164
4165
4166
4167
4168
4169
4170
4171
4172QUntypedBindable QMetaProperty::bindable(QObject *object)
const
4174 QUntypedBindable bindable;
4175 void * argv[1] { &bindable };
4176 mobj->metacall(object, QMetaObject::BindableProperty, data.index(mobj) + mobj->propertyOffset(), argv);
4180
4181
4182
4183
4184
4185
4186
4187QVariant QMetaProperty::readOnGadget(
const void *gadget)
const
4189 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4190 return read(
reinterpret_cast<
const QObject*>(gadget));
4194
4195
4196
4197
4198
4199
4200
4201bool QMetaProperty::writeOnGadget(
void *gadget,
const QVariant &value)
const
4203 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4204 return write(
reinterpret_cast<QObject*>(gadget), value);
4208
4209
4210
4211bool QMetaProperty::writeOnGadget(
void *gadget, QVariant &&value)
const
4213 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4214 return write(
reinterpret_cast<QObject*>(gadget), std::move(value));
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227bool QMetaProperty::resetOnGadget(
void *gadget)
const
4229 Q_ASSERT(priv(mobj->d.data)->flags & PropertyAccessInStaticMetaCall && mobj->d.static_metacall);
4230 return reset(
reinterpret_cast<QObject*>(gadget));
4234
4235
4236
4237
4238
4239bool QMetaProperty::isResettable()
const
4243 return data.flags() & Resettable;
4247
4248
4249
4250
4251bool QMetaProperty::isReadable()
const
4255 return data.flags() & Readable;
4259
4260
4261
4262
4263
4264bool QMetaProperty::hasNotifySignal()
const
4268 return data.notifyIndex() != uint(-1);
4272
4273
4274
4275
4276
4277
4278
4279QMetaMethod QMetaProperty::notifySignal()
const
4281 int id = notifySignalIndex();
4283 return mobj->method(id);
4285 return QMetaMethod();
4289
4290
4291
4292
4293
4294
4295
4296int QMetaProperty::notifySignalIndex()
const
4298 if (!mobj || data.notifyIndex() == std::numeric_limits<uint>::max())
4300 uint methodIndex = data.notifyIndex();
4301 if (!(methodIndex & IsUnresolvedSignal))
4302 return methodIndex + mobj->methodOffset();
4303 methodIndex &= ~IsUnresolvedSignal;
4304 const QByteArrayView signalName = stringDataView(mobj, methodIndex);
4305 const QMetaObject *m = mobj;
4307 int idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, {}, QMetaMethod::Signal);
4309 return idx + m->methodOffset();
4311 QArgumentType argType[] = {metaType()};
4312 idx = QMetaObjectPrivate::indexOfMethodRelative(&m, signalName, argType, QMetaMethod::Signal);
4314 return idx + m->methodOffset();
4315 qWarning(
"QMetaProperty::notifySignal: cannot find the NOTIFY signal %s in class %s for property '%s'",
4316 signalName.constData(), mobj->className(), name());
4322
4323
4324
4325
4326
4327
4328int QMetaProperty::revision()
const
4332 return data.revision();
4336
4337
4338
4339
4340
4341bool QMetaProperty::isWritable()
const
4345 return data.flags() & Writable;
4349
4350
4351
4352
4353
4354bool QMetaProperty::isDesignable()
const
4358 return data.flags() & Designable;
4362
4363
4364
4365
4366
4367bool QMetaProperty::isScriptable()
const
4371 return data.flags() & Scriptable;
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384bool QMetaProperty::isStored()
const
4388 return data.flags() & Stored;
4392
4393
4394
4395
4396
4397
4398
4399bool QMetaProperty::isUser()
const
4403 return data.flags() & User;
4407
4408
4409
4410
4411
4412
4413bool QMetaProperty::isConstant()
const
4417 return data.flags() & Constant;
4421
4422
4423
4424
4425
4426
4427bool QMetaProperty::isFinal()
const
4431 return data.flags() & Final;
4435
4436
4437
4438
4439
4440
4441bool QMetaProperty::isVirtual()
const
4445 return data.flags() & Virtual;
4449
4450
4451
4452
4453
4454
4455bool QMetaProperty::isOverride()
const
4459 return data.flags() & Override;
4463
4464
4465
4466
4467
4468
4469bool QMetaProperty::isRequired()
const
4473 return data.flags() & Required;
4477
4478
4479
4480
4481
4482
4483
4484
4485bool QMetaProperty::isBindable()
const
4489 return (data.flags() & Bindable);
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4517
4518
4519
4522
4523
4524
4527
4528
4529
4530
4531const char *QMetaClassInfo::name()
const
4535 return rawStringData(mobj, data.name());
4539
4540
4541
4542
4543const char *QMetaClassInfo::value()
const
4547 return rawStringData(mobj, data.value());
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4565
4566
4567
4568
4569
4570
4571
4572
4573
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4601
4602
4603
4604
4607
4608
4609
4610
4613
4614
4615
4616
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4632
4633
4634
4635
4636
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4652 Q_ASSERT(local_method_index < get(mobj)->methodCount);
4653 while (QMetaMethod::fromRelativeMethodIndex(mobj, local_method_index).data.flags() & MethodCloned) {
4654 Q_ASSERT(local_method_index > 0);
4655 --local_method_index;
4657 return local_method_index;
4661
4662
4663
4664
4665
4666
4667
4668
4671 QVarLengthArray<QByteArrayView, 10> &typeNames)
4673 const char *signature =
static_cast<
const char *>(memchr(sig.begin(),
'(', sig.size()));
4676 auto name = QByteArrayView{sig.begin(), signature};
4678 if (!sig.endsWith(
')'))
4680 const char *end = sig.end() - 1;
4681 while (signature != end) {
4682 if (*signature ==
',')
4684 const char *begin = signature;
4686 while (signature != end && (level > 0 || *signature !=
',')) {
4687 if (*signature ==
'<')
4689 else if (*signature ==
'>')
4693 typeNames.append(QByteArrayView{begin, signature - begin});