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