summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp38
-rw-r--r--src/plugins/debugger/watchhandler.cpp61
-rw-r--r--src/plugins/debugger/watchutils.cpp9
-rw-r--r--src/plugins/debugger/watchwindow.cpp44
4 files changed, 95 insertions, 57 deletions
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index feb73530ce..2589046edc 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 82c694880b..c6ea415ded 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 1e1137694f..f5ef9250e7 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 b4c7a55aff..005aa5954b 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))