diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp
index 5cd7ed519ce9210042b5fc4cffdf997d76fff0ec..6277c5477cda6ddea509e1bd34dfdd7c981f382f 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.cpp
+++ b/share/qtcreator/gdbmacros/gdbmacros.cpp
@@ -32,6 +32,9 @@
 // this relies on contents copied from qobject_p.h
 #define PRIVATE_OBJECT_ALLOWED 1
 
+#ifdef HAS_QOBJECT_P_H
+#    include <QtCore/private/qobject_p.h>
+#endif
 #include <QtCore/QDateTime>
 #include <QtCore/QDebug>
 #include <QtCore/QDir>
@@ -146,8 +149,7 @@ int qtGhVersion = QT_VERSION;
 #   define NSY ""
 #endif
 
-
-#if PRIVATE_OBJECT_ALLOWED
+#if PRIVATE_OBJECT_ALLOWED && !HAS_QOBJECT_P_H
 
 #if defined(QT_BEGIN_NAMESPACE)
 QT_BEGIN_NAMESPACE
@@ -1532,6 +1534,13 @@ static void qDumpQObject(QDumper &d)
     const QObject *ob = reinterpret_cast<const QObject *>(d.data);
     const QMetaObject *mo = ob->metaObject();
     unsigned childrenOffset = d.extraInt[0];
+#ifdef HAS_QOBJECT_P_H
+    // QObject child offset if known
+    if (!childrenOffset) {
+        QObjectPrivate qop;
+        childrenOffset = (char*)&qop.children - (char*)&qop;
+    }
+#endif
     P(d, "value", ob->objectName());
     P(d, "valueencoded", "2");
     P(d, "type", NS"QObject");
@@ -1588,7 +1597,8 @@ static void qDumpQObject(QDumper &d)
             P(d, "numchild", slotCount);
         d.endHash();
 #endif
-        d.beginHash();
+        if (childrenOffset) {
+            d.beginHash();
             P(d, "name", "children");
             // works always, but causes additional traffic on the list
             //P(d, "exp", "((class '"NS"QObject'*)" << d.data << ")->children()");
@@ -1597,9 +1607,10 @@ static void qDumpQObject(QDumper &d)
             //P(d, "type", NS"QList<QObject *>");
             //P(d, "value", "<" << children.size() << " items>");
             qDumpInnerValue(d, NS"QList<"NS"QObject *>",
-                addOffset(dfunc(ob), childrenOffset));
+                            addOffset(dfunc(ob), childrenOffset));
             P(d, "numchild", children.size());
-        d.endHash();
+            d.endHash();
+        }
 #if 0
         // Unneeded (and not working): Connections are listes as childen
         // of the signal or slot they are connected to.
diff --git a/share/qtcreator/gdbmacros/gdbmacros.pro b/share/qtcreator/gdbmacros/gdbmacros.pro
index 00c7b2403c86cb10f52722974615476d4774e784..5aacbfb84ad759718f92dddc19d227548bd063eb 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.pro
+++ b/share/qtcreator/gdbmacros/gdbmacros.pro
@@ -5,3 +5,7 @@ CONFIG -= release
 CONFIG += debug
 }
 SOURCES=gdbmacros.cpp
+
+exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h) {
+   DEFINES+=HAS_QOBJECT_P_H
+}
diff --git a/share/qtcreator/gdbmacros/test/dumpertest.pro b/share/qtcreator/gdbmacros/test/dumpertest.pro
index 6f59409d5caaf8591bbda0ff08e9dbb3b86de022..7b5fd3e582aacb2283b2679439b70968524b020e 100644
--- a/share/qtcreator/gdbmacros/test/dumpertest.pro
+++ b/share/qtcreator/gdbmacros/test/dumpertest.pro
@@ -14,3 +14,8 @@ TEMPLATE = app
 
 SOURCES += main.cpp \
 ../gdbmacros.cpp
+
+exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h) {
+   DEFINES+=HAS_QOBJECT_P_H
+}
+
diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp
index ae56cb0955f78e0f3e23a261d615794775c3cc12..f760e40aa980b9329349d5cf47a5fb65bd2cec3a 100644
--- a/share/qtcreator/gdbmacros/test/main.cpp
+++ b/share/qtcreator/gdbmacros/test/main.cpp
@@ -133,6 +133,17 @@ static int dumpStdString()
     return 0;
 }
 
+static int dumpStdWString()
+{
+    std::wstring test = L"hallo";
+    prepareInBuffer("std::wstring", "local.wstring", "local.wstring", "");
+    qDumpObjectData440(2, 42, &test, 1, 0, 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+
 static int dumpStdStringList()
 {
     std::list<std::string> test;
@@ -145,6 +156,18 @@ static int dumpStdStringList()
     return 0;
 }
 
+static int dumpStdStringQList()
+{
+    QList<std::string> test;
+    test.push_back("item1");
+    test.push_back("item2");
+    prepareInBuffer("QList", "local.stringqlist", "local.stringqlist", "std::string");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
 static int dumpStdIntList()
 {
     std::list<int> test;
@@ -169,11 +192,28 @@ static int dumpStdIntVector()
     return 0;
 }
 
+static int dumpStdStringVector()
+{
+    std::vector<std::string> test;
+    test.push_back("item1");
+    test.push_back("item2");
+    prepareInBuffer("std::vector", "local.stringvector", "local.stringvector", "std::string");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), sizeof(std::list<int>::allocator_type), 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+
 static int dumpQObject()
 {
     QTimer t;
     QObjectPrivate *tp = reinterpret_cast<QObjectPrivate *>(&t);
+#ifdef KNOWS_OFFSET
     const int childOffset = (char*)&tp->children - (char*)tp;
+#else
+    const int childOffset = 0;
+#endif
     printf("Qt version %s Child offset: %d\n", QT_VERSION_STR, childOffset);
     prepareInBuffer("QObject", "local.qobject", "local.qobject", "");
     qDumpObjectData440(2, 42, &t, 1, childOffset, 0, 0, 0);
@@ -200,16 +240,22 @@ int main(int argc, char *argv[])
             dumpQStringList();
         if (!qstrcmp(arg, "QList<int>"))
             dumpQIntList();
+        if (!qstrcmp(arg, "QList<std::string>"))
+            dumpStdStringQList();
         if (!qstrcmp(arg, "QVector<int>"))
             dumpQIntVector();
         if (!qstrcmp(arg, "string"))
             dumpStdString();
+        if (!qstrcmp(arg, "wstring"))
+            dumpStdWString();
         if (!qstrcmp(arg, "list<int>"))
             dumpStdIntList();
         if (!qstrcmp(arg, "list<string>"))
             dumpStdStringList();
         if (!qstrcmp(arg, "vector<int>"))
             dumpStdIntVector();
+        if (!qstrcmp(arg, "vector<string>"))
+            dumpStdStringVector();
         if (!qstrcmp(arg, "QObject"))
             dumpQObject();
     }
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 27b4fe2551b48f9a491c99f6966d4bf8b9965779..5693c2c2159adfa034117f184ca3df28b498b724 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -367,7 +367,9 @@ QString decodeData(const QByteArray &ba, int encoding)
 // --------------- QtDumperResult
 
 QtDumperResult::Child::Child() :
-   valueEncoded(0)
+   valueEncoded(0),
+   childCount(0),
+   valuedisabled(false)
 {
 }
 
@@ -385,6 +387,7 @@ void QtDumperResult::clear()
     value.clear();
     address.clear();
     type.clear();
+    displayedType.clear();
     valueEncoded = 0;
     valuedisabled = false;
     childCount = 0;
@@ -403,7 +406,7 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const
     const int lastDotIndex = root.iname.lastIndexOf(dot);
     root.exp = root.name = lastDotIndex == -1 ? iname : iname.mid(lastDotIndex + 1);
     root.setValue(decodeData(value, valueEncoded));
-    root.setType(type);
+    root.setType(displayedType.isEmpty() ? type : displayedType);
     root.valuedisabled = valuedisabled;
     root.setAddress(address);
     root.source = source;
@@ -419,8 +422,10 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const
                 wchild.iname = iname;
                 wchild.iname += dot;
                 wchild.iname += dchild.name;                
-                wchild.exp = wchild.name = dchild.name;
-                wchild.setType(childType);
+                wchild.name = dchild.name;
+                wchild.exp = dchild.exp;
+                wchild.valuedisabled = dchild.valuedisabled;
+                wchild.setType(dchild.type.isEmpty() ? childType : dchild.type);
                 wchild.setAddress(dchild.address);
                 wchild.setValue(decodeData(dchild.value, dchild.valueEncoded));
                 wchild.setChildCount(0);
@@ -436,19 +441,23 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const
 QDebug operator<<(QDebug in, const QtDumperResult &d)
 {
     QDebug nospace = in.nospace();
-    nospace << " iname=" << d.iname << " type=" << d.type << " address=" << d.address
+    nospace << " iname=" << d.iname << " type=" << d.type << " displayed=" << d.displayedType
+            << " address=" << d.address
             << " value="  << d.value
             << " disabled=" << d.valuedisabled
             << " encoded=" << d.valueEncoded << " internal=" << d.internal;
-    if (d.childCount) {
-        nospace << " childCount=" << d.childCount
+    const int realChildCount = d.children.size();
+    if (d.childCount || realChildCount) {
+        nospace << " childCount=" << d.childCount << '/' << realChildCount
                 << " childType=" << d.childType << '\n';
-        const int childCount = d.children.size();
-        for (int i = 0; i < childCount; i++) {
+        for (int i = 0; i < realChildCount; i++) {
             const QtDumperResult::Child &c = d.children.at(i);
             nospace << "   #" << i << " addr=" << c.address
+                    << " disabled=" << c.valuedisabled
+                    << " type=" << c.type
                     << " name=" << c.name << " encoded=" << c.valueEncoded
-                    << " value=" << c.value << '\n';
+                    << " value=" << c.value
+                    << "childcount=" << c.childCount << '\n';
         }
     }
     return in;
@@ -602,8 +611,6 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s)
 bool QtDumperHelper::needsExpressionSyntax(Type t)
 {
     switch (t) {
-        case QObjectType:
-        case QWidgetType:
         case QObjectSlotType:
         case QObjectSignalType:
         case QMapType:
@@ -1064,12 +1071,14 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
     switch (td.type) {
     case QObjectType:
     case QWidgetType:
-        extraArgs[0] = QLatin1String("(char*)&((('");
-        extraArgs[0] += m_qtNamespace;
-        extraArgs[0] += QLatin1String("QObjectPrivate'*)&");
-        extraArgs[0] += data.exp;
-        extraArgs[0] += QLatin1String(")->children)-(char*)&");
-        extraArgs[0] += data.exp;
+        if (debugger == GdbDebugger) {
+            extraArgs[0] = QLatin1String("(char*)&((('");
+            extraArgs[0] += m_qtNamespace;
+            extraArgs[0] += QLatin1String("QObjectPrivate'*)&");
+            extraArgs[0] += data.exp;
+            extraArgs[0] += QLatin1String(")->children)-(char*)&");
+            extraArgs[0] += data.exp;
+        }
         break;
     case QVectorType:
         extraArgs[1] = QLatin1String("(char*)&((");
@@ -1201,13 +1210,16 @@ protected:
 
 private:
     enum Mode { None, ExpectingIName, ExpectingAddress, ExpectingValue,
-                ExpectingType, ExpectingInternal,
+                ExpectingType, ExpectingDisplayedType, ExpectingInternal,
                 ExpectingValueDisabled,  ExpectingValueEncoded,
-                ExpectingChildType, ExpectingChildCount,
+                ExpectingCommonChildType, ExpectingChildCount,
                 IgnoreNext,
                 ChildModeStart,
                 ExpectingChildren,ExpectingChildName, ExpectingChildAddress,
-                ExpectingChildValue, ExpectingChildValueEncoded  };
+                ExpectingChildExpression, ExpectingChildType,
+                ExpectingChildValue, ExpectingChildValueEncoded,
+                ExpectingChildValueDisabled, ExpectingChildChildCount
+              };
 
     static inline Mode nextMode(Mode in, const char *keyword, int size);
 
@@ -1226,11 +1238,15 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
 {
     // Careful with same prefix
     switch (size) {
+    case 3:
+        if (!qstrncmp(keyword, "exp", size))
+            return ExpectingChildExpression;
+        break;
     case 4:
         if (!qstrncmp(keyword, "addr", size))
             return in > ChildModeStart ? ExpectingChildAddress : ExpectingAddress;
         if (!qstrncmp(keyword, "type", size))
-            return ExpectingType;
+            return in > ChildModeStart ? ExpectingChildType : ExpectingType;
         if (!qstrncmp(keyword, "name", size))
             return ExpectingChildName;
         break;
@@ -1244,13 +1260,13 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
         if (!qstrncmp(keyword, "children", size))
             return ExpectingChildren;
         if (!qstrncmp(keyword, "numchild", size))
-            return ExpectingChildCount;
+            return in > ChildModeStart ?  ExpectingChildChildCount : ExpectingChildCount;
         if (!qstrncmp(keyword, "internal", size))
             return ExpectingInternal;
         break;
     case 9:
         if (!qstrncmp(keyword, "childtype", size))
-            return ExpectingChildType;
+            return ExpectingCommonChildType;
         break;    
     case 12:
         if (!qstrncmp(keyword, "valueencoded", size))
@@ -1258,7 +1274,9 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
         break;
     case 13:
         if (!qstrncmp(keyword, "valuedisabled", size))
-            return ExpectingValueDisabled;
+            return in > ChildModeStart ? ExpectingChildValueDisabled : ExpectingValueDisabled;
+        if (!qstrncmp(keyword, "displayedtype", size))
+            return ExpectingDisplayedType;
         if (!qstrncmp(keyword, "childnumchild", size))
             return IgnoreNext;
         break;
@@ -1306,10 +1324,13 @@ bool ValueDumperParser::handleValue(const char *k, int size)
     case ExpectingType:
         m_result.type = QString::fromLatin1(valueBA);
         break;
+    case ExpectingDisplayedType:
+        m_result.displayedType = QString::fromLatin1(valueBA);
+        break;
     case ExpectingInternal:
         m_result.internal = valueBA == "true";
         break;
-    case ExpectingChildType:
+    case ExpectingCommonChildType:
         m_result.childType = QString::fromLatin1(valueBA);
         break;
     case ExpectingChildCount:
@@ -1327,9 +1348,21 @@ bool ValueDumperParser::handleValue(const char *k, int size)
     case ExpectingChildValue:
         m_result.children.back().value = valueBA;
         break;
+    case ExpectingChildExpression:
+        m_result.children.back().exp = QString::fromLatin1(valueBA);
+        break;
     case ExpectingChildValueEncoded:
         m_result.children.back().valueEncoded = QString::fromLatin1(valueBA).toInt();
         break;
+    case ExpectingChildValueDisabled:
+        m_result.children.back().valuedisabled = valueBA == "true";
+        break;
+    case ExpectingChildType:
+        m_result.children.back().type = QString::fromLatin1(valueBA);
+        break;
+    case ExpectingChildChildCount:
+        m_result.children.back().childCount = QString::fromLatin1(valueBA).toInt();
+        break;
     }
     return true;
 }
@@ -1340,6 +1373,9 @@ bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r)
     if (!parser.run())
         return false;
     *r = parser.result();
+    // Sanity
+    if (r->childCount < r->children.size())
+        r->childCount  = r->children.size();
     return true;
 }
 
diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h
index 47f73a8bb79cf8e1fbf418887c961d1d782bb0bf..af0a20c3b7c66299f5eba4112996b6fa883517c7 100644
--- a/src/plugins/debugger/watchutils.h
+++ b/src/plugins/debugger/watchutils.h
@@ -76,8 +76,12 @@ struct QtDumperResult
         Child();
 
         int valueEncoded;
+        int childCount;
+        bool valuedisabled;
         QString name;
         QString address;
+        QString exp;
+        QString type;
         QByteArray value;
     };
 
@@ -88,6 +92,7 @@ struct QtDumperResult
     QString iname;
     QString address;
     QString type;
+    QString displayedType;
     QByteArray value;
     int valueEncoded;
     bool valuedisabled;