From a2c83940889beef90f41aecc0417b2574ae234c7 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Thu, 11 Feb 2010 14:36:01 +0100
Subject: [PATCH] debugger: fix assignment to array members

---
 share/qtcreator/gdbmacros/dumper.py           | 14 +++++++---
 src/plugins/debugger/gdb/classicgdbengine.cpp | 11 ++++----
 src/plugins/debugger/gdb/gdbengine.cpp        | 27 ++++++++++++++-----
 src/plugins/debugger/gdb/gdbengine.h          |  1 +
 4 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index 486e4fc7503..24a9b4f0d4b 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -1058,7 +1058,7 @@ class Dumper:
                 self.childTypes.pop()
                 isHandled = True
 
-            # Fall back to plain pointer printing
+            # Fall back to plain pointer printing.
             if not isHandled:
                 #warn("GENERIC PLAIN POINTER: %s" % value.type)
                 self.putType(item.value.type)
@@ -1071,7 +1071,7 @@ class Dumper:
                     self.endChildren()
 
         else:
-            #warn("GENERIC STRUCT: %s" % value.type)
+            #warn("GENERIC STRUCT: %s" % item.value.type)
             #warn("INAME: %s " % item.iname)
             #warn("INAMES: %s " % self.expandedINames)
             #warn("EXPANDED: %s " % (item.iname in self.expandedINames))
@@ -1094,6 +1094,14 @@ class Dumper:
             self.putNumChild(numfields)
 
             if self.isExpanded(item):
+                if value.type.code == gdb.TYPE_CODE_ARRAY:
+                    baseptr = value.cast(value.type.target().pointer())
+                    charptr = gdb.lookup_type("unsigned char").pointer()
+                    addr1 = (baseptr+1).cast(charptr)
+                    addr0 = baseptr.cast(charptr)
+                    self.putField("addrbase", cleanAddress(addr0))
+                    self.putField("addrstep", addr1 - addr0)
+
                 innerType = None
                 if len(fields) == 1 and fields[0].name is None:
                     innerType = value.type.target()
@@ -1117,7 +1125,7 @@ class Dumper:
                             p = p + 1
                         continue
 
-                    # ignore vtable pointers for virtual inheritance
+                    # Ignore vtable pointers for virtual inheritance.
                     if field.name.startswith("_vptr."):
                         continue
 
diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp
index 0e5dc3eca85..dc226b6bbc9 100644
--- a/src/plugins/debugger/gdb/classicgdbengine.cpp
+++ b/src/plugins/debugger/gdb/classicgdbengine.cpp
@@ -734,7 +734,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
     QByteArray exp = item.findChild("exp").data();
     QByteArray name = item.findChild("name").data();
     if (isAccessSpecifier(exp)) {
-        // suppress 'private'/'protected'/'public' level
+        // Suppress 'private'/'protected'/'public' level.
         WatchData data;
         data.variable = name;
         data.iname = parent.iname;
@@ -744,13 +744,13 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
         data.setValueUnneeded();
         data.setHasChildrenUnneeded();
         data.setChildrenUnneeded();
-        //qDebug() << "DATA" << data.toString();
         QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
         //iname += '.' + exp;
         postCommand(cmd, WatchUpdate,
             CB(handleVarListChildrenClassic), QVariant::fromValue(data));
-    } else if (item.findChild("numchild").data() == "0") {
-        // happens for structs without data, e.g. interfaces.
+    } else if (!startsWithDigit(exp)
+            && item.findChild("numchild").data() == "0") {
+        // Happens for structs without data, e.g. interfaces.
         WatchData data;
         data.name = _(exp);
         data.iname = parent.iname + '.' + data.name.toLatin1();
@@ -762,7 +762,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
         data.setHasChildren(false);
         insertData(data);
     } else if (parent.iname.endsWith('.')) {
-        // Happens with anonymous unions
+        // Happens with anonymous unions.
         WatchData data;
         data.iname = name;
         QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
@@ -775,6 +775,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
         // special "clever" hack to avoid clutter in the GUI.
         // I am not sure this is a good idea...
     } else {
+        // Suppress 'private'/'protected'/'public' level.
         WatchData data;
         data.iname = parent.iname + '.' + exp;
         data.variable = name;
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 3d458f8d924..79ba31c3f15 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -3074,11 +3074,15 @@ void GdbEngine::setWatchDataExpression(WatchData &data, const GdbMi &mi)
 
 void GdbEngine::setWatchDataAddress(WatchData &data, const GdbMi &mi)
 {
-    if (mi.isValid()) {
-        data.addr = mi.data();
-        if (data.exp.isEmpty() && !data.addr.startsWith("$"))
-            data.exp = "*(" + gdbQuoteTypes(data.type).toLatin1() + "*)" + data.addr;
-    }
+    if (mi.isValid())
+        setWatchDataAddressHelper(data, mi.data());
+}
+
+void GdbEngine::setWatchDataAddressHelper(WatchData &data, const QByteArray &addr)
+{
+    data.addr = addr;
+    if (data.exp.isEmpty() && !data.addr.startsWith("$"))
+        data.exp = "*(" + gdbQuoteTypes(data.type).toLatin1() + "*)" + data.addr;
 }
 
 void GdbEngine::setWatchDataSAddress(WatchData &data, const GdbMi &mi)
@@ -3319,11 +3323,11 @@ void GdbEngine::handleChildren(const WatchData &data0, const GdbMi &item,
     }
     setWatchDataType(data, item.findChild("type"));
     setWatchDataEditValue(data, item.findChild("editvalue"));
-    setWatchDataExpression(data, item.findChild("exp"));
     setWatchDataChildCount(data, item.findChild("numchild"));
     setWatchDataValue(data, item.findChild("value"),
         item.findChild("valueencoded").data().toInt());
     setWatchDataAddress(data, item.findChild("addr"));
+    setWatchDataExpression(data, item.findChild("exp"));
     setWatchDataSAddress(data, item.findChild("saddr"));
     setWatchDataValueToolTip(data, item.findChild("valuetooltip"),
         item.findChild("valuetooltipencoded").data().toInt());
@@ -3332,7 +3336,11 @@ void GdbEngine::handleChildren(const WatchData &data0, const GdbMi &item,
     //qDebug() << "\nAPPEND TO LIST: " << data.toString() << "\n";
     list->append(data);
 
-    // try not to repeat data too often
+    bool ok = false;
+    qulonglong addressBase = item.findChild("addrbase").data().toULongLong(&ok, 0);
+    qulonglong addressStep = item.findChild("addrstep").data().toULongLong();
+
+    // Try not to repeat data too often.
     WatchData childtemplate;
     setWatchDataType(childtemplate, item.findChild("childtype"));
     setWatchDataChildCount(childtemplate, item.findChild("childnumchild"));
@@ -3353,6 +3361,11 @@ void GdbEngine::handleChildren(const WatchData &data0, const GdbMi &item,
             data1.iname = data.iname + '.' + data1.name.toLatin1();
         if (!data1.name.isEmpty() && data1.name.at(0).isDigit())
             data1.name = _c('[') + data1.name + _c(']');
+        if (addressStep) {
+            const QByteArray addr = "0x" + QByteArray::number(addressBase, 16);
+            setWatchDataAddressHelper(data1, addr);
+            addressBase += addressStep;
+        }
         QByteArray key = child.findChild("key").data();
         if (!key.isEmpty()) {
             int encoding = child.findChild("keyencoded").data().toInt();
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 59dc952e84a..1c127a5dbb5 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -520,6 +520,7 @@ private: ////////// Convenience Functions //////////
     static void setWatchDataValueEditable(WatchData &data, const GdbMi &mi);
     static void setWatchDataExpression(WatchData &data, const GdbMi &mi);
     static void setWatchDataAddress(WatchData &data, const GdbMi &mi);
+    static void setWatchDataAddressHelper(WatchData &data, const QByteArray &addr);
     static void setWatchDataSAddress(WatchData &data, const GdbMi &mi);
 };
 
-- 
GitLab