summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2009-11-25 16:32:44 +0100
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>2009-11-25 16:32:44 +0100
commit2b23ea2a8ac8166820b76476b18fd7fd7014e695 (patch)
treedb212c39dc162b992f58d72dff38c9386068a026
parent32dd4567c819ce42a0bbf53446798800c6c498fd (diff)
downloadqt-creator-2b23ea2a8ac8166820b76476b18fd7fd7014e695.tar.gz
Debugger/CDB: Windows 64 integer handling.
Convert CDB unsigned integer values should they appear in hex, make format flexible. Use int64 for reformatting integers to be able to accommodate 64 bit values on Windows 64. Add some more integer types. Do not save decimal type formats. Add menu option to clear individual formatting. Do not use map[] to query the type formats (inserting 0 everywhere as a side effect). Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
-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))