diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 12de1c163e2d97bbe63791d6a36f0da75f2c8066..323ae8ca2ebbf82ae8138b39896dda2c2d3d2ccf 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -466,7 +466,7 @@ bool CdbEngine::setToolTipExpression(const QPoint &mousePos, int line; int column; DebuggerToolTipContext context = contextIn; - QString exp = cppExpressionAt(editor, context.position, &line, &column, &context.function); + QString exp = fixCppExpression(cppExpressionAt(editor, context.position, &line, &column, &context.function)); // Are we in the current stack frame if (context.function.isEmpty() || exp.isEmpty() || context.function != stackHandler()->currentFrame().function) return false; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index e2b61b11537d9b1c3e14b14cd38218714bec56c1..bfabcfcd59ba97be8df10ef6a75cd72ec08b0819 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1140,6 +1140,7 @@ public slots: int line, column; exp = cppExpressionAt(textEditor, tc.position(), &line, &column); } + exp = fixCppExpression(exp); if (exp.isEmpty()) return; currentEngine()->watchHandler()->watchExpression(exp); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 7c439020ccb1a706b80684c2e37952bbfe950cb0..9a4ddc4a901a5ad1a20a802b62a5dd63d22932b6 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3890,48 +3890,12 @@ bool GdbEngine::setToolTipExpression(const QPoint &mousePos, DebuggerToolTipContext context = contextIn; int line, column; - QString exp = cppExpressionAt(editor, context.position, &line, &column, &context.function); + const QString exp = fixCppExpression(cppExpressionAt(editor, context.position, &line, &column, &context.function)); if (DebuggerToolTipManager::debug()) qDebug() << "GdbEngine::setToolTipExpression1 " << exp << context; if (exp.isEmpty()) return false; - // Extract the first identifier, everything else is considered - // too dangerous. - int pos1 = 0, pos2 = exp.size(); - bool inId = false; - for (int i = 0; i != exp.size(); ++i) { - const QChar c = exp.at(i); - const bool isIdChar = c.isLetterOrNumber() || c.unicode() == '_'; - if (inId && !isIdChar) { - pos2 = i; - break; - } - if (!inId && isIdChar) { - inId = true; - pos1 = i; - } - } - exp = exp.mid(pos1, pos2 - pos1); - - if (exp.isEmpty() || exp.startsWith(QLatin1Char('#')) || !hasLetterOrNumber(exp) || isKeyWord(exp)) - return false; - - if (exp.startsWith(QLatin1Char('"')) && exp.endsWith(QLatin1Char('"'))) - return false; - - if (exp.startsWith(QLatin1String("++")) || exp.startsWith(QLatin1String("--"))) - exp = exp.mid(2); - - if (exp.endsWith(QLatin1String("++")) || exp.endsWith(QLatin1String("--"))) - exp = exp.mid(2); - - if (exp.startsWith(QLatin1Char('<')) || exp.startsWith(QLatin1Char('['))) - return false; - - if (hasSideEffects(exp) || exp.isEmpty()) - return false; - if (!m_toolTipContext.isNull() && m_toolTipContext->expression == exp) { showToolTip(); return true; diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index c5f142d6ea9eb75dafacde906e56b1a6c0551bff..7767dd33f2a88e8e377da7fe52adbc71a1ba7a8b 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -805,6 +805,49 @@ QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, return expr; } +// Ensure an expression can be added as side-effect +// free debugger expression. +QString fixCppExpression(const QString &expIn) +{ + QString exp = expIn; + // Extract the first identifier, everything else is considered + // too dangerous. + int pos1 = 0, pos2 = exp.size(); + bool inId = false; + for (int i = 0; i != exp.size(); ++i) { + const QChar c = exp.at(i); + const bool isIdChar = c.isLetterOrNumber() || c.unicode() == '_'; + if (inId && !isIdChar) { + pos2 = i; + break; + } + if (!inId && isIdChar) { + inId = true; + pos1 = i; + } + } + exp = exp.mid(pos1, pos2 - pos1); + + if (exp.isEmpty() || exp.startsWith(QLatin1Char('#')) || !hasLetterOrNumber(exp) || isKeyWord(exp)) + return QString(); + + if (exp.startsWith(QLatin1Char('"')) && exp.endsWith(QLatin1Char('"'))) + return QString(); + + if (exp.startsWith(QLatin1String("++")) || exp.startsWith(QLatin1String("--"))) + exp.remove(0, 2); + + if (exp.endsWith(QLatin1String("++")) || exp.endsWith(QLatin1String("--"))) + exp.truncate(exp.size() - 2); + + if (exp.startsWith(QLatin1Char('<')) || exp.startsWith(QLatin1Char('['))) + return QString(); + + if (hasSideEffects(exp) || exp.isEmpty()) + return QString(); + return exp; +} + QString cppFunctionAt(const QString &fileName, int line) { using namespace CppTools; diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h index ced524a88a60d7ce88348eca8d133c29a0af9fe1..b62854cdb1055e4b24f4c29f2d8d9f33b33338c4 100644 --- a/src/plugins/debugger/watchutils.h +++ b/src/plugins/debugger/watchutils.h @@ -105,6 +105,7 @@ QString quoteUnprintableLatin1(const QByteArray &ba); bool isCppEditor(Core::IEditor *editor); QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos, int *line, int *column, QString *function = 0); +QString fixCppExpression(const QString &exp); QString cppFunctionAt(const QString &fileName, int line); // Decode string data as returned by the dumper helpers. QString decodeData(const QByteArray &baIn, int encoding);