summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qmetaobjectbuilder.cpp
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-03-19 10:47:29 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2020-06-02 22:42:15 +0200
commitfa987d44417528856d5e80ed7b48ba99e19fa307 (patch)
tree50cd74c1a9dd3c2197f7de2ac0d431a5b16b0a42 /src/corelib/kernel/qmetaobjectbuilder.cpp
parent5306fdabc1ceb09875f791526553b3665017f7ce (diff)
MetaObject: Store the QMetaType of the methods
This does the analog of 46f407126ef3e94d59254012cdc34d6a4ad2faf2 for the methods we care about (signals, slots, Q_INVOKABLEs). In addition to the actual QMetaType, we store an array with offsets so that we later can do a mapping from methodIndex to metatype. The newly added QMetaMethod::{return,parameter}MetaType methods can then be used to retrieve the metatypes. This does however require that all involved types are complete. This is unfortunately not a feasible requirement. Thus, we only populate the metatype array on a best effort basis. For any incomplete type, we store QMetaType::Unknown. Then, when accessing the metatype, we fall back to the old string based code base if it's Unknown. Squashes "moc: support incomplete types" and "Fix compile failures after QMetaMethod change" Fixes: QTBUG-82932 Change-Id: I6b7a587cc364b7cad0c158d6de54e8a204289ad4 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/kernel/qmetaobjectbuilder.cpp')
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp43
1 files changed, 33 insertions, 10 deletions
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index a2dedda0ad3..7b9b06ed3ee 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -1216,7 +1216,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
- int(d->methods.size()) // return "parameters" don't have names
- int(d->constructors.size()); // "this" parameters don't have names
if (buf) {
- Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 8, "QMetaObjectBuilder should generate the same version as moc");
+ Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 9, "QMetaObjectBuilder should generate the same version as moc");
pmeta->revision = QMetaObjectPrivate::OutputRevision;
pmeta->flags = d->flags;
pmeta->className = 0; // Class name is always the first string.
@@ -1228,7 +1228,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
pmeta->methodCount = int(d->methods.size());
pmeta->methodData = dataIndex;
- dataIndex += 5 * int(d->methods.size());
+ dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size());
if (hasRevisionedMethods)
dataIndex += int(d->methods.size());
paramsIndex = dataIndex;
@@ -1248,10 +1248,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
pmeta->constructorCount = int(d->constructors.size());
pmeta->constructorData = dataIndex;
- dataIndex += 5 * int(d->constructors.size());
+ dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
} else {
dataIndex += 2 * int(d->classInfoNames.size());
- dataIndex += 5 * int(d->methods.size());
+ dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size());
if (hasRevisionedMethods)
dataIndex += int(d->methods.size());
paramsIndex = dataIndex;
@@ -1262,7 +1262,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
if (hasRevisionedProperties)
dataIndex += int(d->properties.size());
dataIndex += 5 * int(d->enumerators.size());
- dataIndex += 5 * int(d->constructors.size());
+ dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size());
}
// Allocate space for the enumerator key names and values.
@@ -1307,6 +1307,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
// Output the methods in the class.
Q_ASSERT(!buf || dataIndex == pmeta->methodData);
+ int parameterMetaTypesIndex = d->properties.size();
for (const auto &method : d->methods) {
int name = strings.enter(method.name());
int argc = method.parameterCount();
@@ -1318,11 +1319,13 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
data[dataIndex + 2] = paramsIndex;
data[dataIndex + 3] = tag;
data[dataIndex + 4] = attrs;
+ data[dataIndex + 5] = parameterMetaTypesIndex;
if (method.methodType() == QMetaMethod::Signal)
pmeta->signalCount++;
}
- dataIndex += 5;
+ dataIndex += QMetaObjectPrivate::IntsPerMethod;
paramsIndex += 1 + argc * 2;
+ parameterMetaTypesIndex += 1 + argc;
}
if (hasRevisionedMethods) {
for (const auto &method : d->methods) {
@@ -1333,7 +1336,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
}
// Output the method parameters in the class.
- Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * 5
+ Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * QMetaObjectPrivate::IntsPerMethod
+ (hasRevisionedMethods ? int(d->methods.size()) : 0));
for (int x = 0; x < 2; ++x) {
const std::vector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
@@ -1446,9 +1449,11 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
data[dataIndex + 2] = paramsIndex;
data[dataIndex + 3] = tag;
data[dataIndex + 4] = attrs;
+ data[dataIndex + 5] = parameterMetaTypesIndex;
}
- dataIndex += 5;
+ dataIndex += QMetaObjectPrivate::IntsPerMethod;
paramsIndex += 1 + argc * 2;
+ parameterMetaTypesIndex += argc;
}
size += strings.blobSize();
@@ -1474,7 +1479,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1);
}
- if (d->properties.size() > 0) {
+ if (d->properties.size() > 0 || d->methods.size() > 0 || d->constructors.size() > 0) {
ALIGN(size, QtPrivate::QMetaTypeInterface *);
auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size);
if (buf) {
@@ -1484,8 +1489,26 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
*types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
types++;
}
+ for (const auto &method: d->methods) {
+ QMetaType mt(QMetaType::type(method.returnType));
+ *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
+ types++;
+ for (const auto &parameterType: method.parameterTypes()) {
+ QMetaType mt(QMetaType::type(parameterType));
+ *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
+ types++;
+ }
+ }
+ for (const auto &constructor: d->constructors) {
+ for (const auto &parameterType: constructor.parameterTypes()) {
+ QMetaType mt(QMetaType::type(parameterType));
+ *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt);
+ types++;
+ }
+ }
}
- size += static_cast<int>(sizeof(QMetaType) * d->properties.size());
+ // parameterMetaTypesIndex is equal to the total number of metatypes
+ size += static_cast<int>(sizeof(QMetaType) * parameterMetaTypesIndex);
}
// Align the final size and return it.