QMetaTypeModuleHelper: fix -Wweak-vtable

The only implemented virtual function, convert(), is inline, so the
vtable and type_info for this class were duplicated in QtGui,
QtWidgets, and any other library that may use this.

Fix by exporting the class and de-inlining convert(). The vtable is
now pinned to qmetatype.cpp.

To prevent MSVC from exporting the trivial static helper function and
possibly rendering its constexpr non-functional, make it a template.

We have two macros for this purpose, with different semantics: The
Q_WEAK_OVERLOAD macro is related to overload set management, not to
keeping function out of the ABI, even though it does that, too. And we
have QT_POST_CXX17_API_IN_EXPORTED_CLASS for ABI control, but this
function is not using post-C++17 features, so since both macros need a
comment, and both don't fit 100%, I used the shorter one.

Task-number: QTBUG-45582
Pick-to: 6.7
Change-Id: I2ce4a7110e09def1a595d717c073df844213611c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2024-01-18 08:54:18 +01:00 committed by Thiago Macieira
parent 6d1b4d5740
commit 8d88f1282b
2 changed files with 9 additions and 2 deletions

View File

@ -948,6 +948,12 @@ void QMetaType::unregisterMetaType(QMetaType type)
than the QMetaType \a b, otherwise returns \c false.
*/
/*! \internal */
bool QMetaTypeModuleHelper::convert(const void *, int, void *, int) const
{
return false;
}
#define QT_ADD_STATIC_METATYPE(MetaTypeName, MetaTypeId, RealName) \
{ #RealName, sizeof(#RealName) - 1, MetaTypeId },

View File

@ -38,20 +38,21 @@ QT_BEGIN_NAMESPACE
assign_and_return \
}
class QMetaTypeModuleHelper
class Q_CORE_EXPORT QMetaTypeModuleHelper
{
Q_DISABLE_COPY_MOVE(QMetaTypeModuleHelper)
protected:
QMetaTypeModuleHelper() = default;
~QMetaTypeModuleHelper() = default;
public:
Q_WEAK_OVERLOAD // prevent it from entering the ABI and rendering constexpr useless
static constexpr auto makePair(int from, int to) -> quint64
{
return (quint64(from) << 32) + quint64(to);
}
virtual const QtPrivate::QMetaTypeInterface *interfaceForType(int) const = 0;
virtual bool convert(const void *, int, void *, int) const { return false; }
virtual bool convert(const void *, int, void *, int) const;
};
extern Q_CORE_EXPORT const QMetaTypeModuleHelper *qMetaTypeGuiHelper;