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
qqmlpropertycache_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
5#ifndef QQMLPROPERTYCACHE_P_H
6#define QQMLPROPERTYCACHE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <private/qlinkedstringhash_p.h>
20#include <private/qqmlenumdata_p.h>
21#include <private/qqmlenumvalue_p.h>
22#include <private/qqmlpropertydata_p.h>
23#include <private/qqmlrefcount_p.h>
24#include <private/qexpected_p.h>
25
26#include <QtCore/qvarlengtharray.h>
27#include <QtCore/qvector.h>
28#include <QtCore/qtyperevision.h>
29#include <QtCore/qxpfunctional.h>
30#include <QtCore/qloggingcategory.h>
31
32#include <limits>
33
34class tst_qqmlpropertycache;
35
36QT_BEGIN_NAMESPACE
37
38class QCryptographicHash;
39class QJSEngine;
40class QMetaObjectBuilder;
41class QQmlContextData;
42class QQmlPropertyCache;
44class QQmlVMEMetaObject;
45
47{
48public:
50
56
58 {
59 const auto dd = d.loadAcquire();
60 if (dd & Shared)
61 reinterpret_cast<SharedHolder *>(dd ^ Shared)->release();
62 }
63
64private:
65 friend class QQmlPropertyCache;
67 : d(other.d.loadRelaxed())
68 {
69 // other has to survive until this ctor is done. So d cannot disappear before.
70 const auto od = other.d.loadRelaxed();
71 if (od & Shared)
72 reinterpret_cast<SharedHolder *>(od ^ Shared)->addref();
73 }
74
75 QQmlMetaObjectPointer(QQmlMetaObjectPointer &&other) = delete;
76 QQmlMetaObjectPointer &operator=(QQmlMetaObjectPointer &&other) = delete;
77 QQmlMetaObjectPointer &operator=(const QQmlMetaObjectPointer &other) = delete;
78
79public:
80 void setSharedOnce(QMetaObject *shared) const
81 {
82 SharedHolder *holder = new SharedHolder(shared);
83 if (!d.testAndSetRelease(0, quintptr(holder) | Shared))
84 holder->release();
85 }
86
87 const QMetaObject *metaObject() const
88 {
89 const auto dd = d.loadAcquire();
90 if (dd & Shared)
91 return reinterpret_cast<SharedHolder *>(dd ^ Shared)->metaObject;
92 return reinterpret_cast<const QMetaObject *>(dd);
93 }
94
95 bool isShared() const
96 {
97 // This works because static metaobjects need to be set in the ctor and once a shared
98 // metaobject has been set, it cannot be removed anymore.
99 const auto dd = d.loadRelaxed();
100 return !dd || (dd & Shared);
101 }
102
103 bool isNull() const
104 {
105 return d.loadRelaxed() == 0;
106 }
107
108private:
109 enum Tag {
110 Static = 0,
111 Shared = 1
112 };
113
114 struct SharedHolder final : public QQmlRefCounted<SharedHolder>
115 {
116 Q_DISABLE_COPY_MOVE(SharedHolder)
117 SharedHolder(QMetaObject *shared) : metaObject(shared) {}
118 ~SharedHolder() { free(metaObject); }
119 QMetaObject *metaObject;
120 };
121
122 mutable QBasicAtomicInteger<quintptr> d = 0;
123};
124
125// TODO should be moved somewhere else?
126namespace OverrideSemantics {
127enum class Status : uint8_t {
128 Valid = 0,
129 NoOverride, // Derived { (virtual|final) property var a;} Base {}
130
131 MissingBase, // Derived { override property var a;} Base {}
132 OverridingFinal, // Derived { * property var a;} Base {final property var a;}
133 OverridingNonVirtual, // Derived { (virtual|final) property var a;} Base {property var a;}
134 OverridingNonVirtualError, // Derived { override property var a;} Base {property var a;}
135 MissingOverrideOrFinalSpecifier, // Derived { (virtual) property var a;} Base { virtual property var a;}
136
137 InvokabilityMismatch, // property overrides method(function, slot, invokable) or vice-versa
138
140};
141
142inline bool isValidOverride(Status res)
143{
144 return res == Status::NoOverride
145 || res == Status::Valid
146 // MissingOverrideOrFinalSpecifier, OverridingNonVirtual and InvokabilityMismatch
147 // are currently considered valid to preserve backwards compatibility.
148 // It will become invalid in Qt7
151}
152
153enum class CheckMode : uint8_t {
154 Minimal = 0, // pre virtual and override keywords
156};
157
158[[nodiscard]] Q_AUTOTEST_EXPORT Status handleOverride(QQmlPropertyData &overridingProperty,
161
164
165} // namespace OverrideSemantics
166
167Q_DECLARE_LOGGING_CATEGORY(qqmlPropertyCacheAppend)
168
169/*
170 * QQmlPropertyCache has the following structure:
171 *
172 * It maintains a non-owning map (StringCache) that associates each property name
173 * with a pointer to a QQmlPropertyData object. Each pointer refers to an element
174 * stored in one of the owning containers — for example, PropertyIndexCache or
175 * MethodsIndexCache.
176 *
177 * As a result, if an owning container such as PropertyIndexCache is resized,
178 * the entries in StringCache become invalid.
179 *
180 * To protect users of this class from such undefined behavior, most modifying
181 * methods are kept private. A few trusted classes, such as QQmlPropertyCacheCreator,
182 * are declared as friends. As the name suggests, QQmlPropertyCacheCreator is responsible
183 * for constructing and populating a QQmlPropertyCache instance in one controlled place,
184 * ensuring that all indices and data remain coherent.
185 *
186 * Because the internal logic of this class is non-trivial, the unit test
187 * (tst_qqmlpropertycache) is also declared as a friend to support proper testing
188 * and maintainability.
189 */
190class Q_QML_EXPORT QQmlPropertyCache final : public QQmlRefCounted<QQmlPropertyCache>
191{
192public:
193 using Ptr = QQmlRefPointer<QQmlPropertyCache>;
194
195 struct ConstPtr : public QQmlRefPointer<const QQmlPropertyCache>
196 {
197 using QQmlRefPointer<const QQmlPropertyCache>::QQmlRefPointer;
198
199 ConstPtr(const Ptr &ptr) : ConstPtr(ptr.data(), AddRef) {}
200 ConstPtr(Ptr &&ptr) : ConstPtr(ptr.take(), Adopt) {}
201 ConstPtr &operator=(const Ptr &ptr) { return operator=(ConstPtr(ptr)); }
202 ConstPtr &operator=(Ptr &&ptr) { return operator=(ConstPtr(std::move(ptr))); }
203 };
204
205 static Ptr createStandalone(
206 const QMetaObject *, QTypeRevision metaObjectRevision = QTypeRevision::zero());
207
208 QQmlPropertyCache(
209 OverrideSemantics::HandlerRef handleOverride = OverrideSemantics::handleOverride)
210 : _handleOverride(handleOverride) { };
211 ~QQmlPropertyCache();
212
213 void update(const QMetaObject *);
214 void invalidate(const QMetaObject *);
215
216 QQmlPropertyCache::Ptr copy() const;
217 QQmlPropertyCache::Ptr rebased(const QQmlPropertyCache::ConstPtr &parent) const;
218
219 QQmlPropertyCache::Ptr copyAndAppend(
220 const QMetaObject *, QTypeRevision typeVersion,
221 QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
222 QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
223 QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags()) const;
224
225 QQmlPropertyCache::Ptr copyAndReserve(
226 int propertyCount, int methodCount, int signalCount, int enumCount) const;
227
228 const QMetaObject *metaObject() const;
229 const QMetaObject *createMetaObject() const;
230 const QMetaObject *firstCppMetaObject() const;
231
232 template<typename K>
233 const QQmlPropertyData *property(const K &key, QObject *object,
234 const QQmlRefPointer<QQmlContextData> &context) const
235 {
236 return findProperty(stringCache.find(key), object, context);
237 }
238
239 const QQmlPropertyData *property(int) const;
240 const QQmlPropertyData *maybeUnresolvedProperty(int) const;
241 const QQmlPropertyData *method(int) const;
242 const QQmlPropertyData *signal(int index) const;
243 QQmlEnumData *qmlEnum(int) const;
244 int methodIndexToSignalIndex(int) const;
245
246 QString defaultPropertyName() const;
247 const QQmlPropertyData *defaultProperty() const;
248
249 // Return a reference here so that we don't have to addref/release all the time
250 inline const QQmlPropertyCache::ConstPtr &parent() const;
251
252 // is used by the Qml Designer
253 void setParent(QQmlPropertyCache::ConstPtr newParent);
254
255 inline const QQmlPropertyData *overrideData(const QQmlPropertyData *) const;
256 inline bool isAllowedInRevision(const QQmlPropertyData *) const;
257
258 static const QQmlPropertyData *property(
259 QObject *, QStringView, const QQmlRefPointer<QQmlContextData> &,
260 QQmlPropertyData *);
261 static const QQmlPropertyData *property(QObject *, const QLatin1String &, const QQmlRefPointer<QQmlContextData> &,
262 QQmlPropertyData *);
263 static const QQmlPropertyData *property(QObject *, const QV4::String *, const QQmlRefPointer<QQmlContextData> &,
264 QQmlPropertyData *);
265
266 //see QMetaObjectPrivate::originalClone
267 int originalClone(int index) const;
268 static int originalClone(const QObject *, int index);
269
270 QList<QByteArray> signalParameterNames(int index) const;
271 static QString signalParameterStringForJS(
272 const QList<QByteArray> &parameterNameList, QString *errorString = nullptr);
273
274 const char *className() const;
275
276 inline int propertyCount() const;
277 inline int ownPropertyCount() const { return int(propertyIndexCache.count()); }
278 inline int propertyOffset() const;
279 inline int methodCount() const;
280 inline int ownMethodCount() const { return int(methodIndexCache.count()); }
281 inline int methodOffset() const;
282 inline int signalCount() const;
283 inline int ownSignalCount() const { return int(signalHandlerIndexCache.count()); }
284 inline int signalOffset() const;
285 inline int ownEnumCount() const;
286
287 void toMetaObjectBuilder(QMetaObjectBuilder &) const;
288
289 inline bool callJSFactoryMethod(QObject *object, void **args) const;
290
291 static bool determineMetaObjectSizes(const QMetaObject &mo, int *fieldCount, int *stringCount);
292 static bool addToHash(QCryptographicHash &hash, const QMetaObject &mo);
293
294 QByteArray checksum(QHash<quintptr, QByteArray> *checksums, bool *ok) const;
295
296 QTypeRevision allowedRevision(int index) const { return allowedRevisionCache[index]; }
297 void setAllowedRevision(int index, QTypeRevision allowed) { allowedRevisionCache[index] = allowed; }
298
299 bool isComposite() const { return _metaObject.isShared(); }
300
301private:
302 friend class QQmlEnginePrivate;
303 friend class QQmlCompiler;
304 template <typename T> friend class QQmlPropertyCacheCreator;
305 template <typename T> friend class QQmlPropertyCacheAliasCreator;
306 template <typename T> friend class QQmlComponentAndAliasResolver;
307 friend class QQmlMetaObject;
308 friend class ::tst_qqmlpropertycache;
309
310 QQmlPropertyCache(
311 const QQmlMetaObjectPointer &metaObject,
312 OverrideSemantics::HandlerRef handleOverride = OverrideSemantics::handleOverride)
313 : _handleOverride(handleOverride), _metaObject(metaObject)
314 {
315 }
316
317 inline QQmlPropertyCache::Ptr copy(const QQmlMetaObjectPointer &mo, int reserve) const;
318
319 void append(const QMetaObject *, QTypeRevision typeVersion,
320 QQmlPropertyData::Flags propertyFlags = QQmlPropertyData::Flags(),
321 QQmlPropertyData::Flags methodFlags = QQmlPropertyData::Flags(),
322 QQmlPropertyData::Flags signalFlags = QQmlPropertyData::Flags());
323
324 // TODO incorporate warning from maybeLog
325 using Error = OverrideSemantics::Status;
326 using AppendResult = q23::expected<void, Error>;
327
328 // TODO QTBUG-141728
329 // Always adds a property to the propertyIndex even if override semantics are invalid, not
330 // accessible by name though
331 AppendResult appendPropertyAttr(const QString &name, QQmlPropertyData &&data);
332 AppendResult appendAlias(const QString &, QQmlPropertyData::Flags flags, int coreIndex,
333 QMetaType propType, QTypeRevision version, int notifyIndex,
334 int encodedTargetIndex, int targetObjectId);
335 AppendResult appendComponentWrapper(int coreIndex, int wrappedObjectIndex);
336 void appendSignal(const QString &, QQmlPropertyData::Flags, int coreIndex,
337 const QMetaType *types = nullptr,
338 const QList<QByteArray> &names = QList<QByteArray>());
339 void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex,
340 QMetaType returnType, const QList<QByteArray> &names,
341 const QList<QMetaType> &parameterTypes);
342 void appendEnum(const QString &, const QList<QQmlEnumValue> &);
343
344 QQmlPropertyCacheMethodArguments *createArgumentsObject(int count,
345 const QList<QByteArray> &names);
346
347 typedef QList<QQmlPropertyData> IndexCache;
348 typedef QLinkedStringMultiHash<std::pair<int, QQmlPropertyData *> > StringCache;
349 typedef QList<QTypeRevision> AllowedRevisionCache;
350
351 const QQmlPropertyData *findProperty(StringCache::ConstIterator it, QObject *,
352 const QQmlRefPointer<QQmlContextData> &) const;
353 const QQmlPropertyData *findProperty(StringCache::ConstIterator it, const QQmlVMEMetaObject *,
354 const QQmlRefPointer<QQmlContextData> &) const;
355
356 template<typename K>
357 QQmlPropertyData *findNamedProperty(const K &key) const
358 {
359 StringCache::mapped_type *it = stringCache.value(key);
360 return it ? it->second : 0;
361 }
362
363 template<typename K>
364 void setNamedProperty(const K &key, int index, QQmlPropertyData *data)
365 {
366 stringCache.insert(key, std::make_pair(index, data));
367 }
368
369 // Conditionally logs diagnostics for override semantics.
370 //
371 // Important: "Valid" override semantics do not imply "no warning".
372 // Some override situations are allowed by the language rules but are still
373 // diagnosed to help users avoid surprising or unintended behavior.
374 //
375 // Does not construct diagnostic messages when no logging is required
376 // to compute qPrintable(name) and className() only when needed.
377 template <typename String>
378 void maybeLog(OverrideSemantics::Status status, const String &name) const
379 {
380 switch (status) {
381 case OverrideSemantics::Status::OverridingFinal: {
382 qCWarning(qqmlPropertyCacheAppend).noquote()
383 << QStringLiteral("Final member %1 is overridden in class %2. The "
384 "override won't be used.")
385 .arg(qPrintable(name), className());
386 return;
387 }
388 case OverrideSemantics::Status::MissingBase: {
389 qCWarning(qqmlPropertyCacheAppend).noquote()
390 << QStringLiteral("Member %1 of the object %2 does not override anything."
391 " Consider removing \"override\". ")
392 .arg(qPrintable(name), className());
393 return;
394 }
395 case OverrideSemantics::Status::OverridingNonVirtual: {
396 // TODO: Make this a warning as soon as we can
397 qCDebug(qqmlPropertyCacheAppend).noquote()
398 << QStringLiteral("Member %1 of the object %2 overrides a non-virtual member. "
399 "Consider renaming it or mark it virtual in the base object")
400 .arg(qPrintable(name), className());
401 return;
402 }
403 case OverrideSemantics::Status::OverridingNonVirtualError: {
404 qCWarning(qqmlPropertyCacheAppend).noquote()
405 << QStringLiteral("Member %1 of the object %2 overrides a non-virtual member. "
406 "Consider renaming it or mark it virtual in the base object")
407 .arg(qPrintable(name), className());
408 return;
409 }
410 case OverrideSemantics::Status::MissingOverrideOrFinalSpecifier: {
411 qCWarning(qqmlPropertyCacheAppend).noquote()
412 << QStringLiteral(
413 "Member %1 of the object %2 overrides a member of the base object. "
414 "Consider renaming it or adding final or override specifier")
415 .arg(qPrintable(name), className());
416 return;
417 }
418 // TODO QTBUG-98320, when override is cleaned up for methods, we need a warning for InvokabilityMismatch
419 default:
420 return;
421 }
422 }
423
424private:
425 OverrideSemantics::HandlerRef _handleOverride;
426
427 int propertyIndexCacheStart = 0; // placed here to avoid gap between QQmlRefCount and _parent
428 QQmlPropertyCache::ConstPtr _parent;
429
430 IndexCache propertyIndexCache;
431 IndexCache methodIndexCache;
432 IndexCache signalHandlerIndexCache;
433 StringCache stringCache;
434 AllowedRevisionCache allowedRevisionCache;
435 QList<QQmlEnumData> enumCache;
436
437 QQmlMetaObjectPointer _metaObject;
438 QByteArray _dynamicClassName;
439 QByteArray _dynamicStringData;
440 QByteArray _listPropertyAssignBehavior;
441 QString _defaultPropertyName;
442 QQmlPropertyCacheMethodArguments *argumentsCache = nullptr;
443 int methodIndexCacheStart = 0;
444 int signalHandlerIndexCacheStart = 0;
445 int _jsFactoryMethodIndex = -1;
446};
447
448// Returns this property cache's metaObject. May be null if it hasn't been created yet.
449inline const QMetaObject *QQmlPropertyCache::metaObject() const
450{
451 return _metaObject.metaObject();
452}
453
454// Returns the first C++ type's QMetaObject - that is, the first QMetaObject not created by
455// QML
456inline const QMetaObject *QQmlPropertyCache::firstCppMetaObject() const
457{
458 const QQmlPropertyCache *p = this;
459 while (p->_metaObject.isShared())
460 p = p->parent().data();
461 return p->_metaObject.metaObject();
462}
463
464inline const QQmlPropertyData *QQmlPropertyCache::property(int index) const
465{
466 if (index < 0 || index >= propertyCount())
467 return nullptr;
468
469 if (index < propertyIndexCacheStart)
470 return _parent->property(index);
471
472 return &propertyIndexCache.at(index - propertyIndexCacheStart);
473}
474
475inline const QQmlPropertyData *QQmlPropertyCache::method(int index) const
476{
477 if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.size()))
478 return nullptr;
479
480 if (index < methodIndexCacheStart)
481 return _parent->method(index);
482
483 return const_cast<const QQmlPropertyData *>(&methodIndexCache.at(index - methodIndexCacheStart));
484}
485
486/*! \internal
487 \a index MUST be in the signal index range (see QObjectPrivate::signalIndex()).
488 This is different from QMetaMethod::methodIndex().
489*/
490inline const QQmlPropertyData *QQmlPropertyCache::signal(int index) const
491{
492 if (index < 0 || index >= (signalHandlerIndexCacheStart + signalHandlerIndexCache.size()))
493 return nullptr;
494
495 if (index < signalHandlerIndexCacheStart)
496 return _parent->signal(index);
497
498 const QQmlPropertyData *rv = const_cast<const QQmlPropertyData *>(&methodIndexCache.at(index - signalHandlerIndexCacheStart));
499 Q_ASSERT(rv->isSignal() || rv->coreIndex() == -1);
500 return rv;
501}
502
503inline QQmlEnumData *QQmlPropertyCache::qmlEnum(int index) const
504{
505 if (index < 0 || index >= enumCache.size())
506 return nullptr;
507
508 return const_cast<QQmlEnumData *>(&enumCache.at(index));
509}
510
511inline int QQmlPropertyCache::methodIndexToSignalIndex(int index) const
512{
513 if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.size()))
514 return index;
515
516 if (index < methodIndexCacheStart)
517 return _parent->methodIndexToSignalIndex(index);
518
519 return index - methodIndexCacheStart + signalHandlerIndexCacheStart;
520}
521
522// Returns the name of the default property for this cache
523inline QString QQmlPropertyCache::defaultPropertyName() const
524{
525 return _defaultPropertyName;
526}
527
528inline const QQmlPropertyCache::ConstPtr &QQmlPropertyCache::parent() const
529{
530 return _parent;
531}
532
533const QQmlPropertyData *
534QQmlPropertyCache::overrideData(const QQmlPropertyData *data) const
535{
536 if (!data->hasOverride())
537 return nullptr;
538
539 if (data->overrideIndexIsProperty())
540 return property(data->overrideIndex());
541 else
542 return method(data->overrideIndex());
543}
544
545bool QQmlPropertyCache::isAllowedInRevision(const QQmlPropertyData *data) const
546{
547 // Aliases can't be revisioned.
548 if (data->isAlias())
549 return true;
550
551 const QTypeRevision requested = data->revision();
552 const int offset = data->metaObjectOffset();
553 if (offset == -1 && requested == QTypeRevision::zero())
554 return true;
555
556 Q_ASSERT(offset >= 0);
557 Q_ASSERT(offset < allowedRevisionCache.size());
558 const QTypeRevision allowed = allowedRevisionCache[offset];
559
560 if (requested.hasMajorVersion()) {
561 if (requested.majorVersion() > allowed.majorVersion())
562 return false;
563 if (requested.majorVersion() < allowed.majorVersion())
564 return true;
565 }
566
567 return !requested.hasMinorVersion() || requested.minorVersion() <= allowed.minorVersion();
568}
569
570int QQmlPropertyCache::propertyCount() const
571{
572 return propertyIndexCacheStart + int(propertyIndexCache.size());
573}
574
575int QQmlPropertyCache::propertyOffset() const
576{
577 return propertyIndexCacheStart;
578}
579
580int QQmlPropertyCache::methodCount() const
581{
582 return methodIndexCacheStart + int(methodIndexCache.size());
583}
584
585int QQmlPropertyCache::methodOffset() const
586{
587 return methodIndexCacheStart;
588}
589
590int QQmlPropertyCache::signalCount() const
591{
592 return signalHandlerIndexCacheStart + int(signalHandlerIndexCache.size());
593}
594
595int QQmlPropertyCache::signalOffset() const
596{
597 return signalHandlerIndexCacheStart;
598}
599
600int QQmlPropertyCache::ownEnumCount() const
601{
602 return int(enumCache.size());
603}
604
605bool QQmlPropertyCache::callJSFactoryMethod(QObject *object, void **args) const
606{
607 if (_jsFactoryMethodIndex != -1) {
608 if (const QMetaObject *mo = _metaObject.metaObject()) {
609 mo->d.static_metacall(object, QMetaObject::InvokeMetaMethod,
610 _jsFactoryMethodIndex, args);
611 return true;
612 }
613 return false;
614 }
615 if (_parent)
616 return _parent->callJSFactoryMethod(object, args);
617 return false;
618}
619
620QT_END_NAMESPACE
621
622#endif // QQMLPROPERTYCACHE_P_H
friend class QJSEngine
const QMetaObject * metaObject() const
void setSharedOnce(QMetaObject *shared) const
static Status checkMinimal(const QQmlPropertyData *const existingProperty)
static Status check(const QQmlPropertyData &overridingProperty, const QQmlPropertyData *const existingProperty, CheckMode mode)
static bool hasInvalidModifierCombintation(const QQmlPropertyData &overridingProperty)
static Status checkFull(const QQmlPropertyData &overridingProperty, const QQmlPropertyData *const existingProperty)
Status handleOverride(QQmlPropertyData &overridingProperty, QQmlPropertyData *existingProperty, CheckMode mode)
bool isValidOverride(Status res)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
const QQmlPropertyData * qQmlPropertyCacheProperty(QObject *obj, T name, const QQmlRefPointer< QQmlContextData > &context, QQmlPropertyData *local)
static const QByteArray stringData(const QMetaObject *mo, int index)
static QQmlPropertyData qQmlPropertyCacheCreate(const QMetaObject *metaObject, const T &propertyName)
#define Q_INT16_MAX
static QByteArray qQmlPropertyCacheToString(QLatin1String string)
static QByteArray qQmlPropertyCacheToString(const QV4::String *string)
static std::pair< bool, int > deriveEncodingAndLength(const char *str)
static QHashedString signalNameToHandlerName(const QHashedString &methodName)
static int metaObjectSignalCount(const QMetaObject *metaObject)