Debugger[New CDB]: Work on QList.

Move container size code to container.cpp/h and known type
enumeration to separate knowntype.h.
Add some more types. Change type detection to work without
'class '/'struct ' prefixes for inner types. Add Qt types with
Movable/Primitive flags. Add QStack/QQueue, size for std::deque
and std::stack. Add infrastructure for linked-list type containers
and std::list. Implement QList specialisations depending on type.
This commit is contained in:
Friedemann Kleint
2010-12-13 16:25:54 +01:00
parent 20b6f40756
commit 5fcc706800
8 changed files with 682 additions and 196 deletions

View File

@@ -32,23 +32,190 @@
#include "symbolgroup.h" #include "symbolgroup.h"
#include "stringutils.h" #include "stringutils.h"
#include <functional>
typedef SymbolGroupNode::SymbolGroupNodePtrVector SymbolGroupNodePtrVector; typedef SymbolGroupNode::SymbolGroupNodePtrVector SymbolGroupNodePtrVector;
// Return size of container or -1
int containerSize(KnownType kt, SymbolGroupNode *n, const SymbolGroupValueContext &ctx)
{
if ((kt & KT_ContainerType) == 0)
return -1;
return containerSize(kt, SymbolGroupValue(n, ctx));
}
// Return size from an STL vector (last/first iterators).
static inline int msvcStdVectorSize(const SymbolGroupValue &v)
{
if (const SymbolGroupValue myFirstPtrV = v["_Myfirst"]) {
if (const SymbolGroupValue myLastPtrV = v["_Mylast"]) {
const ULONG64 firstPtr = myFirstPtrV.pointerValue();
const ULONG64 lastPtr = myLastPtrV.pointerValue();
if (!firstPtr || lastPtr < firstPtr)
return -1;
if (lastPtr == firstPtr)
return 0;
// Subtract the pointers: We need to do the pointer arithmetics ourselves
// as we get char *pointers.
const std::string innerType = SymbolGroupValue::stripPointerType(myFirstPtrV.type());
const size_t size = SymbolGroupValue::sizeOf(innerType.c_str());
if (size == 0)
return -1;
return static_cast<int>((lastPtr - firstPtr) / size);
}
}
return -1;
}
// Determine size of containers
int containerSize(KnownType kt, const SymbolGroupValue &v)
{
switch (kt) {
case KT_QStringList:
if (const SymbolGroupValue base = v[unsigned(0)])
return containerSize(KT_QList, base);
break;
case KT_QList:
if (const SymbolGroupValue dV = v["d"]) {
if (const SymbolGroupValue beginV = dV["begin"]) {
const int begin = beginV.intValue();
const int end = dV["end"].intValue();
if (begin >= 0 && end >= begin)
return end - begin;
}
}
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_QQueue:
if (const SymbolGroupValue qList= v[unsigned(0)])
return containerSize(KT_QList, qList);
break;
case KT_QStack:
if (const SymbolGroupValue qVector = v[unsigned(0)])
return containerSize(KT_QVector, qVector);
break;
case KT_QSet:
if (const SymbolGroupValue base = v[unsigned(0)])
return containerSize(KT_QHash, base);
break;
case KT_QMultiMap:
if (const SymbolGroupValue base = v[unsigned(0)])
return containerSize(KT_QMap, base);
break;
case KT_StdVector: {
if (const SymbolGroupValue base = v[unsigned(0)]) {
const int msvc10Size = msvcStdVectorSize(base);
if (msvc10Size >= 0)
return msvc10Size;
}
const int msvc8Size = msvcStdVectorSize(v);
if (msvc8Size >= 0)
return msvc8Size;
}
break;
case KT_StdList:
if (const SymbolGroupValue sizeV = v["_Mysize"]) // VS 8
return sizeV.intValue();
if (const SymbolGroupValue sizeV = v[unsigned(0)][unsigned(0)]["_Mysize"]) // VS10
return sizeV.intValue();
break;
case KT_StdDeque:
if (const SymbolGroupValue sizeV = v[unsigned(0)]["_Mysize"])
return sizeV.intValue();
break;
case KT_StdStack:
if (const SymbolGroupValue deque = v[unsigned(0)])
return containerSize(KT_StdDeque, deque);
break;
case KT_StdSet:
case KT_StdMap:
case KT_StdMultiMap:
if (const SymbolGroupValue baseV = v[unsigned(0)]) {
if (const SymbolGroupValue sizeV = baseV["_Mysize"]) // VS 8
return sizeV.intValue();
if (const SymbolGroupValue sizeV = baseV[unsigned(0)][unsigned(0)]["_Mysize"]) // VS 10
return sizeV.intValue();
}
break;
}
return -1;
}
/* Generate a list of children by invoking the functions to obtain the value
* and the next link */
template <class ValueFunction, class NextFunction>
SymbolGroupNodePtrVector linkedListChildList(SymbolGroupValue headNode,
int count,
ValueFunction valueFunc,
NextFunction nextFunc)
{
SymbolGroupNodePtrVector rc;
rc.reserve(count);
for (int i =0; i < count && headNode; i++) {
if (const SymbolGroupValue value = valueFunc(headNode)) {
rc.push_back(value.node());
headNode = nextFunc(headNode);
} else {
break;
}
}
return rc;
}
// Helper function for linkedListChildList that returns a member by name
class MemberByName : public std::unary_function<const SymbolGroupValue &, SymbolGroupValue> {
public:
explicit MemberByName(const char *name) : m_name(name) {}
SymbolGroupValue operator()(const SymbolGroupValue &v) { return v[m_name]; }
private:
const char *m_name;
};
// std::list<T>: Dummy head node and then a linked list of "_Next", "_Myval".
static inline SymbolGroupNodePtrVector stdListChildList(SymbolGroupNode *n, int count,
const SymbolGroupValueContext &ctx)
{
if (count)
if (const SymbolGroupValue head = SymbolGroupValue(n, ctx)[unsigned(0)][unsigned(0)]["_Myhead"]["_Next"])
return linkedListChildList(head, count, MemberByName("_Myval"), MemberByName("_Next"));
return SymbolGroupNodePtrVector();
}
// QLinkedList<T>: Dummy head node and then a linked list of "n", "t".
static inline SymbolGroupNodePtrVector qLinkedListChildList(SymbolGroupNode *n, int count,
const SymbolGroupValueContext &ctx)
{
if (count)
if (const SymbolGroupValue head = SymbolGroupValue(n, ctx)["e"]["n"])
return linkedListChildList(head, count, MemberByName("t"), MemberByName("n"));
return SymbolGroupNodePtrVector();
}
/* Helper for array-type containers: /* Helper for array-type containers:
* Add a series of "*(innertype *)0x (address + n * size)" fake child symbols. */ * Add a series of "*(innertype *)0x (address + n * size)" fake child symbols. */
static SymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, ULONG64 address, static SymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, ULONG64 address,
int count, const std::string &innerType) const std::string &innerType,
ULONG64 innerTypeSize,
int count)
{ {
SymbolGroupNodePtrVector rc; SymbolGroupNodePtrVector rc;
const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str()); if (!count || !address || !innerTypeSize)
if (!innerTypeSize)
return rc; return rc;
std::string errorMessage; std::string errorMessage;
rc.reserve(count); rc.reserve(count);
for (int i = 0; i < count; i++, address += innerTypeSize) { for (int i = 0; i < count; i++, address += innerTypeSize) {
std::ostringstream str; std::ostringstream str;
str << "*(" << innerType << " *)" << std::showbase << std::hex << address; str << "*(" << innerType;
if (!endsWith(innerType, '*'))
str << ' ';
str << "*)" << std::showbase << std::hex << address;
if (SymbolGroupNode *child = sg->addSymbol(str.str(), toString(i), &errorMessage)) { if (SymbolGroupNode *child = sg->addSymbol(str.str(), toString(i), &errorMessage)) {
rc.push_back(child); rc.push_back(child);
} else { } else {
@@ -58,6 +225,16 @@ static SymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, ULONG64 address,
return rc; return rc;
} }
// Convenience overload that determines the inner size
static inline SymbolGroupNodePtrVector arrayChildList(SymbolGroup *sg, ULONG64 address,
const std::string &innerType,
int count)
{
if (const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str()))
return arrayChildList(sg, address, innerType, innerTypeSize, count);
return SymbolGroupNodePtrVector();
}
// std::vector<T> // std::vector<T>
static inline SymbolGroupNodePtrVector static inline SymbolGroupNodePtrVector
stdVectorChildList(SymbolGroupNode *n, int count, const SymbolGroupValueContext &ctx) stdVectorChildList(SymbolGroupNode *n, int count, const SymbolGroupValueContext &ctx)
@@ -71,8 +248,9 @@ static inline SymbolGroupNodePtrVector
myFirst = vec["_Myfirst"]; // MSVC2008 myFirst = vec["_Myfirst"]; // MSVC2008
if (myFirst) if (myFirst)
if (const ULONG64 address = myFirst.pointerValue()) if (const ULONG64 address = myFirst.pointerValue())
return arrayChildList(n->symbolGroup(), address, count, return arrayChildList(n->symbolGroup(), address,
SymbolGroupValue::stripPointerType(myFirst.type())); SymbolGroupValue::stripPointerType(myFirst.type()),
count);
} }
return SymbolGroupNodePtrVector(); return SymbolGroupNodePtrVector();
} }
@@ -87,28 +265,62 @@ static inline SymbolGroupNodePtrVector
const SymbolGroupValue vec(n, ctx); const SymbolGroupValue vec(n, ctx);
if (const SymbolGroupValue firstElementV = vec["p"]["array"][unsigned(0)]) if (const SymbolGroupValue firstElementV = vec["p"]["array"][unsigned(0)])
if (const ULONG64 arrayAddress = firstElementV.address()) if (const ULONG64 arrayAddress = firstElementV.address())
return arrayChildList(n->symbolGroup(), arrayAddress, count, return arrayChildList(n->symbolGroup(), arrayAddress,
firstElementV.type()); firstElementV.type(), count);
} }
return SymbolGroupNodePtrVector(); return SymbolGroupNodePtrVector();
} }
// QList<> of type array // QList<> of type array: Applicable for POD/pointer types and movable Qt types.
static inline SymbolGroupNodePtrVector static inline SymbolGroupNodePtrVector
qListOfArraryTypeChildren(SymbolGroup *sg, const SymbolGroupValue &v, int count) qListChildList(const SymbolGroupValue &v, int count)
{ {
// QList<T>: d/array is declared as array of void *[]. Dereference first // QList<T>: d/array is declared as array of void *[]. Dereference first
// element to obtain address. // element to obtain address.
if (count) { if (!count)
if (const SymbolGroupValue firstElementV = v["d"]["array"][unsigned(0)]) return SymbolGroupNodePtrVector();
if (const ULONG64 arrayAddress = firstElementV.address()) { const SymbolGroupValue dV = v["d"];
const std::vector<std::string> innerTypes = v.innerTypes(); if (!dV)
if (innerTypes.size() == 1) return SymbolGroupNodePtrVector();
return arrayChildList(sg, arrayAddress, const int begin = dV["begin"].intValue();
count, innerTypes.front()); if (begin < 0)
} return SymbolGroupNodePtrVector();
} const SymbolGroupValue firstElementV = dV["array"][unsigned(0)];
return SymbolGroupNodePtrVector(); if (!firstElementV)
return SymbolGroupNodePtrVector();
const ULONG64 arrayAddress = firstElementV.address();
if (!arrayAddress)
return SymbolGroupNodePtrVector();
const std::vector<std::string> innerTypes = v.innerTypes();
if (innerTypes.size() != 1)
return SymbolGroupNodePtrVector();
const std::string &innerType = innerTypes.front();
const unsigned innerTypeSize = SymbolGroupValue::sizeOf(innerType.c_str());
if (!innerTypeSize)
return SymbolGroupNodePtrVector();
// QList<> is:
// 1) An array of 'T[]' for POD/pointer types and small, movable or primitive Qt types.
// 2) An array of 'T *[]' for anything else (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic)
// isStatic depends on QTypeInfo specializations and hardcoded flags for types.
if (SymbolGroupValue::isPointerType(innerType)) // Quick check: Any pointer is T[]
return arrayChildList(v.node()->symbolGroup(),
arrayAddress + begin * innerTypeSize,
innerType, innerTypeSize, count);
// Check condition for large||static.
bool isLargeOrStatic = innerTypeSize > SymbolGroupValue::pointerSize();
if (!isLargeOrStatic) {
const KnownType kt = knownType(innerType, false); // inner type, no 'class ' prefix.
if (kt != KT_Unknown && !(knownType(innerType, false) & (KT_Qt_PrimitiveType|KT_Qt_MovableType)))
isLargeOrStatic = true;
}
if (isLargeOrStatic)
return arrayChildList(v.node()->symbolGroup(),
arrayAddress + begin * SymbolGroupValue::pointerSize(),
SymbolGroupValue::addPointerType(innerType),
SymbolGroupValue::pointerSize(), count);
return arrayChildList(v.node()->symbolGroup(),
arrayAddress + begin * innerTypeSize,
innerType, innerTypeSize, count);
} }
SymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int type, SymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int type,
@@ -123,13 +335,24 @@ SymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int type,
return qVectorChildList(node, size, ctx); return qVectorChildList(node, size, ctx);
case KT_StdVector: case KT_StdVector:
return stdVectorChildList(node, size, ctx); return stdVectorChildList(node, size, ctx);
case KT_QLinkedList:
return qLinkedListChildList(node, size, ctx);
case KT_QList: case KT_QList:
// Differentiate between array and list return qListChildList(SymbolGroupValue(node, ctx), size);
case KT_QQueue:
if (const SymbolGroupValue qList = SymbolGroupValue(node, ctx)[unsigned(0)])
return qListChildList(qList, size);
break;
case KT_QStack:
if (const SymbolGroupValue qVector = SymbolGroupValue(node, ctx)[unsigned(0)])
return qVectorChildList(qVector.node(), size, ctx);
break; break;
case KT_QStringList: case KT_QStringList:
if (const SymbolGroupValue qList = SymbolGroupValue(node, ctx)[unsigned(0)]) if (const SymbolGroupValue qList = SymbolGroupValue(node, ctx)[unsigned(0)])
return qListOfArraryTypeChildren(node->symbolGroup(), qList, size); return qListChildList(qList, size);
break; break;
case KT_StdList:
return stdListChildList(node, size , ctx);
} }
return SymbolGroupNodePtrVector(); return SymbolGroupNodePtrVector();
} }

View File

@@ -32,11 +32,17 @@
struct SymbolGroupValueContext; struct SymbolGroupValueContext;
class SymbolGroupNode; class SymbolGroupNode;
class SymbolGroupValue;
#include "common.h" #include "common.h"
#include "knowntype.h"
#include <vector> #include <vector>
// Determine size of containers
int containerSize(KnownType kt, const SymbolGroupValue &v);
int containerSize(KnownType kt, SymbolGroupNode *n, const SymbolGroupValueContext &ctx);
/* Create a list of children of containers. */ /* Create a list of children of containers. */
std::vector<SymbolGroupNode *> containerChildren(SymbolGroupNode *node, std::vector<SymbolGroupNode *> containerChildren(SymbolGroupNode *node,
int type, int type,

View File

@@ -0,0 +1,156 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef KNOWNTYPE_H
#define KNOWNTYPE_H
// Helpers for detecting types
enum KnownType
{
KT_Unknown =0,
KT_Qt_Type = 0x10000,
KT_Qt_PrimitiveType = 0x20000,
KT_Qt_MovableType = 0x40000,
KT_STL_Type = 0x80000,
KT_ContainerType = 0x100000,
// Qt Basic
KT_QChar = KT_Qt_Type + KT_Qt_MovableType + 1,
KT_QByteArray = KT_Qt_Type + KT_Qt_MovableType + 2,
KT_QString = KT_Qt_Type + KT_Qt_MovableType + 3,
KT_QColor = KT_Qt_Type + 4,
KT_QFlags = KT_Qt_Type + 5,
KT_QDate = KT_Qt_Type + KT_Qt_MovableType + 6,
KT_QTime = KT_Qt_Type + KT_Qt_MovableType + 7,
KT_QPoint = KT_Qt_Type + KT_Qt_MovableType + 8,
KT_QPointF = KT_Qt_Type +KT_Qt_MovableType + 9,
KT_QSize = KT_Qt_Type + KT_Qt_MovableType + 11,
KT_QSizeF = KT_Qt_Type + KT_Qt_MovableType + 12,
KT_QLine = KT_Qt_Type + KT_Qt_MovableType + 13,
KT_QLineF = KT_Qt_Type + KT_Qt_MovableType + 14,
KT_QRect = KT_Qt_Type + KT_Qt_MovableType + 15,
KT_QRectF = KT_Qt_Type + KT_Qt_MovableType + 16,
KT_QVariant = KT_Qt_Type + KT_Qt_MovableType + 17,
KT_QBasicAtomicInt = KT_Qt_Type + 18,
KT_QAtomicInt = KT_Qt_Type + 19,
KT_QObject = KT_Qt_Type + 20,
KT_QWidget = KT_Qt_Type + 21,
// Various QT movable types
KT_QPen = KT_Qt_Type + KT_Qt_MovableType + 30,
KT_QUrl = KT_Qt_Type + KT_Qt_MovableType + 31,
KT_QIcon = KT_Qt_Type + KT_Qt_MovableType + 32,
KT_QBrush = KT_Qt_Type + KT_Qt_MovableType + 33,
KT_QImage = KT_Qt_Type + KT_Qt_MovableType + 35,
KT_QLocale = KT_Qt_Type + KT_Qt_MovableType + 36,
KT_QMatrix = KT_Qt_Type + KT_Qt_MovableType + 37,
KT_QRegExp = KT_Qt_Type + KT_Qt_MovableType + 38,
KT_QMargins = KT_Qt_Type + KT_Qt_MovableType + 39,
KT_QXmltem = KT_Qt_Type + KT_Qt_MovableType + 40,
KT_QXmlName = KT_Qt_Type + KT_Qt_MovableType + 41,
KT_QBitArray = KT_Qt_Type + KT_Qt_MovableType + 42,
KT_QDateTime = KT_Qt_Type + KT_Qt_MovableType + 43,
KT_QFileInfo = KT_Qt_Type + KT_Qt_MovableType + 44,
KT_QMetaEnum = KT_Qt_Type + KT_Qt_MovableType + 45,
KT_QVector2D = KT_Qt_Type + KT_Qt_MovableType + 46,
KT_QVector3D = KT_Qt_Type + KT_Qt_MovableType + 47,
KT_QVector4D = KT_Qt_Type + KT_Qt_MovableType + 48,
KT_QMatrix4x4 = KT_Qt_Type + KT_Qt_MovableType + 49,
KT_QTextBlock = KT_Qt_Type + KT_Qt_MovableType + 50,
KT_QTransform = KT_Qt_Type + KT_Qt_MovableType + 51,
KT_QBasicTimer = KT_Qt_Type + KT_Qt_MovableType + 52,
KT_QMetaMethod = KT_Qt_Type + KT_Qt_MovableType + 53,
KT_QModelIndex = KT_Qt_Type + KT_Qt_MovableType + 54,
KT_QQuaternion = KT_Qt_Type + KT_Qt_MovableType + 55,
KT_QScriptItem = KT_Qt_Type + KT_Qt_MovableType + 56,
KT_QKeySequence = KT_Qt_Type + KT_Qt_MovableType + 57,
KT_QTextFragment = KT_Qt_Type + KT_Qt_MovableType + 58,
KT_QTreeViewItem = KT_Qt_Type + KT_Qt_MovableType + 59,
KT_QMetaClassInfo = KT_Qt_Type + KT_Qt_MovableType + 60,
KT_QNetworkCookie = KT_Qt_Type + KT_Qt_MovableType + 61,
KT_QHashDummyValue = KT_Qt_Type + KT_Qt_MovableType + 62,
KT_QSourceLocation = KT_Qt_Type + KT_Qt_MovableType + 63,
KT_QNetworkProxyQuery = KT_Qt_Type + KT_Qt_MovableType + 64,
KT_QXmlNodeModelIndex = KT_Qt_Type + KT_Qt_MovableType + 65,
KT_QItemSelectionRange = KT_Qt_Type + KT_Qt_MovableType + 66,
KT_QPaintBufferCommand = KT_Qt_Type + KT_Qt_MovableType + 67,
KT_QTextHtmlParserNode = KT_Qt_Type + KT_Qt_MovableType + 68,
KT_QXmlStreamAttribute = KT_Qt_Type + KT_Qt_MovableType + 69,
KT_QTextBlock_iterator = KT_Qt_Type + KT_Qt_MovableType + 70,
KT_QTextFrame_iterator = KT_Qt_Type + KT_Qt_MovableType + 71,
KT_QPersistentModelIndex = KT_Qt_Type + KT_Qt_MovableType + 72,
KT_QObjectPrivate_Sender = KT_Qt_Type + KT_Qt_MovableType + 73,
KT_QPatternist_AtomicValue = KT_Qt_Type + KT_Qt_MovableType + 74,
KT_QPatternist_Cardinality = KT_Qt_Type + KT_Qt_MovableType + 75,
KT_QObjectPrivate_Connection = KT_Qt_Type + KT_Qt_MovableType + 76,
KT_QPatternist_ItemCacheCell = KT_Qt_Type + KT_Qt_MovableType + 77,
KT_QPatternist_ItemType_Ptr = KT_Qt_Type + KT_Qt_MovableType + 78,
KT_QPatternist_NamePool_Ptr = KT_Qt_Type + KT_Qt_MovableType + 79,
KT_QXmlStreamEntityDeclaration = KT_Qt_Type + KT_Qt_MovableType + 80,
KT_QPatternist_Expression_Ptr = KT_Qt_Type + KT_Qt_MovableType + 81,
KT_QXmlStreamNotationDeclaration = KT_Qt_Type + KT_Qt_MovableType + 82,
KT_QPatternist_SequenceType_Ptr = KT_Qt_Type + KT_Qt_MovableType + 83,
KT_QXmlStreamNamespaceDeclaration = KT_Qt_Type + KT_Qt_MovableType + 84,
KT_QPatternist_Item_Iterator_Ptr = KT_Qt_Type + KT_Qt_MovableType + 85,
KT_QPatternist_ItemSequenceCacheCell = KT_Qt_Type + KT_Qt_MovableType + 86,
KT_QNetworkHeadersPrivate_RawHeaderPair = KT_Qt_Type + KT_Qt_MovableType + 87,
KT_QPatternist_AccelTree_BasicNodeData = KT_Qt_Type + KT_Qt_MovableType + 88,
// Qt primitive types
KT_QFixed = KT_Qt_Type + KT_Qt_PrimitiveType + 90,
KT_QTextItem = KT_Qt_Type + KT_Qt_PrimitiveType + 91,
KT_QFixedSize = KT_Qt_Type + KT_Qt_PrimitiveType + 92,
KT_QFixedPoint = KT_Qt_Type + KT_Qt_PrimitiveType + 93,
KT_QScriptLine = KT_Qt_Type + KT_Qt_PrimitiveType + 94,
KT_QScriptAnalysis = KT_Qt_Type + KT_Qt_PrimitiveType + 95,
KT_QTextUndoCommand = KT_Qt_Type + KT_Qt_PrimitiveType + 96,
KT_QGlyphJustification = KT_Qt_Type + KT_Qt_PrimitiveType + 97,
KT_QPainterPath_Element = KT_Qt_Type + KT_Qt_PrimitiveType + 98,
// Qt Containers
KT_QStringList = KT_Qt_Type + KT_ContainerType + 1,
KT_QList = KT_Qt_Type + KT_ContainerType + 2,
KT_QLinkedList = KT_Qt_Type + KT_ContainerType + 3,
KT_QVector = KT_Qt_Type + KT_ContainerType + 4,
KT_QStack = KT_Qt_Type + KT_ContainerType + 5,
KT_QQueue = KT_Qt_Type + KT_ContainerType + 6,
KT_QSet = KT_Qt_Type + KT_ContainerType + 7,
KT_QHash = KT_Qt_Type + KT_ContainerType + 8,
KT_QMap = KT_Qt_Type + KT_ContainerType + 9,
KT_QMultiMap = KT_Qt_Type + KT_ContainerType + 10,
// STL
KT_StdString = KT_STL_Type + 1,
KT_StdWString = KT_STL_Type + 2,
// STL containers
KT_StdVector = KT_STL_Type + KT_ContainerType + 1,
KT_StdList = KT_STL_Type + KT_ContainerType + 2,
KT_StdStack = KT_STL_Type + KT_ContainerType + 3,
KT_StdDeque = KT_STL_Type + KT_ContainerType + 4,
KT_StdSet = KT_STL_Type + KT_ContainerType + 5,
KT_StdMap = KT_STL_Type + KT_ContainerType + 6,
KT_StdMultiMap = KT_STL_Type + KT_ContainerType + 7,
};
#endif // KNOWNTYPE_H

View File

@@ -67,4 +67,5 @@ HEADERS += extensioncontext.h \
outputcallback.h \ outputcallback.h \
base64.h \ base64.h \
symbolgroupvalue.h \ symbolgroupvalue.h \
containers.h containers.h \
knowntype.h

View File

@@ -73,6 +73,8 @@ std::wstring toWString(const Streamable s)
} }
bool endsWith(const std::string &haystack, const char *needle); bool endsWith(const std::string &haystack, const char *needle);
inline bool endsWith(const std::string &haystack, char needle)
{ return !haystack.empty() && haystack.at(haystack.size() - 1) == needle; }
// Read an integer from a string as '10' or '0xA' // Read an integer from a string as '10' or '0xA'
template <class Integer> template <class Integer>

View File

@@ -756,6 +756,8 @@ std::wstring SymbolGroupNode::simpleDumpValue(const SymbolGroupValueContext &ctx
{ {
if (m_flags & Uninitialized) if (m_flags & Uninitialized)
return L"<not in scope>"; return L"<not in scope>";
if (m_flags & SimpleDumperOk)
return m_dumperValue;
if ((m_flags & SimpleDumperMask) == 0) { if ((m_flags & SimpleDumperMask) == 0) {
m_flags |= dumpSimpleType(this , ctx, &m_dumperValue, m_flags |= dumpSimpleType(this , ctx, &m_dumperValue,
&m_dumperType, &m_dumperContainerSize); &m_dumperType, &m_dumperContainerSize);

View File

@@ -30,6 +30,7 @@
#include "symbolgroupvalue.h" #include "symbolgroupvalue.h"
#include "symbolgroup.h" #include "symbolgroup.h"
#include "stringutils.h" #include "stringutils.h"
#include "containers.h"
#include <iomanip> #include <iomanip>
@@ -215,9 +216,32 @@ std::string SymbolGroupValue::error() const
return m_errorMessage; return m_errorMessage;
} }
bool SymbolGroupValue::isPointerType(const std::string &t)
{
return endsWith(t, " *");
}
unsigned SymbolGroupValue::pointerSize()
{
static unsigned ps = 0;
if (!ps)
ps = SymbolGroupValue::sizeOf("char *");
return ps;
}
std::string SymbolGroupValue::stripPointerType(const std::string &t) std::string SymbolGroupValue::stripPointerType(const std::string &t)
{ {
return endsWith(t, " *") ? t.substr(0, t.size() - 2) : t; return isPointerType(t) ? t.substr(0, t.size() - 2) : t;
}
std::string SymbolGroupValue::addPointerType(const std::string &t)
{
// 'char' -> 'char *' -> 'char **'
std::string rc = t;
if (!endsWith(rc, '*'))
rc.push_back(' ');
rc.push_back('*');
return rc;
} }
std::string SymbolGroupValue::stripArrayType(const std::string &t) std::string SymbolGroupValue::stripArrayType(const std::string &t)
@@ -344,63 +368,61 @@ static inline void formatMilliSeconds(std::wostream &str, int milliSecs)
<< '.' << std::setw(3) << milliSecs; << '.' << std::setw(3) << milliSecs;
} }
static const char stdStringTypeC[] = "std::basic_string<char,std::char_traits<char>,std::allocator<char> >";
static const char stdWStringTypeC[] = "std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >";
static const char stdStringTypeC[] = "class std::basic_string<char,std::char_traits<char>,std::allocator<char> >"; // Determine type starting from a position (with/without 'class '/'struct ' prefix).
static const char stdWStringTypeC[] = "class std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >"; static KnownType knownTypeHelper(const std::string &type, std::string::size_type pos)
// Dump a QString.
KnownType knownType(const std::string &type)
{ {
// Make sure this is 'class X' or 'struct X'. Strip that and pointer
if (type.empty() || (type.at(0) != 'c' && type.at(0) != 's'))
return KT_Unknown;
const bool isClass = type.compare(0, 6, "class ") != 0;
const bool isStruct = isClass ? false : type.compare(0, 7, "struct ") != 0;
if (!isClass && !isStruct)
return KT_Unknown;
// Strip pointer types. // Strip pointer types.
const std::wstring::size_type compareLen = const std::wstring::size_type compareLen =
endsWith(type, " *") ? type.size() -2 : type.size(); endsWith(type, " *") ? type.size() -2 : type.size();
// STL ? // STL ?
const std::wstring::size_type templatePos = type.find('<'); const std::wstring::size_type templatePos = type.find('<', pos);
static const std::wstring::size_type stlClassPos = 11; static const std::wstring::size_type stlClassLen = 5;
if (!type.compare(0, stlClassPos, "class std::")) { if (!type.compare(pos, stlClassLen, "std::")) {
// STL containers // STL containers
const std::wstring::size_type hPos = pos + stlClassLen;
if (templatePos != std::string::npos) { if (templatePos != std::string::npos) {
switch (templatePos - stlClassPos) { switch (templatePos - stlClassLen - pos) {
case 3: case 3:
if (!type.compare(stlClassPos, 3, "set")) if (!type.compare(hPos, 3, "set"))
return KT_StdSet; return KT_StdSet;
if (!type.compare(stlClassPos, 3, "map")) if (!type.compare(hPos, 3, "map"))
return KT_StdMap; return KT_StdMap;
break; break;
case 4: case 4:
if (!type.compare(stlClassPos, 4, "list")) if (!type.compare(hPos, 4, "list"))
return KT_StdList; return KT_StdList;
break; break;
case 5:
if (!type.compare(hPos, 5, "stack"))
return KT_StdStack;
if (!type.compare(hPos, 5, "deque"))
return KT_StdDeque;
break;
case 6: case 6:
if (!type.compare(stlClassPos, 6, "vector")) if (!type.compare(hPos, 6, "vector"))
return KT_StdVector; return KT_StdVector;
break; break;
case 8: case 8:
if (!type.compare(stlClassPos, 8, "multimap")) if (!type.compare(hPos, 8, "multimap"))
return KT_StdMultiMap; return KT_StdMultiMap;
break; break;
} }
} }
// STL strings // STL strings
if (!type.compare(0, compareLen, stdStringTypeC)) if (!type.compare(pos, compareLen - pos, stdStringTypeC))
return KT_StdString; return KT_StdString;
if (!type.compare(0, compareLen, stdWStringTypeC)) if (!type.compare(pos, compareLen - pos, stdWStringTypeC))
return KT_StdWString; return KT_StdWString;
return KT_Unknown; return KT_Unknown;
} // std::sth } // std::sth
// Check for a 'Q' past the last namespace (beware of namespaced Qt: // Check for a 'Q' past the last namespace (beware of namespaced Qt:
// 'nsp::QString'). // 'nsp::QString').
const std::wstring::size_type lastNameSpacePos = type.rfind(':'); const std::wstring::size_type lastNameSpacePos = type.rfind(':', templatePos);
const std::wstring::size_type qPos = const std::wstring::size_type qPos =
lastNameSpacePos == std::string::npos ? type.find('Q') : lastNameSpacePos + 1; lastNameSpacePos == std::string::npos ? type.find('Q', pos) : lastNameSpacePos + 1;
if (qPos == std::string::npos || qPos >= type.size() || type.at(qPos) != 'Q') if (qPos == std::string::npos || qPos >= type.size() || type.at(qPos) != 'Q')
return KT_Unknown; return KT_Unknown;
// Qt types (templates) // Qt types (templates)
@@ -421,6 +443,10 @@ KnownType knownType(const std::string &type)
case 6: case 6:
if (!type.compare(qPos, 6, "QFlags")) if (!type.compare(qPos, 6, "QFlags"))
return KT_QFlags; return KT_QFlags;
if (!type.compare(qPos, 6, "QStack"))
return KT_QStack;
if (!type.compare(qPos, 6, "QQueue"))
return KT_QQueue;
break; break;
case 7: case 7:
if (!type.compare(qPos, 7, "QVector")) if (!type.compare(qPos, 7, "QVector"))
@@ -430,10 +456,21 @@ KnownType knownType(const std::string &type)
if (!type.compare(qPos, 9, "QMultiMap")) if (!type.compare(qPos, 9, "QMultiMap"))
return KT_QMultiMap; return KT_QMultiMap;
break; break;
case 11:
if (!type.compare(qPos, 11, "QLinkedList"))
return KT_QLinkedList;
break;
} }
} }
// Remaining non-template types // Remaining non-template types
switch (compareLen - qPos) { switch (compareLen - qPos) {
case 4:
if (!type.compare(qPos, 4, "QPen"))
return KT_QPen;
if (!type.compare(qPos, 4, "QUrl"))
return KT_QUrl;
break;
case 5: case 5:
if (!type.compare(qPos, 5, "QChar")) if (!type.compare(qPos, 5, "QChar"))
return KT_QChar; return KT_QChar;
@@ -447,6 +484,8 @@ KnownType knownType(const std::string &type)
return KT_QLine; return KT_QLine;
if (!type.compare(qPos, 5, "QRect")) if (!type.compare(qPos, 5, "QRect"))
return KT_QRect; return KT_QRect;
if (!type.compare(qPos, 5, "QIcon"))
return KT_QIcon;
break; break;
case 6: case 6:
if (!type.compare(qPos, 6, "QColor")) if (!type.compare(qPos, 6, "QColor"))
@@ -459,6 +498,12 @@ KnownType knownType(const std::string &type)
return KT_QLineF; return KT_QLineF;
if (!type.compare(qPos, 6, "QRectF")) if (!type.compare(qPos, 6, "QRectF"))
return KT_QRectF; return KT_QRectF;
if (!type.compare(qPos, 6, "QBrush"))
return KT_QBrush;
if (!type.compare(qPos, 6, "QImage"))
return KT_QImage;
if (!type.compare(qPos, 6, "QFixed"))
return KT_QFixed;
break; break;
case 7: case 7:
if (!type.compare(qPos, 7, "QString")) if (!type.compare(qPos, 7, "QString"))
@@ -469,25 +514,207 @@ KnownType knownType(const std::string &type)
return KT_QObject; return KT_QObject;
if (!type.compare(qPos, 7, "QWidget")) if (!type.compare(qPos, 7, "QWidget"))
return KT_QWidget; return KT_QWidget;
if (!type.compare(qPos, 7, "QLocale"))
return KT_QLocale;
if (!type.compare(qPos, 7, "QMatrix"))
return KT_QMatrix;
if (!type.compare(qPos, 7, "QRegExp"))
return KT_QRegExp;
break; break;
case 8: case 8:
if (!type.compare(qPos, 8, "QVariant")) if (!type.compare(qPos, 8, "QVariant"))
return KT_QVariant; return KT_QVariant;
if (!type.compare(qPos, 8, "QMargins"))
return KT_QMargins;
if (!type.compare(qPos, 8, "QXmlItem"))
return KT_QXmltem;
if (!type.compare(qPos, 8, "QXmlName"))
return KT_QXmlName;
break;
case 9:
if (!type.compare(qPos, 9, "QBitArray"))
return KT_QBitArray;
if (!type.compare(qPos, 9, "QDateTime"))
return KT_QDateTime;
if (!type.compare(qPos, 9, "QFileInfo"))
return KT_QFileInfo;
if (!type.compare(qPos, 9, "QMetaEnum"))
return KT_QMetaEnum;
if (!type.compare(qPos, 9, "QTextItem"))
return KT_QTextItem;
if (!type.compare(qPos, 9, "QVector2D"))
return KT_QVector2D;
if (!type.compare(qPos, 9, "QVector3D"))
return KT_QVector3D;
if (!type.compare(qPos, 9, "QVector4D"))
return KT_QVector4D;
break; break;
case 10: case 10:
if (!type.compare(qPos, 10, "QAtomicInt")) if (!type.compare(qPos, 10, "QAtomicInt"))
return KT_QAtomicInt; return KT_QAtomicInt;
if (!type.compare(qPos, 10, "QByteArray")) if (!type.compare(qPos, 10, "QByteArray"))
return KT_QByteArray; return KT_QByteArray;
if (!type.compare(qPos, 10, "QMatrix4x4"))
return KT_QMatrix4x4;
if (!type.compare(qPos, 10, "QTextBlock"))
return KT_QTextBlock;
if (!type.compare(qPos, 10, "QTransform"))
return KT_QTransform;
if (!type.compare(qPos, 10, "QFixedSize"))
return KT_QFixedSize;
break; break;
case 11: case 11:
if (!type.compare(qPos, 11, "QStringList")) if (!type.compare(qPos, 11, "QStringList"))
return KT_QStringList; return KT_QStringList;
if (!type.compare(qPos, 11, "QBasicTimer"))
return KT_QBasicTimer;
if (!type.compare(qPos, 11, "QMetaMethod"))
return KT_QMetaMethod;
if (!type.compare(qPos, 11, "QModelIndex"))
return KT_QModelIndex;
if (!type.compare(qPos, 11, "QQuaternion"))
return KT_QQuaternion;
if (!type.compare(qPos, 11, "QScriptItem"))
return KT_QScriptItem;
if (!type.compare(qPos, 11, "QFixedPoint"))
return KT_QFixedPoint;
if (!type.compare(qPos, 11, "QScriptLine"))
return KT_QScriptLine;
break;
case 12:
if (!type.compare(qPos, 12, "QKeySequence"))
return KT_QKeySequence;
break;
case 13:
if (!type.compare(qPos, 13, "QTextFragment"))
return KT_QTextFragment;
if (!type.compare(qPos, 13, "QTreeViewItem"))
return KT_QTreeViewItem;
break;
case 14:
if (!type.compare(qPos, 14, "QMetaClassInfo"))
return KT_QMetaClassInfo;
if (!type.compare(qPos, 14, "QNetworkCookie"))
return KT_QNetworkCookie;
break; break;
case 15: case 15:
if (!type.compare(qPos, 15, "QBasicAtomicInt")) if (!type.compare(qPos, 15, "QBasicAtomicInt"))
return KT_QBasicAtomicInt; return KT_QBasicAtomicInt;
if (!type.compare(qPos, 15, "QHashDummyValue"))
return KT_QHashDummyValue;
if (!type.compare(qPos, 15, "QSourceLocation"))
return KT_QSourceLocation;
if (!type.compare(qPos, 15, "QScriptAnalysis"))
return KT_QScriptAnalysis;
break; break;
case 16:
if (!type.compare(qPos, 16, "QTextUndoCommand"))
return KT_QTextUndoCommand;
break;
case 18:
if (!type.compare(qPos, 18, "QNetworkProxyQuery"))
return KT_QNetworkProxyQuery;
if (!type.compare(qPos, 18, "QXmlNodeModelIndex"))
return KT_QXmlNodeModelIndex;
break;
case 19:
if (!type.compare(qPos, 19, "QItemSelectionRange"))
return KT_QItemSelectionRange;
if (!type.compare(qPos, 19, "QPaintBufferCommand"))
return KT_QPaintBufferCommand;
if (!type.compare(qPos, 19, "QTextHtmlParserNode"))
return KT_QTextHtmlParserNode;
if (!type.compare(qPos, 19, "QXmlStreamAttribute"))
return KT_QXmlStreamAttribute;
if (!type.compare(qPos, 19, "QGlyphJustification"))
return KT_QGlyphJustification;
break;
case 20:
if (!type.compare(qPos, 20, "QTextBlock::iterator"))
return KT_QTextBlock_iterator;
if (!type.compare(qPos, 20, "QTextFrame::iterator"))
return KT_QTextFrame_iterator;
break;
case 21:
if (!type.compare(qPos, 21, "QPersistentModelIndex"))
return KT_QPersistentModelIndex;
if (!type.compare(qPos, 21, "QPainterPath::Element"))
return KT_QPainterPath_Element;
break;
case 22:
if (!type.compare(qPos, 22, "QObjectPrivate::Sender"))
return KT_QObjectPrivate_Sender;
break;
case 24:
if (!type.compare(qPos, 24, "QPatternist::AtomicValue"))
return KT_QPatternist_AtomicValue;
if (!type.compare(qPos, 24, "QPatternist::Cardinality"))
return KT_QPatternist_Cardinality;
break;
case 26:
if (!type.compare(qPos, 26, "QObjectPrivate::Connection"))
return KT_QObjectPrivate_Connection;
if (!type.compare(qPos, 26, "QPatternist::ItemCacheCell"))
return KT_QPatternist_ItemCacheCell;
if (!type.compare(qPos, 26, "QPatternist::ItemType::Ptr"))
return KT_QPatternist_ItemType_Ptr;
if (!type.compare(qPos, 26, "QPatternist::NamePool::Ptr"))
return KT_QPatternist_NamePool_Ptr;
break;
case 27:
if (!type.compare(qPos, 27, "QXmlStreamEntityDeclaration"))
return KT_QXmlStreamEntityDeclaration;
break;
case 28:
if (!type.compare(qPos, 28, "QPatternist::Expression::Ptr"))
return KT_QPatternist_Expression_Ptr;
break;
case 29:
if (!type.compare(qPos, 29, "QXmlStreamNotationDeclaration"))
return KT_QXmlStreamNotationDeclaration;
case 30:
if (!type.compare(qPos, 30, "QPatternist::SequenceType::Ptr"))
return KT_QPatternist_SequenceType_Ptr;
if (!type.compare(qPos, 30, "QXmlStreamNamespaceDeclaration"))
return KT_QXmlStreamNamespaceDeclaration;
break;
case 32:
break;
if (!type.compare(qPos, 32, "QPatternist::Item::Iterator::Ptr"))
return KT_QPatternist_Item_Iterator_Ptr;
case 34:
break;
if (!type.compare(qPos, 34, "QPatternist::ItemSequenceCacheCell"))
return KT_QPatternist_ItemSequenceCacheCell;
case 37:
break;
if (!type.compare(qPos, 37, "QNetworkHeadersPrivate::RawHeaderPair"))
return KT_QNetworkHeadersPrivate_RawHeaderPair;
if (!type.compare(qPos, 37, "QPatternist::AccelTree::BasicNodeData"))
return KT_QPatternist_AccelTree_BasicNodeData;
break;
}
return KT_Unknown;
}
KnownType knownType(const std::string &type, bool hasClassPrefix)
{
if (type.empty())
return KT_Unknown;
if (hasClassPrefix) {
switch (type.at(0)) { // Check 'class X' or 'struct X'
case 'c':
if (!type.compare(0, 6, "class "))
return knownTypeHelper(type, 6);
break;
case 's':
if (!type.compare(0, 7, "struct "))
return knownTypeHelper(type, 7);
break;
}
} else {
// No prefix, full check
return knownTypeHelper(type, 0);
} }
return KT_Unknown; return KT_Unknown;
} }
@@ -847,100 +1074,6 @@ static bool dumpQVariant(const SymbolGroupValue &v, std::wostream &str)
return true; return true;
} }
// Return size of container or -1
int containerSize(KnownType kt, SymbolGroupNode *n, const SymbolGroupValueContext &ctx)
{
if ((kt & KT_ContainerType) == 0)
return -1;
return containerSize(kt, SymbolGroupValue(n, ctx));
}
// Return size from an STL vector (last/first iterators).
static inline int msvcStdVectorSize(const SymbolGroupValue &v)
{
if (const SymbolGroupValue myFirstPtrV = v["_Myfirst"]) {
if (const SymbolGroupValue myLastPtrV = v["_Mylast"]) {
const ULONG64 firstPtr = myFirstPtrV.pointerValue();
const ULONG64 lastPtr = myLastPtrV.pointerValue();
if (!firstPtr || lastPtr < firstPtr)
return -1;
if (lastPtr == firstPtr)
return 0;
// Subtract the pointers: We need to do the pointer arithmetics ourselves
// as we get char *pointers.
const std::string innerType = SymbolGroupValue::stripPointerType(myFirstPtrV.type());
const size_t size = SymbolGroupValue::sizeOf(innerType.c_str());
if (size == 0)
return -1;
return static_cast<int>((lastPtr - firstPtr) / size);
}
}
return -1;
}
int containerSize(KnownType kt, const SymbolGroupValue &v)
{
switch (kt) {
case KT_QStringList:
if (const SymbolGroupValue base = v[unsigned(0)])
return containerSize(KT_QList, base);
break;
case KT_QList:
if (const SymbolGroupValue dV = v["d"]) {
if (const SymbolGroupValue beginV = dV["begin"]) {
const int begin = beginV.intValue();
const int end = dV["end"].intValue();
if (begin >= 0 && end >= begin)
return end - begin;
}
}
break;
case KT_QHash:
case KT_QMap:
case KT_QVector:
if (const SymbolGroupValue sizeV = v["d"]["size"])
return sizeV.intValue();
break;
case KT_QSet:
if (const SymbolGroupValue base = v[unsigned(0)])
return containerSize(KT_QHash, base);
break;
case KT_QMultiMap:
if (const SymbolGroupValue base = v[unsigned(0)])
return containerSize(KT_QMap, base);
break;
case KT_StdVector: {
if (const SymbolGroupValue base = v[unsigned(0)]) {
const int msvc10Size = msvcStdVectorSize(base);
if (msvc10Size >= 0)
return msvc10Size;
}
const int msvc8Size = msvcStdVectorSize(v);
if (msvc8Size >= 0)
return msvc8Size;
}
break;
case KT_StdList:
if (const SymbolGroupValue sizeV = v["_Mysize"]) // VS 8
return sizeV.intValue();
if (const SymbolGroupValue sizeV = v[unsigned(0)][unsigned(0)]["_Mysize"]) // VS10
return sizeV.intValue();
break;
case KT_StdSet:
case KT_StdMap:
case KT_StdMultiMap:
if (const SymbolGroupValue baseV = v[unsigned(0)]) {
if (const SymbolGroupValue sizeV = baseV["_Mysize"]) // VS 8
return sizeV.intValue();
if (const SymbolGroupValue sizeV = baseV[unsigned(0)][unsigned(0)]["_Mysize"]) // VS 10
return sizeV.intValue();
}
break;
}
return -1;
}
static inline std::wstring msgContainerSize(int s) static inline std::wstring msgContainerSize(int s)
{ {
std::wostringstream str; std::wostringstream str;

View File

@@ -31,6 +31,7 @@
#define SYMBOLGROUPVALUE_H #define SYMBOLGROUPVALUE_H
#include "common.h" #include "common.h"
#include "knowntype.h"
#include <string> #include <string>
#include <vector> #include <vector>
@@ -72,6 +73,8 @@ public:
std::wstring value() const; std::wstring value() const;
unsigned size() const; unsigned size() const;
SymbolGroupNode *node() const { return m_node; }
int intValue(int defaultValue = -1) const; int intValue(int defaultValue = -1) const;
double floatValue(double defaultValue = -999) const; double floatValue(double defaultValue = -999) const;
ULONG64 pointerValue(ULONG64 defaultValue = 0) const; ULONG64 pointerValue(ULONG64 defaultValue = 0) const;
@@ -83,9 +86,14 @@ public:
std::string error() const; std::string error() const;
// Some helpers for manipulating types.
static inline unsigned sizeOf(const char *type) { return GetTypeSize(type); } static inline unsigned sizeOf(const char *type) { return GetTypeSize(type); }
static std::string stripPointerType(const std::string &); static std::string stripPointerType(const std::string &);
static std::string addPointerType(const std::string &);
static std::string stripArrayType(const std::string &); static std::string stripArrayType(const std::string &);
static bool isPointerType(const std::string &);
static unsigned pointerSize();
// get the inner types: "QMap<int, double>" -> "int", "double" // get the inner types: "QMap<int, double>" -> "int", "double"
static std::vector<std::string> innerTypesOf(const std::string &t); static std::vector<std::string> innerTypesOf(const std::string &t);
@@ -98,53 +106,12 @@ private:
mutable std::string m_errorMessage; mutable std::string m_errorMessage;
}; };
// Helpers for detecting types /* Helpers for detecting types reported from IDebugSymbolGroup
enum KnownType { * 1) Class prefix==true is applicable to outer types obtained from
KT_Unknown =0, * from IDebugSymbolGroup: 'class foo' or 'struct foo'.
KT_Qt_Type = 0x10000, * 2) Class prefix==false is for inner types of templates, etc, doing
KT_STL_Type = 0x20000, * a more expensive check: 'foo' */
KT_ContainerType = 0x40000, KnownType knownType(const std::string &type, bool hasClassPrefix = true);
// Qt Basic
KT_QChar = KT_Qt_Type + 1,
KT_QByteArray = KT_Qt_Type + 2,
KT_QString = KT_Qt_Type + 3,
KT_QColor = KT_Qt_Type + 4,
KT_QFlags = KT_Qt_Type + 5,
KT_QDate = KT_Qt_Type + 6,
KT_QTime = KT_Qt_Type + 7,
KT_QPoint = KT_Qt_Type + 8,
KT_QPointF = KT_Qt_Type + 9,
KT_QSize = KT_Qt_Type + 11,
KT_QSizeF = KT_Qt_Type + 12,
KT_QLine = KT_Qt_Type + 13,
KT_QLineF = KT_Qt_Type + 14,
KT_QRect = KT_Qt_Type + 15,
KT_QRectF = KT_Qt_Type + 16,
KT_QVariant = KT_Qt_Type + 17,
KT_QBasicAtomicInt = KT_Qt_Type + 18,
KT_QAtomicInt = KT_Qt_Type + 19,
KT_QObject = KT_Qt_Type + 20,
KT_QWidget = KT_Qt_Type + 21,
// Qt Containers
KT_QStringList = KT_Qt_Type + KT_ContainerType + 1,
KT_QList = KT_Qt_Type + KT_ContainerType + 2,
KT_QVector = KT_Qt_Type + KT_ContainerType + 3,
KT_QSet = KT_Qt_Type + KT_ContainerType + 4,
KT_QHash = KT_Qt_Type + KT_ContainerType + 5,
KT_QMap = KT_Qt_Type + KT_ContainerType + 6,
KT_QMultiMap = KT_Qt_Type + KT_ContainerType + 7,
// STL
KT_StdString = KT_STL_Type + 1,
KT_StdWString = KT_STL_Type + 2,
// STL containers
KT_StdVector = KT_STL_Type + KT_ContainerType + 1,
KT_StdList = KT_STL_Type + KT_ContainerType + 2,
KT_StdSet = KT_STL_Type + KT_ContainerType + 3,
KT_StdMap = KT_STL_Type + KT_ContainerType + 4,
KT_StdMultiMap = KT_STL_Type + KT_ContainerType + 5,
};
KnownType knownType(const std::string &type);
// Dump builtin simple types using SymbolGroupValue expressions, // Dump builtin simple types using SymbolGroupValue expressions,
// returning SymbolGroupNode dumper flags. // returning SymbolGroupNode dumper flags.
@@ -153,8 +120,4 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
int *knownType = 0, int *knownType = 0,
int *containerSizeIn = 0); int *containerSizeIn = 0);
// Return size of container or -1
int containerSize(KnownType ct, const SymbolGroupValue &v);
int containerSize(KnownType ct, SymbolGroupNode *n, const SymbolGroupValueContext &ctx);
#endif // SYMBOLGROUPVALUE_H #endif // SYMBOLGROUPVALUE_H