diff options
author | dt <qtc-committer@nokia.com> | 2009-07-02 16:46:45 +0200 |
---|---|---|
committer | dt <qtc-committer@nokia.com> | 2009-07-02 16:46:45 +0200 |
commit | 7efeb1042e1f944386e0006c8345441462299d5a (patch) | |
tree | 9311049cbfd3be571ecc64b856de80f3b0708bd5 /src | |
parent | 40ff6ab2c492b939b45920347c9ea4a227713488 (diff) | |
parent | 6e93f4544d1f9b0fafc3f0d80a3f7049533fa8c0 (diff) | |
download | qt-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.cpp | 179 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditor.h | 9 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdbdumperhelper.cpp | 11 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdbdumperhelper.h | 4 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdbstackframecontext.cpp | 25 | ||||
-rw-r--r-- | src/plugins/debugger/watchutils.cpp | 155 | ||||
-rw-r--r-- | src/plugins/debugger/watchutils.h | 28 |
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 ¤tRenameSelection, + 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 ¤tRenameSelection = 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 ¤tRenameSelection, + 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; }; |