Revision control
++ // Copyright (C) 2020 The Qt Company Ltd.
++ // Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++ #ifndef QMETAOBJECT_P_H
++ #define QMETAOBJECT_P_H
++
++ //
++ // W A R N I N G
++ // -------------
++ //
++ // This file is not part of the Qt API. It exists for the convenience
++ // of moc. This header file may change from version to version without notice,
++ // or even be removed.
++ //
++ // We mean it.
++ //
++
++ #include <QtCore/qglobal.h>
++ #include <QtCore/qobjectdefs.h>
++ #include <QtCore/qmutex.h>
++ #include <QtCore/qmetaobject.h>
++ #ifndef QT_NO_QOBJECT
++ #include <private/qobject_p.h> // For QObjectPrivate::Connection
++ #endif
++ #include <QtCore/qtmocconstants.h>
++ #include <private/qtools_p.h>
++ #include <QtCore/qvarlengtharray.h>
++
++ QT_BEGIN_NAMESPACE
++ // ### TODO - QTBUG-87869: wrap in a proper Q_NAMESPACE and use scoped enums, to avoid name clashes
++
++ using namespace QtMiscUtils;
++ using namespace QtMocConstants;
++
++ Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
++ Q_DECLARE_OPERATORS_FOR_FLAGS(MetaObjectFlags)
++
++ int qMetaTypeTypeInternal(QByteArrayView name); // in qmetatype.cpp
++
++ class QArgumentType
++ {
++ public:
++ QArgumentType() = default;
++ QArgumentType(QMetaType metaType)
++ : _metaType(metaType)
++ {}
++ explicit QArgumentType(QByteArrayView name)
++ : _metaType(QMetaType{qMetaTypeTypeInternal(name)}), _name(name)
++ {}
++ QMetaType metaType() const noexcept
++ { return _metaType; }
++ QByteArrayView name() const noexcept
++ {
++ if (_name.isEmpty())
++ return metaType().name();
++ return _name;
++ }
++
++ private:
++ friend bool comparesEqual(const QArgumentType &lhs,
++ const QArgumentType &rhs)
++ {
++ if (lhs.metaType().isValid() && rhs.metaType().isValid())
++ return lhs.metaType() == rhs.metaType();
++ else
++ return lhs.name() == rhs.name();
++ }
++ Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QArgumentType)
++
++ QMetaType _metaType;
++ QByteArrayView _name;
++ };
++ Q_DECLARE_TYPEINFO(QArgumentType, Q_RELOCATABLE_TYPE);
++
++ typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
++
++ namespace { class QMetaMethodPrivate; }
++ class QMetaMethodInvoker : public QMetaMethod
++ {
++ QMetaMethodInvoker() = delete;
++
++ public:
++ enum class InvokeFailReason : int {
++ // negative values mean a match was found but the invocation failed
++ // (and a warning has been printed)
++ ReturnTypeMismatch = -1,
++ DeadLockDetected = -2,
++ CallViaVirtualFailed = -3, // no warning
++ ConstructorCallOnObject = -4,
++ ConstructorCallWithoutResult = -5,
++ ConstructorCallFailed = -6, // no warning
++
++ CouldNotQueueParameter = -0x1000,
++
++ // zero is success
++ None = 0,
++
++ // positive values mean the parameters did not match
++ TooFewArguments,
++ FormalParameterMismatch = 0x1000,
++ };
++
++ // shadows the public function
++ static InvokeFailReason Q_CORE_EXPORT
++ invokeImpl(QMetaMethod self, void *target, Qt::ConnectionType, qsizetype paramCount,
++ const void *const *parameters, const char *const *typeNames,
++ const QtPrivate::QMetaTypeInterface *const *metaTypes);
++ };
++
++ struct QMetaObjectPrivate
++ {
++ enum { OutputRevision = QtMocConstants::OutputRevision }; // Used by moc, qmetaobjectbuilder and qdbus
++ enum { IntsPerMethod = QMetaMethod::Data::Size };
++ enum { IntsPerEnum = QMetaEnum::Data::Size };
++ enum { IntsPerProperty = QMetaProperty::Data::Size };
++
++ int revision;
++ int className;
++ int classInfoCount, classInfoData;
++ int methodCount, methodData;
++ int propertyCount, propertyData;
++ int enumeratorCount, enumeratorData;
++ int constructorCount, constructorData;
++ int flags;
++ int signalCount;
++
++ static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
++ { return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
++
++ static int originalClone(const QMetaObject *obj, int local_method_index);
++
++ static QByteArray normalizedSignature(QByteArrayView method);
++ static QByteArrayView decodeMethodSignature(QByteArrayView signature,
++ QArgumentTypeArray &types);
++ static int indexOfSignalRelative(const QMetaObject **baseObject,
++ QByteArrayView name,
++ QSpan<const QArgumentType> types);
++ static int indexOfSlotRelative(const QMetaObject **m,
++ QByteArrayView name,
++ QSpan<const QArgumentType> types);
++ static int indexOfSignal(const QMetaObject *m, QByteArrayView name,
++ QSpan<const QArgumentType> types);
++ static int indexOfSlot(const QMetaObject *m, QByteArrayView name,
++ QSpan<const QArgumentType> types);
++ static int indexOfMethod(const QMetaObject *m, QByteArrayView name,
++ QSpan<const QArgumentType> types);
++ static int indexOfConstructor(const QMetaObject *m, QByteArrayView name,
++ QSpan<const QArgumentType> types);
++
++ enum class Which { Name, Alias };
++ static int indexOfEnumerator(const QMetaObject *m, QByteArrayView name, Which which);
++ static int indexOfEnumerator(const QMetaObject *m, QByteArrayView name);
++
++ Q_CORE_EXPORT static QMetaMethod signal(const QMetaObject *m, int signal_index);
++ static inline int signalOffset(const QMetaObject *m)
++ {
++ Q_ASSERT(m != nullptr);
++ int offset = 0;
++ for (m = m->d.superdata; m; m = m->d.superdata)
++ offset += reinterpret_cast<const QMetaObjectPrivate *>(m->d.data)->signalCount;
++ return offset;
++ }
++ Q_CORE_EXPORT static int absoluteSignalCount(const QMetaObject *m);
++ Q_CORE_EXPORT static int signalIndex(const QMetaMethod &m);
++ static bool checkConnectArgs(QSpan<const QArgumentType> signalTypes,
++ QSpan<const QArgumentType> methodTypes);
++ static bool checkConnectArgs(const QMetaMethodPrivate *signal,
++ const QMetaMethodPrivate *method);
++
++ static QByteArrayView
++ parameterTypeNamesFromSignature(QByteArrayView signature,
++ QVarLengthArray<QByteArrayView, 10> &typeNames);
++
++ #ifndef QT_NO_QOBJECT
++ // defined in qobject.cpp
++ enum DisconnectType { DisconnectAll, DisconnectOne };
++ static void memberIndexes(const QObject *obj, const QMetaMethod &member,
++ int *signalIndex, int *methodIndex);
++ static QObjectPrivate::Connection *connect(const QObject *sender, int signal_index,
++ const QMetaObject *smeta,
++ const QObject *receiver, int method_index_relative,
++ const QMetaObject *rmeta = nullptr,
++ int type = 0, int *types = nullptr);
++ static bool disconnect(const QObject *sender, int signal_index,
++ const QMetaObject *smeta,
++ const QObject *receiver, int method_index, void **slot,
++ DisconnectType = DisconnectAll);
++ static inline bool disconnectHelper(QObjectPrivate::ConnectionData *connections, int signalIndex,
++ const QObject *receiver, int method_index, void **slot,
++ QBasicMutex *senderMutex, DisconnectType = DisconnectAll);
++ #endif
++
++ static inline int indexOfMethodRelative(const QMetaObject **baseObject,
++ QByteArrayView name,
++ QSpan<const QArgumentType> types,
++ QMetaMethod::MethodType what);
++
++ static bool methodMatch(const QMetaObject *m, const QMetaMethod &method,
++ QByteArrayView name,
++ QSpan<const QArgumentType> types);
++ Q_CORE_EXPORT static QMetaMethod firstMethod(const QMetaObject *baseObject, QByteArrayView name);
++
++ };
++
++ // For meta-object generators
++
++ enum { MetaObjectPrivateFieldCount = sizeof(QMetaObjectPrivate) / sizeof(int) };
++
++ #ifndef UTILS_H
++ // mirrored in moc's utils.h
++ static inline bool is_ident_char(char s)
++ {
++ return isAsciiLetterOrNumber(s) || s == '_';
++ }
++
++ static inline bool is_space(char s)
++ {
++ return (s == ' ' || s == '\t');
++ }
++ #endif
++
++ QT_END_NAMESPACE
++
++ #endif
++