Debugger: Add a visualizer for QMultiHash

...and a very primitive test.

Note that the visualization of `QMultiHash::iterator` does not work
(this is a common problem for other containers too).
I am not convinced that making effort to make it work now is worth it.

Fixes: QTCREATORBUG-32313
Change-Id: If68cf17c8aa6d63da752aef07072725131bdbf52
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Andrii Semkiv
2025-01-15 14:08:25 +01:00
parent d14d25ad17
commit 3b7e30349f
2 changed files with 67 additions and 0 deletions

View File

@@ -928,6 +928,13 @@ def qform__QHash():
def qdump__QHash(d, value): def qdump__QHash(d, value):
qdumpHelper_QHash(d, value, value.type[0], value.type[1]) qdumpHelper_QHash(d, value, value.type[0], value.type[1])
def qdump__QMultiHash(d, value):
key_type = value.type[0]
value_type = value.type[1]
if d.qtVersionAtLeast(0x060000):
qdumpHelper_QMultiHash_6(d, value, key_type, value_type)
else:
qdumpHelper_QHash_5(d, value, key_type, value_type)
def qdump__QVariantHash(d, value): def qdump__QVariantHash(d, value):
qdumpHelper_QHash(d, value, d.createType('@QString'), d.createType('@QVariant')) qdumpHelper_QHash(d, value, d.createType('@QString'), d.createType('@QVariant'))
@@ -1033,6 +1040,40 @@ def qdumpHelper_QHash_6(d, value, keyType, valueType):
# d.putValue('total: %s item size: %s' % (count, entry_size)) # d.putValue('total: %s item size: %s' % (count, entry_size))
def qdumpHelper_QMultiHash_6(d, value, key_type, value_type):
dptr, size = d.split('pq', value)
if dptr == 0:
d.putItemCount(0)
return
ref, _pad, _d_size, buckets, _seed, spans = d.split('i@qqqp', dptr)
d.check(0 <= size and size <= 100 * 1000 * 1000)
d.check(-1 <= ref and ref < 100000)
d.putItemCount(size)
if d.isExpanded():
type_code = f'{{{key_type.name}}}@p'
_pp, entry_size, _fields = d.describeStruct(type_code)
with Children(d, size):
span_size = 128 + 2 * d.ptrSize() # Including tail padding.
nspans = int((buckets + 127) / 128)
count = 0
for b in range(nspans):
span = spans + b * span_size
offsets, entries, _allocated, _next_free = d.split('128spbb', span)
for i in range(128):
offset = offsets[i]
if offset != 255: # Entry is used
entry = entries + offset * entry_size
key, _pad, chain = d.split(type_code, entry)
next = chain
while next != 0:
val, _pad, next = d.split(f'{{{value_type.name}}}@p', next)
d.putPairItem(count, (key, val), 'key', 'value')
count += 1
def qform__QHashNode(): def qform__QHashNode():
return [DisplayFormat.CompactMap] return [DisplayFormat.CompactMap]

View File

@@ -2538,6 +2538,32 @@ void tst_Dumpers::dumper_data()
+ Check5("it3.key", "33", "int") + Check5("it3.key", "33", "int")
+ Check5("it3.value", FloatValue("33"), "float"); + Check5("it3.value", FloatValue("33"), "float");
// clang-format off
QTest::newRow("QMultiHash")
<< Data("#include <QMultiHash>",
R"(const QMultiHash<int, int> empty;
QMultiHash<int, int> mh;
mh.insert(1, 1);
mh.insert(2, 2);
mh.insert(1, 3);
mh.insert(2, 4);
mh.insert(1, 5);)",
"&empty, &mh")
+ CoreProfile()
+ Check("empty", "<0 items>", "QMultiHash<int, int>")
+ Check("mh", "<5 items>", "QMultiHash<int, int>")
// due to unordered nature of the container, checking specific item values
// is not possible
+ Check("mh.0.key", ValuePattern("[1,2]"), "int")
+ Check("mh.0.value", ValuePattern("[1-5]"), "int")
+ Check("mh.4.key", ValuePattern("[1,2]"), "int")
+ Check("mh.4.value", ValuePattern("[1-5]"), "int");
// clang-format on
QTest::newRow("QHostAddress") QTest::newRow("QHostAddress")
<< Data("#include <QHostAddress>\n", << Data("#include <QHostAddress>\n",