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 int dataIndex;
1223 int paramsIndex;
1224 int enumIndex;
1225 int index;
1226
1227 // Create the main QMetaObject structure at the start of the buffer.
1228 QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf);
1229 size += sizeof(QMetaObject);
1230 ALIGN(size, int);
1231 if constexpr (mode == Construct) {
1232 meta->d.superdata = d->superClass;
1233 meta->d.relatedMetaObjects = nullptr;
1234 meta->d.extradata = nullptr;
1235 meta->d.metaTypes = nullptr;
1236 meta->d.static_metacall = d->staticMetacallFunction;
1237 }
1238
1239 // Populate the QMetaObjectPrivate structure.
1240 QMetaObjectPrivate *pmeta = buf ? reinterpret_cast<QMetaObjectPrivate *>(buf + size)
1241 : nullptr;
1242 //int pmetaSize = size;
1243 dataIndex = MetaObjectPrivateFieldCount;
1244 int methodParametersDataSize = aggregateParameterCount(d->methods)
1245 + aggregateParameterCount(d->signalVec)
1246 + aggregateParameterCount(d->constructors);
1247 if constexpr (mode == Construct) {
1248 static_assert(QMetaObjectPrivate::OutputRevision == 13, "QMetaObjectBuilder should generate the same version as moc");
1250 pmeta->flags = d->flags.toInt() | AllocatedMetaObject;
1251 pmeta->className = 0; // Class name is always the first string.
1252
1253 pmeta->classInfoCount = d->classInfoNames.size();
1254 pmeta->classInfoData = dataIndex;
1255 dataIndex += 2 * d->classInfoNames.size();
1256
1257 // QMetaObject treats QMetaObjectPrivate::methodData as the beginning of all "methods",
1258 // including signals
1259 pmeta->methodData = dataIndex;
1260 pmeta->signalCount = int(d->signalVec.size());
1261 pmeta->methodCount = int(d->methods.size()) + pmeta->signalCount;
1263 paramsIndex = dataIndex;
1264 dataIndex += methodParametersDataSize;
1265
1266 pmeta->propertyCount = int(d->properties.size());
1267 pmeta->propertyData = dataIndex;
1268 dataIndex += QMetaObjectPrivate::IntsPerProperty * int(d->properties.size());
1269
1270 pmeta->enumeratorCount = int(d->enumerators.size());
1271 pmeta->enumeratorData = dataIndex;
1272 dataIndex += QMetaObjectPrivate::IntsPerEnum * int(d->enumerators.size());
1273
1274 pmeta->constructorCount = int(d->constructors.size());
1275 pmeta->constructorData = dataIndex;
1276 dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
1277 } else {
1278 dataIndex += 2 * int(d->classInfoNames.size());
1279 const auto method_count = int(d->signalVec.size() + d->methods.size());
1280 dataIndex += QMetaObjectPrivate::IntsPerMethod * method_count;
1281 paramsIndex = dataIndex;
1282 dataIndex += methodParametersDataSize;
1283 dataIndex += QMetaObjectPrivate::IntsPerProperty * int(d->properties.size());
1284 dataIndex += QMetaObjectPrivate::IntsPerEnum * int(d->enumerators.size());
1285 dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
1286 }
1287
1288 // Allocate space for the enumerator key names and values.
1289 enumIndex = dataIndex;
1290 for (const auto &enumerator : d->enumerators) {
1291 dataIndex += 2 * enumerator.keys.size();
1292 if (enumerator.flags & EnumIs64Bit)
1293 dataIndex += enumerator.keys.size();
1294 }
1295
1296 // Zero terminator at the end of the data offset table.
1297 ++dataIndex;
1298
1299 // Find the start of the data and string tables.
1300 int *data = reinterpret_cast<int *>(pmeta);
1301 size += dataIndex * sizeof(int);
1302 ALIGN(size, void *);
1303 [[maybe_unused]] char *str = reinterpret_cast<char *>(buf + size);
1304 if constexpr (mode == Construct) {
1305 meta->d.stringdata = reinterpret_cast<const uint *>(str);
1306 meta->d.data = reinterpret_cast<uint *>(data);
1307 }
1308
1309 // Reset the current data position to just past the QMetaObjectPrivate.
1310 dataIndex = MetaObjectPrivateFieldCount;
1311
1312 QMetaStringTable strings(d->className);
1313
1314 // Output the class infos,
1315 Q_ASSERT(!buf || dataIndex == pmeta->classInfoData);
1316 for (index = 0; index < d->classInfoNames.size(); ++index) {
1317 [[maybe_unused]] int name = strings.enter(d->classInfoNames[index]);
1318 [[maybe_unused]] int value = strings.enter(d->classInfoValues[index]);
1319 if constexpr (mode == Construct) {
1320 data[dataIndex] = name;
1321 data[dataIndex + 1] = value;
1322 }
1323 dataIndex += 2;
1324 }
1325
1326 // Output all the methods in the class.
1327 Q_ASSERT(!buf || dataIndex == pmeta->methodData);
1328 // property count + enum count + 1 for metatype of this metaobject
1329 int parameterMetaTypesIndex = int(d->properties.size()) + int(d->enumerators.size()) + 1;
1330
1331 auto add_method = [&](const auto &method) {
1332 [[maybe_unused]] int name = strings.enter(method.name());
1333 int argc = method.parameterCount();
1334 [[maybe_unused]] int tag = strings.enter(method.tag);
1335 [[maybe_unused]] int attrs = method.attributes;
1336 if (method.revision)
1337 ++paramsIndex;
1338 if constexpr (mode == Construct) {
1339 data[dataIndex] = name;
1340 data[dataIndex + 1] = argc;
1341 data[dataIndex + 2] = paramsIndex;
1342 data[dataIndex + 3] = tag;
1343 data[dataIndex + 4] = attrs;
1344 data[dataIndex + 5] = parameterMetaTypesIndex;
1345 }
1347 paramsIndex += 1 + argc * 2;
1348 parameterMetaTypesIndex += 1 + argc;
1349 };
1350
1351 // first output the signals in the class, to match meta-objects generated by moc
1352 for (const auto &signal : d->signalVec)
1353 add_method(signal);
1354
1355 // Output the rest of the methods (QMetaMethod::{Method,Slot}) in the class
1356 for (const auto &method : d->methods)
1357 add_method(method);
1358
1359 auto getTypeInfo = [&](const auto &typeName) {
1360 if (isBuiltinType(typeName))
1361 return QMetaType::fromName(typeName).rawId();
1362 int index;
1363 if constexpr (std::is_same_v<decltype(typeName), const QByteArrayView &>)
1364 index = strings.enter(QByteArray::fromRawData(typeName.constData(), typeName.size()));
1365 else
1366 index = strings.enter(typeName);
1367 return int(IsUnresolvedType | index);
1368 };
1369
1370 // Output the method parameters in the class.
1371 Q_ASSERT(!buf || dataIndex == pmeta->methodData + pmeta->methodCount * QMetaObjectPrivate::IntsPerMethod);
1372 auto processMethodParameters = [&](const auto &methods) {
1373 for (const auto &method : methods) {
1374 if (method.revision) {
1375 if constexpr (mode == Construct)
1376 data[dataIndex] = method.revision;
1377 ++dataIndex;
1378 }
1379
1380 [[maybe_unused]] int typeInfo = getTypeInfo(method.returnType);
1381 if constexpr (mode == Construct)
1382 data[dataIndex] = typeInfo;
1383 ++dataIndex;
1384
1385 const QList<QByteArrayView> paramTypeNames = method.parameterTypes();
1386 for (auto typeName : paramTypeNames) {
1387 [[maybe_unused]] int typeInfo = getTypeInfo(typeName);
1388 if constexpr (mode == Construct)
1389 data[dataIndex] = typeInfo;
1390 ++dataIndex;
1391 }
1392
1393 QList<QByteArray> paramNames = method.parameterNames;
1394 if (const auto paramCount = paramTypeNames.size(); paramNames.size() < paramCount)
1395 paramNames.resize(paramCount);
1396 for (const auto &name : std::as_const(paramNames)) {
1397 [[maybe_unused]] int stringIndex = strings.enter(name);
1398 if constexpr (mode == Construct)
1399 data[dataIndex] = stringIndex;
1400 ++dataIndex;
1401 }
1402 }
1403 };
1404 processMethodParameters(d->signalVec);
1405 processMethodParameters(d->methods);
1406 processMethodParameters(d->constructors);
1407
1408 // Output the properties in the class.
1409 Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
1410 for (QMetaPropertyBuilderPrivate &prop : d->properties) {
1411 [[maybe_unused]] int name = strings.enter(prop.name);
1412
1413 // try to resolve the metatype again if it was unknown
1414 if (!prop.metaType.isValid())
1415 prop.metaType = QMetaType::fromName(prop.type);
1416 [[maybe_unused]] const int typeInfo = prop.metaType.isValid()
1417 ? prop.metaType.id()
1418 : IsUnresolvedType | strings.enter(prop.type);
1419
1420 [[maybe_unused]] int flags = prop.flags;
1421
1422 if (!isBuiltinType(prop.type))
1423 flags |= EnumOrFlag;
1424
1425 if constexpr (mode == Construct) {
1426 data[dataIndex] = name;
1427 data[dataIndex + 1] = typeInfo;
1428 data[dataIndex + 2] = flags;
1429 data[dataIndex + 3] = prop.notifySignal;
1430 data[dataIndex + 4] = prop.revision;
1431 }
1432 dataIndex += QMetaObjectPrivate::IntsPerProperty;
1433 }
1434
1435 // Output the enumerators in the class.
1436 Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData);
1437 for (const auto &enumerator : d->enumerators) {
1438 [[maybe_unused]] int name = strings.enter(enumerator.name);
1439 [[maybe_unused]] int enumName = strings.enter(enumerator.enumName);
1440 int count = enumerator.keys.size();
1441 if constexpr (mode == Construct) {
1442 data[dataIndex] = name;
1443 data[dataIndex + 1] = enumName;
1444 data[dataIndex + 2] = enumerator.flags.toInt();
1445 data[dataIndex + 3] = count;
1446 data[dataIndex + 4] = enumIndex;
1447 }
1448 for (int key = 0; key < count; ++key) {
1449 [[maybe_unused]] int keyIndex = strings.enter(enumerator.keys[key]);
1450 if constexpr (mode == Construct) {
1451 data[enumIndex + 0] = keyIndex;
1452 data[enumIndex + 1] = uint(enumerator.values[key]);
1453 }
1454 enumIndex += 2;
1455 }
1456 bool is64Bit = enumerator.flags.testAnyFlags(EnumIs64Bit);
1457 for (int key = 0; is64Bit && key < count; ++key) {
1458 if constexpr (mode == Construct) {
1459 data[enumIndex] = uint(enumerator.values[key] >> 32);
1460 }
1461 ++enumIndex;
1462 }
1463 dataIndex += QMetaObjectPrivate::IntsPerEnum;
1464 }
1465
1466 // Output the constructors in the class.
1467 Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
1468 for (const auto &ctor : d->constructors) {
1469 [[maybe_unused]] int name = strings.enter(ctor.name());
1470 int argc = ctor.parameterCount();
1471 [[maybe_unused]] int tag = strings.enter(ctor.tag);
1472 [[maybe_unused]] int attrs = ctor.attributes;
1473 if constexpr (mode == Construct) {
1474 data[dataIndex] = name;
1475 data[dataIndex + 1] = argc;
1476 data[dataIndex + 2] = paramsIndex;
1477 data[dataIndex + 3] = tag;
1478 data[dataIndex + 4] = attrs;
1479 data[dataIndex + 5] = parameterMetaTypesIndex;
1480 }
1481 dataIndex += QMetaObjectPrivate::IntsPerMethod;
1482 paramsIndex += 1 + argc * 2;
1483 if (ctor.revision)
1484 ++paramsIndex;
1485 parameterMetaTypesIndex += argc;
1486 }
1487
1488 size += strings.blobSize();
1489
1490 if constexpr (mode == Construct)
1491 strings.writeBlob(str);
1492
1493 // Output the zero terminator in the data array.
1494 if constexpr (mode == Construct)
1495 data[enumIndex] = 0;
1496
1497 // Create the relatedMetaObjects block if we need one.
1498 if (d->relatedMetaObjects.size() > 0) {
1499 using SuperData = QMetaObject::SuperData;
1500 ALIGN(size, SuperData);
1501 auto objects = reinterpret_cast<SuperData *>(buf + size);
1502 if constexpr (mode == Construct) {
1503 meta->d.relatedMetaObjects = objects;
1504 for (index = 0; index < d->relatedMetaObjects.size(); ++index)
1505 objects[index] = d->relatedMetaObjects[index];
1506 objects[index] = nullptr;
1507 }
1508 size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1);
1509 }
1510
1511 ALIGN(size, QtPrivate::QMetaTypeInterface *);
1512 auto types = reinterpret_cast<const QtPrivate::QMetaTypeInterface **>(buf + size);
1513 if constexpr (mode == Construct) {
1514 meta->d.metaTypes = types;
1515 for (const auto &prop : d->properties) {
1516 QMetaType mt = prop.metaType;
1517 *types = mt.iface();
1518 types++;
1519 }
1520 // add metatypes for enumerators
1521 for (const auto &enumerator: d->enumerators) {
1522 QMetaType mt = enumerator.metaType;
1523 mt.registerType();
1524 *types = mt.iface();
1525 types++;
1526 }
1527 // add metatype interface for this metaobject - must be null
1528 // as we can't know our metatype
1529 *types = nullptr;
1530 types++;
1531
1532 auto addMetaTypes = [&](const auto &method) {
1533 QMetaType mt(QMetaType::fromName(method.returnType).rawId());
1534 *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
1535 types++;
1536 for (auto parameterType: method.parameterTypes()) {
1537 QMetaType mt = QMetaType::fromName(parameterType);
1538 *types = mt.iface();
1539 types++;
1540 }
1541 };
1542 for (const auto &method : d->signalVec)
1543 addMetaTypes(method);
1544 for (const auto &method : d->methods)
1545 addMetaTypes(method);
1546
1547 for (const auto &constructor : d->constructors) {
1548 for (auto parameterType : constructor.parameterTypes()) {
1549 QMetaType mt = QMetaType::fromName(parameterType);
1550 *types = mt.iface();
1551 types++;
1552 }
1553 }
1554 }
1555 // parameterMetaTypesIndex is equal to the total number of metatypes
1556 size += sizeof(QMetaType) * parameterMetaTypesIndex;
1557
1558 // Align the final size and return it.
1559 ALIGN(size, void *);
1560 Q_ASSERT(!buf || size == expectedSize);
1561 return size;
1562}
1563
1564/*!
1565 Converts this meta object builder into a concrete QMetaObject.
1566 The return value should be deallocated using free() once it
1567 is no longer needed.
1568
1569 The returned meta object is a snapshot of the state of the
1570 QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder
1571 will not be reflected in previous meta objects returned by
1572 this method.
1573*/
1574QMetaObject *QMetaObjectBuilder::toMetaObject() const
1575{
1576 int size = buildMetaObject<Prepare>(d, nullptr, 0);
1577 char *buf = new (calloc(size, 1)) char[size];
1578 buildMetaObject<Construct>(d, buf, size);
1579 return reinterpret_cast<QMetaObject *>(buf);
1580}
1581
1582/*!
1583 \typedef QMetaObjectBuilder::StaticMetacallFunction
1584
1585 Typedef for static metacall functions. The three parameters are
1586 the call type value, the constructor index, and the
1587 array of parameters.
1588*/
1589
1590/*!
1591 Returns the static metacall function to use to construct objects
1592 of this class. The default value is null.
1593
1594 \sa setStaticMetacallFunction()
1595*/
1596QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const
1597{
1598 return d->staticMetacallFunction;
1599}
1600
1601/*!
1602 Sets the static metacall function to use to construct objects
1603 of this class to \a value. The default value is null.
1604
1605 \sa staticMetacallFunction()
1606*/
1607void QMetaObjectBuilder::setStaticMetacallFunction
1608 (QMetaObjectBuilder::StaticMetacallFunction value)
1609{
1610 d->staticMetacallFunction = value;
1611}
1612
1613/*!
1614 \class QMetaMethodBuilder
1615 \inmodule QtCore
1616 \internal
1617 \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder.
1618*/
1619
1620QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
1621{
1622 if (!_mobj)
1623 return nullptr;
1624 switch (_type) {
1625 case QMetaMethod::Signal:
1626 if (_index < int(_mobj->d->signalVec.size()))
1627 return &(_mobj->d->signalVec[_index]);
1628 break;
1629 case QMetaMethod::Method:
1630 case QMetaMethod::Slot:
1631 if (_index < int(_mobj->d->methods.size()))
1632 return &(_mobj->d->methods[_index]);
1633 break;
1634 case QMetaMethod::Constructor:
1635 if (_index < int(_mobj->d->constructors.size()))
1636 return &(_mobj->d->constructors[_index]);
1637 break;
1638 }
1639 return nullptr;
1640}
1641
1642/*!
1643 \fn QMetaMethodBuilder::QMetaMethodBuilder()
1644 \internal
1645*/
1646
1647/*!
1648 Returns the index of this method within its QMetaObjectBuilder.
1649*/
1650int QMetaMethodBuilder::index() const
1651{
1652 return _index;
1653}
1654
1655/*!
1656 Returns the type of this method (signal, slot, method, or constructor).
1657*/
1658QMetaMethod::MethodType QMetaMethodBuilder::methodType() const
1659{
1660 QMetaMethodBuilderPrivate *d = d_func();
1661 if (d)
1662 return d->methodType();
1663 else
1664 return QMetaMethod::Method;
1665}
1666
1667/*!
1668 Returns the signature of this method.
1669
1670 \sa parameterNames(), returnType()
1671*/
1672QByteArray QMetaMethodBuilder::signature() const
1673{
1674 QMetaMethodBuilderPrivate *d = d_func();
1675 if (d)
1676 return d->signature;
1677 else
1678 return QByteArray();
1679}
1680
1681/*!
1682 Returns the return type for this method; empty if the method's
1683 return type is \c{void}.
1684
1685 \sa setReturnType(), signature()
1686*/
1687QByteArray QMetaMethodBuilder::returnType() const
1688{
1689 QMetaMethodBuilderPrivate *d = d_func();
1690 if (d)
1691 return d->returnType;
1692 else
1693 return QByteArray();
1694}
1695
1696/*!
1697 Sets the return type for this method to \a value. If \a value
1698 is empty, then the method's return type is \c{void}. The \a value
1699 will be normalized before it is added to the method.
1700
1701 \sa returnType(), parameterTypes(), signature()
1702*/
1703void QMetaMethodBuilder::setReturnType(const QByteArray &value)
1704{
1705 QMetaMethodBuilderPrivate *d = d_func();
1706 if (d)
1707 d->returnType = QMetaObject::normalizedType(value);
1708}
1709
1710/*!
1711 Returns the list of parameter types for this method.
1712
1713 \sa returnType(), parameterNames()
1714*/
1715QList<QByteArrayView> QMetaMethodBuilder::parameterTypes() const
1716{
1717 QMetaMethodBuilderPrivate *d = d_func();
1718 if (d)
1719 return d->parameterTypes();
1720 else
1721 return {};
1722}
1723
1724/*!
1725 Returns the list of parameter names for this method.
1726
1727 \sa setParameterNames()
1728*/
1729QList<QByteArray> QMetaMethodBuilder::parameterNames() const
1730{
1731 QMetaMethodBuilderPrivate *d = d_func();
1732 if (d)
1733 return d->parameterNames;
1734 else
1735 return QList<QByteArray>();
1736}
1737
1738/*!
1739 Sets the list of parameter names for this method to \a value.
1740
1741 \sa parameterNames()
1742*/
1743void QMetaMethodBuilder::setParameterNames(const QList<QByteArray> &value)
1744{
1745 QMetaMethodBuilderPrivate *d = d_func();
1746 Q_ASSERT(d->parameterCount() >= value.size());
1747 if (d)
1748 d->parameterNames = value;
1749}
1750
1751/*!
1752 Returns the tag associated with this method.
1753
1754 \sa setTag()
1755*/
1756QByteArray QMetaMethodBuilder::tag() const
1757{
1758 QMetaMethodBuilderPrivate *d = d_func();
1759 if (d)
1760 return d->tag;
1761 else
1762 return QByteArray();
1763}
1764
1765/*!
1766 Sets the tag associated with this method to \a value.
1767
1768 \sa setTag()
1769*/
1770void QMetaMethodBuilder::setTag(const QByteArray &value)
1771{
1772 QMetaMethodBuilderPrivate *d = d_func();
1773 if (d)
1774 d->tag = value;
1775}
1776
1777/*!
1778 Returns the access specification of this method (private, protected,
1779 or public). The default value is QMetaMethod::Public for methods,
1780 slots, signals and constructors.
1781
1782 \sa setAccess()
1783*/
1784QMetaMethod::Access QMetaMethodBuilder::access() const
1785{
1786 QMetaMethodBuilderPrivate *d = d_func();
1787 if (d)
1788 return d->access();
1789 else
1790 return QMetaMethod::Public;
1791}
1792
1793/*!
1794 Sets the access specification of this method (private, protected,
1795 or public) to \a value. If the method is a signal, this function
1796 will be ignored.
1797
1798 \sa access()
1799*/
1800void QMetaMethodBuilder::setAccess(QMetaMethod::Access value)
1801{
1802 QMetaMethodBuilderPrivate *d = d_func();
1803 if (d && d->methodType() != QMetaMethod::Signal)
1804 d->setAccess(value);
1805}
1806
1807/*!
1808 Returns the additional attributes for this method.
1809
1810 \sa setAttributes()
1811*/
1812int QMetaMethodBuilder::attributes() const
1813{
1814 QMetaMethodBuilderPrivate *d = d_func();
1815 if (d)
1816 return (d->attributes >> 4) & 0x7;
1817 else
1818 return 0;
1819}
1820
1821/*!
1822 Sets the additional attributes for this method to \a value.
1823
1824 \sa attributes()
1825*/
1826void QMetaMethodBuilder::setAttributes(int value)
1827{
1828 QMetaMethodBuilderPrivate *d = d_func();
1829 if (d) {
1830 d->attributes &= ~0x70;
1831 d->attributes |= (value & 0x7) << 4;
1832 }
1833}
1834
1835/*!
1836 Returns true if the method is const qualified.
1837 */
1838bool QMetaMethodBuilder::isConst() const
1839{
1840 QMetaMethodBuilderPrivate *d = d_func();
1841 if (!d)
1842 return false;
1843 return (d->attributes & MethodIsConst);
1844}
1845
1846void QMetaMethodBuilder::setConst(bool methodIsConst)
1847{
1848 QMetaMethodBuilderPrivate *d = d_func();
1849 if (!d)
1850 return;
1851 if (methodIsConst)
1852 d->attributes |= MethodIsConst;
1853 else
1854 d->attributes &= ~MethodIsConst;
1855}
1856
1857/*!
1858 Returns the revision of this method.
1859
1860 \sa setRevision()
1861*/
1862int QMetaMethodBuilder::revision() const
1863{
1864 QMetaMethodBuilderPrivate *d = d_func();
1865 if (d)
1866 return d->revision;
1867 return 0;
1868}
1869
1870/*!
1871 Sets the \a revision of this method.
1872
1873 \sa revision()
1874*/
1875void QMetaMethodBuilder::setRevision(int revision)
1876{
1877 QMetaMethodBuilderPrivate *d = d_func();
1878 if (d) {
1879 d->revision = revision;
1880 if (revision)
1881 d->attributes |= MethodRevisioned;
1882 else
1883 d->attributes &= ~MethodRevisioned;
1884 }
1885}
1886
1887/*!
1888 \class QMetaPropertyBuilder
1889 \inmodule QtCore
1890 \internal
1891 \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder.
1892*/
1893
1894QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
1895{
1896 if (_mobj && _index >= 0 && _index < int(_mobj->d->properties.size()))
1897 return &(_mobj->d->properties[_index]);
1898 else
1899 return nullptr;
1900}
1901
1902/*!
1903 \fn QMetaPropertyBuilder::QMetaPropertyBuilder()
1904 \internal
1905*/
1906
1907/*!
1908 \fn int QMetaPropertyBuilder::index() const
1909
1910 Returns the index of this property within its QMetaObjectBuilder.
1911*/
1912
1913/*!
1914 Returns the name associated with this property.
1915
1916 \sa type()
1917*/
1918QByteArray QMetaPropertyBuilder::name() const
1919{
1920 QMetaPropertyBuilderPrivate *d = d_func();
1921 if (d)
1922 return d->name;
1923 else
1924 return QByteArray();
1925}
1926
1927/*!
1928 Returns the type associated with this property.
1929
1930 \sa name()
1931*/
1932QByteArray QMetaPropertyBuilder::type() const
1933{
1934 QMetaPropertyBuilderPrivate *d = d_func();
1935 if (d)
1936 return d->type;
1937 else
1938 return QByteArray();
1939}
1940
1941/*!
1942 Returns \c true if this property has a notify signal; false otherwise.
1943
1944 \sa notifySignal(), setNotifySignal(), removeNotifySignal()
1945*/
1946bool QMetaPropertyBuilder::hasNotifySignal() const
1947{
1948 QMetaPropertyBuilderPrivate *d = d_func();
1949 if (d)
1950 return d->notifySignal != -1;
1951 else
1952 return false;
1953}
1954
1955/*!
1956 Returns the notify signal associated with this property.
1957
1958 \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal()
1959*/
1960QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const
1961{
1962 QMetaPropertyBuilderPrivate *d = d_func();
1963 if (d && d->notifySignal >= 0)
1964 return QMetaMethodBuilder(_mobj, d->notifySignal, QMetaMethod::Signal);
1965 else
1966 return QMetaMethodBuilder();
1967}
1968
1969/*!
1970 Sets the notify signal associated with this property to \a value.
1971
1972 \sa hasNotifySignal(), notifySignal(), removeNotifySignal()
1973*/
1974void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder &value)
1975{
1976 QMetaPropertyBuilderPrivate *d = d_func();
1977 if (d) {
1978 if (value._mobj) {
1979 d->notifySignal = value._index;
1980 } else {
1981 d->notifySignal = -1;
1982 }
1983 }
1984}
1985
1986/*!
1987 Removes the notify signal from this property.
1988
1989 \sa hasNotifySignal(), notifySignal(), setNotifySignal()
1990*/
1991void QMetaPropertyBuilder::removeNotifySignal()
1992{
1993 QMetaPropertyBuilderPrivate *d = d_func();
1994 if (d)
1995 d->notifySignal = -1;
1996}
1997
1998/*!
1999 Returns \c true if this property is readable; otherwise returns \c false.
2000 The default value is true.
2001
2002 \sa setReadable(), isWritable()
2003*/
2004bool QMetaPropertyBuilder::isReadable() const
2005{
2006 QMetaPropertyBuilderPrivate *d = d_func();
2007 if (d)
2008 return d->flag(Readable);
2009 else
2010 return false;
2011}
2012
2013/*!
2014 Returns \c true if this property is writable; otherwise returns \c false.
2015 The default value is true.
2016
2017 \sa setWritable(), isReadable()
2018*/
2019bool QMetaPropertyBuilder::isWritable() const
2020{
2021 QMetaPropertyBuilderPrivate *d = d_func();
2022 if (d)
2023 return d->flag(Writable);
2024 else
2025 return false;
2026}
2027
2028/*!
2029 Returns \c true if this property can be reset to a default value; otherwise
2030 returns \c false. The default value is false.
2031
2032 \sa setResettable()
2033*/
2034bool QMetaPropertyBuilder::isResettable() const
2035{
2036 QMetaPropertyBuilderPrivate *d = d_func();
2037 if (d)
2038 return d->flag(Resettable);
2039 else
2040 return false;
2041}
2042
2043/*!
2044 Returns \c true if this property is designable; otherwise returns \c false.
2045 This default value is false.
2046
2047 \sa setDesignable(), isScriptable(), isStored()
2048*/
2049bool QMetaPropertyBuilder::isDesignable() const
2050{
2051 QMetaPropertyBuilderPrivate *d = d_func();
2052 if (d)
2053 return d->flag(Designable);
2054 else
2055 return false;
2056}
2057
2058/*!
2059 Returns \c true if the property is scriptable; otherwise returns \c false.
2060 This default value is true.
2061
2062 \sa setScriptable(), isDesignable(), isStored()
2063*/
2064bool QMetaPropertyBuilder::isScriptable() const
2065{
2066 QMetaPropertyBuilderPrivate *d = d_func();
2067 if (d)
2068 return d->flag(Scriptable);
2069 else
2070 return false;
2071}
2072
2073/*!
2074 Returns \c true if the property is stored; otherwise returns \c false.
2075 This default value is false.
2076
2077 \sa setStored(), isDesignable(), isScriptable()
2078*/
2079bool QMetaPropertyBuilder::isStored() const
2080{
2081 QMetaPropertyBuilderPrivate *d = d_func();
2082 if (d)
2083 return d->flag(Stored);
2084 else
2085 return false;
2086}
2087
2088/*!
2089 Returns \c true if this property is designated as the \c USER
2090 property, i.e., the one that the user can edit or that is
2091 significant in some other way. Otherwise it returns
2092 false. This default value is false.
2093
2094 \sa setUser(), isDesignable(), isScriptable()
2095*/
2096bool QMetaPropertyBuilder::isUser() const
2097{
2098 QMetaPropertyBuilderPrivate *d = d_func();
2099 if (d)
2100 return d->flag(User);
2101 else
2102 return false;
2103}
2104
2105/*!
2106 Returns \c true if the property has a C++ setter function that
2107 follows Qt's standard "name" / "setName" pattern. Designer and uic
2108 query hasStdCppSet() in order to avoid expensive
2109 QObject::setProperty() calls. All properties in Qt [should] follow
2110 this pattern. The default value is false.
2111
2112 \sa setStdCppSet()
2113*/
2114bool QMetaPropertyBuilder::hasStdCppSet() const
2115{
2116 QMetaPropertyBuilderPrivate *d = d_func();
2117 if (d)
2118 return d->flag(StdCppSet);
2119 else
2120 return false;
2121}
2122
2123/*!
2124 Returns \c true if the property is an enumerator or flag type;
2125 otherwise returns \c false. This default value is false.
2126
2127 \sa setEnumOrFlag()
2128*/
2129bool QMetaPropertyBuilder::isEnumOrFlag() const
2130{
2131 QMetaPropertyBuilderPrivate *d = d_func();
2132 if (d)
2133 return d->flag(EnumOrFlag);
2134 else
2135 return false;
2136}
2137
2138/*!
2139 Returns \c true if the property is constant; otherwise returns \c false.
2140 The default value is false.
2141*/
2142bool QMetaPropertyBuilder::isConstant() const
2143{
2144 QMetaPropertyBuilderPrivate *d = d_func();
2145 if (d)
2146 return d->flag(Constant);
2147 else
2148 return false;
2149}
2150
2151/*!
2152 Returns \c true if the property is final; otherwise returns \c false.
2153 The default value is false.
2154*/
2155bool QMetaPropertyBuilder::isFinal() const
2156{
2157 QMetaPropertyBuilderPrivate *d = d_func();
2158 if (d)
2159 return d->flag(Final);
2160 else
2161 return false;
2162}
2163
2164/*!
2165 Returns \c true if the property is virtual; otherwise returns \c false.
2166 The default value is false.
2167*/
2168bool QMetaPropertyBuilder::isVirtual() const
2169{
2170 QMetaPropertyBuilderPrivate *d = d_func();
2171 if (d)
2172 return d->flag(Virtual);
2173 else
2174 return false;
2175}
2176
2177/*!
2178 Returns \c true if the property does override; otherwise returns \c false.
2179 The default value is false.
2180*/
2181bool QMetaPropertyBuilder::isOverride() const
2182{
2183 QMetaPropertyBuilderPrivate *d = d_func();
2184 if (d)
2185 return d->flag(Override);
2186 else
2187 return false;
2188}
2189
2190/*!
2191 * Returns \c true if the property is an alias.
2192 * The default value is false
2193 */
2194bool QMetaPropertyBuilder::isAlias() const
2195{
2196 QMetaPropertyBuilderPrivate *d = d_func();
2197 if (d)
2198 return d->flag(Alias);
2199 else
2200 return false;
2201}
2202
2203/*!
2204 Returns \c true if the property is bindable
2205 The default value is false
2206 */
2207bool QMetaPropertyBuilder::isBindable() const
2208{
2209 if (auto d = d_func())
2210 return d->flag(Bindable);
2211 else
2212 return false;
2213}
2214/*!
2215 Returns \c true if the property is required.
2216 The default is \c false.
2217 */
2218bool QMetaPropertyBuilder::isRequired() const
2219{
2220 if (auto d = d_func())
2221 return d->flag(Required);
2222 else
2223 return false;
2224}
2225
2226/*!
2227 Sets this property to readable if \a value is true.
2228
2229 \sa isReadable(), setWritable()
2230*/
2231void QMetaPropertyBuilder::setReadable(bool value)
2232{
2233 QMetaPropertyBuilderPrivate *d = d_func();
2234 if (d)
2235 d->setFlag(Readable, value);
2236}
2237
2238/*!
2239 Sets this property to writable if \a value is true.
2240
2241 \sa isWritable(), setReadable()
2242*/
2243void QMetaPropertyBuilder::setWritable(bool value)
2244{
2245 QMetaPropertyBuilderPrivate *d = d_func();
2246 if (d)
2247 d->setFlag(Writable, value);
2248}
2249
2250/*!
2251 Sets this property to resettable if \a value is true.
2252
2253 \sa isResettable()
2254*/
2255void QMetaPropertyBuilder::setResettable(bool value)
2256{
2257 QMetaPropertyBuilderPrivate *d = d_func();
2258 if (d)
2259 d->setFlag(Resettable, value);
2260}
2261
2262/*!
2263 Sets this property to designable if \a value is true.
2264
2265 \sa isDesignable(), setScriptable(), setStored()
2266*/
2267void QMetaPropertyBuilder::setDesignable(bool value)
2268{
2269 QMetaPropertyBuilderPrivate *d = d_func();
2270 if (d)
2271 d->setFlag(Designable, value);
2272}
2273
2274/*!
2275 Sets this property to scriptable if \a value is true.
2276
2277 \sa isScriptable(), setDesignable(), setStored()
2278*/
2279void QMetaPropertyBuilder::setScriptable(bool value)
2280{
2281 QMetaPropertyBuilderPrivate *d = d_func();
2282 if (d)
2283 d->setFlag(Scriptable, value);
2284}
2285
2286/*!
2287 Sets this property to storable if \a value is true.
2288
2289 \sa isStored(), setDesignable(), setScriptable()
2290*/
2291void QMetaPropertyBuilder::setStored(bool value)
2292{
2293 QMetaPropertyBuilderPrivate *d = d_func();
2294 if (d)
2295 d->setFlag(Stored, value);
2296}
2297
2298/*!
2299 Sets the \c USER flag on this property to \a value.
2300
2301 \sa isUser(), setDesignable(), setScriptable()
2302*/
2303void QMetaPropertyBuilder::setUser(bool value)
2304{
2305 QMetaPropertyBuilderPrivate *d = d_func();
2306 if (d)
2307 d->setFlag(User, value);
2308}
2309
2310/*!
2311 Sets the C++ setter flag on this property to \a value, which is
2312 true if the property has a C++ setter function that follows Qt's
2313 standard "name" / "setName" pattern.
2314
2315 \sa hasStdCppSet()
2316*/
2317void QMetaPropertyBuilder::setStdCppSet(bool value)
2318{
2319 QMetaPropertyBuilderPrivate *d = d_func();
2320 if (d)
2321 d->setFlag(StdCppSet, value);
2322}
2323
2324/*!
2325 Sets this property to be of an enumerator or flag type if
2326 \a value is true.
2327
2328 \sa isEnumOrFlag()
2329*/
2330void QMetaPropertyBuilder::setEnumOrFlag(bool value)
2331{
2332 QMetaPropertyBuilderPrivate *d = d_func();
2333 if (d)
2334 d->setFlag(EnumOrFlag, value);
2335}
2336
2337/*!
2338 Sets the \c CONSTANT flag on this property to \a value.
2339
2340 \sa isConstant()
2341*/
2342void QMetaPropertyBuilder::setConstant(bool value)
2343{
2344 QMetaPropertyBuilderPrivate *d = d_func();
2345 if (d)
2346 d->setFlag(Constant, value);
2347}
2348
2349/*!
2350 Sets the \c FINAL flag on this property to \a value.
2351
2352 \sa isFinal()
2353*/
2354void QMetaPropertyBuilder::setFinal(bool value)
2355{
2356 QMetaPropertyBuilderPrivate *d = d_func();
2357 if (d)
2358 d->setFlag(Final, value);
2359}
2360
2361/*!
2362 Sets the \c VIRTUAL flag on this property to \a value.
2363
2364 \sa isFinal()
2365*/
2366void QMetaPropertyBuilder::setVirtual(bool value)
2367{
2368 QMetaPropertyBuilderPrivate *d = d_func();
2369 if (d)
2370 d->setFlag(Virtual, value);
2371}
2372
2373/*!
2374 Sets the \c OVERRIDE flag on this property to \a value.
2375
2376 \sa isOverride()
2377*/
2378void QMetaPropertyBuilder::setOverride(bool value)
2379{
2380 QMetaPropertyBuilderPrivate *d = d_func();
2381 if (d)
2382 d->setFlag(Override, value);
2383}
2384
2385/*!
2386 Sets the \c ALIAS flag on this property to \a value
2387 */
2388void QMetaPropertyBuilder::setAlias(bool value)
2389{
2390 QMetaPropertyBuilderPrivate *d = d_func();
2391 if (d)
2392 d->setFlag(Alias, value);
2393}
2394
2395/*!
2396 Sets the\c BINDABLE flag on this property to \a value
2397 */
2398void QMetaPropertyBuilder::setBindable(bool value)
2399{
2400 if (auto d = d_func())
2401 d->setFlag(Bindable, value);
2402}
2403
2404/*!
2405 Sets the\c REQUIRED flag on this property to \a value
2406 */
2407void QMetaPropertyBuilder::setRequired(bool value)
2408{
2409 if (auto d = d_func())
2410 d->setFlag(Required, value);
2411}
2412
2413/*!
2414 Returns the revision of this property.
2415
2416 \sa setRevision()
2417*/
2418int QMetaPropertyBuilder::revision() const
2419{
2420 QMetaPropertyBuilderPrivate *d = d_func();
2421 if (d)
2422 return d->revision;
2423 return 0;
2424}
2425
2426/*!
2427 Sets the \a revision of this property.
2428
2429 \sa revision()
2430*/
2431void QMetaPropertyBuilder::setRevision(int revision)
2432{
2433 QMetaPropertyBuilderPrivate *d = d_func();
2434 if (d)
2435 d->revision = revision;
2436}
2437
2438/*!
2439 \class QMetaEnumBuilder
2440 \inmodule QtCore
2441 \internal
2442 \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
2443*/
2444
2445QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
2446{
2447 if (_mobj && _index >= 0 && _index < int(_mobj->d->enumerators.size()))
2448 return &(_mobj->d->enumerators[_index]);
2449 else
2450 return nullptr;
2451}
2452
2453/*!
2454 \fn QMetaEnumBuilder::QMetaEnumBuilder()
2455 \internal
2456*/
2457
2458/*!
2459 \fn int QMetaEnumBuilder::index() const
2460
2461 Returns the index of this enumerator within its QMetaObjectBuilder.
2462*/
2463
2464/*!
2465 Returns the type name of the enumerator (without the scope).
2466*/
2467QByteArray QMetaEnumBuilder::name() const
2468{
2469 QMetaEnumBuilderPrivate *d = d_func();
2470 if (d)
2471 return d->name;
2472 else
2473 return QByteArray();
2474}
2475
2476/*!
2477 Returns the enum name of the enumerator (without the scope).
2478
2479 \since 5.12
2480*/
2481QByteArray QMetaEnumBuilder::enumName() const
2482{
2483 QMetaEnumBuilderPrivate *d = d_func();
2484 if (d)
2485 return d->enumName;
2486 else
2487 return QByteArray();
2488}
2489
2490/*!
2491 Sets this enumerator to have the enum name \c alias.
2492
2493 \since 5.12
2494 \sa isFlag(), enumName()
2495*/
2496void QMetaEnumBuilder::setEnumName(const QByteArray &alias)
2497{
2498 QMetaEnumBuilderPrivate *d = d_func();
2499 if (d)
2500 d->enumName = alias;
2501}
2502
2503/*!
2504 Returns the meta type of the enumerator.
2505
2506 \since 6.6
2507*/
2508QMetaType QMetaEnumBuilder::metaType() const
2509{
2510 if (QMetaEnumBuilderPrivate *d = d_func())
2511 return d->metaType;
2512 return QMetaType();
2513}
2514
2515/*!
2516 Sets this enumerator to have the given \c metaType. The is64Bit() flag will
2517 be set to match \a metaType's size.
2518
2519 \since 6.6
2520 \sa metaType()
2521*/
2522void QMetaEnumBuilder::setMetaType(QMetaType metaType)
2523{
2524 QMetaEnumBuilderPrivate *d = d_func();
2525 if (d) {
2526 d->metaType = metaType;
2527 setIs64Bit(metaType.sizeOf() > 4);
2528 }
2529}
2530
2531/*!
2532 Returns \c true if this enumerator is used as a flag; otherwise returns
2533 false.
2534
2535 \sa setIsFlag()
2536*/
2537bool QMetaEnumBuilder::isFlag() const
2538{
2539 QMetaEnumBuilderPrivate *d = d_func();
2540 if (d)
2541 return d->flags.toInt() & EnumIsFlag;
2542 else
2543 return false;
2544}
2545
2546/*!
2547 Sets this enumerator to be used as a flag if \a value is true.
2548
2549 \sa isFlag()
2550*/
2551void QMetaEnumBuilder::setIsFlag(bool value)
2552{
2553 QMetaEnumBuilderPrivate *d = d_func();
2554 if (d)
2555 d->flags.setFlag(EnumIsFlag, value);
2556}
2557
2558/*!
2559 Return \c true if this enumerator should be considered scoped (C++11 enum class).
2560
2561 \sa setIsScoped()
2562*/
2563bool QMetaEnumBuilder::isScoped() const
2564{
2565 QMetaEnumBuilderPrivate *d = d_func();
2566 if (d)
2567 return d->flags.toInt() & EnumIsScoped;
2568 return false;
2569}
2570
2571/*!
2572 Sets this enumerator to be a scoped enum if \value is true
2573
2574 \sa isScoped()
2575*/
2576void QMetaEnumBuilder::setIsScoped(bool value)
2577{
2578 QMetaEnumBuilderPrivate *d = d_func();
2579 if (d)
2580 d->flags.setFlag(EnumIsScoped, value);
2581}
2582
2583/*!
2584 Return \c true if this enumerations in this enumerator are 64-bit.
2585
2586 This flag is autoamtically enabled if a 64-bit value is added with addKey().
2587
2588 \sa setIs64Bit()
2589*/
2590bool QMetaEnumBuilder::is64Bit() const
2591{
2592 QMetaEnumBuilderPrivate *d = d_func();
2593 if (d)
2594 return d->flags.toInt() & EnumIs64Bit;
2595 return false;
2596}
2597
2598/*!
2599 Sets this enumerator to be 64-bit wide if \a value is true. If \a value is
2600 false, any stored 64-bit keys will be truncated to 32 bits.
2601
2602 This flag is autoamtically enabled if a 64-bit value is added with addKey().
2603
2604 \sa is64Bit()
2605*/
2606void QMetaEnumBuilder::setIs64Bit(bool value)
2607{
2608 QMetaEnumBuilderPrivate *d = d_func();
2609 if (d)
2610 d->flags.setFlag(EnumIs64Bit, value);
2611}
2612
2613/*!
2614 Returns the number of keys.
2615
2616 \sa key(), addKey()
2617*/
2618int QMetaEnumBuilder::keyCount() const
2619{
2620 QMetaEnumBuilderPrivate *d = d_func();
2621 if (d)
2622 return d->keys.size();
2623 else
2624 return 0;
2625}
2626
2627/*!
2628 Returns the key with the given \a index, or an empty QByteArray
2629 if no such key exists.
2630
2631 \sa keyCount(), addKey(), value()
2632*/
2633QByteArray QMetaEnumBuilder::key(int index) const
2634{
2635 QMetaEnumBuilderPrivate *d = d_func();
2636 if (d && index >= 0 && index < d->keys.size())
2637 return d->keys[index];
2638 else
2639 return QByteArray();
2640}
2641
2642/*!
2643 Returns the value with the given \a index; or returns -1 if there
2644 is no such value.
2645
2646 If this is a 64-bit enumeration (see is64Bit()), this function returns the
2647 low 32-bit portion of the value. Use value64() to obtain the full value
2648 instead.
2649
2650 \sa value64(), keyCount(), addKey(), key(), is64Bit()
2651*/
2652int QMetaEnumBuilder::value(int index) const
2653{
2654 return value64(index).value_or(-1);
2655}
2656
2657/*!
2658 \since 6.9
2659
2660 Returns the value with the given \a index if it exists; or returns a
2661 disengaged \c{std::optional} if it doesn't.
2662
2663 \include qmetaobject.cpp qmetaenum-32bit-signextend-64bit
2664
2665 \sa keyCount(), key(), addKey()
2666*/
2667std::optional<quint64> QMetaEnumBuilder::value64(int index) const
2668{
2669 QMetaEnumBuilderPrivate *d = d_func();
2670 if (d && index >= 0 && index < d->keys.size()) {
2671 quint64 v = d->values[index];
2672 if (d->flags & EnumIs64Bit)
2673 return v;
2674 return uint(v); // return only the low 32 bits
2675 } else {
2676 return std::nullopt;
2677 }
2678}
2679
2680/*!
2681 Adds a new key called \a name to this enumerator, associated
2682 with \a value. Returns the index of the new key.
2683
2684 \sa keyCount(), key(), value(), removeKey()
2685*/
2686int QMetaEnumBuilder::addKey(const QByteArray &name, int value)
2687{
2688 QMetaEnumBuilderPrivate *d = d_func();
2689 if (d) {
2690 return d->addKey(name, uint(value));
2691 } else {
2692 return -1;
2693 }
2694}
2695
2696/*!
2697 \since 6.9
2698
2699 Adds a new key called \a name to this enumerator, associated
2700 with \a value. Returns the index of the new key.
2701
2702 Using the 64-bit version of this function automatically makes this
2703 enumeration be stored as 64-bit.
2704
2705 \sa keyCount(), key(), value(), removeKey(), is64Bit()
2706*/
2707int QMetaEnumBuilder::addKey(const QByteArray &name, quint64 value)
2708{
2709 QMetaEnumBuilderPrivate *d = d_func();
2710 if (d) {
2711 setIs64Bit(true);
2712 return d->addKey(name, value);
2713 }
2714 return -1;
2715}
2716
2717/*!
2718 Removes the key at \a index from this enumerator.
2719
2720 \sa addKey()
2721*/
2722void QMetaEnumBuilder::removeKey(int index)
2723{
2724 QMetaEnumBuilderPrivate *d = d_func();
2725 if (d && index >= 0 && index < d->keys.size()) {
2726 d->keys.removeAt(index);
2727 d->values.removeAt(index);
2728 }
2729}
2730
2731QT_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)