diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp index d4850e8e6e9c04e706ee0e55d9f2f6c3f3a3a810..bac771c15836963fab1eb405af1bc17f447f3c97 100644 --- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp +++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp @@ -349,11 +349,11 @@ static inline QString fixValue(const QString &value, const QString &type) if (value.endsWith(QLatin1Char('"')) || value.endsWith(QLatin1Char('\''))) return value; const int size = value.size(); - // Unsigned hex numbers - if (isIntType(type) && (size > 2 && value.at(1) == QLatin1Char('x'))) { - quint64 intValue; - if (CdbCore::SymbolGroupContext::getUnsignedHexValue(value, &intValue)) - return QString::number(intValue); + // Integer numbers Unsigned hex numbers (0x)/decimal numbers (0n) + if (isIntType(type)) { + const QVariant intValue = CdbCore::SymbolGroupContext::getIntValue(value); + if (intValue.isValid()) + return intValue.toString(); } return size < 20 ? value : CdbCore::SymbolGroupContext::removeInnerTemplateType(value); } diff --git a/src/plugins/debugger/cdb/symbolgroupcontext.cpp b/src/plugins/debugger/cdb/symbolgroupcontext.cpp index 6996ce403c51693a8f9332894794bf27a2c06ec0..06f13dceef47fbd8b0ddb4972b6ea4fd7ebe6d1d 100644 --- a/src/plugins/debugger/cdb/symbolgroupcontext.cpp +++ b/src/plugins/debugger/cdb/symbolgroupcontext.cpp @@ -34,6 +34,7 @@ #include <QtCore/QCoreApplication> #include <QtCore/QRegExp> #include <QtCore/QString> +#include <QtCore/QVariant> #include <QtCore/QDebug> enum { debug = 0 }; @@ -450,6 +451,42 @@ bool SymbolGroupContext::getUnsignedHexValue(QString stringValue, quint64 *value return ok; } +// Return the format specification of a '0x..', '0n..' +// integer specification or '0' if there is none. +inline char intFormatSpecification(const QString &stringValue) +{ + if (stringValue.size() > 2) { + const QChar format = stringValue.at(1); + if (!format.isDigit()) + return format.toLatin1(); + } + return char(0); +} + +QVariant SymbolGroupContext::getIntValue(const QString &stringValue) +{ + // Is this a "0x<hex'hex>", "0n<decimal>" or something + switch (intFormatSpecification(stringValue)) { + case 'x': { // Hex unsigned + quint64 uvalue; + if (SymbolGroupContext::getUnsignedHexValue(stringValue, &uvalue)) + return QVariant(uvalue); + } + break; + case '0': // Decimal or none + case 'n': { + qint64 nvalue; + if (SymbolGroupContext::getDecimalIntValue(stringValue, &nvalue)) + return QVariant(nvalue); + } + break; + default: + break; + } + qWarning("CDB: Integer conversion failed for '%s'.", qPrintable(stringValue)); + return QVariant(); +} + // check for "0x000", "0x000 class X" or its 64-bit equivalents. bool SymbolGroupContext::isNullPointer(const QString &type , QString valueS) { @@ -621,15 +658,24 @@ unsigned SymbolGroupContext::dumpValue(unsigned long index, return rc; } -// Get integer value of symbol group -bool SymbolGroupContext::getDecimalIntValue(CIDebugSymbolGroup *sg, int index, int *value) +bool SymbolGroupContext::getDecimalIntValue(QString stringValue, qint64 *value) { - const QString valueS = getSymbolString(sg, &IDebugSymbolGroup2::GetSymbolValueTextWide, index); + // Strip '0n<digits>' format specifier that occurs + // with Debugging tools v6.12 or later + if (stringValue.startsWith(QLatin1String("0n"))) + stringValue.remove(0, 2); bool ok; - *value = valueS.toInt(&ok); + *value = stringValue.toInt(&ok); return ok; } +// Get integer value of symbol group +static inline bool getSG_DecimalIntValue(CIDebugSymbolGroup *sg, int index, qint64 *value) +{ + const QString valueS = getSymbolString(sg, &IDebugSymbolGroup2::GetSymbolValueTextWide, index); + return SymbolGroupContext::getDecimalIntValue(valueS, value); +} + // Get pointer value of symbol group ("0xAAB") // Note that this is on "00000000`0250124a" on 64bit systems. static inline bool getSG_UnsignedHexValue(CIDebugSymbolGroup *sg, int index, quint64 *value) @@ -655,8 +701,8 @@ int SymbolGroupContext::dumpQString(unsigned long index, const unsigned long sizeIndex = dIndex + 3; const unsigned long arrayIndex = dIndex + 4; // Get size and pointer - int size; - if (!getDecimalIntValue(m_symbolGroup, sizeIndex, &size)) + qint64 size; + if (!getSG_DecimalIntValue(m_symbolGroup, sizeIndex, &size)) return 4; quint64 array; if (!getSG_UnsignedHexValue(m_symbolGroup, arrayIndex, &array)) @@ -671,7 +717,7 @@ int SymbolGroupContext::dumpQString(unsigned long index, // Should this ever be a remote debugger, need to check byte order. unsigned short *buf = new unsigned short[size + 1]; unsigned long bytesRead; - const HRESULT hr = m_dataSpaces->ReadVirtual(array, buf, size * sizeof(unsigned short), &bytesRead); + const HRESULT hr = m_dataSpaces->ReadVirtual(array, buf, size * ULONG(sizeof(unsigned short)), &bytesRead); if (FAILED(hr)) { delete [] buf; return 1; @@ -705,8 +751,8 @@ int SymbolGroupContext::dumpStdString(unsigned long index, return 2; // Check if size is something sane const int sizeIndex = index + 6; - int size; - if (!getDecimalIntValue(m_symbolGroup, sizeIndex, &size)) + qint64 size; + if (!getSG_DecimalIntValue(m_symbolGroup, sizeIndex, &size)) return 3; if (size < 0) return 1; diff --git a/src/plugins/debugger/cdb/symbolgroupcontext.h b/src/plugins/debugger/cdb/symbolgroupcontext.h index 882c1b52d74861589c7ba05b005817bc31626d22..2c10d315752f62c2602a5f1be1a069b6d848f777 100644 --- a/src/plugins/debugger/cdb/symbolgroupcontext.h +++ b/src/plugins/debugger/cdb/symbolgroupcontext.h @@ -112,10 +112,13 @@ public: unsigned dumpValue(unsigned long index, QString *inameIn, QString *nameIn, ULONG64 *addrIn, ULONG *typeIdIn, QString *typeNameIn, QString *valueIn); - // For 32bit values (returned as dec) - static bool getDecimalIntValue(CIDebugSymbolGroup *sg, int index, int *value); + // For 64bit values (returned as dec), potentially '0n..'. + static bool getDecimalIntValue(QString stringValue, qint64 *value); // For pointers and 64bit values (returned as hex) static bool getUnsignedHexValue(QString stringValue, quint64 *value); + // Convenience to return an integer (hex/decimal) as matching variant (signed/unsigned). + static QVariant getIntValue(const QString &stringValue); + // Null-check for pointers static bool isNullPointer(const QString &type , QString valueS); // Symbol group values may contain template types which is not desired. diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 0e3e7f81387a98851f70d2d4a3023e511f357748..bcb17050feefec7add6d5ed4375a4e1943a95dae 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -539,6 +539,7 @@ bool isIntType(const QString &type) << QLatin1String("long") << QLatin1String("bool") << QLatin1String("signed char") << QLatin1String("unsigned") << QLatin1String("unsigned char") << QLatin1String("unsigned long") + << QLatin1String("short") << QLatin1String("unsigned short") << QLatin1String("long long") << QLatin1String("unsigned long long") << QLatin1String("qint16") << QLatin1String("quint16") << QLatin1String("qint32") << QLatin1String("quint32")