From a31e8b446e8ac7e151036b4aee8e6a757f9efdfd Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Tue, 21 Aug 2012 13:39:53 +0200
Subject: [PATCH] CDB: Pass referenced address in separate GDBMI field.

Use 'origaddr' as gdb does. Do not append address to watch value
if it is already contained in the value.
Fixes the currently grayed-out 'Open memory editor at referenced
address'.

Change-Id: I6f7cf5b7984f93606ad4bb0872348f51c73f9117
Reviewed-by: hjk <qthjk@ovi.com>
---
 src/libs/qtcreatorcdbext/symbolgroupnode.cpp | 22 +++++++++++++++++---
 src/plugins/debugger/watchhandler.cpp        |  9 ++++++--
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp
index 278fc81e5c2..394ce43cc63 100644
--- a/src/libs/qtcreatorcdbext/symbolgroupnode.cpp
+++ b/src/libs/qtcreatorcdbext/symbolgroupnode.cpp
@@ -1066,8 +1066,25 @@ int SymbolGroupNode::dumpNode(std::ostream &str,
     const std::string watchExp = t.empty() ? aName : watchExpression(addr, t, m_dumperType, m_module);
     SymbolGroupNode::dumpBasicData(str, aName, aFullIName, t, watchExp);
 
-    if (addr)
-        str << ",addr=\"" << std::hex << std::showbase << addr << std::noshowbase << std::dec << '"';
+    std::wstring value = simpleDumpValue(ctx);
+
+    if (addr) {
+        ULONG64 referencedAddr = 0;
+        // Determine referenced address of pointers?
+        if (!value.compare(0, 2u, L"0x")) {
+            std::wistringstream str(value.substr(2u, value.size() - 2u));
+            str >> std::hex >> referencedAddr;
+        }
+        // Emulate gdb's behaviour of returning the referenced address
+        // for pointers.
+        str << std::hex << std::showbase;
+        if (referencedAddr) {
+            str << ",addr=\"" << referencedAddr << "\",origaddr=\"" << addr << '"';
+        } else {
+            str << ",addr=\"" << addr << '"';
+        }
+        str << std::noshowbase << std::dec;
+    }
     const ULONG s = size();
     if (s)
         str << ",size=\"" << s << '"';
@@ -1076,7 +1093,6 @@ int SymbolGroupNode::dumpNode(std::ostream &str,
     bool valueEnabled = !uninitialized;
 
     // Shall it be recoded?
-    std::wstring value = simpleDumpValue(ctx);
     int encoding = 0;
     if (dumpParameters.recode(t, aFullIName, ctx, addr, &value, &encoding)) {
         str << ",valueencoded=\"" << encoding
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index d9a2e7548a5..1805d6e5898 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -955,9 +955,14 @@ QString WatchModel::display(const WatchItem *item, int col) const
         case 1:
             result = removeInitialNamespace(
                 truncateValue(formattedValue(*item)));
+            // Append referencing address unless the value contains it.
             if (item->referencingAddress) {
-                result += QLatin1String(" @");
-                result += QString::fromLatin1(item->hexReferencingAddress());
+                if (result.startsWith(QLatin1String("0x"))) {
+                    result.prepend(QLatin1Char('@'));
+                } else {
+                    result += QLatin1String(" @");
+                    result += QString::fromLatin1(item->hexReferencingAddress());
+                }
             }
             break;
         case 2:
-- 
GitLab