forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -325,8 +325,11 @@ QString decodeItemHelper(const double &t)
|
|||||||
return QString::number(t, 'g', 16);
|
return QString::number(t, 'g', 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ArrayDataDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
template <class T>
|
template <class T>
|
||||||
void decodeArrayHelper(WatchItem *item, const QByteArray &rawData, int size, const QByteArray &childType)
|
void decodeArrayHelper(int childSize)
|
||||||
{
|
{
|
||||||
const QByteArray ba = QByteArray::fromHex(rawData);
|
const QByteArray ba = QByteArray::fromHex(rawData);
|
||||||
const T *p = (const T *) ba.data();
|
const T *p = (const T *) ba.data();
|
||||||
@@ -334,46 +337,49 @@ void decodeArrayHelper(WatchItem *item, const QByteArray &rawData, int size, con
|
|||||||
WatchItem *child = new WatchItem;
|
WatchItem *child = new WatchItem;
|
||||||
child->arrayIndex = i;
|
child->arrayIndex = i;
|
||||||
child->value = decodeItemHelper(p[i]);
|
child->value = decodeItemHelper(p[i]);
|
||||||
child->size = size;
|
child->size = childSize;
|
||||||
child->type = childType;
|
child->type = childType;
|
||||||
|
child->address = addrbase + i * addrstep;
|
||||||
|
child->valueEditable = true;
|
||||||
child->setAllUnneeded();
|
child->setAllUnneeded();
|
||||||
item->appendChild(child);
|
item->appendChild(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decodeArrayData(WatchItem *item, const QByteArray &rawData,
|
void decode()
|
||||||
const DebuggerEncoding &encoding, const QByteArray &childType)
|
|
||||||
{
|
{
|
||||||
|
if (addrstep == 0)
|
||||||
|
addrstep = encoding.size;
|
||||||
switch (encoding.type) {
|
switch (encoding.type) {
|
||||||
case DebuggerEncoding::HexEncodedSignedInteger:
|
case DebuggerEncoding::HexEncodedSignedInteger:
|
||||||
switch (encoding.size) {
|
switch (encoding.size) {
|
||||||
case 1:
|
case 1:
|
||||||
return decodeArrayHelper<signed char>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<signed char>(encoding.size);
|
||||||
case 2:
|
case 2:
|
||||||
return decodeArrayHelper<short>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<short>(encoding.size);
|
||||||
case 4:
|
case 4:
|
||||||
return decodeArrayHelper<int>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<int>(encoding.size);
|
||||||
case 8:
|
case 8:
|
||||||
return decodeArrayHelper<qint64>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<qint64>(encoding.size);
|
||||||
}
|
}
|
||||||
case DebuggerEncoding::HexEncodedUnsignedInteger:
|
case DebuggerEncoding::HexEncodedUnsignedInteger:
|
||||||
switch (encoding.size) {
|
switch (encoding.size) {
|
||||||
case 1:
|
case 1:
|
||||||
return decodeArrayHelper<uchar>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<uchar>(encoding.size);
|
||||||
case 2:
|
case 2:
|
||||||
return decodeArrayHelper<ushort>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<ushort>(encoding.size);
|
||||||
case 4:
|
case 4:
|
||||||
return decodeArrayHelper<uint>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<uint>(encoding.size);
|
||||||
case 8:
|
case 8:
|
||||||
return decodeArrayHelper<quint64>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<quint64>(encoding.size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DebuggerEncoding::HexEncodedFloat:
|
case DebuggerEncoding::HexEncodedFloat:
|
||||||
switch (encoding.size) {
|
switch (encoding.size) {
|
||||||
case 4:
|
case 4:
|
||||||
return decodeArrayHelper<float>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<float>(encoding.size);
|
||||||
case 8:
|
case 8:
|
||||||
return decodeArrayHelper<double>(item, rawData, encoding.size, childType);
|
return decodeArrayHelper<double>(encoding.size);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -381,6 +387,14 @@ static void decodeArrayData(WatchItem *item, const QByteArray &rawData,
|
|||||||
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)
|
static bool sortByName(const Utils::TreeItem *a, const Utils::TreeItem *b)
|
||||||
{
|
{
|
||||||
auto aa = static_cast<const WatchItem *>(a);
|
auto aa = static_cast<const WatchItem *>(a);
|
||||||
@@ -474,9 +488,14 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
|
|||||||
|
|
||||||
mi = input["arraydata"];
|
mi = input["arraydata"];
|
||||||
if (mi.isValid()) {
|
if (mi.isValid()) {
|
||||||
DebuggerEncoding encoding(input["arrayencoding"].data());
|
ArrayDataDecoder decoder;
|
||||||
QByteArray childType = input["childtype"].data();
|
decoder.item = this;
|
||||||
decodeArrayData(this, mi.data(), encoding, childType);
|
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 {
|
} else {
|
||||||
const GdbMi children = input["children"];
|
const GdbMi children = input["children"];
|
||||||
if (children.isValid()) {
|
if (children.isValid()) {
|
||||||
@@ -511,7 +530,8 @@ void WatchItem::parseHelper(const GdbMi &input, bool maySort)
|
|||||||
child->iname = this->iname + '.' + nn;
|
child->iname = this->iname + '.' + nn;
|
||||||
if (addressStep) {
|
if (addressStep) {
|
||||||
child->address = addressBase + i * 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();
|
QByteArray key = subinput["key"].data();
|
||||||
if (!key.isEmpty())
|
if (!key.isEmpty())
|
||||||
@@ -582,8 +602,8 @@ QString WatchItem::toToolTip() const
|
|||||||
}
|
}
|
||||||
formatToolTipRow(str, tr("Value"), val);
|
formatToolTipRow(str, tr("Value"), val);
|
||||||
}
|
}
|
||||||
if (realAddress())
|
if (address)
|
||||||
formatToolTipRow(str, tr("Object Address"), formatToolTipAddress(realAddress()));
|
formatToolTipRow(str, tr("Object Address"), formatToolTipAddress(address));
|
||||||
if (origaddr)
|
if (origaddr)
|
||||||
formatToolTipRow(str, tr("Pointer Address"), formatToolTipAddress(origaddr));
|
formatToolTipRow(str, tr("Pointer Address"), formatToolTipAddress(origaddr));
|
||||||
if (arrayIndex >= 0)
|
if (arrayIndex >= 0)
|
||||||
@@ -619,15 +639,6 @@ bool WatchItem::isInspect() const
|
|||||||
return iname.startsWith("inspect.");
|
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
|
QByteArray WatchItem::internalName() const
|
||||||
{
|
{
|
||||||
if (arrayIndex >= 0) {
|
if (arrayIndex >= 0) {
|
||||||
@@ -648,7 +659,7 @@ QString WatchItem::expression() const
|
|||||||
{
|
{
|
||||||
if (!exp.isEmpty())
|
if (!exp.isEmpty())
|
||||||
return QString::fromLatin1(exp);
|
return QString::fromLatin1(exp);
|
||||||
if (quint64 addr = realAddress()) {
|
if (quint64 addr = address) {
|
||||||
if (!type.isEmpty())
|
if (!type.isEmpty())
|
||||||
return QString::fromLatin1("*(%1*)0x%2").arg(QLatin1String(type)).arg(addr, 0, 16);
|
return QString::fromLatin1("*(%1*)0x%2").arg(QLatin1String(type)).arg(addr, 0, 16);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ public:
|
|||||||
|
|
||||||
QString expression() const;
|
QString expression() const;
|
||||||
QString realName() const;
|
QString realName() const;
|
||||||
quint64 realAddress() const;
|
|
||||||
QByteArray internalName() const;
|
QByteArray internalName() const;
|
||||||
QString toToolTip() const;
|
QString toToolTip() const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user