diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp index feb73530ce80b86e1c0ba98662772f610b84d185..2589046edcbb7b3ba88c40d1cdfa95900246cda8 100644 --- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp +++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp @@ -402,16 +402,20 @@ QString CdbSymbolGroupContext::symbolINameAt(unsigned long index) const } // Return hexadecimal pointer value from a CDB pointer value -// which look like "0x000032a" or "0x00000000`0250124a" on 64-bit systems. -static bool inline getPointerValue(QString stringValue, quint64 *value) +// which look like "0x000032a" or "0x00000000`0250124a" or +// "0x1`0250124a" on 64-bit systems. +static bool inline getUnsignedHexValue(QString stringValue, quint64 *value) { *value = 0; if (!stringValue.startsWith(QLatin1String("0x"))) return false; stringValue.remove(0, 2); // Remove 64bit separator - if (stringValue.size() > 8 && stringValue.at(8) == QLatin1Char('`')) - stringValue.remove(8, 1); + if (stringValue.size() > 9) { + const int sepPos = stringValue.size() - 9; + if (stringValue.at(sepPos) == QLatin1Char('`')) + stringValue.remove(sepPos, 1); + } bool ok; *value = stringValue.toULongLong(&ok, 16); return ok; @@ -427,7 +431,7 @@ static inline bool isNullPointer(const WatchData &wd) if (blankPos != -1) stringValue.truncate(blankPos); quint64 value; - return getPointerValue(stringValue, &value) && value == 0u; + return getUnsignedHexValue(stringValue, &value) && value == 0u; } // Fix a symbol group value. It is set to the class type for @@ -445,11 +449,21 @@ static inline QString removeInnerTemplateType(QString value) return value; } -static inline QString fixValue(const QString &value) +// Fix display values: Pass through strings, convert unsigned integers +// to decimal ('0x5454`fedf'), remove inner templates from +// "0x4343 class list<>". +static inline QString fixValue(const QString &value, const QString &type) { - if (value.size() < 20 || value.endsWith(QLatin1Char('"'))) + if (value.endsWith(QLatin1Char('"'))) // Pass through strings return value; - return removeInnerTemplateType(value); + const int size = value.size(); + // Unsigned hex numbers + if (isIntType(type) && (size > 2 && value.at(1) == QLatin1Char('x'))) { + quint64 intValue; + if (getUnsignedHexValue(value, &intValue)) + return QString::number(intValue); + } + return size < 20 ? value : removeInnerTemplateType(value); } WatchData CdbSymbolGroupContext::watchDataAt(unsigned long index) const @@ -481,7 +495,7 @@ WatchData CdbSymbolGroupContext::watchDataAt(unsigned long index) const return wd; } const QString value = getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolValueTextWide, index); - wd.setValue(fixValue(value)); + wd.setValue(fixValue(value, type)); wd.setChildrenNeeded(); // compensate side effects of above setters // Figure out children. The SubElement is only a guess unless the symbol, // is expanded, so, we leave this as a guess for later updates. @@ -729,10 +743,10 @@ static inline bool getIntValue(CIDebugSymbolGroup *sg, int index, int *value) // Get pointer value of symbol group ("0xAAB") // Note that this is on "00000000`0250124a" on 64bit systems. -static inline bool getPointerValue(CIDebugSymbolGroup *sg, int index, quint64 *value) +static inline bool getUnsignedHexValue(CIDebugSymbolGroup *sg, int index, quint64 *value) { const QString stringValue = getSymbolString(sg, &IDebugSymbolGroup2::GetSymbolValueTextWide, index); - return getPointerValue(stringValue, value); + return getUnsignedHexValue(stringValue, value); } int CdbSymbolGroupContext::dumpQString(CIDebugDataSpaces *ds, WatchData *wd) @@ -756,7 +770,7 @@ int CdbSymbolGroupContext::dumpQString(CIDebugDataSpaces *ds, WatchData *wd) if (!getIntValue(m_symbolGroup, sizeIndex, &size)) return 4; quint64 array; - if (!getPointerValue(m_symbolGroup, arrayIndex, &array)) + if (!getUnsignedHexValue(m_symbolGroup, arrayIndex, &array)) return 5; // Fetch const bool truncated = size > maxLength; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 82c694880bac279e7093bf8519502a17fa6a4fae..c6ea415dedfceea1ee8ecf2c8b0034174beaf6ce 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -588,21 +588,32 @@ QString niceType(const QString typeIn) return type; } +template <class IntType> QString reformatInteger(IntType value, int format) +{ + switch (format) { + case HexadecimalFormat: + return ("(hex) ") + QString::number(value, 16); + case BinaryFormat: + return ("(bin) ") + QString::number(value, 2); + case OctalFormat: + return ("(oct) ") + QString::number(value, 8); + } + return QString::number(value); // not reached +} + static QString formattedValue(const WatchData &data, int individualFormat, int typeFormat) { if (isIntType(data.type)) { - int format = individualFormat == -1 ? typeFormat : individualFormat; - int value = data.value.toInt(); - if (format == HexadecimalFormat) - return ("(hex) ") + QString::number(value, 16); - if (format == BinaryFormat) - return ("(bin) ") + QString::number(value, 2); - if (format == OctalFormat) - return ("(oct) ") + QString::number(value, 8); - return data.value; + const int format = individualFormat == -1 ? typeFormat : individualFormat; + if (format <= 0) + return data.value; + if (data.type.contains(QLatin1String("unsigned"))) { + return reformatInteger(data.value.toULongLong(), format); + } else { + return reformatInteger(data.value.toLongLong(), format); + } } - return data.value; } @@ -769,15 +780,9 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const break; case TypeFormatRole: - return m_handler->m_typeFormats[data.type]; - - case IndividualFormatRole: { - int format = m_handler->m_individualFormats[data.iname]; - if (format == -1) - return m_handler->m_typeFormats[data.type]; - return format; - } - + return m_handler->m_typeFormats.value(data.type, -1); + case IndividualFormatRole: + return m_handler->m_individualFormats.value(data.iname, -1); case AddressRole: { if (!data.addr.isEmpty()) return data.addr; @@ -807,8 +812,13 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro } } else if (role == TypeFormatRole) { m_handler->setFormat(data.type, value.toInt()); - } else if (role == IndividualFormatRole) { - m_handler->m_individualFormats[data.iname] = value.toInt(); + } else if (role == IndividualFormatRole) { + const int format = value.toInt(); + if (format == -1) { + m_handler->m_individualFormats.remove(data.iname); + } else { + m_handler->m_individualFormats[data.iname] = format; + } } emit dataChanged(index, index); return true; @@ -1373,9 +1383,12 @@ void WatchHandler::saveTypeFormats() QHashIterator<QString, int> it(m_typeFormats); while (it.hasNext()) { it.next(); - QString key = it.key().trimmed(); - if (!key.isEmpty()) - typeFormats.insert(key, it.value()); + const int format = it.value(); + if (format != DecimalFormat) { + const QString key = it.key().trimmed(); + if (!key.isEmpty()) + typeFormats.insert(key, format); + } } m_manager->setSessionValue("DefaultFormats", QVariant(typeFormats)); } diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 1e1137694fdc9d95578a29e2426436263d97a06c..f5ef9250e7e52a7fc5a96d6ae91f85c6cc4f7c18 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -542,8 +542,13 @@ bool isIntType(const QString &type) << QLatin1String("long") << QLatin1String("bool") << QLatin1String("signed char") << QLatin1String("unsigned") << QLatin1String("unsigned char") << QLatin1String("unsigned long") - << QLatin1String("long long") << QLatin1String("unsigned long long"); - return type.endsWith(QLatin1String(" int")) || types.contains(type); + << QLatin1String("long long") << QLatin1String("unsigned long long") + << QLatin1String("qint16") << QLatin1String("quint16") + << QLatin1String("qint32") << QLatin1String("quint32") + << QLatin1String("qint64") << QLatin1String("quint64"); + return type.endsWith(QLatin1String(" int")) + || type.endsWith(QLatin1String(" int64")) + || types.contains(type); } bool isSymbianIntType(const QString &type) diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index b4c7a55afff557c60b03a0635352df17aaf76817..005aa5954baaca3851660154b4c7a256511cf237 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -210,36 +210,40 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev) QStringList alternativeFormats = model()->data(mi0, TypeFormatListRole).toStringList(); - int typeFormat = - model()->data(mi0, TypeFormatRole).toInt(); - int individualFormat = - model()->data(mi0, IndividualFormatRole).toInt(); + const int typeFormat = qMax(int(DecimalFormat), model()->data(mi0, TypeFormatRole).toInt()); + const int individualFormat = model()->data(mi0, IndividualFormatRole).toInt(); + const int effectiveIndividualFormat = individualFormat == -1 ? typeFormat : individualFormat; QMenu typeFormatMenu; QMenu individualFormatMenu; QList<QAction *> typeFormatActions; QList<QAction *> individualFormatActions; + QAction *clearIndividualFormatAction = 0; if (idx.isValid()) { typeFormatMenu.setTitle(tr("Change format for type '%1'").arg(type)); individualFormatMenu.setTitle(tr("Change format for expression '%1'").arg(exp)); - for (int i = 0; i != alternativeFormats.size(); ++i) { - const QString format = alternativeFormats.at(i); - QAction *act = new QAction(format, &typeFormatMenu); - act->setCheckable(true); - if (i == typeFormat) - act->setChecked(true); - typeFormatMenu.addAction(act); - typeFormatActions.append(act); - act = new QAction(format, &individualFormatMenu); - act->setCheckable(true); - if (i == individualFormat) - act->setChecked(true); - individualFormatMenu.addAction(act); - individualFormatActions.append(act); - } if (alternativeFormats.isEmpty()) { typeFormatMenu.setEnabled(false); individualFormatMenu.setEnabled(false); + } else { + clearIndividualFormatAction = individualFormatMenu.addAction(tr("Clear")); + clearIndividualFormatAction->setEnabled(individualFormat != -1); + individualFormatMenu.addSeparator(); + for (int i = 0; i != alternativeFormats.size(); ++i) { + const QString format = alternativeFormats.at(i); + QAction *act = new QAction(format, &typeFormatMenu); + act->setCheckable(true); + if (i == typeFormat) + act->setChecked(true); + typeFormatMenu.addAction(act); + typeFormatActions.append(act); + act = new QAction(format, &individualFormatMenu); + act->setCheckable(true); + if (i == effectiveIndividualFormat) + act->setChecked(true); + individualFormatMenu.addAction(act); + individualFormatActions.append(act); + } } } else { typeFormatMenu.setTitle(tr("Change format for type")); @@ -316,6 +320,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev) m_grabbing = true; } else if (act == actClearCodeModelSnapshot) { m_manager->clearCppCodeModelSnapshot(); + } else if (clearIndividualFormatAction && act == clearIndividualFormatAction) { + model()->setData(mi1, -1, IndividualFormatRole); } else { for (int i = 0; i != alternativeFormats.size(); ++i) { if (act == typeFormatActions.at(i))