diff options
author | hjk <qtc-committer@nokia.com> | 2011-08-31 16:45:44 +0200 |
---|---|---|
committer | hjk <qthjk@ovi.com> | 2011-08-31 16:51:54 +0200 |
commit | 188156977ca956e7366923682021322afac4a055 (patch) | |
tree | 2d6220871481b1a815361a35989b985868bbc975 /src/plugins/debugger/registerhandler.cpp | |
parent | 5d82ba7d87d0d2576108f4c8852fb0a553108145 (diff) | |
download | qt-creator-188156977ca956e7366923682021322afac4a055.tar.gz |
debugger: prepare support for partial register display
Change-Id: I74e971cfb41afbdd07f4193c14c3bb7ecd634859
Reviewed-on: http://codereview.qt.nokia.com/3990
Reviewed-by: hjk <qthjk@ovi.com>
Diffstat (limited to 'src/plugins/debugger/registerhandler.cpp')
-rw-r--r-- | src/plugins/debugger/registerhandler.cpp | 309 |
1 files changed, 276 insertions, 33 deletions
diff --git a/src/plugins/debugger/registerhandler.cpp b/src/plugins/debugger/registerhandler.cpp index bc9d8248a5..ebd739b95a 100644 --- a/src/plugins/debugger/registerhandler.cpp +++ b/src/plugins/debugger/registerhandler.cpp @@ -33,29 +33,231 @@ #include "registerhandler.h" #include "watchdelegatewidgets.h" +#if USE_REGISTER_MODEL_TEST +#include "modeltest.h" +#endif + +#include <utils/qtcassert.h> + +namespace Debugger { +namespace Internal { + ////////////////////////////////////////////////////////////////// // -// RegisterHandler +// Register // ////////////////////////////////////////////////////////////////// -namespace Debugger { -namespace Internal { +enum RegisterType +{ + RegisterUnknown, + //RegisterDummy, // like AH if EAX is present. + RegisterI8, + RegisterI16, + RegisterI32, + RegisterI64, + RegisterF32, + RegisterF64, + RegisterF80, + RegisterXMM, + RegisterMMX, + RegisterNeon, + RegisterFlags32 +}; + +static struct RegisterNameAndType +{ + const char *name; + RegisterType type; +} theNameAndType[] = { + { "eax", RegisterI32 }, + { "ecx", RegisterI32 }, + { "edx", RegisterI32 }, + { "ebx", RegisterI32 }, + { "esp", RegisterI32 }, + { "ebp", RegisterI32 }, + { "esi", RegisterI32 }, + { "edi", RegisterI32 }, + { "eip", RegisterI32 }, + { "eflags", RegisterFlags32 }, + { "cs", RegisterI32 }, + { "ss", RegisterI32 }, + { "ds", RegisterI32 }, + { "es", RegisterI32 }, + { "fs", RegisterI32 }, + { "gs", RegisterI32 }, + { "st0", RegisterF80 }, + { "st1", RegisterF80 }, + { "st2", RegisterF80 }, + { "st3", RegisterF80 }, + { "st4", RegisterF80 }, + { "st5", RegisterF80 }, + { "st6", RegisterF80 }, + { "st7", RegisterF80 }, + { "fctrl", RegisterFlags32 }, + { "fstat", RegisterFlags32 }, + { "ftag", RegisterFlags32 }, + { "fiseg", RegisterFlags32 }, + { "fioff", RegisterFlags32 }, + { "foseg", RegisterFlags32 }, + { "fooff", RegisterFlags32 }, + { "fop", RegisterFlags32 }, + { "xmm0", RegisterXMM }, + { "xmm1", RegisterXMM }, + { "xmm2", RegisterXMM }, + { "xmm3", RegisterXMM }, + { "xmm4", RegisterXMM }, + { "xmm5", RegisterXMM }, + { "xmm6", RegisterXMM }, + { "xmm7", RegisterXMM }, + { "mxcsr", RegisterFlags32 }, + { "orig_eax", RegisterI32 }, + { "al", RegisterI8 }, + { "cl", RegisterI8 }, + { "dl", RegisterI8 }, + { "bl", RegisterI8 }, + { "ah", RegisterI8 }, + { "ch", RegisterI8 }, + { "dh", RegisterI8 }, + { "bh", RegisterI8 }, + { "ax", RegisterI16 }, + { "cx", RegisterI16 }, + { "dx", RegisterI16 }, + { "bx", RegisterI16 }, + { "bp", RegisterI16 }, + { "si", RegisterI16 }, + { "di", RegisterI16 }, + { "mm0", RegisterMMX }, + { "mm1", RegisterMMX }, + { "mm2", RegisterMMX }, + { "mm3", RegisterMMX }, + { "mm4", RegisterMMX }, + { "mm5", RegisterMMX }, + { "mm6", RegisterMMX }, + { "mm7", RegisterMMX } + }; + +static RegisterType guessType(const QByteArray &name) +{ + static QHash<QByteArray, RegisterType> theTypes; + if (theTypes.isEmpty()) { + for (int i = 0; i != sizeof(theNameAndType) / sizeof(theNameAndType[0]); ++i) + theTypes[theNameAndType[i].name] = theNameAndType[i].type; + } + return theTypes.value(name, RegisterUnknown); +} + +static int childCountFromType(int type) +{ + switch (type) { + case RegisterUnknown: return 0; + case RegisterI8: return 0; + case RegisterI16: return 1; + case RegisterI32: return 2; + case RegisterI64: return 3; + case RegisterF32: return 0; + case RegisterF64: return 0; + case RegisterF80: return 0; + case RegisterXMM: return 3; + case RegisterMMX: return 3; + case RegisterNeon: return 3; + case RegisterFlags32: return 0; + } + QTC_ASSERT(false, /**/); + return 0; +} + +static int bitWidthFromType(int type, int subType) +{ + const uint integer[] = { 8, 16, 32, 64 }; + const uint xmm[] = { 8, 16, 32, 64 }; + const uint mmx[] = { 8, 16, 32, 64 }; + const uint neon[] = { 8, 16, 32, 64 }; + + switch (type) { + case RegisterUnknown: return 0; + case RegisterI8: return 8; + case RegisterI16: return integer[subType]; + case RegisterI32: return integer[subType]; + case RegisterI64: return integer[subType]; + case RegisterF32: return 0; + case RegisterF64: return 0; + case RegisterF80: return 0; + case RegisterXMM: return xmm[subType]; + case RegisterMMX: return mmx[subType]; + case RegisterNeon: return neon[subType]; + case RegisterFlags32: return 0; + } + QTC_ASSERT(false, /**/); + return 0; +} + +Register::Register(const QByteArray &name_) + : name(name_), changed(true) +{ + type = guessType(name); +} + + +////////////////////////////////////////////////////////////////// +// +// RegisterHandler +// +////////////////////////////////////////////////////////////////// RegisterHandler::RegisterHandler() - : m_base(-1) { - setNumberBase(16); + m_base = 16; + calculateWidth(); +#if USE_REGISTER_MODEL_TEST + new ModelTest(this, 0); +#endif +} + +int RegisterHandler::rowCount(const QModelIndex &idx) const +{ + if (idx.column() > 0) + return 0; + if (!idx.isValid()) + return m_registers.size(); // Top level. + if (idx.internalId() >= 0) + return 0; // Sub-Items don't have children. + if (idx.row() >= m_registers.size()) + return 0; + return childCountFromType(m_registers[idx.row()].type); +} + +int RegisterHandler::columnCount(const QModelIndex &idx) const +{ + if (idx.column() > 0) + return 0; + if (!idx.isValid()) + return 2; + if (idx.internalId() >= 0) + return 0; // Sub-Items don't have children. + return 2; } -int RegisterHandler::rowCount(const QModelIndex &parent) const +QModelIndex RegisterHandler::index(int row, int col, const QModelIndex &parent) const { - return parent.isValid() ? 0 : m_registers.size(); + if (row < 0 || col < 0 || col >= 2) + return QModelIndex(); + if (!parent.isValid()) // Top level. + return createIndex(row, col, -1); + if (parent.internalId() >= 0) // Sub-Item has no children. + return QModelIndex(); + if (parent.column() > 0) + return QModelIndex(); + return createIndex(row, col, parent.row()); } -int RegisterHandler::columnCount(const QModelIndex &parent) const +QModelIndex RegisterHandler::parent(const QModelIndex &idx) const { - return parent.isValid() ? 0 : 2; + if (!idx.isValid()) + return QModelIndex(); + if (idx.internalId() >= 0) + return createIndex(idx.internalId(), 0, -1); + return QModelIndex(); } // Editor value: Preferably number, else string. @@ -83,27 +285,67 @@ QString Register::displayValue(int base, int strlen) const QVariant RegisterHandler::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= m_registers.size()) + if (!index.isValid()) + return QVariant(); + + QModelIndex topLevel = index.parent(); + const int mainRow = topLevel.isValid() ? topLevel.row() : index.row(); + + if (mainRow >= m_registers.size()) return QVariant(); - const Register ® = m_registers.at(index.row()); - switch (role) { - case Qt::DisplayRole: - switch (index.column()) { - case 0: { - const QString padding = QLatin1String(" "); - return QVariant(padding + reg.name + padding); + const Register ® = m_registers.at(mainRow); + + if (topLevel.isValid()) { + // + // Nested + // + int subType = index.row(); + int bitWidth = bitWidthFromType(reg.type, subType); + + switch (role) { + case Qt::DisplayRole: + switch (index.column()) { + case 0: { + switch (bitWidth) { + case 8: return "[Bytes]"; + case 16: return "[Words]"; + case 32: return "[DWords]"; + case 64: return "[QWords]"; + case -32: return "[Single]"; + case -64: return "[Double]"; + return QVariant(bitWidth); + } + } + } + default: + break; + } + + } else { + // + // Toplevel + // + + switch (role) { + case Qt::DisplayRole: + switch (index.column()) { + case 0: { + const QString padding = QLatin1String(" "); + return QVariant(padding + reg.name + padding); + //return QVariant(reg.name); + } + case 1: // Display: Pad value for alignment + return reg.displayValue(m_base, m_strlen); + } // switch column + case Qt::EditRole: // Edit: Unpadded for editing + return reg.editValue(); + case Qt::TextAlignmentRole: + return index.column() == 1 ? QVariant(Qt::AlignRight) : QVariant(); + default: + break; } - case 1: // Display: Pad value for alignment - return reg.displayValue(m_base, m_strlen); - } // switch column - case Qt::EditRole: // Edit: Unpadded for editing - return reg.editValue(); - case Qt::TextAlignmentRole: - return index.column() == 1 ? QVariant(Qt::AlignRight) : QVariant(); - default: - break; } return QVariant(); } @@ -113,8 +355,8 @@ QVariant RegisterHandler::headerData(int section, Qt::Orientation orientation, { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { - case 0: return tr("Name"); - case 1: return tr("Value (base %1)").arg(m_base); + case 0: return tr("Name"); + case 1: return tr("Value (Base %1)").arg(m_base); }; } return QVariant(); @@ -128,7 +370,7 @@ Qt::ItemFlags RegisterHandler::flags(const QModelIndex &idx) const const Qt::ItemFlags notEditable = Qt::ItemIsSelectable|Qt::ItemIsEnabled; // Can edit registers if they are hex numbers and not arrays. if (idx.column() == 1 - && IntegerWatchLineEdit::isUnsignedHexNumber(m_registers.at(idx.row()).value)) + && IntegerWatchLineEdit::isUnsignedHexNumber(m_registers.at(idx.row()).value)) return notEditable | Qt::ItemIsEditable; return notEditable; } @@ -173,15 +415,16 @@ void RegisterHandler::setAndMarkRegisters(const Registers ®isters) return; } const int size = m_registers.size(); - for (int r = 0; r < size; r++) { - const QModelIndex regIndex = index(r, 1); + for (int r = 0; r != size; ++r) { + const QModelIndex regIndex = index(r, 1, QModelIndex()); if (m_registers.at(r).value != registers.at(r).value) { // Indicate red if values change, keep changed. - m_registers[r].changed = m_registers[r].changed || !m_registers.at(r).value.isEmpty(); + m_registers[r].changed = m_registers.at(r).changed + || !m_registers.at(r).value.isEmpty(); m_registers[r].value = registers.at(r).value; emit dataChanged(regIndex, regIndex); } - emit registerSet(regIndex); // notify attached memory views. + emit registerSet(regIndex); // Notify attached memory views. } } |