558QMetaPropertyBuilder QMetaObjectBuilder::addProperty(
const QMetaProperty &prototype)
560 QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName(), prototype.metaType());
561 property.setReadable(prototype.isReadable());
562 property.setWritable(prototype.isWritable());
563 property.setResettable(prototype.isResettable());
564 property.setDesignable(prototype.isDesignable());
565 property.setScriptable(prototype.isScriptable());
566 property.setStored(prototype.isStored());
567 property.setUser(prototype.isUser());
568 property.setStdCppSet(prototype.hasStdCppSet());
569 property.setEnumOrFlag(prototype.isEnumType());
570 property.setConstant(prototype.isConstant());
571 property.setFinal(prototype.isFinal());
572 property.setVirtual(prototype.isVirtual());
573 property.setOverride(prototype.isOverride());
574 property.setRevision(prototype.revision());
575 if (prototype.hasNotifySignal()) {
577 QMetaMethod method = prototype.notifySignal();
578 const QByteArray signature = method.methodSignature();
579 int index = indexOfSignal(signature);
581 index = addSignal(signature).index();
582 d->properties[property._index].notifySignal = index;
667void QMetaObjectBuilder::addMetaObject(
const QMetaObject *prototype,
668 QMetaObjectBuilder::AddMembers members)
673 if ((members & ClassName) != 0)
674 d->className = prototype->className();
676 if ((members & SuperClass) != 0)
677 d->superClass = prototype->superClass();
679 if ((members & (Methods | Signals | Slots)) != 0) {
680 for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) {
681 QMetaMethod method = prototype->method(index);
682 if (method.methodType() != QMetaMethod::Signal) {
683 switch (method.access()) {
684 case QMetaMethod::Public:
685 if ((members & PublicMethods) == 0)
688 case QMetaMethod::Private:
689 if ((members & PrivateMethods) == 0)
692 case QMetaMethod::Protected:
693 if ((members & ProtectedMethods) == 0)
698 switch (method.methodType()) {
699 case QMetaMethod::Method:
700 if (members & Methods)
703 case QMetaMethod::Signal:
704 if (members & Signals)
707 case QMetaMethod::Slot:
711 case QMetaMethod::Constructor:
717 if ((members & Constructors) != 0) {
718 for (index = 0; index < prototype->constructorCount(); ++index)
719 addConstructor(prototype->constructor(index));
722 if ((members & Properties) != 0) {
723 for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index)
724 addProperty(prototype->property(index));
727 if ((members & Enumerators) != 0) {
728 for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index)
729 addEnumerator(prototype->enumerator(index));
732 if ((members & ClassInfos) != 0) {
733 for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) {
734 QMetaClassInfo ci = prototype->classInfo(index);
735 addClassInfo(ci.name(), ci.value());
739 if ((members & RelatedMetaObjects) != 0) {
740 Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 2);
741 const auto *objects = prototype->d.relatedMetaObjects;
743 while (*objects !=
nullptr) {
744 addRelatedMetaObject(*objects);
750 if ((members & StaticMetacall) != 0) {
751 Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 6);
752 if (prototype->d.static_metacall)
753 setStaticMetacallFunction(prototype->d.static_metacall);
1219 Q_UNUSED(expectedSize);
1224 const auto bufferAt = [&](qsizetype offset) ->
char * {
1226 return buf + offset;
1238 QMetaObject *meta =
reinterpret_cast<QMetaObject *>(buf);
1239 size +=
sizeof(QMetaObject);
1242 meta->d.superdata = d->superClass;
1243 meta->d.relatedMetaObjects =
nullptr;
1244 meta->d.extradata =
nullptr;
1245 meta->d.metaTypes =
nullptr;
1246 meta->d.static_metacall = d->staticMetacallFunction;
1253 int methodParametersDataSize = aggregateParameterCount(d->methods)
1254 + aggregateParameterCount(d->signalVec)
1255 + aggregateParameterCount(d->constructors);
1259 pmeta->flags = d->flags.toInt() | AllocatedMetaObject;
1264 dataIndex += 2 * d->classInfoNames.size();
1272 paramsIndex = dataIndex;
1273 dataIndex += methodParametersDataSize;
1287 dataIndex += 2 *
int(d->classInfoNames.size());
1288 const auto method_count =
int(d->signalVec.size() + d->methods.size());
1290 paramsIndex = dataIndex;
1291 dataIndex += methodParametersDataSize;
1298 enumIndex = dataIndex;
1299 for (
const auto &enumerator : d->enumerators) {
1300 dataIndex += 2 * enumerator.keys.size();
1301 if (enumerator.flags & EnumIs64Bit)
1302 dataIndex += enumerator.keys.size();
1309 int *data =
reinterpret_cast<
int *>(pmeta);
1310 size += dataIndex *
sizeof(
int);
1311 ALIGN(size,
void *);
1312 [[maybe_unused]]
char *str = bufferAt(size);
1314 meta->d.stringdata =
reinterpret_cast<
const uint *>(str);
1315 meta->d.data =
reinterpret_cast<uint *>(data);
1325 for (index = 0; index < d->classInfoNames.size(); ++index) {
1326 [[maybe_unused]]
int name = strings.enter(d->classInfoNames[index]);
1327 [[maybe_unused]]
int value = strings.enter(d->classInfoValues[index]);
1329 data[dataIndex] = name;
1330 data[dataIndex + 1] = value;
1338 int parameterMetaTypesIndex =
int(d->properties.size()) +
int(d->enumerators.size()) + 1;
1340 auto add_method = [&](
const auto &method) {
1341 [[maybe_unused]]
int name = strings.enter(method.name());
1342 int argc = method.parameterCount();
1343 [[maybe_unused]]
int tag = strings.enter(method.tag);
1344 [[maybe_unused]]
int attrs = method.attributes;
1345 if (method.revision)
1348 data[dataIndex] = name;
1349 data[dataIndex + 1] = argc;
1350 data[dataIndex + 2] = paramsIndex;
1351 data[dataIndex + 3] = tag;
1352 data[dataIndex + 4] = attrs;
1353 data[dataIndex + 5] = parameterMetaTypesIndex;
1356 paramsIndex += 1 + argc * 2;
1357 parameterMetaTypesIndex += 1 + argc;
1361 for (
const auto &signal : d->signalVec)
1365 for (
const auto &method : d->methods)
1368 auto getTypeInfo = [&](
const auto &typeName) {
1369 if (isBuiltinType(typeName))
1370 return QMetaType::fromName(typeName).rawId();
1372 if constexpr (std::is_same_v<
decltype(typeName),
const QByteArrayView &>)
1373 index = strings.enter(QByteArray::fromRawData(typeName.constData(), typeName.size()));
1375 index = strings.enter(typeName);
1376 return int(IsUnresolvedType | index);
1381 auto processMethodParameters = [&](
const auto &methods) {
1382 for (
const auto &method : methods) {
1383 if (method.revision) {
1385 data[dataIndex] = method.revision;
1389 [[maybe_unused]]
int typeInfo = getTypeInfo(method.returnType);
1391 data[dataIndex] = typeInfo;
1394 const QList<QByteArrayView> paramTypeNames = method.parameterTypes();
1395 for (
auto typeName : paramTypeNames) {
1396 [[maybe_unused]]
int typeInfo = getTypeInfo(typeName);
1397 if constexpr (mode == Construct)
1398 data[dataIndex] = typeInfo;
1402 QList<QByteArray> paramNames = method.parameterNames;
1403 if (
const auto paramCount = paramTypeNames.size(); paramNames.size() < paramCount)
1404 paramNames.resize(paramCount);
1405 for (
const auto &name : std::as_const(paramNames)) {
1406 [[maybe_unused]]
int stringIndex = strings.enter(name);
1407 if constexpr (mode == Construct)
1408 data[dataIndex] = stringIndex;
1413 processMethodParameters(d->signalVec);
1414 processMethodParameters(d->methods);
1415 processMethodParameters(d->constructors);
1419 for (QMetaPropertyBuilderPrivate &prop : d->properties) {
1420 [[maybe_unused]]
int name = strings.enter(prop.name);
1423 if (!prop.metaType.isValid())
1424 prop.metaType = QMetaType::fromName(prop.type);
1425 [[maybe_unused]]
const int typeInfo = prop.metaType.isValid()
1426 ? prop.metaType.id()
1427 : IsUnresolvedType | strings.enter(prop.type);
1429 [[maybe_unused]]
int flags = prop.flags;
1431 if (!isBuiltinType(prop.type))
1432 flags |= EnumOrFlag;
1434 if constexpr (mode == Construct) {
1435 data[dataIndex] = name;
1436 data[dataIndex + 1] = typeInfo;
1437 data[dataIndex + 2] = flags;
1438 data[dataIndex + 3] = prop.notifySignal;
1439 data[dataIndex + 4] = prop.revision;
1441 dataIndex += QMetaObjectPrivate::IntsPerProperty;
1446 for (
const auto &enumerator : d->enumerators) {
1447 [[maybe_unused]]
int name = strings.enter(enumerator.name);
1448 [[maybe_unused]]
int enumName = strings.enter(enumerator.enumName);
1449 int count = enumerator.keys.size();
1450 if constexpr (mode == Construct) {
1451 data[dataIndex] = name;
1452 data[dataIndex + 1] = enumName;
1453 data[dataIndex + 2] = enumerator.flags.toInt();
1454 data[dataIndex + 3] = count;
1455 data[dataIndex + 4] = enumIndex;
1457 for (
int key = 0; key < count; ++key) {
1458 [[maybe_unused]]
int keyIndex = strings.enter(enumerator.keys[key]);
1459 if constexpr (mode == Construct) {
1460 data[enumIndex + 0] = keyIndex;
1461 data[enumIndex + 1] = uint(enumerator.values[key]);
1465 bool is64Bit = enumerator.flags.testAnyFlags(EnumIs64Bit);
1466 for (
int key = 0; is64Bit && key < count; ++key) {
1467 if constexpr (mode == Construct) {
1468 data[enumIndex] = uint(enumerator.values[key] >> 32);
1472 dataIndex += QMetaObjectPrivate::IntsPerEnum;
1477 for (
const auto &ctor : d->constructors) {
1478 [[maybe_unused]]
int name = strings.enter(ctor.name());
1479 int argc = ctor.parameterCount();
1480 [[maybe_unused]]
int tag = strings.enter(ctor.tag);
1481 [[maybe_unused]]
int attrs = ctor.attributes;
1482 if constexpr (mode == Construct) {
1483 data[dataIndex] = name;
1484 data[dataIndex + 1] = argc;
1485 data[dataIndex + 2] = paramsIndex;
1486 data[dataIndex + 3] = tag;
1487 data[dataIndex + 4] = attrs;
1488 data[dataIndex + 5] = parameterMetaTypesIndex;
1490 dataIndex += QMetaObjectPrivate::IntsPerMethod;
1491 paramsIndex += 1 + argc * 2;
1494 parameterMetaTypesIndex += argc;
1497 size += strings.blobSize();
1499 if constexpr (mode == Construct)
1500 strings.writeBlob(str);
1504 data[enumIndex] = 0;
1507 if (d->relatedMetaObjects.size() > 0) {
1508 using SuperData = QMetaObject::SuperData;
1509 ALIGN(size, SuperData);
1510 auto objects =
reinterpret_cast<SuperData *>(bufferAt(size));
1512 meta->d.relatedMetaObjects = objects;
1513 for (index = 0; index < d->relatedMetaObjects.size(); ++index)
1514 objects[index] = d->relatedMetaObjects[index];
1515 objects[index] =
nullptr;
1517 size +=
sizeof(SuperData) * (d->relatedMetaObjects.size() + 1);
1520 ALIGN(size, QtPrivate::QMetaTypeInterface *);
1521 auto types =
reinterpret_cast<
const QtPrivate::QMetaTypeInterface **>(bufferAt(size));
1523 meta->d.metaTypes = types;
1524 for (
const auto &prop : d->properties) {
1525 QMetaType mt = prop.metaType;
1526 *types = mt.iface();
1530 for (
const auto &enumerator: d->enumerators) {
1531 QMetaType mt = enumerator.metaType;
1533 *types = mt.iface();
1541 auto addMetaTypes = [&](
const auto &method) {
1542 QMetaType mt(QMetaType::fromName(method.returnType).rawId());
1543 *types =
reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
1545 for (
auto parameterType: method.parameterTypes()) {
1546 QMetaType mt = QMetaType::fromName(parameterType);
1547 *types = mt.iface();
1551 for (
const auto &method : d->signalVec)
1552 addMetaTypes(method);
1553 for (
const auto &method : d->methods)
1554 addMetaTypes(method);
1556 for (
const auto &constructor : d->constructors) {
1557 for (
auto parameterType : constructor.parameterTypes()) {
1558 QMetaType mt = QMetaType::fromName(parameterType);
1559 *types = mt.iface();
1565 size +=
sizeof(QMetaType) * parameterMetaTypesIndex;
1568 ALIGN(size,
void *);
1569 Q_ASSERT(!buf || size == expectedSize);