forked from qt-creator/qt-creator
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:
@@ -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(',')
|
||||
|
@@ -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(">"));
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
Reference in New Issue
Block a user