From ee9e3a10d967874eddc5400b2b7aa36950140b9b Mon Sep 17 00:00:00 2001 From: Sami Shalayel Date: Wed, 12 Oct 2022 15:56:00 +0200 Subject: qmltc: fix handlers for c++-signals Allow qmltc to generate handlers for c++-defined signals with const parameters by changing the safeguard to avoid type mismatch between slots and signals. First, remove the qOverload in the generated QObject::connect call to be able the connect slots and signals with different types (namely, pass by const references and pass by value should be interchangeable but is not allowed by qOverload). Second, save in QQmlJSMetaParameter when types are passed by pointer. Like this, qqmljsimportvisitor can check if a value type is indeed passed by value or const reference in a C++ signal. The same for reference types that need to be passed by (const and non-const) pointer. Print a message when an type is passed by argument in an incompatible way instead of letting qmltc generate uncompilable code, which makes the compiler print out cryptical messages. Third, add a qqmlcpptypehelpers template that decides if value types should be passed by value or reference, by letting the c++ compiler check if sizeof(T) > 3*sizeof(void*). Fixes: QTBUG-107625 Fixes: QTBUG-107622 Change-Id: I1a00532df591d10f74c1fd00dff5b7fccf40cb22 Reviewed-by: Ulf Hermann --- tools/qmltc/qmltccodewriter.cpp | 1 + tools/qmltc/qmltccompiler.cpp | 28 +++++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/qmltc/qmltccodewriter.cpp b/tools/qmltc/qmltccodewriter.cpp index 68bd803b15..c4c5c30f83 100644 --- a/tools/qmltc/qmltccodewriter.cpp +++ b/tools/qmltc/qmltccodewriter.cpp @@ -137,6 +137,7 @@ void QmltcCodeWriter::writeGlobalHeader(QmltcOutputWrapper &code, const QString code.rawAppendToCpp(u"// qmltc support library:"); code.rawAppendToCpp(u"#include "); // QmltcSupportLib code.rawAppendToCpp(u"#include "); // QmltcSupportLib + code.rawAppendToHeader(u"#include "); // QmltcSupportLib code.rawAppendToCpp(u"#include "); // createComponent() code.rawAppendToCpp(u"#include "); // QQmlComponentPrivate::get() diff --git a/tools/qmltc/qmltccompiler.cpp b/tools/qmltc/qmltccompiler.cpp index a69f8619e9..4050136ef2 100644 --- a/tools/qmltc/qmltccompiler.cpp +++ b/tools/qmltc/qmltccompiler.cpp @@ -425,7 +425,24 @@ compileMethodParameters(const QList ¶meterInfos, bool a Q_ASSERT(allowUnnamed || !name.isEmpty()); // assume verified if (name.isEmpty() && allowUnnamed) name = u"unnamed_" + QString::number(i); - parameters.emplaceBack(p.type()->augmentedInternalName(), name, QString()); + + QString internalName; + const QQmlJSScope::AccessSemantics semantics = p.type()->accessSemantics(); + + switch (semantics) { + case QQmlJSScope::AccessSemantics::Reference: + if (p.typeQualifier() == QQmlJSMetaParameter::Const) + internalName = u"const "_s; + internalName += u"%1*"_s.arg(p.type()->internalName()); + break; + case QQmlJSScope::AccessSemantics::Value: + case QQmlJSScope::AccessSemantics::Sequence: + internalName = u"passByConstRefOrValue<%1>"_s.arg(p.type()->internalName()); + break; + case QQmlJSScope::AccessSemantics::None: + Q_ASSERT(false); // or maybe print an error message + } + parameters.emplaceBack(internalName, name, QString()); } return parameters; } @@ -1658,12 +1675,9 @@ void QmltcCompiler::compileScriptBinding(QmltcType ¤t, slotMethod.type = QQmlJSMetaMethod::Slot; current.functions << std::move(slotMethod); - current.setComplexBindings.body - << u"QObject::connect(" + This_signal + u", " - + QmltcCodeGenerator::wrap_qOverload( - slotParameters, u"&" + objectClassName_signal + u"::" + signalName) - + u", " + This_slot + u", &" + objectClassName_slot + u"::" + slotName - + u");"; + current.setComplexBindings.body << u"QObject::connect(" + This_signal + u", " + u"&" + + objectClassName_signal + u"::" + signalName + u", " + This_slot + u", &" + + objectClassName_slot + u"::" + slotName + u");"; }; switch (binding.scriptKind()) { -- cgit v1.2.1