diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-01-31 13:53:44 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-02-02 15:57:09 +0100 |
commit | 41248f259005aa3052d569def9f873afee4ac8f6 (patch) | |
tree | 216562ae545e0ec41a69bb366d6d4f182a311402 /src/tools/moc | |
parent | b2912174572dea2a7bff59414418d602ef58a00a (diff) |
moc: Allow calling ctors on pre-allocated data
When calling a ctor this way, an object is created in the memory pointed
to by _a[0] using the other arguments for the ctor.
This allows separate allocation and initialization of an object through
the metaobject system.
Fixes: QTBUG-108879
Change-Id: Ifb154373ee42faab281cfb62aa14334980ec6b7d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/tools/moc')
-rw-r--r-- | src/tools/moc/generator.cpp | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 1214600a7e..ca6a4181b6 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1073,33 +1073,45 @@ void Generator::generateStaticMetacall() bool needElse = false; bool isUsed_a = false; + const auto generateCtorArguments = [&](int ctorindex) { + const FunctionDef &f = cdef->constructorList.at(ctorindex); + Q_ASSERT(!f.isPrivateSignal); // That would be a strange ctor indeed + int offset = 1; + + int argsCount = f.arguments.size(); + for (int j = 0; j < argsCount; ++j) { + const ArgumentDef &a = f.arguments.at(j); + if (j) + fprintf(out, ","); + fprintf(out, "(*reinterpret_cast<%s>(_a[%d]))", + a.typeNameForCast.constData(), offset++); + } + }; + if (!cdef->constructorList.isEmpty()) { fprintf(out, " if (_c == QMetaObject::CreateInstance) {\n"); fprintf(out, " switch (_id) {\n"); - for (int ctorindex = 0; ctorindex < cdef->constructorList.size(); ++ctorindex) { + const int ctorend = cdef->constructorList.size(); + for (int ctorindex = 0; ctorindex < ctorend; ++ctorindex) { fprintf(out, " case %d: { %s *_r = new %s(", ctorindex, cdef->classname.constData(), cdef->classname.constData()); - const FunctionDef &f = cdef->constructorList.at(ctorindex); - int offset = 1; - - int argsCount = f.arguments.size(); - for (int j = 0; j < argsCount; ++j) { - const ArgumentDef &a = f.arguments.at(j); - if (j) - fprintf(out, ","); - fprintf(out, "(*reinterpret_cast< %s>(_a[%d]))", a.typeNameForCast.constData(), offset++); - } - if (f.isPrivateSignal) { - if (argsCount > 0) - fprintf(out, ", "); - fprintf(out, "%s", QByteArray("QPrivateSignal()").constData()); - } + generateCtorArguments(ctorindex); fprintf(out, ");\n"); fprintf(out, " if (_a[0]) *reinterpret_cast<%s**>(_a[0]) = _r; } break;\n", (cdef->hasQGadget || cdef->hasQNamespace) ? "void" : "QObject"); } fprintf(out, " default: break;\n"); fprintf(out, " }\n"); + fprintf(out, " } else if (_c == QMetaObject::ConstructInPlace) {\n"); + fprintf(out, " switch (_id) {\n"); + for (int ctorindex = 0; ctorindex < ctorend; ++ctorindex) { + fprintf(out, " case %d: { new (_a[0]) %s(", + ctorindex, cdef->classname.constData()); + generateCtorArguments(ctorindex); + fprintf(out, "); } break;\n"); + } + fprintf(out, " default: break;\n"); + fprintf(out, " }\n"); fprintf(out, " }"); needElse = true; isUsed_a = true; |