Debugger: Implement dumper for std::unordered_{set,map}

Task-number: QTCREATORBUG-9855

Change-Id: I985745530d93e1c191442431a7a9449a1c4c059a
Reviewed-by: hjk <hjk121@nokiamail.com>
Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
hjk
2013-08-16 00:44:26 +02:00
committed by David Schulz
parent cb4c649ac0
commit 958a1d2d4e
4 changed files with 135 additions and 0 deletions

View File

@@ -2508,6 +2508,58 @@ def qdump__std____1__unique_ptr(d, value):
d.putSubItem("data", i.dereference())
def qform__std__unordered_map():
return mapForms()
def qdump__std__unordered_map(d, value):
try:
size = value["_M_element_count"]
start = value["_M_before_begin"]["_M_nxt"]
except:
size = value["_M_h"]["_M_element_count"]
start = value["_M_h"]["_M_bbegin"]["_M_node"]["_M_nxt"]
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded():
p = pointerValue(start)
keyType = d.templateArgument(value.type, 0)
valueType = d.templateArgument(value.type, 1)
allocatorType = d.templateArgument(value.type, 4)
pairType = d.templateArgument(allocatorType, 0)
ptrSize = d.ptrSize()
if d.isMapCompact(keyType, valueType):
with Children(d, size, childType=valueType):
for i in d.childRange():
pair = d.createValue(p + ptrSize, pairType)
with SubItem(d, i):
d.putField("iname", d.currentIName)
d.putName("[%s] %s" % (i, pair["first"]))
d.putValue(pair["second"])
p = d.dereference(p)
else:
with Children(d, size, childType=pairType):
for i in d.childRange():
d.putSubItem(i, d.createValue(p + ptrSize, pairType))
p = d.dereference(p)
def qdump__std__unordered_set(d, value):
try:
size = value["_M_element_count"]
start = value["_M_before_begin"]["_M_nxt"]
except:
size = value["_M_h"]["_M_element_count"]
start = value["_M_h"]["_M_bbegin"]["_M_node"]["_M_nxt"]
d.putItemCount(size)
d.putNumChild(size)
if d.isExpanded():
p = pointerValue(start)
valueType = d.templateArgument(value.type, 0)
with Children(d, size, childType=valueType):
ptrSize = d.ptrSize()
for i in d.childRange():
d.putSubItem(i, d.createValue(p + ptrSize, valueType))
p = d.dereference(p)
def qedit__std__vector(expr, value):
values = value.split(',')

View File

@@ -586,6 +586,14 @@ CPLUSPLUS_EXPORT QString simplifySTLType(const QString &typeIn)
if (setRE.indexIn(type) != -1)
type.replace(setRE.cap(0), QString::fromLatin1("set<%1>").arg(inner));
// std::unordered_set
QRegExp unorderedSetRE(QString::fromLatin1("unordered_set<%1, ?std::hash<%2>, ?std::equal_to<%3>, ?%4\\s*>")
.arg(innerEsc, innerEsc, innerEsc, allocEsc));
unorderedSetRE.setMinimal(true);
QTC_ASSERT(unorderedSetRE.isValid(), return typeIn);
if (unorderedSetRE.indexIn(type) != -1)
type.replace(unorderedSetRE.cap(0), QString::fromLatin1("unordered_set<%1>").arg(inner));
// std::map
if (inner.startsWith(QLatin1String("std::pair<"))) {
// search for outermost ',', split key and value
@@ -621,6 +629,35 @@ CPLUSPLUS_EXPORT QString simplifySTLType(const QString &typeIn)
type.replace(mapRE2.cap(0), QString::fromLatin1("map<const %1, %2>").arg(key, value));
}
}
// std::unordered_map
if (inner.startsWith(QLatin1String("std::pair<"))) {
// search for outermost ',', split key and value
int pos;
int level = 0;
for (pos = 10; pos < inner.size(); ++pos) {
int c = inner.at(pos).unicode();
if (c == '<')
++level;
else if (c == '>')
--level;
else if (c == ',' && level == 0)
break;
}
const QString key = chopConst(inner.mid(10, pos - 10));
const QString keyEsc = QRegExp::escape(key);
// Get value: MSVC: 'pair<a const ,b>', gcc: 'pair<const a, b>'
if (inner.at(++pos) == QLatin1Char(' '))
pos++;
const QString value = inner.mid(pos, inner.size() - pos - 1).trimmed();
const QString valueEsc = QRegExp::escape(value);
QRegExp mapRE1(QString::fromLatin1("unordered_map<%1, ?%2, ?std::hash<%3 ?>, ?std::equal_to<%4 ?>, ?%5\\s*>")
.arg(keyEsc, valueEsc, keyEsc, keyEsc, allocEsc));
mapRE1.setMinimal(true);
QTC_ASSERT(mapRE1.isValid(), return typeIn);
if (mapRE1.indexIn(type) != -1)
type.replace(mapRE1.cap(0), QString::fromLatin1("unordered_map<%1, %2>").arg(key, value));
}
}
type.replace(QLatin1Char('@'), QLatin1Char('*'));
type.replace(QLatin1String(" >"), QLatin1String(">"));

View File

@@ -42,6 +42,8 @@ const char *description[] =
"g++_stringset",
"g++_stringvector",
"g++_wstringvector",
"g++_unordered_set",
"g++_unordered_map",
"libc++_stringvector",
"msvc_stdstring",
"msvc_stdwstring",
@@ -64,6 +66,10 @@ const char *input[] =
"std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >",
"std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >",
"std::vector<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > >",
"std::unordered_set<int, std::hash<int>, std::equal_to<int>, std::allocator<int> >",
"std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, int> > >",
// libc++
"std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >",
// MSVC
@@ -88,6 +94,8 @@ const char *output[] =
"std::set<std::string>",
"std::vector<std::string>",
"std::vector<std::wstring>",
"std::unordered_set<int>",
"std::unordered_map<int, int>",
// libc++
"std::vector<std::string>",
// MSVC

View File

@@ -2951,6 +2951,44 @@ void tst_Dumpers::dumper_data()
% Check("is", "", "std::ifstream")
% Check("ok", "true", "bool");
QTest::newRow("StdUnorderedMap1")
<< Data("#include <unordered_map>\n",
"std::unordered_map<unsigned int, unsigned int> map;\n"
"map[11] = 1;\n"
"map[22] = 2;\n")
% Check("map", "<2 items>", "std::unordered_map<unsigned int, unsigned int>")
% Cxx11Profile()
% Check("map.0", "[0] 22", "2", "unsigned int")
% Check("map.1", "[1] 11", "1", "unsigned int");
QTest::newRow("StdUnorderedMap2")
<< Data("#include <unordered_map>\n"
"#include <string>\n",
"std::unordered_map<std::string, float> map;\n"
"map[\"11.0\"] = 11.0;\n"
"map[\"22.0\"] = 22.0;\n")
% Cxx11Profile()
% Check("map", "<2 items>", "std::unordered_map<std::string, float>")
//% Check("map.0", "[0]", "", "std::pair<std:string const, float>")
% Check("map.0.first", "\"22.0\"", "std::string")
% Check("map.0.second", "22", "float")
//% Check("map.1", "[1]", "", "std::pair<std::string const, float>")
% Check("map.1.first", "\"11.0\"", "std::string")
% Check("map.1.second", "11", "float");
QTest::newRow("StdUnorderedSet1")
<< Data("#include <unordered_set>\n",
"std::unordered_set<int> set;\n"
"set.insert(11);\n"
"set.insert(22);\n"
"set.insert(33);\n")
% Cxx11Profile()
% Check("set", "<3 items>", "std::unordered_set<int>")
% Check("set.0", "[0]", "33", "int")
% Check("set.1", "[1]", "22", "int")
% Check("set.2", "[2]", "11", "int");
QTest::newRow("ItemModel")
<< Data("#include <QStandardItemModel>\n",
"QStandardItemModel m;\n"