diff options
author | hjk <hjk@theqtcompany.com> | 2016-06-03 15:58:19 +0200 |
---|---|---|
committer | hjk <hjk@theqtcompany.com> | 2016-06-06 09:17:14 +0000 |
commit | 023b78545f32caa634589eb25a6d5d5e64ce125c (patch) | |
tree | 9edab0b91be5d2881b399bbe94f9a5789e059921 | |
parent | b50e9e546f06162d25887d7a31021474abac1a52 (diff) | |
download | qt-creator-023b78545f32caa634589eb25a6d5d5e64ce125c.tar.gz |
Debugger: Revert parts of the 'arrayIndex' optimization
The parent's address is not always the base address of the array
data, but often a wrapper like QVector, so the correct computation
of the item's address is more involved, removing the benefits of
the optimization.
Change-Id: Iecb19799addc1502649fefbad0953b77947f4193
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r-- | src/plugins/debugger/watchdata.cpp | 147 | ||||
-rw-r--r-- | src/plugins/debugger/watchdata.h | 1 |
2 files changed, 79 insertions, 69 deletions
diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 9cc7f944fa..439b2fa33a 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -325,61 +325,75 @@ QString decodeItemHelper(const double &t) return QString::number(t, 'g', 16); } -template <class T> -void decodeArrayHelper(WatchItem *item, const QByteArray &rawData, int size, const QByteArray &childType) -{ - const QByteArray ba = QByteArray::fromHex(rawData); - const T *p = (const T *) ba.data(); - for (int i = 0, n = ba.size() / sizeof(T); i < n; ++i) { - WatchItem *child = new WatchItem; - child->arrayIndex = i; - child->value = decodeItemHelper(p[i]); - child->size = size; - child->type = childType; - child->setAllUnneeded(); - item->appendChild(child); +class ArrayDataDecoder +{ +public: + template <class T> + void decodeArrayHelper(int childSize) + { + const QByteArray ba = QByteArray::fromHex(rawData); + const T *p = (const T *) ba.data(); + for (int i = 0, n = ba.size() / sizeof(T); i < n; ++i) { + WatchItem *child = new WatchItem; + child->arrayIndex = i; + child->value = decodeItemHelper(p[i]); + child->size = childSize; + child->type = childType; + child->address = addrbase + i * addrstep; + child->valueEditable = true; + child->setAllUnneeded(); + item->appendChild(child); + } } -} -static void decodeArrayData(WatchItem *item, const QByteArray &rawData, - const DebuggerEncoding &encoding, const QByteArray &childType) -{ - switch (encoding.type) { - case DebuggerEncoding::HexEncodedSignedInteger: - switch (encoding.size) { - case 1: - return decodeArrayHelper<signed char>(item, rawData, encoding.size, childType); - case 2: - return decodeArrayHelper<short>(item, rawData, encoding.size, childType); - case 4: - return decodeArrayHelper<int>(item, rawData, encoding.size, childType); - case 8: - return decodeArrayHelper<qint64>(item, rawData, encoding.size, childType); - } - case DebuggerEncoding::HexEncodedUnsignedInteger: - switch (encoding.size) { - case 1: - return decodeArrayHelper<uchar>(item, rawData, encoding.size, childType); - case 2: - return decodeArrayHelper<ushort>(item, rawData, encoding.size, childType); - case 4: - return decodeArrayHelper<uint>(item, rawData, encoding.size, childType); - case 8: - return decodeArrayHelper<quint64>(item, rawData, encoding.size, childType); - } - break; - case DebuggerEncoding::HexEncodedFloat: - switch (encoding.size) { - case 4: - return decodeArrayHelper<float>(item, rawData, encoding.size, childType); - case 8: - return decodeArrayHelper<double>(item, rawData, encoding.size, childType); - } - default: - break; + void decode() + { + if (addrstep == 0) + addrstep = encoding.size; + switch (encoding.type) { + case DebuggerEncoding::HexEncodedSignedInteger: + switch (encoding.size) { + case 1: + return decodeArrayHelper<signed char>(encoding.size); + case 2: + return decodeArrayHelper<short>(encoding.size); + case 4: + return decodeArrayHelper<int>(encoding.size); + case 8: + return decodeArrayHelper<qint64>(encoding.size); + } + case DebuggerEncoding::HexEncodedUnsignedInteger: + switch (encoding.size) { + case 1: + return decodeArrayHelper<uchar>(encoding.size); + case 2: + return decodeArrayHelper<ushort>(encoding.size); + case 4: + return decodeArrayHelper<uint>(encoding.size); + case 8: + return decodeArrayHelper<quint64>(encoding.size); + } + break; + case DebuggerEncoding::HexEncodedFloat: + switch (encoding.size) { + case 4: + return decodeArrayHelper<float>(encoding.size); + case 8: + return decodeArrayHelper<double>(encoding.size); + } + default: + break; + } + qDebug() << "ENCODING ERROR: " << encoding.toString(); } - qDebug() << "ENCODING ERROR: " << encoding.toString(); -} + + WatchItem *item; + QByteArray rawData; + QByteArray childType; + DebuggerEncoding encoding; + quint64 addrbase; + quint64 addrstep; +}; static bool sortByName(const Utils::TreeItem *a, const Utils::TreeItem *b) { @@ -474,9 +488,14 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort) mi = input["arraydata"]; if (mi.isValid()) { - DebuggerEncoding encoding(input["arrayencoding"].data()); - QByteArray childType = input["childtype"].data(); - decodeArrayData(this, mi.data(), encoding, childType); + ArrayDataDecoder decoder; + decoder.item = this; + decoder.rawData = mi.data(); + decoder.childType = input["childtype"].data(); + decoder.addrbase = input["addrbase"].toAddress(); + decoder.addrstep = input["addrstep"].toAddress(); + decoder.encoding = DebuggerEncoding(input["arrayencoding"].data()); + decoder.decode(); } else { const GdbMi children = input["children"]; if (children.isValid()) { @@ -511,7 +530,8 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort) child->iname = this->iname + '.' + nn; if (addressStep) { child->address = addressBase + i * addressStep; - child->exp = "*(" + gdbQuoteTypes(child->type) + "*)" + child->hexAddress(); + child->exp = "*(" + gdbQuoteTypes(child->type) + "*)0x" + + QByteArray::number(child->address, 16); } QByteArray key = subinput["key"].data(); if (!key.isEmpty()) @@ -582,8 +602,8 @@ QString WatchItem::toToolTip() const } formatToolTipRow(str, tr("Value"), val); } - if (realAddress()) - formatToolTipRow(str, tr("Object Address"), formatToolTipAddress(realAddress())); + if (address) + formatToolTipRow(str, tr("Object Address"), formatToolTipAddress(address)); if (origaddr) formatToolTipRow(str, tr("Pointer Address"), formatToolTipAddress(origaddr)); if (arrayIndex >= 0) @@ -619,15 +639,6 @@ bool WatchItem::isInspect() const return iname.startsWith("inspect."); } -quint64 WatchItem::realAddress() const -{ - if (arrayIndex >= 0) { - if (const WatchItem *p = parentItem()) - return p->address + arrayIndex * size; - } - return address; -} - QByteArray WatchItem::internalName() const { if (arrayIndex >= 0) { @@ -648,7 +659,7 @@ QString WatchItem::expression() const { if (!exp.isEmpty()) return QString::fromLatin1(exp); - if (quint64 addr = realAddress()) { + if (quint64 addr = address) { if (!type.isEmpty()) return QString::fromLatin1("*(%1*)0x%2").arg(QLatin1String(type)).arg(addr, 0, 16); } diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h index 160117608a..2082cfd0f0 100644 --- a/src/plugins/debugger/watchdata.h +++ b/src/plugins/debugger/watchdata.h @@ -53,7 +53,6 @@ public: QString expression() const; QString realName() const; - quint64 realAddress() const; QByteArray internalName() const; QString toToolTip() const; |