forked from qt-creator/qt-creator
Fix STL container dumpers with _GLIBCXX_DEBUG
Fixed behavior of the libstdc++ dumpers for the following types with `_GLIBCXX_DEBUG` macro enabled: * `std::deque` * `std::list` * `std::multimap` * `std::multiset` Fixed libc++ dumpers for the following types: * `std::unordered_map` * `std::unordered_multimap` * `std::unordered_multiset` * `std::unordered_set` Added a dumper for `std::forward_list`. Fixes: QTCREATORBUG-20476 Change-Id: I802b0eaf31cdea77d980ca18d4c3fae15a86a3d4 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
from stdtypes import qdump__std__array, qdump__std__complex, qdump__std__once_flag, qdump__std__unique_ptr, qdumpHelper__std__deque__libcxx, qdumpHelper__std__vector__libcxx
|
||||
from stdtypes import qdump__std__array, qdump__std__complex, qdump__std__once_flag, qdump__std__unique_ptr, qdumpHelper__std__deque__libcxx, qdumpHelper__std__vector__libcxx, qdump__std__forward_list
|
||||
from utils import DisplayFormat
|
||||
from dumper import Children, DumperBase
|
||||
|
||||
@@ -23,6 +23,10 @@ def qdump__std____1__deque(d, value):
|
||||
qdumpHelper__std__deque__libcxx(d, value)
|
||||
|
||||
|
||||
def qdump__std____1__forward_list(d, value):
|
||||
qdump__std__forward_list(d, value)
|
||||
|
||||
|
||||
def qdump__std____1__list(d, value):
|
||||
if value.type.size() == 3 * d.ptrSize():
|
||||
# C++11 only.
|
||||
@@ -308,7 +312,7 @@ def qform__std____1__unordered_map():
|
||||
|
||||
|
||||
def qdump__std____1__unordered_map(d, value):
|
||||
(size, _) = value["__table_"]["__p2_"].split("pp")
|
||||
size = value["__table_"]["__p2_"]["__value_"].integer()
|
||||
d.putItemCount(size)
|
||||
|
||||
keyType = value.type[0]
|
||||
@@ -316,7 +320,7 @@ def qdump__std____1__unordered_map(d, value):
|
||||
pairType = value.type[4][0]
|
||||
|
||||
if d.isExpanded():
|
||||
curr = value["__table_"]["__p1_"].split("pp")[0]
|
||||
curr = value["__table_"]["__p1_"].split("p")[0]
|
||||
|
||||
def traverse_list(node):
|
||||
while node:
|
||||
@@ -329,14 +333,18 @@ def qdump__std____1__unordered_map(d, value):
|
||||
d.putPairItem(i, value, 'key', 'value')
|
||||
|
||||
|
||||
def qdump__std____1__unordered_multimap(d, value):
|
||||
qdump__std____1__unordered_map(d, value)
|
||||
|
||||
|
||||
def qdump__std____1__unordered_set(d, value):
|
||||
(size, _) = value["__table_"]["__p2_"].split("pp")
|
||||
size = value["__table_"]["__p2_"]["__value_"].integer()
|
||||
d.putItemCount(size)
|
||||
|
||||
valueType = value.type[0]
|
||||
|
||||
if d.isExpanded():
|
||||
curr = value["__table_"]["__p1_"].split("pp")[0]
|
||||
curr = value["__table_"]["__p1_"].split("p")[0]
|
||||
|
||||
def traverse_list(node):
|
||||
while node:
|
||||
|
@@ -62,8 +62,14 @@ def qdumpHelper__std__deque__libstdcxx(d, value):
|
||||
innerSize = innerType.size()
|
||||
bufsize = 512 // innerSize if innerSize < 512 else 1
|
||||
|
||||
(mapptr, mapsize, startCur, startFirst, startLast, startNode,
|
||||
finishCur, finishFirst, finishLast, finishNode) = value.split("pppppppppp")
|
||||
start = value['_M_start']
|
||||
startCur = start['_M_cur'].pointer()
|
||||
startLast = start['_M_last'].pointer()
|
||||
startNode = start['_M_node'].pointer()
|
||||
finish = value['_M_finish']
|
||||
finishCur = finish['_M_cur'].pointer()
|
||||
finishFirst = finish['_M_first'].pointer()
|
||||
finishNode = finish['_M_node'].pointer()
|
||||
|
||||
size = bufsize * ((finishNode - startNode) // d.ptrSize() - 1)
|
||||
size += (finishCur - finishFirst) // innerSize
|
||||
@@ -178,9 +184,16 @@ def qdump__std__list(d, value):
|
||||
qdump__std__list__QNX(d, value)
|
||||
return
|
||||
|
||||
if value.type.size() == 3 * d.ptrSize():
|
||||
# QTCREATORBUG-20476: GCC with _GLIBCXX_DEBUG prepends the head node
|
||||
# with some debug information
|
||||
if value.hasMember('_M_impl'):
|
||||
sentinel = value['_M_impl']['_M_node']
|
||||
else:
|
||||
sentinel = value
|
||||
|
||||
if sentinel.type.size() == 3 * d.ptrSize():
|
||||
# C++11 only.
|
||||
(dummy1, dummy2, size) = value.split("ppp")
|
||||
(dummy1, dummy2, size) = sentinel.split("ppp")
|
||||
d.putItemCount(size)
|
||||
else:
|
||||
# Need to count manually.
|
||||
@@ -193,7 +206,7 @@ def qdump__std__list(d, value):
|
||||
d.putItemCount(size, 1000)
|
||||
|
||||
if d.isExpanded():
|
||||
p = d.extractPointer(value)
|
||||
p = d.extractPointer(sentinel)
|
||||
innerType = value.type[0]
|
||||
with Children(d, size, maxNumChild=1000, childType=innerType):
|
||||
for i in d.childRange():
|
||||
@@ -232,6 +245,43 @@ def qdump__std____cxx11__list(d, value):
|
||||
qdump__std__list(d, value)
|
||||
|
||||
|
||||
def qdump__std__forward_list(d, value):
|
||||
# QTCREATORBUG-20476: GCC with _GLIBCXX_DEBUG prepends the head node
|
||||
# with some debug information
|
||||
if value.hasMember('_M_impl'):
|
||||
head = value['_M_impl']['_M_head']
|
||||
# MSVC stores the head in a compressed pair with the allocator
|
||||
# (which is normally an empty class)
|
||||
elif value.hasMember('_Mypair'):
|
||||
head = value['_Mypair']['_Myval2']['_Myhead']
|
||||
else:
|
||||
head = value
|
||||
|
||||
# Need to count manually.
|
||||
p = d.extractPointer(head)
|
||||
size = 0
|
||||
while p and size < 1001:
|
||||
size += 1
|
||||
p = d.extractPointer(p)
|
||||
d.putItemCount(size, 1000)
|
||||
|
||||
if d.isExpanded():
|
||||
p = d.extractPointer(head)
|
||||
innerType = value.type[0]
|
||||
with Children(d, size, maxNumChild=1000, childType=innerType):
|
||||
for i in d.childRange():
|
||||
d.putSubItem(i, d.createValue(p + d.ptrSize(), innerType))
|
||||
p = d.extractPointer(p)
|
||||
|
||||
|
||||
def qdump__std____debug__forward_list(d, value):
|
||||
qdump__std__forward_list(d, value)
|
||||
|
||||
|
||||
def qdump__std____cxx11__forward_list(d, value):
|
||||
qdump__std__forward_list(d, value)
|
||||
|
||||
|
||||
def qform__std__map():
|
||||
return [DisplayFormat.CompactMap]
|
||||
|
||||
@@ -242,7 +292,7 @@ def qdump__std__map(d, value):
|
||||
return
|
||||
|
||||
# stuff is actually (color, pad) with 'I@', but we can save cycles/
|
||||
(compare, stuff, parent, left, right) = value.split('ppppp')
|
||||
parent = value["_M_t"]["_M_impl"]["_M_header"]
|
||||
size = value["_M_t"]["_M_impl"]["_M_node_count"].integer()
|
||||
d.check(0 <= size and size <= 100 * 1000 * 1000)
|
||||
d.putItemCount(size)
|
||||
@@ -321,6 +371,14 @@ def qdump__std__multiset(d, value):
|
||||
qdump__std__set(d, value)
|
||||
|
||||
|
||||
def qdump__std____debug__multiset(d, value):
|
||||
qdump__std__multiset(d, value)
|
||||
|
||||
|
||||
def qdump__std____cxx1998__multiset(d, value):
|
||||
qdump__std__multiset(d, value)
|
||||
|
||||
|
||||
def qdump__std____cxx1998__map(d, value):
|
||||
qdump__std__map(d, value)
|
||||
|
||||
@@ -333,6 +391,14 @@ def qdump__std__multimap(d, value):
|
||||
return qdump__std__map(d, value)
|
||||
|
||||
|
||||
def qdump__std____debug__multimap(d, value):
|
||||
qdump__std__multimap(d, value)
|
||||
|
||||
|
||||
def qdump__std____cxx1998__multimap(d, value):
|
||||
qdump__std__multimap(d, value)
|
||||
|
||||
|
||||
def qdumpHelper__std__tree__iterator(d, value, isSet=False):
|
||||
treeTypeName = None
|
||||
if value.type.name.endswith("::iterator"):
|
||||
|
@@ -4905,6 +4905,33 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("l4.@1.1", "[1]", "2", "int");
|
||||
|
||||
|
||||
QTest::newRow("StdForwardList")
|
||||
<< Data("#include <forward_list>\n",
|
||||
|
||||
"std::forward_list<int> fl0;\n"
|
||||
|
||||
"std::forward_list<int> fl1;\n"
|
||||
"for (int i = 0; i < 10000; ++i)\n"
|
||||
" fl1.push_front(i);\n"
|
||||
|
||||
"std::forward_list<bool> fl2 = {true, false};\n",
|
||||
|
||||
"&fl0, &fl1, &fl2")
|
||||
|
||||
+ BigArrayProfile()
|
||||
|
||||
+ Check("fl0", "<0 items>", "std::forward_list<int>")
|
||||
|
||||
+ Check("fl1", ValuePattern("<.*1000.* items>"), "std::forward_list<int>")
|
||||
+ Check("fl1.0", "[0]", "9999", "int")
|
||||
+ Check("fl1.1", "[1]", "9998", "int")
|
||||
+ Check("fl1.999", "[999]", "9000", "int")
|
||||
|
||||
+ Check("fl2", "<2 items>", "std::forward_list<bool>")
|
||||
+ Check("fl2.0", "[0]", "1", "bool")
|
||||
+ Check("fl2.1", "[1]", "0", "bool");
|
||||
|
||||
|
||||
QTest::newRow("StdListQt")
|
||||
<< Data("#include <list>\n" + fooData,
|
||||
|
||||
|
Reference in New Issue
Block a user