Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qmetaobjectbuilder.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include "qobject_p.h"
9
10#include <QtCore/qstring.h>
11
12#include <vector>
13#include <stdlib.h>
14
15QT_BEGIN_NAMESPACE
16
17using namespace Qt::StringLiterals;
18
19/*!
20 \class QMetaObjectBuilder
21 \inmodule QtCore
22 \internal
23 \brief The QMetaObjectBuilder class supports building QMetaObject objects at runtime.
24
25*/
26
27/*!
28 \enum QMetaObjectBuilder::AddMember
29 This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject()
30
31 \value ClassName Add the class name.
32 \value SuperClass Add the super class.
33 \value Methods Add methods that aren't signals or slots.
34 \value Signals Add signals.
35 \value Slots Add slots.
36 \value Constructors Add constructors.
37 \value Properties Add properties.
38 \value Enumerators Add enumerators.
39 \value ClassInfos Add items of class information.
40 \value RelatedMetaObjects Add related meta objects.
41 \value StaticMetacall Add the static metacall function.
42 \value PublicMethods Add public methods (ignored for signals).
43 \value ProtectedMethods Add protected methods (ignored for signals).
44 \value PrivateMethods All private methods (ignored for signals).
45 \value AllMembers Add all members.
46 \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function.
47*/
48
49static bool isBuiltinType(QByteArrayView type)
50{
51 int id = QMetaType::fromName(type).rawId();
52 if (!id && !type.isEmpty() && type != "void")
53 return false;
54 return (id < QMetaType::User);
55}
56
57// copied from qmetaobject.cpp
58[[maybe_unused]] static inline const QMetaObjectPrivate *qmobPriv(const uint* data)
59{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
60
62{
63public:
65 (QMetaMethod::MethodType _methodType,
66 const QByteArray& _signature,
67 const QByteArray& _returnType = QByteArray("void"),
68 QMetaMethod::Access _access = QMetaMethod::Public,
69 int _revision = 0)
72 attributes(((int)_access) | (((int)_methodType) << 2)),
73 revision(_revision)
74 {
75 Q_ASSERT((_methodType == QMetaMethod::Constructor) == returnType.isNull());
76 }
77
84
86 {
87 return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2);
88 }
89
91 {
92 return (QMetaMethod::Access)(attributes & AccessMask);
93 }
94
95 void setAccess(QMetaMethod::Access value)
96 {
97 attributes = ((attributes & ~AccessMask) | (int)value);
98 }
99
101 {
102 QVarLengthArray<QByteArrayView, 10> typeNames;
103 QMetaObjectPrivate::parameterTypeNamesFromSignature(signature, typeNames);
104 QList<QByteArrayView> list;
105 list.reserve(typeNames.size());
106 for (auto n : typeNames)
107 list.emplace_back(n);
108 return list;
109 }
110
111 int parameterCount() const
112 {
113 return parameterTypes().size();
114 }
115
117 {
118 return signature.left(qMax(signature.indexOf('('), 0));
119 }
120};
122
124{
125public:
127 (const QByteArray& _name, const QByteArray& _type, QMetaType _metaType, int notifierIdx=-1,
128 int _revision = 0)
129 : name(_name),
132 flags(Readable | Writable | Scriptable), notifySignal(notifierIdx),
133 revision(_revision)
134 {
135
136 }
137
141 int flags;
144
145 bool flag(int f) const
146 {
147 return ((flags & f) != 0);
148 }
149
150 void setFlag(int f, bool value)
151 {
152 if (value)
153 flags |= f;
154 else
155 flags &= ~f;
156 }
157};
159
161{
162public:
163 QMetaEnumBuilderPrivate(const QByteArray &_name)
165 {
166 }
167
174
175 int addKey(const QByteArray &name, quint64 value)
176 {
177 int index = keys.size();
178 keys += name;
179 values += value;
180 return index;
181 }
182};
184
208
209/*!
210 Constructs a new QMetaObjectBuilder.
211*/
212QMetaObjectBuilder::QMetaObjectBuilder()
213{
214 d = new QMetaObjectBuilderPrivate();
215}
216
217/*!
218 Constructs a new QMetaObjectBuilder which is a copy of the
219 meta object information in \a prototype. Note: the super class
220 contents for \a prototype are not copied, only the immediate
221 class that is defined by \a prototype.
222
223 The \a members parameter indicates which members of \a prototype
224 should be added. The default is AllMembers.
225
226 \sa addMetaObject()
227*/
228QMetaObjectBuilder::QMetaObjectBuilder(const QMetaObject *prototype,
229 QMetaObjectBuilder::AddMembers members)
230{
231 d = new QMetaObjectBuilderPrivate();
232 addMetaObject(prototype, members);
233}
234
235/*!
236 Destroys this meta object builder.
237*/
238QMetaObjectBuilder::~QMetaObjectBuilder()
239{
240 delete d;
241}
242
243/*!
244 Returns the name of the class being constructed by this
245 meta object builder. The default value is an empty QByteArray.
246
247 \sa setClassName(), superClass()
248*/
249QByteArray QMetaObjectBuilder::className() const
250{
251 return d->className;
252}
253
254/*!
255 Sets the \a name of the class being constructed by this
256 meta object builder.
257
258 \sa className(), setSuperClass()
259*/
260void QMetaObjectBuilder::setClassName(const QByteArray &name)
261{
262 d->className = name;
263}
264
265/*!
266 Returns the superclass meta object of the class being constructed
267 by this meta object builder. The default value is the meta object
268 for QObject.
269
270 \sa setSuperClass(), className()
271*/
272const QMetaObject *QMetaObjectBuilder::superClass() const
273{
274 return d->superClass;
275}
276
277/*!
278 Sets the superclass meta object of the class being constructed
279 by this meta object builder to \a meta. The \a meta parameter
280 must not be null.
281
282 \sa superClass(), setClassName()
283*/
284void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta)
285{
286 Q_ASSERT(meta);
287 d->superClass = meta;
288}
289
290/*!
291 Returns the flags of the class being constructed by this meta object
292 builder.
293
294 \sa setFlags()
295*/
296MetaObjectFlags QMetaObjectBuilder::flags() const
297{
298 return d->flags;
299}
300
301/*!
302 Sets the \a flags of the class being constructed by this meta object
303 builder.
304
305 \sa flags()
306*/
307void QMetaObjectBuilder::setFlags(MetaObjectFlags flags)
308{
309 d->flags = flags;
310}
311
312/*!
313 Returns the number of methods in this class, excluding the number
314 of methods in the base class. These include signals and slots
315 as well as normal member functions.
316
317 \sa addMethod(), method(), removeMethod(), indexOfMethod()
318*/
319int QMetaObjectBuilder::methodCount() const
320{
321 return int(d->signalVec.size() + d->methods.size());
322}
323
324/*!
325 Returns the number of constructors in this class.
326
327 \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor()
328*/
329int QMetaObjectBuilder::constructorCount() const
330{
331 return int(d->constructors.size());
332}
333
334/*!
335 Returns the number of properties in this class, excluding the number
336 of properties in the base class.
337
338 \sa addProperty(), property(), removeProperty(), indexOfProperty()
339*/
340int QMetaObjectBuilder::propertyCount() const
341{
342 return int(d->properties.size());
343}
344
345/*!
346 Returns the number of enumerators in this class, excluding the
347 number of enumerators in the base class.
348
349 \sa addEnumerator(), enumerator(), removeEnumerator()
350 \sa indexOfEnumerator()
351*/
352int QMetaObjectBuilder::enumeratorCount() const
353{
354 return int(d->enumerators.size());
355}
356
357/*!
358 Returns the number of items of class information in this class,
359 exclusing the number of items of class information in the base class.
360
361 \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo()
362 \sa indexOfClassInfo()
363*/
364int QMetaObjectBuilder::classInfoCount() const
365{
366 return d->classInfoNames.size();
367}
368
369/*!
370 Returns the number of related meta objects that are associated
371 with this class.
372
373 Related meta objects are used when resolving the enumerated type
374 associated with a property, where the enumerated type is in a
375 different class from the property.
376
377 \sa addRelatedMetaObject(), relatedMetaObject()
378 \sa removeRelatedMetaObject()
379*/
380int QMetaObjectBuilder::relatedMetaObjectCount() const
381{
382 return d->relatedMetaObjects.size();
383}
384
385/*!
386 Adds a new public method to this class with the specified \a signature.
387 Returns an object that can be used to adjust the other attributes
388 of the method. The \a signature will be normalized before it is
389 added to the class.
390
391 \sa method(), methodCount(), removeMethod(), indexOfMethod()
392*/
393QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray &signature)
394{
395 int index = int(d->methods.size());
396 d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature));
397 return QMetaMethodBuilder(this, index, QMetaMethod::Method);
398}
399
400/*!
401 Adds a new public method to this class with the specified
402 \a signature and \a returnType. Returns an object that can be
403 used to adjust the other attributes of the method. The \a signature
404 and \a returnType will be normalized before they are added to
405 the class.
406
407 \sa method(), methodCount(), removeMethod(), indexOfMethod()
408*/
409QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray &signature,
410 const QByteArray &returnType)
411{
412 int index = int(d->methods.size());
413 d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature, returnType));
414 return QMetaMethodBuilder(this, index, QMetaMethod::Method);
415}
416
417/*!
418 Adds a new public method to this class that has the same information as
419 \a prototype. This is used to clone the methods of an existing
420 QMetaObject. Returns an object that can be used to adjust the
421 attributes of the method.
422
423 This function will detect if \a prototype is an ordinary method,
424 signal, slot, or constructor and act accordingly.
425
426 \sa method(), methodCount(), removeMethod(), indexOfMethod()
427*/
428QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod &prototype)
429{
430 QMetaMethodBuilder method;
431 switch (prototype.methodType()) {
432 case QMetaMethod::Method:
433 method = addMethod(prototype.methodSignature());
434 break;
435 case QMetaMethod::Signal:
436 method = addSignal(prototype.methodSignature());
437 break;
438 case QMetaMethod::Slot:
439 method = addSlot(prototype.methodSignature());
440 break;
441 case QMetaMethod::Constructor:
442 method = addConstructor(prototype.methodSignature());
443 break;
444 }
445 method.setReturnType(prototype.typeName());
446 method.setParameterNames(prototype.parameterNames());
447 method.setTag(prototype.tag());
448 method.setAccess(prototype.access());
449 method.setAttributes(prototype.attributes());
450 method.setRevision(prototype.revision());
451 method.setConst(prototype.isConst());
452 return method;
453}
454
455/*!
456 Adds a new public slot to this class with the specified \a signature.
457 Returns an object that can be used to adjust the other attributes
458 of the slot. The \a signature will be normalized before it is
459 added to the class.
460
461 \sa addMethod(), addSignal(), indexOfSlot()
462*/
463QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray &signature)
464{
465 int index = int(d->methods.size());
466 d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature));
467 return QMetaMethodBuilder(this, index, QMetaMethod::Slot);
468}
469
470/*!
471 Adds a new signal to this class with the specified \a signature.
472 Returns an object that can be used to adjust the other attributes
473 of the signal. The \a signature will be normalized before it is
474 added to the class.
475
476 \sa addMethod(), addSlot(), indexOfSignal()
477*/
478QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray &signature)
479{
480 int index = int(d->signalVec.size());
481 d->signalVec.emplace_back(QMetaMethod::Signal, signature, "void"_ba, QMetaMethod::Public);
482 return QMetaMethodBuilder(this, index, QMetaMethod::Signal);
483}
484
485/*!
486 Adds a new constructor to this class with the specified \a signature.
487 Returns an object that can be used to adjust the other attributes
488 of the constructor. The \a signature will be normalized before it is
489 added to the class.
490
491 \sa constructor(), constructorCount(), removeConstructor()
492 \sa indexOfConstructor()
493*/
494QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray &signature)
495{
496 int index = int(d->constructors.size());
497 d->constructors.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature,
498 /*returnType=*/QByteArray()));
499 return QMetaMethodBuilder(this, index, QMetaMethod::Constructor);
500}
501
502/*!
503 Adds a new constructor to this class that has the same information as
504 \a prototype. This is used to clone the constructors of an existing
505 QMetaObject. Returns an object that can be used to adjust the
506 attributes of the constructor.
507
508 This function requires that \a prototype be a constructor.
509
510 \sa constructor(), constructorCount(), removeConstructor()
511 \sa indexOfConstructor()
512*/
513QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod &prototype)
514{
515 Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
516 QMetaMethodBuilder ctor = addConstructor(prototype.methodSignature());
517 ctor.setReturnType(prototype.typeName());
518 ctor.setParameterNames(prototype.parameterNames());
519 ctor.setTag(prototype.tag());
520 ctor.setAccess(prototype.access());
521 ctor.setAttributes(prototype.attributes());
522 return ctor;
523}
524
525/*!
526 Adds a new readable/writable property to this class with the
527 specified \a name and \a type. Returns an object that can be used
528 to adjust the other attributes of the property. The \a type will
529 be normalized before it is added to the class. \a notifierId will
530 be registered as the property's \e notify signal.
531
532 \sa property(), propertyCount(), removeProperty(), indexOfProperty()
533*/
534QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, const QByteArray &type,
535 int notifierId)
536{
537 return addProperty(name, type, QMetaType::fromName(type), notifierId);
538}
539
540/*!
541 \overload
542 */
543QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, const QByteArray &type, QMetaType metaType, int notifierId)
544{
545 int index = int(d->properties.size());
546 d->properties.push_back(QMetaPropertyBuilderPrivate(name, type, metaType, notifierId));
547 return QMetaPropertyBuilder(this, index);
548}
549
550/*!
551 Adds a new property to this class that has the same information as
552 \a prototype. This is used to clone the properties of an existing
553 QMetaObject. Returns an object that can be used to adjust the
554 attributes of the property.
555
556 \sa property(), propertyCount(), removeProperty(), indexOfProperty()
557*/
558QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty &prototype)
559{
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()) {
576 // Find an existing method for the notify signal, or add a new one.
577 QMetaMethod method = prototype.notifySignal();
578 const QByteArray signature = method.methodSignature();
579 int index = indexOfSignal(signature);
580 if (index == -1)
581 index = addSignal(signature).index();
582 d->properties[property._index].notifySignal = index;
583 }
584 return property;
585}
586
587/*!
588 Adds a new enumerator to this class with the specified
589 \a name. Returns an object that can be used to adjust
590 the other attributes of the enumerator.
591
592 \sa enumerator(), enumeratorCount(), removeEnumerator()
593 \sa indexOfEnumerator()
594*/
595QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray &name)
596{
597 int index = int(d->enumerators.size());
598 d->enumerators.push_back(QMetaEnumBuilderPrivate(name));
599 return QMetaEnumBuilder(this, index);
600}
601
602/*!
603 Adds a new enumerator to this class that has the same information as
604 \a prototype. This is used to clone the enumerators of an existing
605 QMetaObject. Returns an object that can be used to adjust the
606 attributes of the enumerator.
607
608 \sa enumerator(), enumeratorCount(), removeEnumerator()
609 \sa indexOfEnumerator()
610*/
611QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum &prototype)
612{
613 QMetaEnumBuilder en = addEnumerator(prototype.name());
614 en.setEnumName(prototype.enumName());
615 en.setMetaType(prototype.metaType());
616 en.setIsFlag(prototype.isFlag());
617 en.setIsScoped(prototype.isScoped());
618 int count = prototype.keyCount();
619 for (int index = 0; index < count; ++index)
620 en.addKey(prototype.key(index), prototype.value64(index).value_or(0));
621 // reset the is64Bit() flag if necessary
622 en.setIs64Bit(prototype.is64Bit());
623 return en;
624}
625
626/*!
627 Adds \a name and \a value as an item of class information to this class.
628 Returns the index of the new item of class information.
629
630 \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo()
631 \sa indexOfClassInfo()
632*/
633int QMetaObjectBuilder::addClassInfo(const QByteArray &name, const QByteArray &value)
634{
635 int index = d->classInfoNames.size();
636 d->classInfoNames += name;
637 d->classInfoValues += value;
638 return index;
639}
640
641/*!
642 Adds \a meta to this class as a related meta object. Returns
643 the index of the new related meta object entry.
644
645 Related meta objects are used when resolving the enumerated type
646 associated with a property, where the enumerated type is in a
647 different class from the property.
648
649 \sa relatedMetaObjectCount(), relatedMetaObject()
650 \sa removeRelatedMetaObject()
651*/
652int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta)
653{
654 Q_ASSERT(meta);
655 int index = d->relatedMetaObjects.size();
656 d->relatedMetaObjects.append(meta);
657 return index;
658}
659
660/*!
661 Adds the contents of \a prototype to this meta object builder.
662 This function is useful for cloning the contents of an existing QMetaObject.
663
664 The \a members parameter indicates which members of \a prototype
665 should be added. The default is AllMembers.
666*/
667void QMetaObjectBuilder::addMetaObject(const QMetaObject *prototype,
668 QMetaObjectBuilder::AddMembers members)
669{
670 Q_ASSERT(prototype);
671 int index;
672
673 if ((members & ClassName) != 0)
674 d->className = prototype->className();
675
676 if ((members & SuperClass) != 0)
677 d->superClass = prototype->superClass();
678
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)
686 continue;
687 break;
688 case QMetaMethod::Private:
689 if ((members & PrivateMethods) == 0)
690 continue;
691 break;
692 case QMetaMethod::Protected:
693 if ((members & ProtectedMethods) == 0)
694 continue;
695 break;
696 }
697 }
698 switch (method.methodType()) {
699 case QMetaMethod::Method:
700 if (members & Methods)
701 addMethod(method);
702 break;
703 case QMetaMethod::Signal:
704 if (members & Signals)
705 addMethod(method);
706 break;
707 case QMetaMethod::Slot:
708 if (members & Slots)
709 addMethod(method);
710 break;
711 case QMetaMethod::Constructor:
712 ;
713 }
714 }
715 }
716
717 if ((members & Constructors) != 0) {
718 for (index = 0; index < prototype->constructorCount(); ++index)
719 addConstructor(prototype->constructor(index));
720 }
721
722 if ((members & Properties) != 0) {
723 for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index)
724 addProperty(prototype->property(index));
725 }
726
727 if ((members & Enumerators) != 0) {
728 for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index)
729 addEnumerator(prototype->enumerator(index));
730 }
731
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());
736 }
737 }
738
739 if ((members & RelatedMetaObjects) != 0) {
740 Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 2);
741 const auto *objects = prototype->d.relatedMetaObjects;
742 if (objects) {
743 while (*objects != nullptr) {
744 addRelatedMetaObject(*objects);
745 ++objects;
746 }
747 }
748 }
749
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);
754 }
755}
756
757/*!
758 Returns the method at \a index in this class. The returned object's type is
759 either QMetaMethod::Method or QMetaMethod::Slot. For signals, use signal().
760
761 \note Starting from Qt 6.12, this function can only be used for
762 QMetaMethod::Method or QMetaMethod::Slot functions. Before Qt 6.12
763 this method could be used for signals too.
764
765 \sa signal(), methodCount(), addMethod(), removeMethod(), indexOfMethod()
766*/
767QMetaMethodBuilder QMetaObjectBuilder::method(int index) const
768{
769 if (uint(index) < d->methods.size())
770 return QMetaMethodBuilder(this, index, QMetaMethod::Method);
771 else
772 return QMetaMethodBuilder();
773}
774
775
776/*! \since 6.12
777
778 Returns the signal at \a index in this class. The returned object's
779 type is QMetaMethod::Signal.
780
781 \sa method(), slot(), indexOfSignal()
782*/
783QMetaMethodBuilder QMetaObjectBuilder::signal(int index) const
784{
785 if (size_t(index) < d->signalVec.size())
786 return QMetaMethodBuilder(this, index, QMetaMethod::Signal);
787 return QMetaMethodBuilder();
788}
789
790/*!
791 Returns the constructor at \a index in this class.
792
793 \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor()
794*/
795QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const
796{
797 if (uint(index) < d->constructors.size())
798 return QMetaMethodBuilder(this, index, QMetaMethod::Constructor);
799 else
800 return QMetaMethodBuilder();
801}
802
803/*!
804 Returns the property at \a index in this class.
805
806 \sa methodCount(), addMethod(), removeMethod(), indexOfProperty()
807*/
808QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const
809{
810 if (uint(index) < d->properties.size())
811 return QMetaPropertyBuilder(this, index);
812 else
813 return QMetaPropertyBuilder();
814}
815
816/*!
817 Returns the enumerator at \a index in this class.
818
819 \sa enumeratorCount(), addEnumerator(), removeEnumerator()
820 \sa indexOfEnumerator()
821*/
822QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const
823{
824 if (uint(index) < d->enumerators.size())
825 return QMetaEnumBuilder(this, index);
826 else
827 return QMetaEnumBuilder();
828}
829
830/*!
831 Returns the related meta object at \a index in this class.
832
833 Related meta objects are used when resolving the enumerated type
834 associated with a property, where the enumerated type is in a
835 different class from the property.
836
837 \sa relatedMetaObjectCount(), addRelatedMetaObject()
838 \sa removeRelatedMetaObject()
839*/
840const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const
841{
842 if (index >= 0 && index < d->relatedMetaObjects.size())
843 return d->relatedMetaObjects[index];
844 else
845 return nullptr;
846}
847
848/*!
849 Returns the name of the item of class information at \a index
850 in this class.
851
852 \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo()
853 \sa indexOfClassInfo()
854*/
855QByteArray QMetaObjectBuilder::classInfoName(int index) const
856{
857 if (index >= 0 && index < d->classInfoNames.size())
858 return d->classInfoNames[index];
859 else
860 return QByteArray();
861}
862
863/*!
864 Returns the value of the item of class information at \a index
865 in this class.
866
867 \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo()
868 \sa indexOfClassInfo()
869*/
870QByteArray QMetaObjectBuilder::classInfoValue(int index) const
871{
872 if (index >= 0 && index < d->classInfoValues.size())
873 return d->classInfoValues[index];
874 else
875 return QByteArray();
876}
877
878/*!
879 Removes the method at \a index from this class. This method's type is either
880 QMetaMethod::Method or QMetaMethod::Slot. The indices of all following
881 methods and slots will be decremented by 1. For signals use removeSignal().
882
883 \note Starting from Qt 6.12, this function can only be used for
884 QMetaMethod::Method or QMetaMethod::Slot functions. Before Qt 6.12 this
885 function could be used to remove signals too.
886
887 \sa removeSignal(), methodCount(), addMethod(), method(), indexOfMethod()
888*/
889void QMetaObjectBuilder::removeMethod(int index)
890{
891 if (size_t(index) < d->methods.size())
892 d->methods.erase(d->methods.begin() + index);
893}
894
895/*! \since 6.12
896
897 Removes the signal at \a index from this class. The indices of all
898 following signals will be decremented by 1. If the signal is registered
899 as a notify signal on a property, then the notify signal will be removed
900 from the property.
901
902 \sa removeMethod()
903*/
904void QMetaObjectBuilder::removeSignal(int index)
905{
906 if (size_t(index) < d->signalVec.size()) {
907 d->signalVec.erase(d->signalVec.begin() + index);
908 for (auto &property : d->properties) {
909 // Adjust the indices of property notify signal references.
910 if (property.notifySignal == index) {
911 property.notifySignal = -1;
912 } else if (property.notifySignal > index)
913 property.notifySignal--;
914 }
915 }
916}
917
918/*!
919 Removes the constructor at \a index from this class. The indices of
920 all following constructors will be adjusted downwards by 1.
921
922 \sa constructorCount(), addConstructor(), constructor()
923 \sa indexOfConstructor()
924*/
925void QMetaObjectBuilder::removeConstructor(int index)
926{
927 if (uint(index) < d->constructors.size())
928 d->constructors.erase(d->constructors.begin() + index);
929}
930
931/*!
932 Removes the property at \a index from this class. The indices of
933 all following properties will be adjusted downwards by 1.
934
935 \sa propertyCount(), addProperty(), property(), indexOfProperty()
936*/
937void QMetaObjectBuilder::removeProperty(int index)
938{
939 if (uint(index) < d->properties.size())
940 d->properties.erase(d->properties.begin() + index);
941}
942
943/*!
944 Removes the enumerator at \a index from this class. The indices of
945 all following enumerators will be adjusted downwards by 1.
946
947 \sa enumertorCount(), addEnumerator(), enumerator()
948 \sa indexOfEnumerator()
949*/
950void QMetaObjectBuilder::removeEnumerator(int index)
951{
952 if (uint(index) < d->enumerators.size())
953 d->enumerators.erase(d->enumerators.begin() + index);
954}
955
956/*!
957 Removes the item of class information at \a index from this class.
958 The indices of all following items will be adjusted downwards by 1.
959
960 \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue()
961 \sa indexOfClassInfo()
962*/
963void QMetaObjectBuilder::removeClassInfo(int index)
964{
965 if (index >= 0 && index < d->classInfoNames.size()) {
966 d->classInfoNames.removeAt(index);
967 d->classInfoValues.removeAt(index);
968 }
969}
970
971/*!
972 Removes the related meta object at \a index from this class.
973 The indices of all following related meta objects will be adjusted
974 downwards by 1.
975
976 Related meta objects are used when resolving the enumerated type
977 associated with a property, where the enumerated type is in a
978 different class from the property.
979
980 \sa relatedMetaObjectCount(), addRelatedMetaObject()
981 \sa relatedMetaObject()
982*/
983void QMetaObjectBuilder::removeRelatedMetaObject(int index)
984{
985 if (index >= 0 && index < d->relatedMetaObjects.size())
986 d->relatedMetaObjects.removeAt(index);
987}
988
989/*!
990 Finds a method with the specified \a signature and returns its index;
991 otherwise returns -1. The \a signature will be normalized by this method.
992
993 \sa method(), methodCount(), addMethod(), removeMethod()
994*/
995int QMetaObjectBuilder::indexOfMethod(const QByteArray &signature)
996{
997 QByteArray sig = QMetaObject::normalizedSignature(signature);
998 for (const auto &method : d->methods) {
999 if (sig == method.signature)
1000 return int(&method - &d->methods.front());
1001 }
1002 return -1;
1003}
1004
1005/*!
1006 Finds a signal with the specified \a signature and returns its index;
1007 otherwise returns -1. The \a signature will be normalized by this method.
1008
1009 \sa indexOfMethod(), indexOfSlot()
1010*/
1011int QMetaObjectBuilder::indexOfSignal(const QByteArray &signature)
1012{
1013 QByteArray sig = QMetaObject::normalizedSignature(signature);
1014 for (size_t i = 0; i < d->signalVec.size(); ++i) {
1015 if (sig == d->signalVec[i].signature)
1016 return int(i);
1017 }
1018 return -1;
1019}
1020
1021/*!
1022 Finds a slot with the specified \a signature and returns its index;
1023 otherwise returns -1. The \a signature will be normalized by this method.
1024
1025 \sa indexOfMethod(), indexOfSignal()
1026*/
1027int QMetaObjectBuilder::indexOfSlot(const QByteArray &signature)
1028{
1029 QByteArray sig = QMetaObject::normalizedSignature(signature);
1030 for (const auto &method : d->methods) {
1031 if (method.methodType() == QMetaMethod::Slot && sig == method.signature)
1032 return int(&method - &d->methods.front());
1033 }
1034 return -1;
1035}
1036
1037/*!
1038 Finds a constructor with the specified \a signature and returns its index;
1039 otherwise returns -1. The \a signature will be normalized by this method.
1040
1041 \sa constructor(), constructorCount(), addConstructor(), removeConstructor()
1042*/
1043int QMetaObjectBuilder::indexOfConstructor(const QByteArray &signature)
1044{
1045 QByteArray sig = QMetaObject::normalizedSignature(signature);
1046 for (const auto &constructor : d->constructors) {
1047 if (sig == constructor.signature)
1048 return int(&constructor - &d->constructors.front());
1049 }
1050 return -1;
1051}
1052
1053/*!
1054 Finds a property with the specified \a name and returns its index;
1055 otherwise returns -1.
1056
1057 \sa property(), propertyCount(), addProperty(), removeProperty()
1058*/
1059int QMetaObjectBuilder::indexOfProperty(const QByteArray &name)
1060{
1061 for (const auto &property : d->properties) {
1062 if (name == property.name)
1063 return int(&property - &d->properties.front());
1064 }
1065 return -1;
1066}
1067
1068/*!
1069 Finds an enumerator with the specified \a name and returns its index;
1070 otherwise returns -1.
1071
1072 \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator()
1073*/
1074int QMetaObjectBuilder::indexOfEnumerator(const QByteArray &name)
1075{
1076 for (const auto &enumerator : d->enumerators) {
1077 if (name == enumerator.name)
1078 return int(&enumerator - &d->enumerators.front());
1079 }
1080 return -1;
1081}
1082
1083/*!
1084 Finds an item of class information with the specified \a name and
1085 returns its index; otherwise returns -1.
1086
1087 \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo()
1088 \sa removeClassInfo()
1089*/
1090int QMetaObjectBuilder::indexOfClassInfo(const QByteArray &name)
1091{
1092 for (int index = 0; index < d->classInfoNames.size(); ++index) {
1093 if (name == d->classInfoNames[index])
1094 return index;
1095 }
1096 return -1;
1097}
1098
1099// Align on a specific type boundary.
1100#ifdef ALIGN
1101# undef ALIGN
1102#endif
1103#define ALIGN(size,type)
1104 (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
1105
1106/*!
1107 \class QMetaStringTable
1108 \inmodule QtCore
1109 \internal
1110 \brief The QMetaStringTable class can generate a meta-object string table at runtime.
1111*/
1112
1113QMetaStringTable::QMetaStringTable(const QByteArray &className)
1114 : m_index(0)
1115 , m_className(className)
1116{
1117 const int index = enter(m_className);
1118 Q_ASSERT(index == 0);
1119 Q_UNUSED(index);
1120}
1121
1122// Enters the given value into the string table (if it hasn't already been
1123// entered). Returns the index of the string.
1124int QMetaStringTable::enter(const QByteArray &value)
1125{
1126 auto [it, inserted] = m_entries.tryInsert(value, m_index);
1127 if (inserted)
1128 ++m_index;
1129 return it.value();
1130}
1131
1132int QMetaStringTable::preferredAlignment()
1133{
1134 return alignof(uint);
1135}
1136
1137// Returns the size (in bytes) required for serializing this string table.
1138int QMetaStringTable::blobSize() const
1139{
1140 int size = int(m_entries.size() * 2 * sizeof(uint));
1141 Entries::const_iterator it;
1142 for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it)
1143 size += it.key().size() + 1;
1144 return size;
1145}
1146
1147static void writeString(char *out, int i, const QByteArray &str,
1148 const int offsetOfStringdataMember, int &stringdataOffset)
1149{
1150 int size = str.size();
1151 int offset = offsetOfStringdataMember + stringdataOffset;
1152 uint offsetLen[2] = { uint(offset), uint(size) };
1153
1154 memcpy(out + 2 * i * sizeof(uint), &offsetLen, 2 * sizeof(uint));
1155
1156 memcpy(out + offset, str.constData(), size);
1157 out[offset + size] = '\0';
1158
1159 stringdataOffset += size + 1;
1160}
1161
1162// Writes strings to string data struct.
1163// The struct consists of an array of QByteArrayData, followed by a char array
1164// containing the actual strings. This format must match the one produced by
1165// moc (see generator.cpp).
1166void QMetaStringTable::writeBlob(char *out) const
1167{
1168 Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment() - 1)));
1169
1170 int offsetOfStringdataMember = int(m_entries.size() * 2 * sizeof(uint));
1171 int stringdataOffset = 0;
1172
1173 // qt_metacast expects the first string in the string table to be the class name.
1174 writeString(out, /*index*/ 0, m_className, offsetOfStringdataMember, stringdataOffset);
1175
1176 for (Entries::ConstIterator it = m_entries.constBegin(), end = m_entries.constEnd();
1177 it != end; ++it) {
1178 const int i = it.value();
1179 if (i == 0)
1180 continue;
1181 const QByteArray &str = it.key();
1182
1183 writeString(out, i, str, offsetOfStringdataMember, stringdataOffset);
1184 }
1185}
1186
1187// Returns the number of integers needed to store these methods' parameter type
1188// infos or type names, parameter names and, if present, the method revision.
1189// This is needed for calculating the size of the methods' parameter type/name
1190// meta-data.
1191static int aggregateParameterCount(const std::vector<QMetaMethodBuilderPrivate> &methods)
1192{
1193 int sum = 0;
1194 for (const auto &method : methods) {
1195 if (method.revision)
1196 ++sum;
1197
1198 // type infos or type names; +1 for return type (constructors don't
1199 // have one, so this stores a link to an empty string)
1200 sum += method.parameterCount() + 1;
1201
1202 // parameter names (return type doesn't get one)
1203 sum += method.parameterCount();
1204 }
1205 return sum;
1206}
1207
1208enum Mode {
1209 Prepare, // compute the size of the metaobject
1210 Construct // construct metaobject in pre-allocated buffer
1211};
1212// Build a QMetaObject in "buf" based on the information in "d".
1213// If the mode is prepare, then return the number of bytes needed to
1214// build the QMetaObject.
1215template<Mode mode>
1217 int expectedSize)
1218{
1219 Q_UNUSED(expectedSize); // Avoid warning in release mode
1220 Q_UNUSED(buf);
1221 qsizetype size = 0;
1222
1223 // With Mode == Prepare, we are passed a null buffer pointer.
1224 const auto bufferAt = [&](qsizetype offset) -> char * {
1225 if constexpr (mode == Construct) {
1226 return buf + offset;
1227 } else {
1228 Q_UNUSED(offset);
1229 return nullptr;
1230 }
1231 };
1232 int dataIndex;
1233 int paramsIndex;
1234 int enumIndex;
1235 int index;
1236
1237 // Create the main QMetaObject structure at the start of the buffer.
1238 QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf);
1239 size += sizeof(QMetaObject);
1240 ALIGN(size, int);
1241 if constexpr (mode == Construct) {
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;
1247 }
1248
1249 // Populate the QMetaObjectPrivate structure.
1250 QMetaObjectPrivate *pmeta = reinterpret_cast<QMetaObjectPrivate *>(bufferAt(size));
1251 //int pmetaSize = size;
1252 dataIndex = MetaObjectPrivateFieldCount;
1253 int methodParametersDataSize = aggregateParameterCount(d->methods)
1254 + aggregateParameterCount(d->signalVec)
1255 + aggregateParameterCount(d->constructors);
1256 if constexpr (mode == Construct) {
1257 static_assert(QMetaObjectPrivate::OutputRevision == 13, "QMetaObjectBuilder should generate the same version as moc");
1259 pmeta->flags = d->flags.toInt() | AllocatedMetaObject;
1260 pmeta->className = 0; // Class name is always the first string.
1261
1262 pmeta->classInfoCount = d->classInfoNames.size();
1263 pmeta->classInfoData = dataIndex;
1264 dataIndex += 2 * d->classInfoNames.size();
1265
1266 // QMetaObject treats QMetaObjectPrivate::methodData as the beginning of all "methods",
1267 // including signals
1268 pmeta->methodData = dataIndex;
1269 pmeta->signalCount = int(d->signalVec.size());
1270 pmeta->methodCount = int(d->methods.size()) + pmeta->signalCount;
1272 paramsIndex = dataIndex;
1273 dataIndex += methodParametersDataSize;
1274
1275 pmeta->propertyCount = int(d->properties.size());
1276 pmeta->propertyData = dataIndex;
1277 dataIndex += QMetaObjectPrivate::IntsPerProperty * int(d->properties.size());
1278
1279 pmeta->enumeratorCount = int(d->enumerators.size());
1280 pmeta->enumeratorData = dataIndex;
1281 dataIndex += QMetaObjectPrivate::IntsPerEnum * int(d->enumerators.size());
1282
1283 pmeta->constructorCount = int(d->constructors.size());
1284 pmeta->constructorData = dataIndex;
1285 dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
1286 } else {
1287 dataIndex += 2 * int(d->classInfoNames.size());
1288 const auto method_count = int(d->signalVec.size() + d->methods.size());
1289 dataIndex += QMetaObjectPrivate::IntsPerMethod * method_count;
1290 paramsIndex = dataIndex;
1291 dataIndex += methodParametersDataSize;
1292 dataIndex += QMetaObjectPrivate::IntsPerProperty * int(d->properties.size());
1293 dataIndex += QMetaObjectPrivate::IntsPerEnum * int(d->enumerators.size());
1294 dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
1295 }
1296
1297 // Allocate space for the enumerator key names and values.
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();
1303 }
1304
1305 // Zero terminator at the end of the data offset table.
1306 ++dataIndex;
1307
1308 // Find the start of the data and string tables.
1309 int *data = reinterpret_cast<int *>(pmeta);
1310 size += dataIndex * sizeof(int);
1311 ALIGN(size, void *);
1312 [[maybe_unused]] char *str = bufferAt(size);
1313 if constexpr (mode == Construct) {
1314 meta->d.stringdata = reinterpret_cast<const uint *>(str);
1315 meta->d.data = reinterpret_cast<uint *>(data);
1316 }
1317
1318 // Reset the current data position to just past the QMetaObjectPrivate.
1319 dataIndex = MetaObjectPrivateFieldCount;
1320
1321 QMetaStringTable strings(d->className);
1322
1323 // Output the class infos,
1324 Q_ASSERT(!buf || dataIndex == pmeta->classInfoData);
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]);
1328 if constexpr (mode == Construct) {
1329 data[dataIndex] = name;
1330 data[dataIndex + 1] = value;
1331 }
1332 dataIndex += 2;
1333 }
1334
1335 // Output all the methods in the class.
1336 Q_ASSERT(!buf || dataIndex == pmeta->methodData);
1337 // property count + enum count + 1 for metatype of this metaobject
1338 int parameterMetaTypesIndex = int(d->properties.size()) + int(d->enumerators.size()) + 1;
1339
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)
1346 ++paramsIndex;
1347 if constexpr (mode == Construct) {
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;
1354 }
1356 paramsIndex += 1 + argc * 2;
1357 parameterMetaTypesIndex += 1 + argc;
1358 };
1359
1360 // first output the signals in the class, to match meta-objects generated by moc
1361 for (const auto &signal : d->signalVec)
1362 add_method(signal);
1363
1364 // Output the rest of the methods (QMetaMethod::{Method,Slot}) in the class
1365 for (const auto &method : d->methods)
1366 add_method(method);
1367
1368 auto getTypeInfo = [&](const auto &typeName) {
1369 if (isBuiltinType(typeName))
1370 return QMetaType::fromName(typeName).rawId();
1371 int index;
1372 if constexpr (std::is_same_v<decltype(typeName), const QByteArrayView &>)
1373 index = strings.enter(QByteArray::fromRawData(typeName.constData(), typeName.size()));
1374 else
1375 index = strings.enter(typeName);
1376 return int(IsUnresolvedType | index);
1377 };
1378
1379 // Output the method parameters in the class.
1380 Q_ASSERT(!buf || dataIndex == pmeta->methodData + pmeta->methodCount * QMetaObjectPrivate::IntsPerMethod);
1381 auto processMethodParameters = [&](const auto &methods) {
1382 for (const auto &method : methods) {
1383 if (method.revision) {
1384 if constexpr (mode == Construct)
1385 data[dataIndex] = method.revision;
1386 ++dataIndex;
1387 }
1388
1389 [[maybe_unused]] int typeInfo = getTypeInfo(method.returnType);
1390 if constexpr (mode == Construct)
1391 data[dataIndex] = typeInfo;
1392 ++dataIndex;
1393
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;
1399 ++dataIndex;
1400 }
1401
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;
1409 ++dataIndex;
1410 }
1411 }
1412 };
1413 processMethodParameters(d->signalVec);
1414 processMethodParameters(d->methods);
1415 processMethodParameters(d->constructors);
1416
1417 // Output the properties in the class.
1418 Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
1419 for (QMetaPropertyBuilderPrivate &prop : d->properties) {
1420 [[maybe_unused]] int name = strings.enter(prop.name);
1421
1422 // try to resolve the metatype again if it was unknown
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);
1428
1429 [[maybe_unused]] int flags = prop.flags;
1430
1431 if (!isBuiltinType(prop.type))
1432 flags |= EnumOrFlag;
1433
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;
1440 }
1441 dataIndex += QMetaObjectPrivate::IntsPerProperty;
1442 }
1443
1444 // Output the enumerators in the class.
1445 Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData);
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;
1456 }
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]);
1462 }
1463 enumIndex += 2;
1464 }
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);
1469 }
1470 ++enumIndex;
1471 }
1472 dataIndex += QMetaObjectPrivate::IntsPerEnum;
1473 }
1474
1475 // Output the constructors in the class.
1476 Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
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;
1489 }
1490 dataIndex += QMetaObjectPrivate::IntsPerMethod;
1491 paramsIndex += 1 + argc * 2;
1492 if (ctor.revision)
1493 ++paramsIndex;
1494 parameterMetaTypesIndex += argc;
1495 }
1496
1497 size += strings.blobSize();
1498
1499 if constexpr (mode == Construct)
1500 strings.writeBlob(str);
1501
1502 // Output the zero terminator in the data array.
1503 if constexpr (mode == Construct)
1504 data[enumIndex] = 0;
1505
1506 // Create the relatedMetaObjects block if we need one.
1507 if (d->relatedMetaObjects.size() > 0) {
1508 using SuperData = QMetaObject::SuperData;
1509 ALIGN(size, SuperData);
1510 auto objects = reinterpret_cast<SuperData *>(bufferAt(size));
1511 if constexpr (mode == Construct) {
1512 meta->d.relatedMetaObjects = objects;
1513 for (index = 0; index < d->relatedMetaObjects.size(); ++index)
1514 objects[index] = d->relatedMetaObjects[index];
1515 objects[index] = nullptr;
1516 }
1517 size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1);
1518 }
1519
1520 ALIGN(size, QtPrivate::QMetaTypeInterface *);
1521 auto types = reinterpret_cast<const QtPrivate::QMetaTypeInterface **>(bufferAt(size));
1522 if constexpr (mode == Construct) {
1523 meta->d.metaTypes = types;
1524 for (const auto &prop : d->properties) {
1525 QMetaType mt = prop.metaType;
1526 *types = mt.iface();
1527 types++;
1528 }
1529 // add metatypes for enumerators
1530 for (const auto &enumerator: d->enumerators) {
1531 QMetaType mt = enumerator.metaType;
1532 mt.registerType();
1533 *types = mt.iface();
1534 types++;
1535 }
1536 // add metatype interface for this metaobject - must be null
1537 // as we can't know our metatype
1538 *types = nullptr;
1539 types++;
1540
1541 auto addMetaTypes = [&](const auto &method) {
1542 QMetaType mt(QMetaType::fromName(method.returnType).rawId());
1543 *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
1544 types++;
1545 for (auto parameterType: method.parameterTypes()) {
1546 QMetaType mt = QMetaType::fromName(parameterType);
1547 *types = mt.iface();
1548 types++;
1549 }
1550 };
1551 for (const auto &method : d->signalVec)
1552 addMetaTypes(method);
1553 for (const auto &method : d->methods)
1554 addMetaTypes(method);
1555
1556 for (const auto &constructor : d->constructors) {
1557 for (auto parameterType : constructor.parameterTypes()) {
1558 QMetaType mt = QMetaType::fromName(parameterType);
1559 *types = mt.iface();
1560 types++;
1561 }
1562 }
1563 }
1564 // parameterMetaTypesIndex is equal to the total number of metatypes
1565 size += sizeof(QMetaType) * parameterMetaTypesIndex;
1566
1567 // Align the final size and return it.
1568 ALIGN(size, void *);
1569 Q_ASSERT(!buf || size == expectedSize);
1570 return size;
1571}
1572
1573/*!
1574 Converts this meta object builder into a concrete QMetaObject.
1575 The return value should be deallocated using free() once it
1576 is no longer needed.
1577
1578 The returned meta object is a snapshot of the state of the
1579 QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder
1580 will not be reflected in previous meta objects returned by
1581 this method.
1582*/
1583QMetaObject *QMetaObjectBuilder::toMetaObject() const
1584{
1585 int size = buildMetaObject<Prepare>(d, nullptr, 0);
1586 char *buf = new (calloc(size, 1)) char[size];
1587 buildMetaObject<Construct>(d, buf, size);
1588 return reinterpret_cast<QMetaObject *>(buf);
1589}
1590
1591/*!
1592 \typedef QMetaObjectBuilder::StaticMetacallFunction
1593
1594 Typedef for static metacall functions. The three parameters are
1595 the call type value, the constructor index, and the
1596 array of parameters.
1597*/
1598
1599/*!
1600 Returns the static metacall function to use to construct objects
1601 of this class. The default value is null.
1602
1603 \sa setStaticMetacallFunction()
1604*/
1605QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const
1606{
1607 return d->staticMetacallFunction;
1608}
1609
1610/*!
1611 Sets the static metacall function to use to construct objects
1612 of this class to \a value. The default value is null.
1613
1614 \sa staticMetacallFunction()
1615*/
1616void QMetaObjectBuilder::setStaticMetacallFunction
1617 (QMetaObjectBuilder::StaticMetacallFunction value)
1618{
1619 d->staticMetacallFunction = value;
1620}
1621
1622/*!
1623 \class QMetaMethodBuilder
1624 \inmodule QtCore
1625 \internal
1626 \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder.
1627*/
1628
1629QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
1630{
1631 if (!_mobj)
1632 return nullptr;
1633 switch (_type) {
1634 case QMetaMethod::Signal:
1635 if (_index < int(_mobj->d->signalVec.size()))
1636 return &(_mobj->d->signalVec[_index]);
1637 break;
1638 case QMetaMethod::Method:
1639 case QMetaMethod::Slot:
1640 if (_index < int(_mobj->d->methods.size()))
1641 return &(_mobj->d->methods[_index]);
1642 break;
1643 case QMetaMethod::Constructor:
1644 if (_index < int(_mobj->d->constructors.size()))
1645 return &(_mobj->d->constructors[_index]);
1646 break;
1647 }
1648 return nullptr;
1649}
1650
1651/*!
1652 \fn QMetaMethodBuilder::QMetaMethodBuilder()
1653 \internal
1654*/
1655
1656/*!
1657 Returns the index of this method within its QMetaObjectBuilder.
1658*/
1659int QMetaMethodBuilder::index() const
1660{
1661 return _index;
1662}
1663
1664/*!
1665 Returns the type of this method (signal, slot, method, or constructor).
1666*/
1667QMetaMethod::MethodType QMetaMethodBuilder::methodType() const
1668{
1669 QMetaMethodBuilderPrivate *d = d_func();
1670 if (d)
1671 return d->methodType();
1672 else
1673 return QMetaMethod::Method;
1674}
1675
1676/*!
1677 Returns the signature of this method.
1678
1679 \sa parameterNames(), returnType()
1680*/
1681QByteArray QMetaMethodBuilder::signature() const
1682{
1683 QMetaMethodBuilderPrivate *d = d_func();
1684 if (d)
1685 return d->signature;
1686 else
1687 return QByteArray();
1688}
1689
1690/*!
1691 Returns the return type for this method; empty if the method's
1692 return type is \c{void}.
1693
1694 \sa setReturnType(), signature()
1695*/
1696QByteArray QMetaMethodBuilder::returnType() const
1697{
1698 QMetaMethodBuilderPrivate *d = d_func();
1699 if (d)
1700 return d->returnType;
1701 else
1702 return QByteArray();
1703}
1704
1705/*!
1706 Sets the return type for this method to \a value. If \a value
1707 is empty, then the method's return type is \c{void}. The \a value
1708 will be normalized before it is added to the method.
1709
1710 \sa returnType(), parameterTypes(), signature()
1711*/
1712void QMetaMethodBuilder::setReturnType(const QByteArray &value)
1713{
1714 QMetaMethodBuilderPrivate *d = d_func();
1715 if (d)
1716 d->returnType = QMetaObject::normalizedType(value);
1717}
1718
1719/*!
1720 Returns the list of parameter types for this method.
1721
1722 \sa returnType(), parameterNames()
1723*/
1724QList<QByteArrayView> QMetaMethodBuilder::parameterTypes() const
1725{
1726 QMetaMethodBuilderPrivate *d = d_func();
1727 if (d)
1728 return d->parameterTypes();
1729 else
1730 return {};
1731}
1732
1733/*!
1734 Returns the list of parameter names for this method.
1735
1736 \sa setParameterNames()
1737*/
1738QList<QByteArray> QMetaMethodBuilder::parameterNames() const
1739{
1740 QMetaMethodBuilderPrivate *d = d_func();
1741 if (d)
1742 return d->parameterNames;
1743 else
1744 return QList<QByteArray>();
1745}
1746
1747/*!
1748 Sets the list of parameter names for this method to \a value.
1749
1750 \sa parameterNames()
1751*/
1752void QMetaMethodBuilder::setParameterNames(const QList<QByteArray> &value)
1753{
1754 QMetaMethodBuilderPrivate *d = d_func();
1755 Q_ASSERT(d->parameterCount() >= value.size());
1756 if (d)
1757 d->parameterNames = value;
1758}
1759
1760/*!
1761 Returns the tag associated with this method.
1762
1763 \sa setTag()
1764*/
1765QByteArray QMetaMethodBuilder::tag() const
1766{
1767 QMetaMethodBuilderPrivate *d = d_func();
1768 if (d)
1769 return d->tag;
1770 else
1771 return QByteArray();
1772}
1773
1774/*!
1775 Sets the tag associated with this method to \a value.
1776
1777 \sa setTag()
1778*/
1779void QMetaMethodBuilder::setTag(const QByteArray &value)
1780{
1781 QMetaMethodBuilderPrivate *d = d_func();
1782 if (d)
1783 d->tag = value;
1784}
1785
1786/*!
1787 Returns the access specification of this method (private, protected,
1788 or public). The default value is QMetaMethod::Public for methods,
1789 slots, signals and constructors.
1790
1791 \sa setAccess()
1792*/
1793QMetaMethod::Access QMetaMethodBuilder::access() const
1794{
1795 QMetaMethodBuilderPrivate *d = d_func();
1796 if (d)
1797 return d->access();
1798 else
1799 return QMetaMethod::Public;
1800}
1801
1802/*!
1803 Sets the access specification of this method (private, protected,
1804 or public) to \a value. If the method is a signal, this function
1805 will be ignored.
1806
1807 \sa access()
1808*/
1809void QMetaMethodBuilder::setAccess(QMetaMethod::Access value)
1810{
1811 QMetaMethodBuilderPrivate *d = d_func();
1812 if (d && d->methodType() != QMetaMethod::Signal)
1813 d->setAccess(value);
1814}
1815
1816/*!
1817 Returns the additional attributes for this method.
1818
1819 \sa setAttributes()
1820*/
1821int QMetaMethodBuilder::attributes() const
1822{
1823 QMetaMethodBuilderPrivate *d = d_func();
1824 if (d)
1825 return (d->attributes >> 4) & 0x7;
1826 else
1827 return 0;
1828}
1829
1830/*!
1831 Sets the additional attributes for this method to \a value.
1832
1833 \sa attributes()
1834*/
1835void QMetaMethodBuilder::setAttributes(int value)
1836{
1837 QMetaMethodBuilderPrivate *d = d_func();
1838 if (d) {
1839 d->attributes &= ~0x70;
1840 d->attributes |= (value & 0x7) << 4;
1841 }
1842}
1843
1844/*!
1845 Returns true if the method is const qualified.
1846 */
1847bool QMetaMethodBuilder::isConst() const
1848{
1849 QMetaMethodBuilderPrivate *d = d_func();
1850 if (!d)
1851 return false;
1852 return (d->attributes & MethodIsConst);
1853}
1854
1855void QMetaMethodBuilder::setConst(bool methodIsConst)
1856{
1857 QMetaMethodBuilderPrivate *d = d_func();
1858 if (!d)
1859 return;
1860 if (methodIsConst)
1861 d->attributes |= MethodIsConst;
1862 else
1863 d->attributes &= ~MethodIsConst;
1864}
1865
1866/*!
1867 Returns the revision of this method.
1868
1869 \sa setRevision()
1870*/
1871int QMetaMethodBuilder::revision() const
1872{
1873 QMetaMethodBuilderPrivate *d = d_func();
1874 if (d)
1875 return d->revision;
1876 return 0;
1877}
1878
1879/*!
1880 Sets the \a revision of this method.
1881
1882 \sa revision()
1883*/
1884void QMetaMethodBuilder::setRevision(int revision)
1885{
1886 QMetaMethodBuilderPrivate *d = d_func();
1887 if (d) {
1888 d->revision = revision;
1889 if (revision)
1890 d->attributes |= MethodRevisioned;
1891 else
1892 d->attributes &= ~MethodRevisioned;
1893 }
1894}
1895
1896/*!
1897 \class QMetaPropertyBuilder
1898 \inmodule QtCore
1899 \internal
1900 \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder.
1901*/
1902
1903QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
1904{
1905 if (_mobj && _index >= 0 && _index < int(_mobj->d->properties.size()))
1906 return &(_mobj->d->properties[_index]);
1907 else
1908 return nullptr;
1909}
1910
1911/*!
1912 \fn QMetaPropertyBuilder::QMetaPropertyBuilder()
1913 \internal
1914*/
1915
1916/*!
1917 \fn int QMetaPropertyBuilder::index() const
1918
1919 Returns the index of this property within its QMetaObjectBuilder.
1920*/
1921
1922/*!
1923 Returns the name associated with this property.
1924
1925 \sa type()
1926*/
1927QByteArray QMetaPropertyBuilder::name() const
1928{
1929 QMetaPropertyBuilderPrivate *d = d_func();
1930 if (d)
1931 return d->name;
1932 else
1933 return QByteArray();
1934}
1935
1936/*!
1937 Returns the type associated with this property.
1938
1939 \sa name()
1940*/
1941QByteArray QMetaPropertyBuilder::type() const
1942{
1943 QMetaPropertyBuilderPrivate *d = d_func();
1944 if (d)
1945 return d->type;
1946 else
1947 return QByteArray();
1948}
1949
1950/*!
1951 Returns \c true if this property has a notify signal; false otherwise.
1952
1953 \sa notifySignal(), setNotifySignal(), removeNotifySignal()
1954*/
1955bool QMetaPropertyBuilder::hasNotifySignal() const
1956{
1957 QMetaPropertyBuilderPrivate *d = d_func();
1958 if (d)
1959 return d->notifySignal != -1;
1960 else
1961 return false;
1962}
1963
1964/*!
1965 Returns the notify signal associated with this property.
1966
1967 \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal()
1968*/
1969QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const
1970{
1971 QMetaPropertyBuilderPrivate *d = d_func();
1972 if (d && d->notifySignal >= 0)
1973 return QMetaMethodBuilder(_mobj, d->notifySignal, QMetaMethod::Signal);
1974 else
1975 return QMetaMethodBuilder();
1976}
1977
1978/*!
1979 Sets the notify signal associated with this property to \a value.
1980
1981 \sa hasNotifySignal(), notifySignal(), removeNotifySignal()
1982*/
1983void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder &value)
1984{
1985 QMetaPropertyBuilderPrivate *d = d_func();
1986 if (d) {
1987 if (value._mobj) {
1988 d->notifySignal = value._index;
1989 } else {
1990 d->notifySignal = -1;
1991 }
1992 }
1993}
1994
1995/*!
1996 Removes the notify signal from this property.
1997
1998 \sa hasNotifySignal(), notifySignal(), setNotifySignal()
1999*/
2000void QMetaPropertyBuilder::removeNotifySignal()
2001{
2002 QMetaPropertyBuilderPrivate *d = d_func();
2003 if (d)
2004 d->notifySignal = -1;
2005}
2006
2007/*!
2008 Returns \c true if this property is readable; otherwise returns \c false.
2009 The default value is true.
2010
2011 \sa setReadable(), isWritable()
2012*/
2013bool QMetaPropertyBuilder::isReadable() const
2014{
2015 QMetaPropertyBuilderPrivate *d = d_func();
2016 if (d)
2017 return d->flag(Readable);
2018 else
2019 return false;
2020}
2021
2022/*!
2023 Returns \c true if this property is writable; otherwise returns \c false.
2024 The default value is true.
2025
2026 \sa setWritable(), isReadable()
2027*/
2028bool QMetaPropertyBuilder::isWritable() const
2029{
2030 QMetaPropertyBuilderPrivate *d = d_func();
2031 if (d)
2032 return d->flag(Writable);
2033 else
2034 return false;
2035}
2036
2037/*!
2038 Returns \c true if this property can be reset to a default value; otherwise
2039 returns \c false. The default value is false.
2040
2041 \sa setResettable()
2042*/
2043bool QMetaPropertyBuilder::isResettable() const
2044{
2045 QMetaPropertyBuilderPrivate *d = d_func();
2046 if (d)
2047 return d->flag(Resettable);
2048 else
2049 return false;
2050}
2051
2052/*!
2053 Returns \c true if this property is designable; otherwise returns \c false.
2054 This default value is false.
2055
2056 \sa setDesignable(), isScriptable(), isStored()
2057*/
2058bool QMetaPropertyBuilder::isDesignable() const
2059{
2060 QMetaPropertyBuilderPrivate *d = d_func();
2061 if (d)
2062 return d->flag(Designable);
2063 else
2064 return false;
2065}
2066
2067/*!
2068 Returns \c true if the property is scriptable; otherwise returns \c false.
2069 This default value is true.
2070
2071 \sa setScriptable(), isDesignable(), isStored()
2072*/
2073bool QMetaPropertyBuilder::isScriptable() const
2074{
2075 QMetaPropertyBuilderPrivate *d = d_func();
2076 if (d)
2077 return d->flag(Scriptable);
2078 else
2079 return false;
2080}
2081
2082/*!
2083 Returns \c true if the property is stored; otherwise returns \c false.
2084 This default value is false.
2085
2086 \sa setStored(), isDesignable(), isScriptable()
2087*/
2088bool QMetaPropertyBuilder::isStored() const
2089{
2090 QMetaPropertyBuilderPrivate *d = d_func();
2091 if (d)
2092 return d->flag(Stored);
2093 else
2094 return false;
2095}
2096
2097/*!
2098 Returns \c true if this property is designated as the \c USER
2099 property, i.e., the one that the user can edit or that is
2100 significant in some other way. Otherwise it returns
2101 false. This default value is false.
2102
2103 \sa setUser(), isDesignable(), isScriptable()
2104*/
2105bool QMetaPropertyBuilder::isUser() const
2106{
2107 QMetaPropertyBuilderPrivate *d = d_func();
2108 if (d)
2109 return d->flag(User);
2110 else
2111 return false;
2112}
2113
2114/*!
2115 Returns \c true if the property has a C++ setter function that
2116 follows Qt's standard "name" / "setName" pattern. Designer and uic
2117 query hasStdCppSet() in order to avoid expensive
2118 QObject::setProperty() calls. All properties in Qt [should] follow
2119 this pattern. The default value is false.
2120
2121 \sa setStdCppSet()
2122*/
2123bool QMetaPropertyBuilder::hasStdCppSet() const
2124{
2125 QMetaPropertyBuilderPrivate *d = d_func();
2126 if (d)
2127 return d->flag(StdCppSet);
2128 else
2129 return false;
2130}
2131
2132/*!
2133 Returns \c true if the property is an enumerator or flag type;
2134 otherwise returns \c false. This default value is false.
2135
2136 \sa setEnumOrFlag()
2137*/
2138bool QMetaPropertyBuilder::isEnumOrFlag() const
2139{
2140 QMetaPropertyBuilderPrivate *d = d_func();
2141 if (d)
2142 return d->flag(EnumOrFlag);
2143 else
2144 return false;
2145}
2146
2147/*!
2148 Returns \c true if the property is constant; otherwise returns \c false.
2149 The default value is false.
2150*/
2151bool QMetaPropertyBuilder::isConstant() const
2152{
2153 QMetaPropertyBuilderPrivate *d = d_func();
2154 if (d)
2155 return d->flag(Constant);
2156 else
2157 return false;
2158}
2159
2160/*!
2161 Returns \c true if the property is final; otherwise returns \c false.
2162 The default value is false.
2163*/
2164bool QMetaPropertyBuilder::isFinal() const
2165{
2166 QMetaPropertyBuilderPrivate *d = d_func();
2167 if (d)
2168 return d->flag(Final);
2169 else
2170 return false;
2171}
2172
2173/*!
2174 Returns \c true if the property is virtual; otherwise returns \c false.
2175 The default value is false.
2176*/
2177bool QMetaPropertyBuilder::isVirtual() const
2178{
2179 QMetaPropertyBuilderPrivate *d = d_func();
2180 if (d)
2181 return d->flag(Virtual);
2182 else
2183 return false;
2184}
2185
2186/*!
2187 Returns \c true if the property does override; otherwise returns \c false.
2188 The default value is false.
2189*/
2190bool QMetaPropertyBuilder::isOverride() const
2191{
2192 QMetaPropertyBuilderPrivate *d = d_func();
2193 if (d)
2194 return d->flag(Override);
2195 else
2196 return false;
2197}
2198
2199/*!
2200 * Returns \c true if the property is an alias.
2201 * The default value is false
2202 */
2203bool QMetaPropertyBuilder::isAlias() const
2204{
2205 QMetaPropertyBuilderPrivate *d = d_func();
2206 if (d)
2207 return d->flag(Alias);
2208 else
2209 return false;
2210}
2211
2212/*!
2213 Returns \c true if the property is bindable
2214 The default value is false
2215 */
2216bool QMetaPropertyBuilder::isBindable() const
2217{
2218 if (auto d = d_func())
2219 return d->flag(Bindable);
2220 else
2221 return false;
2222}
2223/*!
2224 Returns \c true if the property is required.
2225 The default is \c false.
2226 */
2227bool QMetaPropertyBuilder::isRequired() const
2228{
2229 if (auto d = d_func())
2230 return d->flag(Required);
2231 else
2232 return false;
2233}
2234
2235/*!
2236 Sets this property to readable if \a value is true.
2237
2238 \sa isReadable(), setWritable()
2239*/
2240void QMetaPropertyBuilder::setReadable(bool value)
2241{
2242 QMetaPropertyBuilderPrivate *d = d_func();
2243 if (d)
2244 d->setFlag(Readable, value);
2245}
2246
2247/*!
2248 Sets this property to writable if \a value is true.
2249
2250 \sa isWritable(), setReadable()
2251*/
2252void QMetaPropertyBuilder::setWritable(bool value)
2253{
2254 QMetaPropertyBuilderPrivate *d = d_func();
2255 if (d)
2256 d->setFlag(Writable, value);
2257}
2258
2259/*!
2260 Sets this property to resettable if \a value is true.
2261
2262 \sa isResettable()
2263*/
2264void QMetaPropertyBuilder::setResettable(bool value)
2265{
2266 QMetaPropertyBuilderPrivate *d = d_func();
2267 if (d)
2268 d->setFlag(Resettable, value);
2269}
2270
2271/*!
2272 Sets this property to designable if \a value is true.
2273
2274 \sa isDesignable(), setScriptable(), setStored()
2275*/
2276void QMetaPropertyBuilder::setDesignable(bool value)
2277{
2278 QMetaPropertyBuilderPrivate *d = d_func();
2279 if (d)
2280 d->setFlag(Designable, value);
2281}
2282
2283/*!
2284 Sets this property to scriptable if \a value is true.
2285
2286 \sa isScriptable(), setDesignable(), setStored()
2287*/
2288void QMetaPropertyBuilder::setScriptable(bool value)
2289{
2290 QMetaPropertyBuilderPrivate *d = d_func();
2291 if (d)
2292 d->setFlag(Scriptable, value);
2293}
2294
2295/*!
2296 Sets this property to storable if \a value is true.
2297
2298 \sa isStored(), setDesignable(), setScriptable()
2299*/
2300void QMetaPropertyBuilder::setStored(bool value)
2301{
2302 QMetaPropertyBuilderPrivate *d = d_func();
2303 if (d)
2304 d->setFlag(Stored, value);
2305}
2306
2307/*!
2308 Sets the \c USER flag on this property to \a value.
2309
2310 \sa isUser(), setDesignable(), setScriptable()
2311*/
2312void QMetaPropertyBuilder::setUser(bool value)
2313{
2314 QMetaPropertyBuilderPrivate *d = d_func();
2315 if (d)
2316 d->setFlag(User, value);
2317}
2318
2319/*!
2320 Sets the C++ setter flag on this property to \a value, which is
2321 true if the property has a C++ setter function that follows Qt's
2322 standard "name" / "setName" pattern.
2323
2324 \sa hasStdCppSet()
2325*/
2326void QMetaPropertyBuilder::setStdCppSet(bool value)
2327{
2328 QMetaPropertyBuilderPrivate *d = d_func();
2329 if (d)
2330 d->setFlag(StdCppSet, value);
2331}
2332
2333/*!
2334 Sets this property to be of an enumerator or flag type if
2335 \a value is true.
2336
2337 \sa isEnumOrFlag()
2338*/
2339void QMetaPropertyBuilder::setEnumOrFlag(bool value)
2340{
2341 QMetaPropertyBuilderPrivate *d = d_func();
2342 if (d)
2343 d->setFlag(EnumOrFlag, value);
2344}
2345
2346/*!
2347 Sets the \c CONSTANT flag on this property to \a value.
2348
2349 \sa isConstant()
2350*/
2351void QMetaPropertyBuilder::setConstant(bool value)
2352{
2353 QMetaPropertyBuilderPrivate *d = d_func();
2354 if (d)
2355 d->setFlag(Constant, value);
2356}
2357
2358/*!
2359 Sets the \c FINAL flag on this property to \a value.
2360
2361 \sa isFinal()
2362*/
2363void QMetaPropertyBuilder::setFinal(bool value)
2364{
2365 QMetaPropertyBuilderPrivate *d = d_func();
2366 if (d)
2367 d->setFlag(Final, value);
2368}
2369
2370/*!
2371 Sets the \c VIRTUAL flag on this property to \a value.
2372
2373 \sa isFinal()
2374*/
2375void QMetaPropertyBuilder::setVirtual(bool value)
2376{
2377 QMetaPropertyBuilderPrivate *d = d_func();
2378 if (d)
2379 d->setFlag(Virtual, value);
2380}
2381
2382/*!
2383 Sets the \c OVERRIDE flag on this property to \a value.
2384
2385 \sa isOverride()
2386*/
2387void QMetaPropertyBuilder::setOverride(bool value)
2388{
2389 QMetaPropertyBuilderPrivate *d = d_func();
2390 if (d)
2391 d->setFlag(Override, value);
2392}
2393
2394/*!
2395 Sets the \c ALIAS flag on this property to \a value
2396 */
2397void QMetaPropertyBuilder::setAlias(bool value)
2398{
2399 QMetaPropertyBuilderPrivate *d = d_func();
2400 if (d)
2401 d->setFlag(Alias, value);
2402}
2403
2404/*!
2405 Sets the\c BINDABLE flag on this property to \a value
2406 */
2407void QMetaPropertyBuilder::setBindable(bool value)
2408{
2409 if (auto d = d_func())
2410 d->setFlag(Bindable, value);
2411}
2412
2413/*!
2414 Sets the\c REQUIRED flag on this property to \a value
2415 */
2416void QMetaPropertyBuilder::setRequired(bool value)
2417{
2418 if (auto d = d_func())
2419 d->setFlag(Required, value);
2420}
2421
2422/*!
2423 Returns the revision of this property.
2424
2425 \sa setRevision()
2426*/
2427int QMetaPropertyBuilder::revision() const
2428{
2429 QMetaPropertyBuilderPrivate *d = d_func();
2430 if (d)
2431 return d->revision;
2432 return 0;
2433}
2434
2435/*!
2436 Sets the \a revision of this property.
2437
2438 \sa revision()
2439*/
2440void QMetaPropertyBuilder::setRevision(int revision)
2441{
2442 QMetaPropertyBuilderPrivate *d = d_func();
2443 if (d)
2444 d->revision = revision;
2445}
2446
2447/*!
2448 \class QMetaEnumBuilder
2449 \inmodule QtCore
2450 \internal
2451 \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
2452*/
2453
2454QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
2455{
2456 if (_mobj && _index >= 0 && _index < int(_mobj->d->enumerators.size()))
2457 return &(_mobj->d->enumerators[_index]);
2458 else
2459 return nullptr;
2460}
2461
2462/*!
2463 \fn QMetaEnumBuilder::QMetaEnumBuilder()
2464 \internal
2465*/
2466
2467/*!
2468 \fn int QMetaEnumBuilder::index() const
2469
2470 Returns the index of this enumerator within its QMetaObjectBuilder.
2471*/
2472
2473/*!
2474 Returns the type name of the enumerator (without the scope).
2475*/
2476QByteArray QMetaEnumBuilder::name() const
2477{
2478 QMetaEnumBuilderPrivate *d = d_func();
2479 if (d)
2480 return d->name;
2481 else
2482 return QByteArray();
2483}
2484
2485/*!
2486 Returns the enum name of the enumerator (without the scope).
2487
2488 \since 5.12
2489*/
2490QByteArray QMetaEnumBuilder::enumName() const
2491{
2492 QMetaEnumBuilderPrivate *d = d_func();
2493 if (d)
2494 return d->enumName;
2495 else
2496 return QByteArray();
2497}
2498
2499/*!
2500 Sets this enumerator to have the enum name \c alias.
2501
2502 \since 5.12
2503 \sa isFlag(), enumName()
2504*/
2505void QMetaEnumBuilder::setEnumName(const QByteArray &alias)
2506{
2507 QMetaEnumBuilderPrivate *d = d_func();
2508 if (d)
2509 d->enumName = alias;
2510}
2511
2512/*!
2513 Returns the meta type of the enumerator.
2514
2515 \since 6.6
2516*/
2517QMetaType QMetaEnumBuilder::metaType() const
2518{
2519 if (QMetaEnumBuilderPrivate *d = d_func())
2520 return d->metaType;
2521 return QMetaType();
2522}
2523
2524/*!
2525 Sets this enumerator to have the given \c metaType. The is64Bit() flag will
2526 be set to match \a metaType's size.
2527
2528 \since 6.6
2529 \sa metaType()
2530*/
2531void QMetaEnumBuilder::setMetaType(QMetaType metaType)
2532{
2533 QMetaEnumBuilderPrivate *d = d_func();
2534 if (d) {
2535 d->metaType = metaType;
2536 setIs64Bit(metaType.sizeOf() > 4);
2537 }
2538}
2539
2540/*!
2541 Returns \c true if this enumerator is used as a flag; otherwise returns
2542 false.
2543
2544 \sa setIsFlag()
2545*/
2546bool QMetaEnumBuilder::isFlag() const
2547{
2548 QMetaEnumBuilderPrivate *d = d_func();
2549 if (d)
2550 return d->flags.toInt() & EnumIsFlag;
2551 else
2552 return false;
2553}
2554
2555/*!
2556 Sets this enumerator to be used as a flag if \a value is true.
2557
2558 \sa isFlag()
2559*/
2560void QMetaEnumBuilder::setIsFlag(bool value)
2561{
2562 QMetaEnumBuilderPrivate *d = d_func();
2563 if (d)
2564 d->flags.setFlag(EnumIsFlag, value);
2565}
2566
2567/*!
2568 Return \c true if this enumerator should be considered scoped (C++11 enum class).
2569
2570 \sa setIsScoped()
2571*/
2572bool QMetaEnumBuilder::isScoped() const
2573{
2574 QMetaEnumBuilderPrivate *d = d_func();
2575 if (d)
2576 return d->flags.toInt() & EnumIsScoped;
2577 return false;
2578}
2579
2580/*!
2581 Sets this enumerator to be a scoped enum if \value is true
2582
2583 \sa isScoped()
2584*/
2585void QMetaEnumBuilder::setIsScoped(bool value)
2586{
2587 QMetaEnumBuilderPrivate *d = d_func();
2588 if (d)
2589 d->flags.setFlag(EnumIsScoped, value);
2590}
2591
2592/*!
2593 Return \c true if this enumerations in this enumerator are 64-bit.
2594
2595 This flag is autoamtically enabled if a 64-bit value is added with addKey().
2596
2597 \sa setIs64Bit()
2598*/
2599bool QMetaEnumBuilder::is64Bit() const
2600{
2601 QMetaEnumBuilderPrivate *d = d_func();
2602 if (d)
2603 return d->flags.toInt() & EnumIs64Bit;
2604 return false;
2605}
2606
2607/*!
2608 Sets this enumerator to be 64-bit wide if \a value is true. If \a value is
2609 false, any stored 64-bit keys will be truncated to 32 bits.
2610
2611 This flag is autoamtically enabled if a 64-bit value is added with addKey().
2612
2613 \sa is64Bit()
2614*/
2615void QMetaEnumBuilder::setIs64Bit(bool value)
2616{
2617 QMetaEnumBuilderPrivate *d = d_func();
2618 if (d)
2619 d->flags.setFlag(EnumIs64Bit, value);
2620}
2621
2622/*!
2623 Returns the number of keys.
2624
2625 \sa key(), addKey()
2626*/
2627int QMetaEnumBuilder::keyCount() const
2628{
2629 QMetaEnumBuilderPrivate *d = d_func();
2630 if (d)
2631 return d->keys.size();
2632 else
2633 return 0;
2634}
2635
2636/*!
2637 Returns the key with the given \a index, or an empty QByteArray
2638 if no such key exists.
2639
2640 \sa keyCount(), addKey(), value()
2641*/
2642QByteArray QMetaEnumBuilder::key(int index) const
2643{
2644 QMetaEnumBuilderPrivate *d = d_func();
2645 if (d && index >= 0 && index < d->keys.size())
2646 return d->keys[index];
2647 else
2648 return QByteArray();
2649}
2650
2651/*!
2652 Returns the value with the given \a index; or returns -1 if there
2653 is no such value.
2654
2655 If this is a 64-bit enumeration (see is64Bit()), this function returns the
2656 low 32-bit portion of the value. Use value64() to obtain the full value
2657 instead.
2658
2659 \sa value64(), keyCount(), addKey(), key(), is64Bit()
2660*/
2661int QMetaEnumBuilder::value(int index) const
2662{
2663 return value64(index).value_or(-1);
2664}
2665
2666/*!
2667 \since 6.9
2668
2669 Returns the value with the given \a index if it exists; or returns a
2670 disengaged \c{std::optional} if it doesn't.
2671
2672 \include qmetaobject.cpp qmetaenum-32bit-signextend-64bit
2673
2674 \sa keyCount(), key(), addKey()
2675*/
2676std::optional<quint64> QMetaEnumBuilder::value64(int index) const
2677{
2678 QMetaEnumBuilderPrivate *d = d_func();
2679 if (d && index >= 0 && index < d->keys.size()) {
2680 quint64 v = d->values[index];
2681 if (d->flags & EnumIs64Bit)
2682 return v;
2683 return uint(v); // return only the low 32 bits
2684 } else {
2685 return std::nullopt;
2686 }
2687}
2688
2689/*!
2690 Adds a new key called \a name to this enumerator, associated
2691 with \a value. Returns the index of the new key.
2692
2693 \sa keyCount(), key(), value(), removeKey()
2694*/
2695int QMetaEnumBuilder::addKey(const QByteArray &name, int value)
2696{
2697 QMetaEnumBuilderPrivate *d = d_func();
2698 if (d) {
2699 return d->addKey(name, uint(value));
2700 } else {
2701 return -1;
2702 }
2703}
2704
2705/*!
2706 \since 6.9
2707
2708 Adds a new key called \a name to this enumerator, associated
2709 with \a value. Returns the index of the new key.
2710
2711 Using the 64-bit version of this function automatically makes this
2712 enumeration be stored as 64-bit.
2713
2714 \sa keyCount(), key(), value(), removeKey(), is64Bit()
2715*/
2716int QMetaEnumBuilder::addKey(const QByteArray &name, quint64 value)
2717{
2718 QMetaEnumBuilderPrivate *d = d_func();
2719 if (d) {
2720 setIs64Bit(true);
2721 return d->addKey(name, value);
2722 }
2723 return -1;
2724}
2725
2726/*!
2727 Removes the key at \a index from this enumerator.
2728
2729 \sa addKey()
2730*/
2731void QMetaEnumBuilder::removeKey(int index)
2732{
2733 QMetaEnumBuilderPrivate *d = d_func();
2734 if (d && index >= 0 && index < d->keys.size()) {
2735 d->keys.removeAt(index);
2736 d->values.removeAt(index);
2737 }
2738}
2739
2740QT_END_NAMESPACE
QMetaEnumBuilderPrivate(const QByteArray &_name)
int addKey(const QByteArray &name, quint64 value)
QList< QByteArray > parameterNames
void setAccess(QMetaMethod::Access value)
QMetaMethod::Access access() const
QMetaMethod::MethodType methodType() const
QMetaMethodBuilderPrivate(QMetaMethod::MethodType _methodType, const QByteArray &_signature, const QByteArray &_returnType=QByteArray("void"), QMetaMethod::Access _access=QMetaMethod::Public, int _revision=0)
QList< QByteArrayView > parameterTypes() const
QList< const QMetaObject * > relatedMetaObjects
std::vector< QMetaMethodBuilderPrivate > methods
QList< QByteArray > classInfoValues
std::vector< QMetaMethodBuilderPrivate > signalVec
std::vector< QMetaPropertyBuilderPrivate > properties
std::vector< QMetaMethodBuilderPrivate > constructors
std::vector< QMetaEnumBuilderPrivate > enumerators
QList< QByteArray > classInfoNames
void setFlag(int f, bool value)
QMetaPropertyBuilderPrivate(const QByteArray &_name, const QByteArray &_type, QMetaType _metaType, int notifierIdx=-1, int _revision=0)
@ MetaObjectPrivateFieldCount
#define ALIGN(size, type)
static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, int expectedSize)
static const QMetaObjectPrivate * qmobPriv(const uint *data)
static void writeString(char *out, int i, const QByteArray &str, const int offsetOfStringdataMember, int &stringdataOffset)
static bool isBuiltinType(QByteArrayView type)
static int aggregateParameterCount(const std::vector< QMetaMethodBuilderPrivate > &methods)
Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_RELOCATABLE_TYPE)
Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_RELOCATABLE_TYPE)
Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_RELOCATABLE_TYPE)