forked from qt-creator/qt-creator
Adapt CDB debug helpers to pending container changes.
- Adapt QByteArray, QString, QVector. - Disable QMap for Qt 5. Change-Id: I113d546fc69165b504ce4998b3bf7ac9c44130fb Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
@@ -151,11 +151,19 @@ int containerSize(KnownType kt, const SymbolGroupValue &v)
|
||||
break;
|
||||
case KT_QLinkedList:
|
||||
case KT_QHash:
|
||||
case KT_QMap:
|
||||
case KT_QVector:
|
||||
if (const SymbolGroupValue sizeV = v["d"]["size"])
|
||||
return sizeV.intValue();
|
||||
break;
|
||||
case KT_QMap:
|
||||
case KT_QVector: {
|
||||
// Inheritance from QVectorTypedData, QMapData<> in Qt 5.
|
||||
const SymbolGroupValue sizeV =
|
||||
QtInfo::get(v.context()).version >= 5 ?
|
||||
v["d"][unsigned(0)]["size"] : v["d"]["size"];
|
||||
if (sizeV)
|
||||
return sizeV.intValue();
|
||||
}
|
||||
break;
|
||||
case KT_QMultiHash:
|
||||
if (const SymbolGroupValue qHash = v[unsigned(0)])
|
||||
return containerSize(KT_QHash, qHash);
|
||||
@@ -646,16 +654,33 @@ static inline AbstractSymbolGroupNodePtrVector
|
||||
static inline AbstractSymbolGroupNodePtrVector
|
||||
qVectorChildList(SymbolGroupNode *n, int count, const SymbolGroupValueContext &ctx)
|
||||
{
|
||||
if (count) {
|
||||
// QVector<T>: p/array is declared as array of T. Dereference first
|
||||
if (!count)
|
||||
return AbstractSymbolGroupNodePtrVector();
|
||||
const SymbolGroupValue vec(n, ctx);
|
||||
const int qtVersion = QtInfo::get(vec.context()).version;
|
||||
if (qtVersion < 5) {
|
||||
// Qt 4: QVector<T>: p/array is declared as array of T. Dereference first
|
||||
// element to obtain address.
|
||||
const SymbolGroupValue vec(n, ctx);
|
||||
if (const SymbolGroupValue firstElementV = vec["p"]["array"][unsigned(0)]) {
|
||||
if (const ULONG64 arrayAddress = firstElementV.address()) {
|
||||
const std::string fixedInnerType = fixInnerType(firstElementV.type(), vec);
|
||||
return arrayChildList(n->symbolGroup(), arrayAddress, n->module(), fixedInnerType, count);
|
||||
}
|
||||
}
|
||||
return AbstractSymbolGroupNodePtrVector();
|
||||
}
|
||||
// Qt 5: Data are located in a pool behind 'd' (similar to QString,
|
||||
// QByteArray).
|
||||
const SymbolGroupValue dV = vec["d"][unsigned(0)];
|
||||
const SymbolGroupValue offsetV = dV["offset"];
|
||||
if (!dV || !offsetV)
|
||||
return AbstractSymbolGroupNodePtrVector();
|
||||
const ULONG64 arrayAddress = dV.address() + offsetV.intValue();
|
||||
std::vector<std::string> innerTypes = SymbolGroupValue::innerTypesOf(vec.type());
|
||||
if (arrayAddress && !innerTypes.empty()) {
|
||||
return arrayChildList(n->symbolGroup(), arrayAddress, n->module(),
|
||||
fixInnerType(innerTypes.front(), vec),
|
||||
count);
|
||||
}
|
||||
return AbstractSymbolGroupNodePtrVector();
|
||||
}
|
||||
@@ -939,6 +964,8 @@ static inline AbstractSymbolGroupNodePtrVector
|
||||
|
||||
if (!count)
|
||||
return AbstractSymbolGroupNodePtrVector();
|
||||
if (QtInfo::get(v.context()).version >= 5) // ### fixme: Qt 5 map is a rb tree.
|
||||
return AbstractSymbolGroupNodePtrVector();
|
||||
// Get node type: 'class namespace::QMap<K,T>'
|
||||
// ->'QtCored4!namespace::QMapNode<K,T>'
|
||||
// Note: Any types QMapNode<> will not be found without modules!
|
||||
|
||||
@@ -1414,7 +1414,8 @@ struct QtStringAddressData
|
||||
/* Helper to determine the location and size of the data of
|
||||
* QStrings/QByteArrays for versions 4,5. In Qt 4, 'd' has a 'data'
|
||||
* pointer. In Qt 5, the d-elements and the data are in a storage pool
|
||||
* and the data are at an offset behind the d-structures. */
|
||||
* and the data are at an offset behind the d-structures (QString,
|
||||
* QByteArray, QVector). */
|
||||
QtStringAddressData readQtStringAddressData(const SymbolGroupValue &dV,
|
||||
int qtMajorVersion)
|
||||
{
|
||||
@@ -1431,15 +1432,13 @@ QtStringAddressData readQtStringAddressData(const SymbolGroupValue &dV,
|
||||
} else {
|
||||
// Qt 5: Memory pool after the data element.
|
||||
const SymbolGroupValue offsetV = dV["offset"];
|
||||
const SymbolGroupValue arrayV = dV["d"];
|
||||
if (!offsetV || !arrayV)
|
||||
if (!offsetV)
|
||||
return QtStringAddressData();
|
||||
int offset = offsetV.intValue();
|
||||
if (arrayV.type().find("short") != std::string::npos)
|
||||
offset /= sizeof(short); // QString: offset is in short[].
|
||||
result.address = arrayV.address()
|
||||
+ SymbolGroupValue::pointerDiffSize()
|
||||
+ offset;
|
||||
// Take the address for QTypeArrayData of QByteArray, else
|
||||
// pointer value of D-pointer.
|
||||
const ULONG64 baseAddress = SymbolGroupValue::isPointerType(dV.type()) ?
|
||||
dV.pointerValue() : dV.address();
|
||||
result.address = baseAddress + offsetV.intValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1578,7 +1577,10 @@ static inline bool dumpQByteArray(const SymbolGroupValue &v, std::wostream &str)
|
||||
char *memory;
|
||||
unsigned fullSize;
|
||||
unsigned size;
|
||||
if (!readQt5StringData(dV, qtInfo.version, false, 10240, &fullSize, &size, &memory))
|
||||
const SymbolGroupValue typeArrayV = dV[unsigned(0)];
|
||||
if (!typeArrayV)
|
||||
return false;
|
||||
if (!readQt5StringData(typeArrayV, qtInfo.version, false, 10240, &fullSize, &size, &memory))
|
||||
return false;
|
||||
if (size) {
|
||||
// Emulate CDB's behavior of replacing unprintable characters
|
||||
|
||||
Reference in New Issue
Block a user