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