1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2020 The Qt Company Ltd. |
4 | ** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com> |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the QtCore module of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:LGPL$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU Lesser General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
22 | ** packaging of this file. Please review the following information to |
23 | ** ensure the GNU Lesser General Public License version 3 requirements |
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
25 | ** |
26 | ** GNU General Public License Usage |
27 | ** Alternatively, this file may be used under the terms of the GNU |
28 | ** General Public License version 2.0 or (at your option) the GNU General |
29 | ** Public license version 3 or any later version approved by the KDE Free |
30 | ** Qt Foundation. The licenses are as published by the Free Software |
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
32 | ** included in the packaging of this file. Please review the following |
33 | ** information to ensure the GNU General Public License requirements will |
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
36 | ** |
37 | ** $QT_END_LICENSE$ |
38 | ** |
39 | ****************************************************************************/ |
40 | |
41 | #ifndef QMETAOBJECT_P_H |
42 | #define QMETAOBJECT_P_H |
43 | |
44 | // |
45 | // W A R N I N G |
46 | // ------------- |
47 | // |
48 | // This file is not part of the Qt API. It exists for the convenience |
49 | // of moc. This header file may change from version to version without notice, |
50 | // or even be removed. |
51 | // |
52 | // We mean it. |
53 | // |
54 | |
55 | #include <QtCore/qglobal.h> |
56 | #include <QtCore/qobjectdefs.h> |
57 | #include <QtCore/qmutex.h> |
58 | #include <QtCore/qmetaobject.h> |
59 | #ifndef QT_NO_QOBJECT |
60 | #include <private/qobject_p.h> // For QObjectPrivate::Connection |
61 | #endif |
62 | #include <QtCore/qvarlengtharray.h> |
63 | |
64 | QT_BEGIN_NAMESPACE |
65 | // ### TODO Qt6: add a proper namespace with Q_NAMESPACE and use scoped enums |
66 | // A namespace and scoped are needed to avoid enum clashes |
67 | |
68 | enum PropertyFlags { |
69 | Invalid = 0x00000000, |
70 | Readable = 0x00000001, |
71 | Writable = 0x00000002, |
72 | Resettable = 0x00000004, |
73 | EnumOrFlag = 0x00000008, |
74 | Alias = 0x00000010, |
75 | // Reserved for future usage = 0x00000020, |
76 | StdCppSet = 0x00000100, |
77 | Constant = 0x00000400, |
78 | Final = 0x00000800, |
79 | Designable = 0x00001000, |
80 | Scriptable = 0x00004000, |
81 | Stored = 0x00010000, |
82 | User = 0x00100000, |
83 | Required = 0x01000000, |
84 | Bindable = 0x02000000 |
85 | }; |
86 | |
87 | enum MethodFlags { |
88 | AccessPrivate = 0x00, |
89 | AccessProtected = 0x01, |
90 | AccessPublic = 0x02, |
91 | AccessMask = 0x03, // mask |
92 | |
93 | MethodMethod = 0x00, |
94 | MethodSignal = 0x04, |
95 | MethodSlot = 0x08, |
96 | MethodConstructor = 0x0c, |
97 | MethodTypeMask = 0x0c, |
98 | |
99 | MethodCompatibility = 0x10, |
100 | MethodCloned = 0x20, |
101 | MethodScriptable = 0x40, |
102 | MethodRevisioned = 0x80 |
103 | }; |
104 | |
105 | enum MetaObjectFlag { |
106 | DynamicMetaObject = 0x01, |
107 | RequiresVariantMetaObject = 0x02, |
108 | PropertyAccessInStaticMetaCall = 0x04 // since Qt 5.5, property code is in the static metacall |
109 | }; |
110 | Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag) |
111 | Q_DECLARE_OPERATORS_FOR_FLAGS(MetaObjectFlags) |
112 | |
113 | enum MetaDataFlags { |
114 | IsUnresolvedType = 0x80000000, |
115 | TypeNameIndexMask = 0x7FFFFFFF, |
116 | IsUnresolvedSignal = 0x70000000 |
117 | }; |
118 | |
119 | enum EnumFlags { |
120 | EnumIsFlag = 0x1, |
121 | EnumIsScoped = 0x2 |
122 | }; |
123 | |
124 | Q_CORE_EXPORT int qMetaTypeTypeInternal(const char *); |
125 | |
126 | class QArgumentType |
127 | { |
128 | public: |
129 | QArgumentType(int type) |
130 | : _type(type) |
131 | {} |
132 | QArgumentType(const QByteArray &name) |
133 | : _type(qMetaTypeTypeInternal(name.constData())), _name(name) |
134 | {} |
135 | QArgumentType() |
136 | : _type(0) |
137 | {} |
138 | int type() const |
139 | { return _type; } |
140 | QByteArray name() const |
141 | { |
142 | if (_type && _name.isEmpty()) |
143 | const_cast<QArgumentType *>(this)->_name = QMetaType(_type).name(); |
144 | return _name; |
145 | } |
146 | bool operator==(const QArgumentType &other) const |
147 | { |
148 | if (_type && other._type) |
149 | return _type == other._type; |
150 | else |
151 | return name() == other.name(); |
152 | } |
153 | bool operator!=(const QArgumentType &other) const |
154 | { |
155 | if (_type && other._type) |
156 | return _type != other._type; |
157 | else |
158 | return name() != other.name(); |
159 | } |
160 | |
161 | private: |
162 | int _type; |
163 | QByteArray _name; |
164 | }; |
165 | Q_DECLARE_TYPEINFO(QArgumentType, Q_MOVABLE_TYPE); |
166 | |
167 | typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray; |
168 | |
169 | class QMetaMethodPrivate; |
170 | |
171 | struct QMetaObjectPrivate |
172 | { |
173 | // revision 7 is Qt 5.0 everything lower is not supported |
174 | // revision 8 is Qt 5.12: It adds the enum name to QMetaEnum |
175 | // revision 9 is Qt 6.0: It adds the metatype of properties and methods |
176 | enum { OutputRevision = 9 }; // Used by moc, qmetaobjectbuilder and qdbus |
177 | enum { IntsPerMethod = QMetaMethod::Data::Size }; |
178 | enum { IntsPerEnum = QMetaEnum::Data::Size }; |
179 | enum { IntsPerProperty = QMetaProperty::Data::Size }; |
180 | |
181 | int revision; |
182 | int className; |
183 | int classInfoCount, classInfoData; |
184 | int methodCount, methodData; |
185 | int propertyCount, propertyData; |
186 | int enumeratorCount, enumeratorData; |
187 | int constructorCount, constructorData; |
188 | int flags; |
189 | int signalCount; |
190 | |
191 | static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject) |
192 | { return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); } |
193 | |
194 | static int originalClone(const QMetaObject *obj, int local_method_index); |
195 | |
196 | static QByteArray decodeMethodSignature(const char *signature, |
197 | QArgumentTypeArray &types); |
198 | static int indexOfSignalRelative(const QMetaObject **baseObject, |
199 | const QByteArray &name, int argc, |
200 | const QArgumentType *types); |
201 | static int indexOfSlotRelative(const QMetaObject **m, |
202 | const QByteArray &name, int argc, |
203 | const QArgumentType *types); |
204 | static int indexOfSignal(const QMetaObject *m, const QByteArray &name, |
205 | int argc, const QArgumentType *types); |
206 | static int indexOfSlot(const QMetaObject *m, const QByteArray &name, |
207 | int argc, const QArgumentType *types); |
208 | static int indexOfMethod(const QMetaObject *m, const QByteArray &name, |
209 | int argc, const QArgumentType *types); |
210 | static int indexOfConstructor(const QMetaObject *m, const QByteArray &name, |
211 | int argc, const QArgumentType *types); |
212 | Q_CORE_EXPORT static QMetaMethod signal(const QMetaObject *m, int signal_index); |
213 | static inline int signalOffset(const QMetaObject *m) |
214 | { |
215 | Q_ASSERT(m != nullptr); |
216 | int offset = 0; |
217 | for (m = m->d.superdata; m; m = m->d.superdata) |
218 | offset += reinterpret_cast<const QMetaObjectPrivate *>(m->d.data)->signalCount; |
219 | return offset; |
220 | } |
221 | Q_CORE_EXPORT static int absoluteSignalCount(const QMetaObject *m); |
222 | Q_CORE_EXPORT static int signalIndex(const QMetaMethod &m); |
223 | static bool checkConnectArgs(int signalArgc, const QArgumentType *signalTypes, |
224 | int methodArgc, const QArgumentType *methodTypes); |
225 | static bool checkConnectArgs(const QMetaMethodPrivate *signal, |
226 | const QMetaMethodPrivate *method); |
227 | |
228 | static QList<QByteArray> parameterTypeNamesFromSignature(const char *signature); |
229 | |
230 | #ifndef QT_NO_QOBJECT |
231 | // defined in qobject.cpp |
232 | enum DisconnectType { DisconnectAll, DisconnectOne }; |
233 | static void memberIndexes(const QObject *obj, const QMetaMethod &member, |
234 | int *signalIndex, int *methodIndex); |
235 | static QObjectPrivate::Connection *connect(const QObject *sender, int signal_index, |
236 | const QMetaObject *smeta, |
237 | const QObject *receiver, int method_index_relative, |
238 | const QMetaObject *rmeta = nullptr, |
239 | int type = 0, int *types = nullptr); |
240 | static bool disconnect(const QObject *sender, int signal_index, |
241 | const QMetaObject *smeta, |
242 | const QObject *receiver, int method_index, void **slot, |
243 | DisconnectType = DisconnectAll); |
244 | static inline bool disconnectHelper(QObjectPrivate::ConnectionData *connections, int signalIndex, |
245 | const QObject *receiver, int method_index, void **slot, |
246 | QBasicMutex *senderMutex, DisconnectType = DisconnectAll); |
247 | #endif |
248 | |
249 | template<int MethodType> |
250 | static inline int indexOfMethodRelative(const QMetaObject **baseObject, |
251 | const QByteArray &name, int argc, |
252 | const QArgumentType *types); |
253 | |
254 | static bool methodMatch(const QMetaObject *m, const QMetaMethod &method, |
255 | const QByteArray &name, int argc, |
256 | const QArgumentType *types); |
257 | |
258 | }; |
259 | |
260 | // For meta-object generators |
261 | |
262 | enum { MetaObjectPrivateFieldCount = sizeof(QMetaObjectPrivate) / sizeof(int) }; |
263 | |
264 | #ifndef UTILS_H |
265 | // mirrored in moc's utils.h |
266 | static inline bool is_ident_char(char s) |
267 | { |
268 | return ((s >= 'a' && s <= 'z') |
269 | || (s >= 'A' && s <= 'Z') |
270 | || (s >= '0' && s <= '9') |
271 | || s == '_' |
272 | ); |
273 | } |
274 | |
275 | static inline bool is_space(char s) |
276 | { |
277 | return (s == ' ' || s == '\t'); |
278 | } |
279 | #endif |
280 | |
281 | /* |
282 | This function is shared with moc.cpp. The implementation lives in qmetaobject_moc_p.h, which |
283 | should be included where needed. The declaration here is not used to avoid warnings from |
284 | the compiler about unused functions. |
285 | |
286 | static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixScope = false, bool adjustConst = true); |
287 | */ |
288 | |
289 | QT_END_NAMESPACE |
290 | |
291 | #endif |
292 | |
293 | |