1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QMETAOBJECT_P_H
6#define QMETAOBJECT_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 for the convenience
13// of moc. This header file may change from version to version without notice,
14// or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/qglobal.h>
20#include <QtCore/qobjectdefs.h>
21#include <QtCore/qmutex.h>
22#include <QtCore/qmetaobject.h>
23#ifndef QT_NO_QOBJECT
24#include <private/qobject_p.h> // For QObjectPrivate::Connection
25#endif
26#include <QtCore/qtmocconstants.h>
27#include <private/qtools_p.h>
28#include <QtCore/qvarlengtharray.h>
29
30QT_BEGIN_NAMESPACE
31// ### TODO - QTBUG-87869: wrap in a proper Q_NAMESPACE and use scoped enums, to avoid name clashes
32
33using namespace QtMiscUtils;
34using namespace QtMocConstants;
35
36Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
37Q_DECLARE_OPERATORS_FOR_FLAGS(MetaObjectFlags)
38
39Q_CORE_EXPORT int qMetaTypeTypeInternal(QByteArrayView name);
40
41class QArgumentType
42{
43public:
44 QArgumentType() = default;
45 QArgumentType(QMetaType metaType)
46 : _metaType(metaType)
47 {}
48 QArgumentType(const QByteArray &name)
49 : _metaType(QMetaType{qMetaTypeTypeInternal(name: qToByteArrayViewIgnoringNull(b: name))}), _name(name)
50 {}
51 QMetaType metaType() const noexcept
52 { return _metaType; }
53 QByteArrayView name() const noexcept
54 {
55 if (_name.isEmpty())
56 return metaType().name();
57 return _name;
58 }
59
60private:
61 friend bool comparesEqual(const QArgumentType &lhs,
62 const QArgumentType &rhs)
63 {
64 if (lhs.metaType().isValid() && rhs.metaType().isValid())
65 return lhs.metaType() == rhs.metaType();
66 else
67 return lhs.name() == rhs.name();
68 }
69 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QArgumentType)
70
71 QMetaType _metaType;
72 QByteArray _name;
73};
74Q_DECLARE_TYPEINFO(QArgumentType, Q_RELOCATABLE_TYPE);
75
76typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
77
78namespace { class QMetaMethodPrivate; }
79class QMetaMethodInvoker : public QMetaMethod
80{
81 QMetaMethodInvoker() = delete;
82
83public:
84 enum class InvokeFailReason : int {
85 // negative values mean a match was found but the invocation failed
86 // (and a warning has been printed)
87 ReturnTypeMismatch = -1,
88 DeadLockDetected = -2,
89 CallViaVirtualFailed = -3, // no warning
90 ConstructorCallOnObject = -4,
91 ConstructorCallWithoutResult = -5,
92 ConstructorCallFailed = -6, // no warning
93
94 CouldNotQueueParameter = -0x1000,
95
96 // zero is success
97 None = 0,
98
99 // positive values mean the parameters did not match
100 TooFewArguments,
101 FormalParameterMismatch = 0x1000,
102 };
103
104 // shadows the public function
105 static InvokeFailReason Q_CORE_EXPORT
106 invokeImpl(QMetaMethod self, void *target, Qt::ConnectionType, qsizetype paramCount,
107 const void *const *parameters, const char *const *typeNames,
108 const QtPrivate::QMetaTypeInterface *const *metaTypes);
109};
110
111struct QMetaObjectPrivate
112{
113 enum { OutputRevision = QtMocConstants::OutputRevision }; // Used by moc, qmetaobjectbuilder and qdbus
114 enum { IntsPerMethod = QMetaMethod::Data::Size };
115 enum { IntsPerEnum = QMetaEnum::Data::Size };
116 enum { IntsPerProperty = QMetaProperty::Data::Size };
117
118 int revision;
119 int className;
120 int classInfoCount, classInfoData;
121 int methodCount, methodData;
122 int propertyCount, propertyData;
123 int enumeratorCount, enumeratorData;
124 int constructorCount, constructorData;
125 int flags;
126 int signalCount;
127
128 static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
129 { return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
130
131 static int originalClone(const QMetaObject *obj, int local_method_index);
132
133 static QByteArrayView decodeMethodSignature(const char *signature,
134 QArgumentTypeArray &types);
135 static int indexOfSignalRelative(const QMetaObject **baseObject,
136 QByteArrayView name, int argc,
137 const QArgumentType *types);
138 static int indexOfSlotRelative(const QMetaObject **m,
139 QByteArrayView name, int argc,
140 const QArgumentType *types);
141 static int indexOfSignal(const QMetaObject *m, QByteArrayView name,
142 int argc, const QArgumentType *types);
143 static int indexOfSlot(const QMetaObject *m, QByteArrayView name,
144 int argc, const QArgumentType *types);
145 static int indexOfMethod(const QMetaObject *m, QByteArrayView name,
146 int argc, const QArgumentType *types);
147 static int indexOfConstructor(const QMetaObject *m, QByteArrayView name,
148 int argc, const QArgumentType *types);
149
150 enum class Which { Name, Alias };
151 static int indexOfEnumerator(const QMetaObject *m, QByteArrayView name, Which which);
152 static int indexOfEnumerator(const QMetaObject *m, QByteArrayView name);
153
154 Q_CORE_EXPORT static QMetaMethod signal(const QMetaObject *m, int signal_index);
155 static inline int signalOffset(const QMetaObject *m)
156 {
157 Q_ASSERT(m != nullptr);
158 int offset = 0;
159 for (m = m->d.superdata; m; m = m->d.superdata)
160 offset += reinterpret_cast<const QMetaObjectPrivate *>(m->d.data)->signalCount;
161 return offset;
162 }
163 Q_CORE_EXPORT static int absoluteSignalCount(const QMetaObject *m);
164 Q_CORE_EXPORT static int signalIndex(const QMetaMethod &m);
165 static bool checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
166 int methodArgc, const QArgumentType *methodTypes);
167 static bool checkConnectArgs(const QMetaMethodPrivate *signal,
168 const QMetaMethodPrivate *method);
169
170 static QList<QByteArray> parameterTypeNamesFromSignature(QByteArrayView sig);
171
172#ifndef QT_NO_QOBJECT
173 // defined in qobject.cpp
174 enum DisconnectType { DisconnectAll, DisconnectOne };
175 static void memberIndexes(const QObject *obj, const QMetaMethod &member,
176 int *signalIndex, int *methodIndex);
177 static QObjectPrivate::Connection *connect(const QObject *sender, int signal_index,
178 const QMetaObject *smeta,
179 const QObject *receiver, int method_index_relative,
180 const QMetaObject *rmeta = nullptr,
181 int type = 0, int *types = nullptr);
182 static bool disconnect(const QObject *sender, int signal_index,
183 const QMetaObject *smeta,
184 const QObject *receiver, int method_index, void **slot,
185 DisconnectType = DisconnectAll);
186 static inline bool disconnectHelper(QObjectPrivate::ConnectionData *connections, int signalIndex,
187 const QObject *receiver, int method_index, void **slot,
188 QBasicMutex *senderMutex, DisconnectType = DisconnectAll);
189#endif
190
191 template<int MethodType>
192 static inline int indexOfMethodRelative(const QMetaObject **baseObject,
193 QByteArrayView name, int argc,
194 const QArgumentType *types);
195
196 static bool methodMatch(const QMetaObject *m, const QMetaMethod &method,
197 QByteArrayView name, int argc,
198 const QArgumentType *types);
199 Q_CORE_EXPORT static QMetaMethod firstMethod(const QMetaObject *baseObject, QByteArrayView name);
200
201};
202
203// For meta-object generators
204
205enum { MetaObjectPrivateFieldCount = sizeof(QMetaObjectPrivate) / sizeof(int) };
206
207#ifndef UTILS_H
208// mirrored in moc's utils.h
209static inline bool is_ident_char(char s)
210{
211 return isAsciiLetterOrNumber(c: s) || s == '_';
212}
213
214static inline bool is_space(char s)
215{
216 return (s == ' ' || s == '\t');
217}
218#endif
219
220QT_END_NAMESPACE
221
222#endif
223
224

source code of qtbase/src/corelib/kernel/qmetaobject_p.h