From 353025f37fcc1730b428a2871fa49d1a805f65c7 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 9 Apr 2009 13:47:54 +0200 Subject: [PATCH] debugger: potential fix for cases where the std:: namespace is not reported properly --- share/qtcreator/gdbmacros/gdbmacros.cpp | 29 +++++++-- src/plugins/debugger/gdbengine.cpp | 12 ++-- src/plugins/debugger/watchhandler.cpp | 83 +++++++++++++++++++------ 3 files changed, 96 insertions(+), 28 deletions(-) diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index 80ab420c5fa..e688fa3fa28 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -2396,6 +2396,10 @@ static void handleProtocolVersion2and3(QDumper & d) const char *type = stripNamespace(d.outertype); // type[0] is usally 'Q', so don't use it switch (type[1]) { + case 'a': + if (isEqual(type, "map")) + qDumpStdMap(d); + break; case 'B': if (isEqual(type, "QByteArray")) qDumpQByteArray(d); @@ -2406,6 +2410,12 @@ static void handleProtocolVersion2and3(QDumper & d) else if (isEqual(type, "QDir")) qDumpQDir(d); break; + case 'e': + if (isEqual(type, "vector")) + qDumpStdVector(d); + else if (isEqual(type, "set")) + qDumpStdSet(d); + break; case 'F': if (isEqual(type, "QFile")) qDumpQFile(d); @@ -2418,6 +2428,10 @@ static void handleProtocolVersion2and3(QDumper & d) else if (isEqual(type, "QHashNode")) qDumpQHashNode(d); break; + case 'i': + if (isEqual(type, "list")) + qDumpStdList(d); + break; case 'I': if (isEqual(type, "QImage")) qDumpQImage(d); @@ -2545,18 +2559,18 @@ void qDumpObjectData440( "\""NS"QMap\"," "\""NS"QMapNode\"," "\""NS"QModelIndex\"," - #if QT_VERSION >= 0x040500 +#if QT_VERSION >= 0x040500 "\""NS"QMultiMap\"," - #endif +#endif "\""NS"QObject\"," "\""NS"QObjectMethodList\"," // hack to get nested properties display "\""NS"QObjectPropertyList\"," - #if PRIVATE_OBJECT_ALLOWED +#if PRIVATE_OBJECT_ALLOWED "\""NS"QObjectSignal\"," "\""NS"QObjectSignalList\"," "\""NS"QObjectSlot\"," "\""NS"QObjectSlotList\"," - #endif // PRIVATE_OBJECT_ALLOWED +#endif // PRIVATE_OBJECT_ALLOWED // << "\""NS"QRegion\"," "\""NS"QSet\"," "\""NS"QString\"," @@ -2565,8 +2579,15 @@ void qDumpObjectData440( "\""NS"QVariant\"," "\""NS"QVector\"," "\""NS"QWidget\"," +#ifdef Q_OS_WIN + "\"basic_string\"," + "\"list\"," + "\"map\"," + "\"set\"," "\"string\"," + "\"vector\"," "\"wstring\"," +#endif "\"std::basic_string\"," "\"std::list\"," "\"std::map\"," diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 906b38a72b1..9d2d69220a7 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -3027,7 +3027,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren) } else if (outertype == m_namespace + "QMapNode") { extraArgs[2] = sizeofTypeExpression(data.type); extraArgs[3] = "(size_t)&(('" + data.type + "'*)0)->value"; - } else if (outertype == "std::vector") { + } else if (outertype == "std::vector" || outertype == "vector") { //qDebug() << "EXTRACT TEMPLATE: " << outertype << inners; if (inners.at(0) == "bool") { outertype = "std::vector::bool"; @@ -3035,18 +3035,18 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren) //extraArgs[extraArgCount++] = sizeofTypeExpression(data.type); //extraArgs[extraArgCount++] = "(size_t)&(('" + data.type + "'*)0)->value"; } - } else if (outertype == "std::deque") { + } else if (outertype == "std::deque" || outertype == "deque") { // remove 'std::allocator<...>': extraArgs[1] = "0"; - } else if (outertype == "std::stack") { + } else if (outertype == "std::stack" || outertype == "stack") { // remove 'std::allocator<...>': extraArgs[1] = "0"; - } else if (outertype == "std::set") { + } else if (outertype == "std::set" || outertype == "set") { // remove 'std::less<...>': extraArgs[1] = "0"; // remove 'std::allocator<...>': extraArgs[2] = "0"; - } else if (outertype == "std::map") { + } else if (outertype == "std::map" || outertype == "map") { // We don't want the comparator and the allocator confuse gdb. // But we need the offset of the second item in the value pair. // We read the type of the pair from the allocator argument because @@ -3057,7 +3057,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren) pairType = pairType.mid(15, pairType.size() - 15 - 2); extraArgs[2] = "(size_t)&(('" + pairType + "'*)0)->second"; extraArgs[3] = "0"; - } else if (outertype == "std::basic_string") { + } else if (outertype == "std::basic_string" || outertype == "basic_string") { //qDebug() << "EXTRACT TEMPLATE: " << outertype << inners; if (inners.at(0) == "char") { outertype = "std::string"; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 9ccfb791d62..bd5b799049e 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -356,54 +356,101 @@ WatchHandler::WatchHandler() SIGNAL(triggered()), this, SLOT(collapseChildren())); } +static QString chopConst(QString type) +{ + while (1) { + if (type.startsWith("const")) + type = type.mid(5); + else if (type.startsWith(' ')) + type = type.mid(1); + else if (type.endsWith("const")) + type.chop(5); + else if (type.endsWith(' ')) + type.chop(1); + else + break; + } + return type; +} + static QString niceType(QString type) { if (type.contains(QLatin1String("std::"))) { // std::string - type.replace(QLatin1String("std::basic_string, " - "std::allocator >"), QLatin1String("std::string")); + type.replace(QLatin1String("basic_string, " + "std::allocator >"), QLatin1String("string")); // std::wstring - type.replace(QLatin1String("std::basic_string, " - "std::allocator >"), QLatin1String("std::wstring")); + type.replace(QLatin1String("basic_string, " + "std::allocator >"), QLatin1String("wstring")); // std::vector - static QRegExp re1(QLatin1String("std::vector<(.*), std::allocator<(.*)>\\s*>")); + static QRegExp re1(QLatin1String("vector<(.*), std::allocator<(.*)>\\s*>")); re1.setMinimal(true); for (int i = 0; i != 10; ++i) { if (re1.indexIn(type) == -1 || re1.cap(1) != re1.cap(2)) break; - type.replace(re1.cap(0), QLatin1String("std::vector<") + re1.cap(1) + QLatin1Char('>')); + type.replace(re1.cap(0), QLatin1String("vector<") + re1.cap(1) + QLatin1Char('>')); + } + + // std::deque + static QRegExp re5(QLatin1String("deque<(.*), std::allocator<(.*)>\\s*>")); + re5.setMinimal(true); + for (int i = 0; i != 10; ++i) { + if (re5.indexIn(type) == -1 || re5.cap(1) != re5.cap(2)) + break; + type.replace(re5.cap(0), QLatin1String("deque<") + re5.cap(1) + QLatin1Char('>')); + } + + // std::stack + static QRegExp re6(QLatin1String("stack<(.*), std::deque<(.*), std::allocator<(.*)>\\s*> >")); + re6.setMinimal(true); + for (int i = 0; i != 10; ++i) { + if (re6.indexIn(type) == -1 || re6.cap(1) != re6.cap(2) + || re6.cap(1) != re6.cap(2)) + break; + type.replace(re6.cap(0), QLatin1String("stack<") + re6.cap(1) + QLatin1Char('>')); } // std::list - static QRegExp re2(QLatin1String("std::list<(.*), std::allocator<(.*)>\\s*>")); + static QRegExp re2(QLatin1String("list<(.*), std::allocator<(.*)>\\s*>")); re2.setMinimal(true); for (int i = 0; i != 10; ++i) { if (re2.indexIn(type) == -1 || re2.cap(1) != re2.cap(2)) break; - type.replace(re2.cap(0), QLatin1String("std::list<") + re2.cap(1) + QLatin1Char('>')); + type.replace(re2.cap(0), QLatin1String("list<") + re2.cap(1) + QLatin1Char('>')); } // std::map - static QRegExp re3(QLatin1String("std::map<(.*), (.*), std::less<(.*)\\s*>, " - "std::allocator > >")); - re3.setMinimal(true); - for (int i = 0; i != 10; ++i) { - if (re3.indexIn(type) == -1 || re3.cap(1) != re3.cap(3) - || re3.cap(1) != re3.cap(4) || re3.cap(2) != re3.cap(5)) - break; - type.replace(re3.cap(0), QLatin1String("std::map<") + re3.cap(1) + QLatin1String(", ") + re3.cap(2) + QLatin1Char('>')); + { + static QRegExp re(QLatin1String("map<(.*), (.*), std::less<(.*)>, " + "std::allocator > >")); + re.setMinimal(true); + for (int i = 0; i != 10; ++i) { + if (re.indexIn(type) == -1) + break; + QString key = chopConst(re.cap(1)); + QString value = chopConst(re.cap(2)); + QString key1 = chopConst(re.cap(3)); + QString key2 = chopConst(re.cap(4)); + QString value2 = chopConst(re.cap(5)); + if (value != value2 || key != key1 || key != key2) { + qDebug() << key << key1 << key2 << value << value2 + << (key == key1) << (key == key2) << (value == value2); + break; + } + type.replace(re.cap(0), QString("map<%1, %2>").arg(key).arg(value)); + } } // std::set - static QRegExp re4(QLatin1String("std::set<(.*), std::less<(.*)>, std::allocator<(.*)>\\s*>")); + static QRegExp re4(QLatin1String("set<(.*), std::less<(.*)>, std::allocator<(.*)>\\s*>")); re1.setMinimal(true); for (int i = 0; i != 10; ++i) { if (re4.indexIn(type) == -1 || re4.cap(1) != re4.cap(2) || re4.cap(1) != re4.cap(3)) break; - type.replace(re4.cap(0), QLatin1String("std::set<") + re4.cap(1) + QLatin1Char('>')); + type.replace(re4.cap(0), QLatin1String("set<") + re4.cap(1) + QLatin1Char('>')); } type.replace(QLatin1String(" >"), QString(QLatin1Char('>')));