diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp
index 13017b01baffc5387fddb95328ba21667415152e..5f039321de4045922534ecd47174ed04cb034abe 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.cpp
+++ b/share/qtcreator/gdbmacros/gdbmacros.cpp
@@ -40,6 +40,7 @@
 #include <QtCore/QMap>
 #include <QtCore/QMetaObject>
 #include <QtCore/QMetaProperty>
+#include <QtCore/QMetaEnum>
 #include <QtCore/QModelIndex>
 #include <QtCore/QObject>
 #include <QtCore/QPointer>
@@ -1786,9 +1787,8 @@ static void qDumpQMapNode(QDumper &d)
 
     d.putItem("value", "");
     d.putItem("numchild", 2);
+    InnerValueResult innerValueResult = InnerValueChildrenSpecified;
     if (d.dumpChildren) {
-        //unsigned keySize = d.extraInt[0];
-        //unsigned valueSize = d.extraInt[1];
         unsigned mapnodesize = d.extraInt[2];
         unsigned valueOff = d.extraInt[3];
 
@@ -1803,11 +1803,11 @@ static void qDumpQMapNode(QDumper &d)
         d.endHash();
         d.beginHash();
         d.putItem("name", "value");
-        qDumpInnerValue(d, valueType, addOffset(h, valueOffset));
+        innerValueResult = qDumpInnerValue(d, valueType, addOffset(h, valueOffset));
         d.endHash();
         d.endChildren();
     }
-
+    dumpChildNumChildren(d, innerValueResult);
     d.disarm();
 }
 
@@ -2163,21 +2163,25 @@ static void qDumpQVariant(QDumper &d, const QVariant *v)
         d.putItem("valueencoded", "5");
     }
     d.putItem("type", NS"QVariant");
-    d.putItem("numchild", (isInvalid ? "0" : "1"));
-    if (d.dumpChildren) {
-        d.beginChildren();
-        d.beginHash();
-        d.putItem("name", "value");
-        if (!exp.isEmpty())
-            d.putItem("exp", qPrintable(exp));
-        if (!value.isEmpty()) {
-            d.putItem("value", value);
-            d.putItem("valueencoded", "4");
+    if (isInvalid || !numchild) {
+        d.putItem("numchild", "0");
+    } else {
+        d.putItem("numchild", "1");
+        if (d.dumpChildren) {
+            d.beginChildren();
+            d.beginHash();
+            d.putItem("name", "value");
+            if (!exp.isEmpty())
+                d.putItem("exp", qPrintable(exp));
+            if (!value.isEmpty()) {
+                d.putItem("value", value);
+                d.putItem("valueencoded", "4");
+            }
+            d.putItem("type", v->typeName());
+            d.putItem("numchild", numchild);
+            d.endHash();
+            d.endChildren();
         }
-        d.putItem("type", v->typeName());
-        d.putItem("numchild", numchild);
-        d.endHash();
-        d.endChildren();
     }
     d.disarm();
 }
@@ -2187,17 +2191,67 @@ static inline void qDumpQVariant(QDumper &d)
     qDumpQVariant(d, reinterpret_cast<const QVariant *>(d.data));
 }
 
+// Meta enumeration helpers
+static inline void dumpMetaEnumType(QDumper &d, const QMetaEnum &me)
+{
+    QByteArray type = me.scope();
+    if (!type.isEmpty())
+        type += "::";
+    type += me.name();
+    d.putItem("type", type.constData());
+}
+
+static inline void dumpMetaEnumValue(QDumper &d, const QMetaProperty &mop,
+                                     int value)
+{
+
+    const QMetaEnum me = mop.enumerator();
+    dumpMetaEnumType(d, me);
+    if (const char *enumValue = me.valueToKey(value)) {
+        d.putItem("value", enumValue);
+    } else {
+        d.putItem("value", value);
+    }
+    d.putItem("numchild", 0);
+}
+
+static inline void dumpMetaFlagValue(QDumper &d, const QMetaProperty &mop,
+                                     int value)
+{
+    const QMetaEnum me = mop.enumerator();
+    dumpMetaEnumType(d, me);
+    const QByteArray flagsValue = me.valueToKeys(value);
+    if (flagsValue.isEmpty()) {
+        d.putItem("value", value);
+    } else {
+        d.putItem("value", flagsValue.constData());
+    }
+    d.putItem("numchild", 0);
+}
+
 static void qDumpQObjectProperty(QDumper &d)
 {
     const QObject *ob = (const QObject *)d.data;
+    const QMetaObject *mob = ob->metaObject();
     // extract "local.Object.property"
     QString iname = d.iname;
     const int dotPos = iname.lastIndexOf(QLatin1Char('.'));
     if (dotPos == -1)
         return;
     iname.remove(0, dotPos + 1);
-    const QVariant v = ob->property(iname.toAscii().constData());
-    qDumpQVariant(d, &v);
+    const int index = mob->indexOfProperty(iname.toAscii());
+    if (index == -1)
+        return;
+    const QMetaProperty mop = mob->property(index);
+    const QVariant value = mop.read(ob);
+    const bool isInteger = value.type() == QVariant::Int;
+    if (isInteger && mop.isEnumType()) {
+        dumpMetaEnumValue(d, mop, value.toInt());
+    } else if (isInteger && mop.isFlagType()) {
+        dumpMetaFlagValue(d, mop, value.toInt());
+    } else {
+        qDumpQVariant(d, &value);
+    }
     d.disarm();
 }
 
@@ -2229,8 +2283,14 @@ static void qDumpQObjectPropertyList(QDumper &d)
                 d.putItem("numchild", "0");
                 break;
             case QVariant::Int:
-                d.putItem("value", prop.read(ob).toInt());
-                d.putItem("numchild", "0");
+                if (prop.isEnumType()) {
+                    dumpMetaEnumValue(d, prop, prop.read(ob).toInt());
+                } else if (prop.isFlagType()) {
+                    dumpMetaFlagValue(d, prop, prop.read(ob).toInt());
+                } else {
+                    d.putItem("value", prop.read(ob).toInt());
+                    d.putItem("numchild", "0");
+                }
                 break;
             default:
                 d.putItem("addr", d.data);
@@ -2312,7 +2372,7 @@ static inline void qDumpQObjectConnectionPart(QDumper &d,
     d.put(number).put(namePostfix);
     d.endItem();
     if (partner == owner) {
-        d.putItem("value", "<this>");
+        d.putItem("value", QLatin1String("<this>"));
         d.putItem("valueencoded", "2");
         d.putItem("type", owner->metaObject()->className());
         d.putItem("numchild", 0);
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index 12d78c0fc1c2bda8f004379244618371d580b543..098b30c86c580c6ce7baf7a6ee7066ec45bedd98 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
@@ -368,16 +368,42 @@ static inline bool isNullPointer(const WatchData &wd)
     return hexNullPattern.exactMatch(addr);
 }
 
+// Fix a symbol group value. It is set to the class type for
+// expandable classes (type="class std::foo<..>[*]",
+// value="std::foo<...>[*]". This is not desired
+// as it widens the value column for complex std::template types.
+// Remove the inner template type.
+
+static inline QString removeInnerTemplateType(QString value)
+{
+    const int firstBracketPos = value.indexOf(QLatin1Char('<'));
+    const int lastBracketPos = firstBracketPos != -1 ? value.lastIndexOf(QLatin1Char('>')) : -1;
+    if (lastBracketPos != -1)
+        value.replace(firstBracketPos + 1, lastBracketPos - firstBracketPos -1, QLatin1String("..."));
+    return value;
+}
+
+static inline QString fixValue(const QString &value)
+{
+    if (value.size() < 20 || value.endsWith(QLatin1Char('"')))
+        return value;
+    return removeInnerTemplateType(value);
+}
+
 WatchData CdbSymbolGroupContext::symbolAt(unsigned long index) const
 {
     WatchData wd;
     wd.iname = symbolINameAt(index);
     wd.exp = wd.iname;
     const int lastDelimiterPos = wd.iname.lastIndexOf(m_nameDelimiter);
-    wd.name = lastDelimiterPos == -1 ? wd.iname : wd.iname.mid(lastDelimiterPos + 1);
+    // For class hierarchies, we get sometimes complicated std::template types here.
+    // Remove them for display
+    wd.name = removeInnerTemplateType(lastDelimiterPos == -1 ? wd.iname : wd.iname.mid(lastDelimiterPos + 1));
     wd.addr = hexSymbolOffset(m_symbolGroup, index);
-    wd.setType(getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolTypeNameWide, index));
-    wd.setValue(getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolValueTextWide, index).toUtf8());
+    const QString type = getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolTypeNameWide, index);
+    const QString value = getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolValueTextWide, index);
+    wd.setType(type);
+    wd.setValue(fixValue(value));
     wd.setChildrenNeeded(); // compensate side effects of above setters
     // Figure out children. The SubElement is only a guess unless the symbol,
     // is expanded, so, we leave this as a guess for later updates.