summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordt <qtc-committer@nokia.com>2009-07-02 16:46:45 +0200
committerdt <qtc-committer@nokia.com>2009-07-02 16:46:45 +0200
commit7efeb1042e1f944386e0006c8345441462299d5a (patch)
tree9311049cbfd3be571ecc64b856de80f3b0708bd5 /src
parent40ff6ab2c492b939b45920347c9ea4a227713488 (diff)
parent6e93f4544d1f9b0fafc3f0d80a3f7049533fa8c0 (diff)
downloadqt-creator-7efeb1042e1f944386e0006c8345441462299d5a.tar.gz
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
Diffstat (limited to 'src')
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp179
-rw-r--r--src/plugins/cppeditor/cppeditor.h9
-rw-r--r--src/plugins/debugger/cdb/cdbdumperhelper.cpp11
-rw-r--r--src/plugins/debugger/cdb/cdbdumperhelper.h4
-rw-r--r--src/plugins/debugger/cdb/cdbstackframecontext.cpp25
-rw-r--r--src/plugins/debugger/watchutils.cpp155
-rw-r--r--src/plugins/debugger/watchutils.h28
7 files changed, 254 insertions, 157 deletions
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 5295a01350..8b3b62a99d 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -654,6 +654,48 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
static_cast<QHBoxLayout*>(w->layout())->insertWidget(0, m_methodCombo, 1);
}
+void CPPEditor::inAllRenameSelections(EditOperation operation,
+ const QTextEdit::ExtraSelection &currentRenameSelection,
+ QTextCursor cursor,
+ const QString &text)
+{
+ m_inRename = true;
+ cursor.beginEditBlock();
+
+ const int offset = cursor.position() - currentRenameSelection.cursor.anchor();
+
+ for (int i = 0; i < m_renameSelections.size(); ++i) {
+ QTextEdit::ExtraSelection &s = m_renameSelections[i];
+ int pos = s.cursor.anchor();
+ int endPos = s.cursor.position();
+ s.cursor.setPosition(s.cursor.anchor() + offset);
+
+ switch (operation) {
+ case DeletePreviousChar:
+ s.cursor.deletePreviousChar();
+ --endPos;
+ break;
+ case DeleteChar:
+ s.cursor.deleteChar();
+ --endPos;
+ break;
+ case InsertText:
+ s.cursor.insertText(text);
+ endPos += text.length();
+ break;
+ }
+
+ s.cursor.setPosition(pos);
+ s.cursor.setPosition(endPos, QTextCursor::KeepAnchor);
+ }
+
+ cursor.endEditBlock();
+ m_inRename = false;
+
+ setExtraSelections(CodeSemanticsSelection, m_renameSelections);
+ setTextCursor(cursor);
+}
+
void CPPEditor::abortRename()
{
m_currentRenameSelection = -1;
@@ -805,7 +847,7 @@ void CPPEditor::renameInPlace()
for (int i = 0; i < m_renameSelections.size(); ++i) {
QTextEdit::ExtraSelection s = m_renameSelections.at(i);
if (c.position() >= s.cursor.anchor()
- && c.position() < s.cursor.position()) {
+ && c.position() <= s.cursor.position()) {
m_currentRenameSelection = i;
m_renameSelections[i].format.setBackground(QColor(255, 200, 200));
setExtraSelections(CodeSemanticsSelection, m_renameSelections);
@@ -816,6 +858,9 @@ void CPPEditor::renameInPlace()
void CPPEditor::onContentsChanged(int position, int charsRemoved, int charsAdded)
{
+ Q_UNUSED(position)
+ Q_UNUSED(charsAdded)
+
if (!m_inRename)
abortRename();
@@ -1372,10 +1417,6 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
foreach (QAction *action, contextMenu->actions())
menu->addAction(action);
- QAction *simplifyDeclarations = new QAction(tr("Simplify Declarations"), menu);
- connect(simplifyDeclarations, SIGNAL(triggered()), this, SLOT(simplifyDeclarations()));
- menu->addAction(simplifyDeclarations);
-
const QList<QTextEdit::ExtraSelection> selections =
extraSelections(BaseTextEditor::CodeSemanticsSelection);
@@ -1458,9 +1499,10 @@ void CPPEditor::keyPressEvent(QKeyEvent *e)
return;
}
- QTextEdit::ExtraSelection currentRenameSelection = m_renameSelections.at(m_currentRenameSelection);
-
- QTextCursor::MoveMode moveMode = (e->modifiers() & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor;
+ const QTextEdit::ExtraSelection &currentRenameSelection = m_renameSelections.at(m_currentRenameSelection);
+ QTextCursor cursor = textCursor();
+ const QTextCursor::MoveMode moveMode =
+ (e->modifiers() & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor;
switch (e->key()) {
case Qt::Key_Enter:
@@ -1470,86 +1512,50 @@ void CPPEditor::keyPressEvent(QKeyEvent *e)
e->accept();
return;
case Qt::Key_Home: {
- QTextCursor c = textCursor();
- c.setPosition(currentRenameSelection.cursor.anchor(), moveMode);
- setTextCursor(c);
- e->accept();
- return;
+ // Send home to start of name when within the name and not at the start
+ if (cursor.position() > currentRenameSelection.cursor.anchor()
+ && cursor.position() <= currentRenameSelection.cursor.position()) {
+ cursor.setPosition(currentRenameSelection.cursor.anchor(), moveMode);
+ setTextCursor(cursor);
+ e->accept();
+ return;
+ }
+ break;
}
case Qt::Key_End: {
- QTextCursor c = textCursor();
- c.setPosition(currentRenameSelection.cursor.position(), moveMode);
- setTextCursor(c);
- e->accept();
- return;
+ // Send end to end of name when within the name and not at the end
+ if (cursor.position() >= currentRenameSelection.cursor.anchor()
+ && cursor.position() < currentRenameSelection.cursor.position()) {
+ cursor.setPosition(currentRenameSelection.cursor.position(), moveMode);
+ setTextCursor(cursor);
+ e->accept();
+ return;
+ }
+ break;
}
case Qt::Key_Backspace: {
- QTextCursor c = textCursor();
-
- if (c.position() == currentRenameSelection.cursor.anchor()) {
- // Eat
+ if (cursor.position() == currentRenameSelection.cursor.anchor()) {
+ // Eat backspace at start of name
e->accept();
return;
- } else if (c.position() > currentRenameSelection.cursor.anchor()
- && c.position() <= currentRenameSelection.cursor.position()) {
-
- int offset = c.position() - currentRenameSelection.cursor.anchor();
-
- m_inRename = true;
-
- c.beginEditBlock();
- for (int i = 0; i < m_renameSelections.size(); ++i) {
- QTextEdit::ExtraSelection &s = m_renameSelections[i];
- int pos = s.cursor.anchor();
- int endPos = s.cursor.position();
- s.cursor.setPosition(s.cursor.anchor() + offset);
- s.cursor.deletePreviousChar();
- s.cursor.setPosition(pos);
- s.cursor.setPosition(endPos - 1, QTextCursor::KeepAnchor);
- }
- c.endEditBlock();
-
- m_inRename = false;
-
- setTextCursor(c);
- setExtraSelections(CodeSemanticsSelection, m_renameSelections);
+ } else if (cursor.position() > currentRenameSelection.cursor.anchor()
+ && cursor.position() <= currentRenameSelection.cursor.position()) {
+ inAllRenameSelections(DeletePreviousChar, currentRenameSelection, cursor);
e->accept();
return;
}
break;
}
case Qt::Key_Delete: {
- QTextCursor c = textCursor();
-
- if (c.position() == currentRenameSelection.cursor.position()) {
- // Eat
+ if (cursor.position() == currentRenameSelection.cursor.position()) {
+ // Eat delete at end of name
e->accept();
return;
- } else if (c.position() >= currentRenameSelection.cursor.anchor()
- && c.position() < currentRenameSelection.cursor.position()) {
-
- int offset = c.position() - currentRenameSelection.cursor.anchor();
-
- m_inRename = true;
-
- c.beginEditBlock();
- for (int i = 0; i < m_renameSelections.size(); ++i) {
- QTextEdit::ExtraSelection &s = m_renameSelections[i];
- int pos = s.cursor.anchor();
- int endPos = s.cursor.position();
- s.cursor.setPosition(s.cursor.anchor() + offset);
- s.cursor.deleteChar();
- s.cursor.setPosition(pos);
- s.cursor.setPosition(endPos - 1, QTextCursor::KeepAnchor);
- }
- c.endEditBlock();
-
- m_inRename = false;
-
- setTextCursor(c);
- setExtraSelections(CodeSemanticsSelection, m_renameSelections);
+ } else if (cursor.position() >= currentRenameSelection.cursor.anchor()
+ && cursor.position() < currentRenameSelection.cursor.position()) {
+ inAllRenameSelections(DeleteChar, currentRenameSelection, cursor);
e->accept();
return;
}
@@ -1557,34 +1563,11 @@ void CPPEditor::keyPressEvent(QKeyEvent *e)
}
default: {
QString text = e->text();
-
if (! text.isEmpty() && text.at(0).isPrint()) {
- QTextCursor c = textCursor();
-
- if (c.position() >= currentRenameSelection.cursor.anchor()
- && c.position() <= currentRenameSelection.cursor.position()) {
-
- int offset = c.position() - currentRenameSelection.cursor.anchor();
-
- m_inRename = true;
-
- c.beginEditBlock();
- for (int i = 0; i < m_renameSelections.size(); ++i) {
- QTextEdit::ExtraSelection &s = m_renameSelections[i];
- int pos = s.cursor.anchor();
- int endPos = s.cursor.position();
- s.cursor.setPosition(s.cursor.anchor() + offset);
- s.cursor.insertText(text);
- s.cursor.setPosition(pos);
- s.cursor.setPosition(endPos + text.length(), QTextCursor::KeepAnchor);
- }
- c.endEditBlock();
-
- m_inRename = false;
-
- setTextCursor(c);
- setExtraSelections(CodeSemanticsSelection, m_renameSelections);
+ if (cursor.position() >= currentRenameSelection.cursor.anchor()
+ && cursor.position() <= currentRenameSelection.cursor.position()) {
+ inAllRenameSelections(InsertText, currentRenameSelection, cursor, text);
e->accept();
return;
}
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 35d7b1a5ea..a02747f99a 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -143,6 +143,15 @@ private:
void createToolBar(CPPEditorEditable *editable);
+ enum EditOperation {
+ DeleteChar,
+ DeletePreviousChar,
+ InsertText
+ };
+ void inAllRenameSelections(EditOperation operation,
+ const QTextEdit::ExtraSelection &currentRenameSelection,
+ QTextCursor cursor,
+ const QString &text = QString());
void abortRename();
struct Link
diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.cpp b/src/plugins/debugger/cdb/cdbdumperhelper.cpp
index 910eae6aa7..0209a08e2b 100644
--- a/src/plugins/debugger/cdb/cdbdumperhelper.cpp
+++ b/src/plugins/debugger/cdb/cdbdumperhelper.cpp
@@ -576,8 +576,9 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool
return DumpOk;
// Cache types that fail due to complicated template size expressions.
// Exceptions OTOH might occur when accessing variables that are not
- // yet initialized in a particular breakpoint. That should be ignored
- if (der == DumpExecuteSizeFailed)
+ // yet initialized in a particular breakpoint. That should be ignored.
+ // Also fail for complex expression that were not cached/replaced by the helper.
+ if (der == DumpExecuteSizeFailed || der == DumpComplexExpressionEncountered)
m_failedTypes.push_back(wd.type);
// log error
*errorMessage = msgDumpFailed(wd, errorMessage);
@@ -611,6 +612,12 @@ CdbDumperHelper::DumpExecuteResult
if (!sizeOk)
return DumpExecuteSizeFailed;
ep = QString::number(size);
+ continue;
+ }
+ // We cannot evaluate any other expressions than 'sizeof()' ;-(
+ if (!ep.isEmpty() && !ep.at(0).isDigit()) {
+ *errorMessage = QString::fromLatin1("Unable to evaluate: '%1'").arg(ep);
+ return DumpComplexExpressionEncountered;
}
}
// Execute call
diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.h b/src/plugins/debugger/cdb/cdbdumperhelper.h
index ccff93f0b6..3359093ab5 100644
--- a/src/plugins/debugger/cdb/cdbdumperhelper.h
+++ b/src/plugins/debugger/cdb/cdbdumperhelper.h
@@ -109,7 +109,9 @@ private:
bool callDumper(const QString &call, const QByteArray &inBuffer, const char **outputPtr,
bool ignoreAccessViolation, QString *errorMessage);
- enum DumpExecuteResult { DumpExecuteOk, DumpExecuteSizeFailed, DumpExecuteCallFailed };
+ enum DumpExecuteResult { DumpExecuteOk, DumpExecuteSizeFailed,
+ DumpComplexExpressionEncountered,
+ DumpExecuteCallFailed };
DumpExecuteResult executeDump(const WatchData &wd,
const QtDumperHelper::TypeData& td, bool dumpChildren, int source,
QList<WatchData> *result, QString *errorMessage);
diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
index 0a4cbc1280..9cd7589636 100644
--- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
@@ -112,7 +112,7 @@ WatchHandleDumperInserter::WatchHandleDumperInserter(WatchHandler *wh,
const SharedPointerCdbDumperHelper &dumper) :
m_hexNullPattern(QLatin1String("0x0+")),
m_wh(wh),
- m_dumper(dumper)
+ m_dumper(dumper)
{
Q_ASSERT(m_hexNullPattern.isValid());
}
@@ -179,6 +179,10 @@ WatchHandleDumperInserter &WatchHandleDumperInserter::operator=(WatchData &wd)
case CdbDumperHelper::DumpOk:
if (debugCDBWatchHandling)
qDebug() << "dumper triggered";
+ // Dumpers omit types for complicated templates
+ if (!m_dumperResult.isEmpty() && m_dumperResult.front().type.isEmpty()
+ && m_dumperResult.front().iname == wd.iname)
+ m_dumperResult.front().setType(wd.type);
// Discard the original item and insert the dumper results
foreach(const WatchData &dwd, m_dumperResult)
m_wh->insertData(dwd);
@@ -245,13 +249,20 @@ bool CdbStackFrameContext::completeData(const WatchData &incompleteLocal,
errorMessage);
}
- // Expand dumper items (not implemented)
+ // Expand artifical dumper items
if (incompleteLocal.source == OwnerDumper) {
- if (debugCDBWatchHandling)
- qDebug() << "ignored dumper item";
- WatchData wd = incompleteLocal;
- wd.setAllUnneeded();
- wh->insertData(wd);
+ QList<WatchData> dumperResult;
+ const CdbDumperHelper::DumpResult dr = m_dumper->dumpType(incompleteLocal, true, OwnerDumper, &dumperResult, errorMessage);
+ if (dr == CdbDumperHelper::DumpOk) {
+ foreach(const WatchData &dwd, dumperResult)
+ wh->insertData(dwd);
+ } else {
+ const QString msg = QString::fromLatin1("Unable to further expand dumper watch data: %1 (%2): %3/%4").arg(incompleteLocal.name, incompleteLocal.type).arg(int(dr)).arg(*errorMessage);
+ qWarning("%s", qPrintable(msg));
+ WatchData wd = incompleteLocal;
+ wd.setAllUnneeded();
+ wh->insertData(wd);
+ }
return true;
}
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 60b75fdc76..6933b68ff8 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -560,14 +560,10 @@ void QtDumperHelper::TypeData::clear()
}
// ----------------- QtDumperHelper
-const QString stdAllocatorPrefix = QLatin1String("std::allocator");
-
QtDumperHelper::QtDumperHelper() :
- m_intSize(0),
- m_pointerSize(0),
- m_stdAllocatorSize(0),
m_qtVersion(0)
{
+ qFill(m_specialSizes, m_specialSizes + SpecialSizeCount, 0);
}
void QtDumperHelper::clear()
@@ -576,9 +572,8 @@ void QtDumperHelper::clear()
m_qtVersion = 0;
m_qtNamespace.clear();
m_sizeCache.clear();
- m_intSize = 0;
- m_pointerSize = 0;
- m_stdAllocatorSize = 0;
+ qFill(m_specialSizes, m_specialSizes + SpecialSizeCount, 0);
+ m_expressionCache.clear();
}
static inline void formatQtVersion(int v, QTextStream &str)
@@ -593,13 +588,15 @@ QString QtDumperHelper::toString(bool debug) const
QTextStream str(&rc);
str << "version=";
formatQtVersion(m_qtVersion, str);
- str << " namespace='" << m_qtNamespace << "'," << m_nameTypeMap.size() << " known types: ";
+ str << " namespace='" << m_qtNamespace << "'," << m_nameTypeMap.size() << " known types <type enum>: ";
const NameTypeMap::const_iterator cend = m_nameTypeMap.constEnd();
for (NameTypeMap::const_iterator it = m_nameTypeMap.constBegin(); it != cend; ++it) {
str <<",[" << it.key() << ',' << it.value() << ']';
}
- str << "Sizes: intsize=" << m_intSize << " pointer size=" << m_pointerSize
- << " allocatorsize=" << m_stdAllocatorSize;
+ str << "\nSpecial size: ";
+ for (int i = 0; i < SpecialSizeCount; i++)
+ str << ' ' << m_specialSizes[i];
+ str << "\nSize cache: ";
const SizeCache::const_iterator scend = m_sizeCache.constEnd();
for (SizeCache::const_iterator it = m_sizeCache.constBegin(); it != scend; ++it) {
str << ' ' << it.key() << '=' << it.value();
@@ -693,22 +690,23 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s)
return UnknownType;
}
-bool QtDumperHelper::needsExpressionSyntax(Type t)
+QtDumperHelper::ExpressionRequirement QtDumperHelper::expressionRequirements(Type t)
{
switch (t) {
- case QAbstractItemType:
- case QObjectSlotType:
- case QObjectSignalType:
- case QMapType:
- case QVectorType:
- case QMultiMapType:
- case QMapNodeType:
- case StdMapType:
- return true;
- default:
- break;
+ case QAbstractItemType:
+ case QObjectSlotType:
+ case QObjectSignalType:
+ case QVectorType:
+ case StdMapType:
+ return NeedsComplexExpression;
+ case QMapType:
+ case QMultiMapType:
+ case QMapNodeType:
+ return NeedsCachedExpression;
+ default:
+ break;
}
- return false;
+ return NeedsNoExpression;
}
QString QtDumperHelper::qtVersionString() const
@@ -745,7 +743,7 @@ void QtDumperHelper::parseQueryTypes(const QStringList &l, Debugger debugger)
const Type t = specialType(l.at(i));
if (t != UnknownType) {
// Exclude types that require expression syntax for CDB
- if (debugger == GdbDebugger || !needsExpressionSyntax(t))
+ if (debugger == GdbDebugger || expressionRequirements(t) != NeedsComplexExpression)
m_nameTypeMap.insert(l.at(i), t);
} else {
m_nameTypeMap.insert(l.at(i), SupportedType);
@@ -940,6 +938,7 @@ public:
QString qtVersion;
QStringList types;
QList<SizeEntry> sizes;
+ QMap<QString, QString> expressionCache;
};
inline Data data() const { return m_data; }
@@ -952,10 +951,12 @@ protected:
virtual bool handleValue(const char *k, int size);
private:
- enum Mode { None, ExpectingDumpers, ExpectingVersion, ExpectingNameSpace, ExpectingSizes };
+ enum Mode { None, ExpectingDumpers, ExpectingVersion,
+ ExpectingNameSpace, ExpectingSizes, ExpectingExpressionCache };
Mode m_mode;
Data m_data;
QString m_lastSizeType;
+ QString m_lastExpression;
};
QueryDumperParser::QueryDumperParser(const char *s) :
@@ -965,10 +966,16 @@ QueryDumperParser::QueryDumperParser(const char *s) :
}
bool QueryDumperParser::handleKeyword(const char *k, int size)
-{
- if (m_mode == ExpectingSizes) {
+{
+ switch (m_mode) {
+ case ExpectingSizes:
m_lastSizeType = QString::fromLatin1(k, size);
return true;
+ case ExpectingExpressionCache:
+ m_lastExpression = QString::fromLatin1(k, size);
+ return true;
+ default:
+ break;
}
if (!qstrncmp(k, "dumpers", size)) {
m_mode = ExpectingDumpers;
@@ -986,6 +993,10 @@ bool QueryDumperParser::handleKeyword(const char *k, int size)
m_mode = ExpectingSizes;
return true;
}
+ if (!qstrncmp(k, "expressions", size)) {
+ m_mode = ExpectingExpressionCache;
+ return true;
+ }
qWarning("%s Unexpected keyword %s.\n", Q_FUNC_INFO, QByteArray(k, size).constData());
return false;
}
@@ -1026,6 +1037,9 @@ bool QueryDumperParser::handleValue(const char *k, int size)
case ExpectingSizes:
m_data.sizes.push_back(SizeEntry(m_lastSizeType, QString::fromLatin1(k, size).toInt()));
break;
+ case ExpectingExpressionCache:
+ m_data.expressionCache.insert(m_lastExpression, QString::fromLatin1(k, size));
+ break;
}
return true;
}
@@ -1042,25 +1056,24 @@ bool QtDumperHelper::parseQuery(const char *data, Debugger debugger)
parseQueryTypes(parser.data().types, debugger);
foreach (const QueryDumperParser::SizeEntry &se, parser.data().sizes)
addSize(se.first, se.second);
+ m_expressionCache = parser.data().expressionCache;
+ qDebug() << m_expressionCache;
return true;
}
void QtDumperHelper::addSize(const QString &name, int size)
{
// Special interest cases
+ if (name == QLatin1String("char*")) {
+ m_specialSizes[PointerSize] = size;
+ return;
+ }
+ const SpecialSizeType st = specialSizeType(name);
+ if (st != SpecialSizeCount) {
+ m_specialSizes[st] = size;
+ return;
+ }
do {
- if (name == QLatin1String("char*")) {
- m_pointerSize = size;
- break;
- }
- if (name == QLatin1String("int")) {
- m_intSize = size;
- break;
- }
- if (name.startsWith(stdAllocatorPrefix)) {
- m_stdAllocatorSize = size;
- break;
- }
if (name == QLatin1String("std::string")) {
m_sizeCache.insert(QLatin1String("std::basic_string<char,std::char_traits<char>,std::allocator<char>>"), size);
break;
@@ -1104,11 +1117,13 @@ QtDumperHelper::TypeData QtDumperHelper::typeData(const QString &typeName) const
QString QtDumperHelper::evaluationSizeofTypeExpression(const QString &typeName,
Debugger /* debugger */) const
{
- // Look up fixed types
- if (m_pointerSize && isPointerType(typeName))
- return QString::number(m_pointerSize);
- if (m_stdAllocatorSize && typeName.startsWith(stdAllocatorPrefix))
- return QString::number(m_stdAllocatorSize);
+ // Look up special size types
+ const SpecialSizeType st = specialSizeType(typeName);
+ if (st != SpecialSizeCount) {
+ if (const int size = m_specialSizes[st])
+ return QString::number(size);
+ }
+ // Look up size cache
const SizeCache::const_iterator sit = m_sizeCache.constFind(typeName);
if (sit != m_sizeCache.constEnd())
return QString::number(sit.value());
@@ -1116,6 +1131,42 @@ QString QtDumperHelper::evaluationSizeofTypeExpression(const QString &typeName,
return sizeofTypeExpression(typeName);
}
+QtDumperHelper::SpecialSizeType QtDumperHelper::specialSizeType(const QString &typeName)
+{
+ if (isPointerType(typeName))
+ return PointerSize;
+ static const QString intType = QLatin1String("int");
+ static const QString stdAllocatorPrefix = QLatin1String("std::allocator");
+ static const QString qPointerPrefix = QLatin1String("QPointer");
+ static const QString qSharedPointerPrefix = QLatin1String("QSharedPointer");
+ static const QString qSharedDataPointerPrefix = QLatin1String("QSharedDataPointer");
+ static const QString qWeakPointerPrefix = QLatin1String("QWeakPointer");
+ if (typeName == intType)
+ return IntSize;
+ if (typeName.startsWith(stdAllocatorPrefix))
+ return StdAllocatorSize;
+ if (typeName.startsWith(qPointerPrefix))
+ return QPointerSize;
+ if (typeName.startsWith(qSharedPointerPrefix))
+ return QSharedPointerSize;
+ if (typeName.startsWith(qSharedDataPointerPrefix))
+ return QSharedDataPointerSize;
+ if (typeName.startsWith(qWeakPointerPrefix))
+ return QWeakPointerSize;
+ return SpecialSizeCount;
+}
+
+static inline bool isInteger(const QString &n)
+{
+ const int size = n.size();
+ if (!size)
+ return false;
+ for (int i = 0; i < size; i++)
+ if (!n.at(i).isDigit())
+ return false;
+ return true;
+}
+
void QtDumperHelper::evaluationParameters(const WatchData &data,
const TypeData &td,
Debugger debugger,
@@ -1265,6 +1316,20 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
break;
}
+ // Look up expressions in the cache
+ if (!m_expressionCache.empty()) {
+ const QMap<QString, QString>::const_iterator excCend = m_expressionCache.constEnd();
+ const QStringList::iterator eend = extraArgs.end();
+ for (QStringList::iterator it = extraArgs.begin(); it != eend; ++it) {
+ QString &e = *it;
+ if (!e.isEmpty() && e != zero && !isInteger(e)) {
+ const QMap<QString, QString>::const_iterator eit = m_expressionCache.constFind(e);
+ if (eit != excCend)
+ e = eit.value();
+ }
+ }
+ }
+
inBuffer->clear();
inBuffer->append(outertype.toUtf8());
inBuffer->append('\0');
diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h
index 52339fb0bf..d9a43d136f 100644
--- a/src/plugins/debugger/watchutils.h
+++ b/src/plugins/debugger/watchutils.h
@@ -198,7 +198,16 @@ public:
// 'data' excludes the leading indicator character.
static bool parseValue(const char *data, QtDumperResult *r);
- static bool needsExpressionSyntax(Type t);
+ // What kind of debugger expressions are required to dump that type.
+ // A debugger with restricted expression syntax can handle
+ // 'NeedsNoExpression' and 'NeedsCachedExpression' if it is found in
+ // the cache.
+ enum ExpressionRequirement {
+ NeedsNoExpression, // None, easy.
+ NeedsCachedExpression, // Common values might be found in expression cache.
+ NeedsComplexExpression // Totally arbitrary, adress-dependent expressions
+ };
+ static ExpressionRequirement expressionRequirements(Type t);
QString toString(bool debug = false) const;
@@ -214,9 +223,20 @@ private:
NameTypeMap m_nameTypeMap;
SizeCache m_sizeCache;
- int m_intSize;
- int m_pointerSize;
- int m_stdAllocatorSize;
+
+ // The initial dumper query function returns sizes of some special
+ // types to aid CDB since it cannot determine the size of classes.
+ // They are not complete (std::allocator<X>).
+ enum SpecialSizeType { IntSize, PointerSize, StdAllocatorSize,
+ QSharedPointerSize, QSharedDataPointerSize,
+ QWeakPointerSize, QPointerSize, SpecialSizeCount };
+
+ // Resolve name to enumeration or SpecialSizeCount (invalid)
+ static SpecialSizeType specialSizeType(const QString &t);
+
+ int m_specialSizes[SpecialSizeCount];
+
+ QMap<QString, QString> m_expressionCache;
int m_qtVersion;
QString m_qtNamespace;
};