From d918a320907f66598b1f7af8a71d6cb9964f0835 Mon Sep 17 00:00:00 2001
From: Eike Ziller <eike.ziller@digia.com>
Date: Mon, 28 Oct 2013 22:33:05 +0100
Subject: [PATCH] debugger: fix QHashNode dumper and QHashNode type check for
 Qt4

The previous workaround for the Qt 4 optimized int,uint,short,ushort
QHashNode wasn't working for the QHashNode dumper itself because of
unknown key type. Instead we first try to find the 'key' child directly,
if that fails we look for it in the second child (which would be the
anonymous union from the optimized hash node, which contains the key).

Also fix the expected type for QHashNode in the optimized case for Qt4

Change-Id: Ib48c2c0afec081ff38cd750c3d515a5e678e9661
Reviewed-by: hjk <hjk121@nokiamail.com>
---
 share/qtcreator/debugger/qttypes.py | 22 +++++++++----------
 tests/auto/debugger/tst_dumpers.cpp | 33 +++++++++++++++++++++++++----
 2 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py
index e28df11ea31..c585829cf33 100644
--- a/share/qtcreator/debugger/qttypes.py
+++ b/share/qtcreator/debugger/qttypes.py
@@ -541,10 +541,12 @@ def qdump__QHash(d, value):
                 it = nodePtr.dereference().cast(innerType)
                 with SubItem(d, i):
                     if isCompact:
-                        # cannot reference "key" directly because it is inside
-                        # anonymous union for (u)int key in Qt4
-                        keyAddress = d.addressOf(it) + d.ptrSize() # addr + QHashNode*
-                        d.putMapName(d.createValue(keyAddress, keyType))
+                        key = it["key"]
+                        if not key:
+                            # LLDB can't access directly since it's in anonymous union
+                            # for Qt4 optimized int keytype
+                            key = it[1]["key"]
+                        d.putMapName(key)
                         d.putItem(it["value"])
                         d.putType(valueType)
                     else:
@@ -553,17 +555,13 @@ def qdump__QHash(d, value):
 
 
 def qdump__QHashNode(d, value):
-    keyType = d.templateArgument(value.type, 0)
-    valueType = d.templateArgument(value.type, 1)
     key = value["key"]
+    if not key:
+        # LLDB can't access directly since it's in anonymous union
+        # for Qt4 optimized int keytype
+        key = value[1]["key"]
     val = value["value"]
-
-    #if d.isSimpleType(keyType) and d.isSimpleType(valueType):
-    #    d.putName(key)
-    #    d.putValue(val)
-    #else:
     d.putEmptyValue()
-
     d.putNumChild(2)
     if d.isExpanded():
         with Children(d):
diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp
index 2e6e1b3ed25..8cf8311e3a4 100644
--- a/tests/auto/debugger/tst_dumpers.cpp
+++ b/tests/auto/debugger/tst_dumpers.cpp
@@ -289,12 +289,25 @@ struct UnsubstitutedValue : Value
 
 struct Type
 {
-    Type() {}
-    Type(const char *str) : type(str) {}
-    Type(const QByteArray &ba) : type(ba) {}
+    Type() : version(0) {}
+    Type(const char *str) : type(str), version(0) {}
+    Type(const QByteArray &ba) : type(ba), version(0) {}
 
     bool matches(const QByteArray &actualType0, const Context &context) const
     {
+        if (context.qtVersion) {
+            if (version == 4) {
+                if (context.qtVersion < 0x40000 || context.qtVersion >= 0x50000) {
+                    //QWARN("Qt 4 specific case skipped");
+                    return true;
+                }
+            } else if (version == 5) {
+                if (context.qtVersion < 0x50000 || context.qtVersion >= 0x60000) {
+                    //QWARN("Qt 5 specific case skipped");
+                    return true;
+                }
+            }
+        }
         QByteArray actualType =
             CPlusPlus::simplifySTLType(QString::fromLatin1(actualType0)).toLatin1();
         actualType.replace(' ', "");
@@ -306,6 +319,17 @@ struct Type
         return actualType == expectedType;
     }
     QByteArray type;
+    int version;
+};
+
+struct Type4 : Type
+{
+    Type4(const QByteArray &ba) : Type(ba) { version = 4; }
+};
+
+struct Type5 : Type
+{
+    Type5(const QByteArray &ba) : Type(ba) { version = 5; }
 };
 
 enum DebuggerEngine
@@ -1420,7 +1444,8 @@ void tst_Dumpers::dumper_data()
                     "hash[22] = \"22.0\";\n")
                % CoreProfile()
                % Check("hash", "<1 items>", "@QHash<int, @QString>")
-               % Check("hash.0", "[0]", "", "@QHashNode<int, @QString>")
+               % Check("hash.0", "[0]", "", Type4("@QHashNode<@QString>"))
+               % Check("hash.0", "[0]", "", Type5("@QHashNode<int, @QString>"))
                % Check("hash.0.key", "22", "int")
                % Check("hash.0.value", "\"22.0\"", "@QString");
 
-- 
GitLab