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 <private/qtools_p.h>
27#include <QtCore/qvarlengtharray.h>
28
29QT_BEGIN_NAMESPACE
30// ### TODO - QTBUG-87869: wrap in a proper Q_NAMESPACE and use scoped enums, to avoid name clashes
31
32using namespace QtMiscUtils;
33
34enum PropertyFlags {
35 Invalid = 0x00000000,
36 Readable = 0x00000001,
37 Writable = 0x00000002,
38 Resettable = 0x00000004,
39 EnumOrFlag = 0x00000008,
40 Alias = 0x00000010,
41 // Reserved for future usage = 0x00000020,
42 StdCppSet = 0x00000100,
43 Constant = 0x00000400,
44 Final = 0x00000800,
45 Designable = 0x00001000,
46 Scriptable = 0x00004000,
47 Stored = 0x00010000,
48 User = 0x00100000,
49 Required = 0x01000000,
50 Bindable = 0x02000000
51};
52
53enum MethodFlags {
54 AccessPrivate = 0x00,
55 AccessProtected = 0x01,
56 AccessPublic = 0x02,
57 AccessMask = 0x03, // mask
58
59 MethodMethod = 0x00,
60 MethodSignal = 0x04,
61 MethodSlot = 0x08,
62 MethodConstructor = 0x0c,
63 MethodTypeMask = 0x0c,
64
65 MethodCompatibility = 0x10,
66 MethodCloned = 0x20,
67 MethodScriptable = 0x40,
68 MethodRevisioned = 0x80,
69
70 MethodIsConst = 0x100, // no use case for volatile so far
71};
72
73enum MetaObjectFlag {
74 DynamicMetaObject = 0x01,
75 RequiresVariantMetaObject = 0x02,
76 PropertyAccessInStaticMetaCall = 0x04 // since Qt 5.5, property code is in the static metacall
77};
78Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
79Q_DECLARE_OPERATORS_FOR_FLAGS(MetaObjectFlags)
80
81enum MetaDataFlags {
82 IsUnresolvedType = 0x80000000,
83 TypeNameIndexMask = 0x7FFFFFFF,
84 IsUnresolvedSignal = 0x70000000
85};
86
87enum EnumFlags {
88 EnumIsFlag = 0x1,
89 EnumIsScoped = 0x2
90};
91
92Q_CORE_EXPORT int qMetaTypeTypeInternal(const char *);
93
94class QArgumentType
95{
96public:
97 QArgumentType(int type)
98 : _type(type)
99 {}
100 QArgumentType(const QByteArray &name)
101 : _type(qMetaTypeTypeInternal(name.constData())), _name(name)
102 {}
103 QArgumentType()
104 : _type(0)
105 {}
106 int type() const
107 { return _type; }
108 QByteArray name() const
109 {
110 if (_type && _name.isEmpty())
111 const_cast<QArgumentType *>(this)->_name = QMetaType(_type).name();
112 return _name;
113 }
114
115private:
116 friend bool comparesEqual(const QArgumentType &lhs,
117 const QArgumentType &rhs)
118 {
119 if (lhs._type && rhs._type)
120 return lhs._type == rhs._type;
121 else
122 return lhs.name() == rhs.name();
123 }
124 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QArgumentType)
125
126 int _type;
127 QByteArray _name;
128};
129Q_DECLARE_TYPEINFO(QArgumentType, Q_RELOCATABLE_TYPE);
130
131typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
132
133namespace { class QMetaMethodPrivate; }
134class QMetaMethodInvoker : public QMetaMethod
135{
136 QMetaMethodInvoker() = delete;
137
138public:
139 enum class InvokeFailReason : int {
140 // negative values mean a match was found but the invocation failed
141 // (and a warning has been printed)
142 ReturnTypeMismatch = -1,
143 DeadLockDetected = -2,
144 CallViaVirtualFailed = -3, // no warning
145 ConstructorCallOnObject = -4,
146 ConstructorCallWithoutResult = -5,
147 ConstructorCallFailed = -6, // no warning
148
149 CouldNotQueueParameter = -0x1000,
150
151 // zero is success
152 None = 0,
153
154 // positive values mean the parameters did not match
155 TooFewArguments,
156 FormalParameterMismatch = 0x1000,
157 };
158
159 // shadows the public function
160 static InvokeFailReason Q_CORE_EXPORT
161 invokeImpl(QMetaMethod self, void *target, Qt::ConnectionType, qsizetype paramCount,
162 const void *const *parameters, const char *const *typeNames,
163 const QtPrivate::QMetaTypeInterface *const *metaTypes);
164};
165
166struct QMetaObjectPrivate
167{
168 // revision 7 is Qt 5.0 everything lower is not supported
169 // revision 8 is Qt 5.12: It adds the enum name to QMetaEnum
170 // revision 9 is Qt 6.0: It adds the metatype of properties and methods
171 // revision 10 is Qt 6.2: The metatype of the metaobject is stored in the metatypes array
172 // and metamethods store a flag stating whether they are const
173 // revision 11 is Qt 6.5: The metatype for void is stored in the metatypes array
174 // revision 12 is Qt 6.6: It adds the metatype for enums
175 enum { OutputRevision = 12 }; // Used by moc, qmetaobjectbuilder and qdbus
176 enum { IntsPerMethod = QMetaMethod::Data::Size };
177 enum { IntsPerEnum = QMetaEnum::Data::Size };
178 enum { IntsPerProperty = QMetaProperty::Data::Size };
179
180 int revision;
181 int className;
182 int classInfoCount, classInfoData;
183 int methodCount, methodData;
184 int propertyCount, propertyData;
185 int enumeratorCount, enumeratorData;
186 int constructorCount, constructorData;
187 int flags;
188 int signalCount;
189
190 static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
191 { return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
192
193 static int originalClone(const QMetaObject *obj, int local_method_index);
194
195 static QByteArray decodeMethodSignature(const char *signature,
196 QArgumentTypeArray &types);
197 static int indexOfSignalRelative(const QMetaObject **baseObject,
198 const QByteArray &name, int argc,
199 const QArgumentType *types);
200 static int indexOfSlotRelative(const QMetaObject **m,
201 const QByteArray &name, int argc,
202 const QArgumentType *types);
203 static int indexOfSignal(const QMetaObject *m, const QByteArray &name,
204 int argc, const QArgumentType *types);
205 static int indexOfSlot(const QMetaObject *m, const QByteArray &name,
206 int argc, const QArgumentType *types);
207 static int indexOfMethod(const QMetaObject *m, const QByteArray &name,
208 int argc, const QArgumentType *types);
209 static int indexOfConstructor(const QMetaObject *m, const QByteArray &name,
210 int argc, const QArgumentType *types);
211
212 enum class Which { Name, Alias };
213 static int indexOfEnumerator(const QMetaObject *m, QByteArrayView name, Which which);
214 static int indexOfEnumerator(const QMetaObject *m, QByteArrayView name);
215
216 Q_CORE_EXPORT static QMetaMethod signal(const QMetaObject *m, int signal_index);
217 static inline int signalOffset(const QMetaObject *m)
218 {
219 Q_ASSERT(m != nullptr);
220 int offset = 0;
221 for (m = m->d.superdata; m; m = m->d.superdata)
222 offset += reinterpret_cast<const QMetaObjectPrivate *>(m->d.data)->signalCount;
223 return offset;
224 }
225 Q_CORE_EXPORT static int absoluteSignalCount(const QMetaObject *m);
226 Q_CORE_EXPORT static int signalIndex(const QMetaMethod &m);
227 static bool checkConnectArgs(int signalArgc, const QArgumentType *signalTypes,
228 int methodArgc, const QArgumentType *methodTypes);
229 static bool checkConnectArgs(const QMetaMethodPrivate *signal,
230 const QMetaMethodPrivate *method);
231
232 static QList<QByteArray> parameterTypeNamesFromSignature(const char *signature);
233
234#ifndef QT_NO_QOBJECT
235 // defined in qobject.cpp
236 enum DisconnectType { DisconnectAll, DisconnectOne };
237 static void memberIndexes(const QObject *obj, const QMetaMethod &member,
238 int *signalIndex, int *methodIndex);
239 static QObjectPrivate::Connection *connect(const QObject *sender, int signal_index,
240 const QMetaObject *smeta,
241 const QObject *receiver, int method_index_relative,
242 const QMetaObject *rmeta = nullptr,
243 int type = 0, int *types = nullptr);
244 static bool disconnect(const QObject *sender, int signal_index,
245 const QMetaObject *smeta,
246 const QObject *receiver, int method_index, void **slot,
247 DisconnectType = DisconnectAll);
248 static inline bool disconnectHelper(QObjectPrivate::ConnectionData *connections, int signalIndex,
249 const QObject *receiver, int method_index, void **slot,
250 QBasicMutex *senderMutex, DisconnectType = DisconnectAll);
251#endif
252
253 template<int MethodType>
254 static inline int indexOfMethodRelative(const QMetaObject **baseObject,
255 const QByteArray &name, int argc,
256 const QArgumentType *types);
257
258 static bool methodMatch(const QMetaObject *m, const QMetaMethod &method,
259 const QByteArray &name, int argc,
260 const QArgumentType *types);
261 Q_CORE_EXPORT static QMetaMethod firstMethod(const QMetaObject *baseObject, QByteArrayView name);
262
263};
264
265// For meta-object generators
266
267enum { MetaObjectPrivateFieldCount = sizeof(QMetaObjectPrivate) / sizeof(int) };
268
269#ifndef UTILS_H
270// mirrored in moc's utils.h
271static inline bool is_ident_char(char s)
272{
273 return isAsciiLetterOrNumber(c: s) || s == '_';
274}
275
276static inline bool is_space(char s)
277{
278 return (s == ' ' || s == '\t');
279}
280#endif
281
282/*
283 This function is shared with moc.cpp. The implementation lives in qmetaobject_moc_p.h, which
284 should be included where needed. The declaration here is not used to avoid warnings from
285 the compiler about unused functions.
286
287static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixScope = false, bool adjustConst = true);
288*/
289
290QT_END_NAMESPACE
291
292#endif
293
294

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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