moc: Use a much, much shorter structure name for the StringData

The old one kept all the indices in the type name, which was completely
unnecessary. This caused the symbol name to explode for some very large
meta object, notably that of the Qt namespace itself, causing gdb to
produce this warning at every start:

warning: internal error: string "StringData<3, 12, 7, 7, 6, 6, 9, 5, 10,
4, 6, 5, 5, 8, 7, 8, 10, 9, 9, 12, 11, 12, 12, 8, 6, 5, 13, 12, 9,
[many lines suppressed]
33, 6, 6, 5, 6, 17, 12, 17, 13, 8, 7>" failed to be canonicalized

To ensure there's no binary-compatibility problem with a StringData of
two entries, the first parameter is now of type int.

Pick-to: 6.5
Change-Id: I6f518d59e63249ddbf43fffd1759fbb66adc1299
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
This commit is contained in:
Thiago Macieira 2023-04-27 20:31:36 -07:00
parent 53a4f02b01
commit 6000fa2adf

View File

@ -26,37 +26,38 @@
QT_BEGIN_NAMESPACE
namespace QtMocHelpers {
template <uint... Nx> struct StringData
// The maximum Size of a string literal is 2 GB on 32-bit and 4 GB on 64-bit
// (but the compiler is likely to give up before you get anywhere near that much)
static constexpr size_t MaxStringSize =
(std::min)(size_t((std::numeric_limits<uint>::max)()),
size_t((std::numeric_limits<qsizetype>::max)()));
template <uint... Nx> constexpr size_t stringDataSizeHelper(std::integer_sequence<uint, Nx...>)
{
static constexpr size_t calculateStringSize()
{
// same as:
// return (0 + ... + Nx);
// but not using the fold expression to avoid exceeding compiler limits
size_t total = 0;
uint sizes[] = { Nx... };
for (uint n : sizes)
total += n;
return total;
}
// same as:
// return (0 + ... + Nx);
// but not using the fold expression to avoid exceeding compiler limits
size_t total = 0;
uint sizes[] = { Nx... };
for (uint n : sizes)
total += n;
return total;
}
// The maximum Size of a string literal is 2 GB on 32-bit and 4 GB on 64-bit
// (but the compiler is likely to give up before you get anywhere near that much)
static constexpr size_t MaxStringSize =
(std::min)(size_t((std::numeric_limits<uint>::max)()),
size_t((std::numeric_limits<qsizetype>::max)()));
static constexpr size_t StringSize = calculateStringSize();
template <int Count, size_t StringSize> struct StringData
{
static_assert(StringSize <= MaxStringSize, "Meta Object data is too big");
uint offsetsAndSizes[2 * sizeof...(Nx)] = {};
uint offsetsAndSizes[Count] = {};
char stringdata0[StringSize] = {};
constexpr StringData() = default;
};
template <uint... Nx> constexpr auto stringData(const char (&...strings)[Nx])
{
StringData<Nx...> result;
constexpr size_t StringSize = stringDataSizeHelper<Nx...>({});
constexpr size_t Count = 2 * sizeof...(Nx);
StringData<Count, StringSize> result;
const char *inputs[] = { strings... };
uint sizes[] = { Nx... };