Prevent repeated instantiations of qRegisterNormalizedMetaType<QList<QModelIndex>>()

This, finally, shows some expected results:

Clang -ftime-trace:

  $ ClangBuildAnalyzer --analyze qtgui-spec-before.trace | head -n6
  Analyzing build trace from 'qtgui-spec-before.trace'...
  **** Time summary:
  Compilation (523 times):
    Parsing (frontend):          665.7 s
    Codegen & opts (backend):    298.9 s

  $ ClangBuildAnalyzer --analyze qtgui-spec-after.trace | head -n6
  Analyzing build trace from 'qtgui-spec-after.trace'...
  **** Time summary:
  Compilation (525 times):
    Parsing (frontend):          628.3 s
    Codegen & opts (backend):    301.0 s

GCC 11 time (bash builtin):

  $ time for ((i=0; i < 3; ++i)) do touch ../qt5/qtbase/src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done
  [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so
  [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so
  [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so

  real    4m10,918s
  user    49m10,099s
  sys     3m11,719s
  $ git revert --no-commit HEAD
  $ time for ((i=0; i < 3; ++i)) do touch ../qt5/qtbase/src/gui/painting/qpolygon.h ; ninja libQt6Gui.so; done
  [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so
  [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so
  [268/268] Creating library symlink qtbase/lib/libQt6Gui.so.6 qtbase/lib/libQt6Gui.so

  real    4m18,630s
  user    51m11,491s
  sys     3m16,479s

The technique in the comment in qmetatype.h doesn't work on Clang - it
runs into -Winstantiation-after-specialization. The whole extern
template stuff so miserably fails to meet the goals set out in N1448,
not only for MSVC and class templates, but, it seems, on all
compilers, and for function templates, too, that I'm giving up on it
for now.

Unfortunately, I'm not really seeing a way to hide this stuff behind a
macro, yet.

Task-number: QTBUG-97601
Pick-to: 6.3
Change-Id: I500fd04555e0bd76ac021f75582bd8d8cf339378
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Marc Mutz 2022-01-14 17:54:55 +01:00
parent b749163bb8
commit 7d63efc16f
3 changed files with 24 additions and 1 deletions

View File

@ -60,6 +60,9 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcCheckIndex, "qt.core.qabstractitemmodel.checkindex")
int qRegisterNormalizedMetaType_QList_QModelIndex(const QByteArray &name)
{ return qRegisterNormalizedMetaTypeImplementation<QList<QModelIndex>>(name); }
QPersistentModelIndexData *QPersistentModelIndexData::create(const QModelIndex &index)
{
Q_ASSERT(index.isValid()); // we will _never_ insert an invalid index in the list

View File

@ -537,6 +537,10 @@ inline Qt::ItemFlags QModelIndex::flags() const
inline size_t qHash(const QModelIndex &index, size_t seed = 0) noexcept
{ return size_t((size_t(index.row()) << 4) + size_t(index.column()) + index.internalId()) ^ seed; }
Q_CORE_EXPORT int qRegisterNormalizedMetaType_QList_QModelIndex(const QByteArray &name);
template <> inline int qRegisterNormalizedMetaType<QList<QModelIndex>>(const QByteArray &name)
{ return qRegisterNormalizedMetaType_QList_QModelIndex(name); }
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QModelIndexList)

View File

@ -1226,7 +1226,7 @@ namespace QtPrivate {
}
template <typename T>
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
int qRegisterNormalizedMetaTypeImplementation(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
{
#ifndef QT_NO_QOBJECT
Q_ASSERT_X(normalizedTypeName == QMetaObject::normalizedType(normalizedTypeName.constData()),
@ -1254,6 +1254,22 @@ int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normaliz
return id;
}
// This primary template calls the -Implementation, like all other specialisations should.
// But the split allows to
// - in a header:
// - declare, but not define, a specialization of this template
// - add an explicit instantiation declaration (extern template ...)
// - in the .cpp file:
// - define the specialization to call the -Implementation
// - add an explicit instantiation definition
// This prevents the compiler from taking the leeway for inline functions in
// [temp.explicit]/13 Note 4
template <typename T>
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName)
{
return qRegisterNormalizedMetaTypeImplementation<T>(normalizedTypeName);
}
template <typename T>
int qRegisterMetaType(const char *typeName)
{