From b6d0f3f43231dff6ca58908f0d87dceac58428cc Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 9 May 2011 17:02:46 +0200 Subject: [PATCH] Debugger[CDB]: Correct breakpoint locations in source files. Skip comments, move to end of multi-line statements and other things. Initial-patch-by: Erik Verbruggen --- src/plugins/debugger/cdb/cdbengine.cpp | 75 +++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 53dcd16866..3cfd53c22b 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -56,6 +56,8 @@ #include "gdb/gdbmi.h" #include "shared/cdbsymbolpathlisteditor.h" +#include + #include #include #include @@ -66,6 +68,11 @@ #include #include #include +#include + +#include +#include +#include #include #include @@ -2365,8 +2372,65 @@ bool CdbEngine::acceptsBreakpoint(BreakpointId id) const return true; } +// Context for fixing file/line-type breakpoints, for delayed creation. +class BreakpointCorrectionContext +{ +public: + explicit BreakpointCorrectionContext(const CPlusPlus::Snapshot &s, + const CPlusPlus::CppModelManagerInterface::WorkingCopy &workingCopy) : + m_snapshot(s), m_workingCopy(workingCopy) {} + + unsigned fixLineNumber(const QString &fileName, unsigned lineNumber) const; + +private: + const CPlusPlus::Snapshot m_snapshot; + CPlusPlus::CppModelManagerInterface::WorkingCopy m_workingCopy; +}; + +static CPlusPlus::Document::Ptr getParsedDocument(const QString &fileName, + const CPlusPlus::CppModelManagerInterface::WorkingCopy &workingCopy, + const CPlusPlus::Snapshot &snapshot) +{ + QString src; + if (workingCopy.contains(fileName)) { + src = workingCopy.source(fileName); + } else { + Utils::FileReader reader; + if (reader.fetch(fileName)) // ### FIXME error reporting + src = QString::fromLocal8Bit(reader.data()); // ### FIXME encoding + } + + QByteArray source = snapshot.preprocessedCode(src, fileName); + + CPlusPlus::Document::Ptr doc = snapshot.documentFromSource(source, fileName); + doc->parse(); + return doc; +} + +unsigned BreakpointCorrectionContext::fixLineNumber(const QString &fileName, + unsigned lineNumber) const +{ + CPlusPlus::Document::Ptr doc = m_snapshot.document(fileName); + if (!doc || !doc->translationUnit()->ast()) + doc = getParsedDocument(fileName, m_workingCopy, m_snapshot); + + CPlusPlus::FindCdbBreakpoint findVisitor(doc->translationUnit()); + const unsigned correctedLine = findVisitor(lineNumber); + if (!correctedLine) { + qWarning("Unable to find breakpoint location for %s:%d", + qPrintable(QDir::toNativeSeparators(fileName)), lineNumber); + return lineNumber; + } + if (debug) + qDebug("Code model: Breakpoint line %u -> %u in %s", + lineNumber, correctedLine, qPrintable(fileName)); + return correctedLine; +} + void CdbEngine::attemptBreakpointSynchronization() { + + if (debug) qDebug("attemptBreakpointSynchronization in %s", stateName(state())); // Check if there is anything to be done at all. @@ -2415,6 +2479,7 @@ void CdbEngine::attemptBreakpointSynchronization() // Breakhandler::setResponse() on pending breakpoints clears the pending flag. // handleBreakPoints will the complete that information and set it on the break handler. bool addedChanged = false; + QScopedPointer lineCorrection; foreach (BreakpointId id, ids) { BreakpointParameters parameters = handler->breakpointData(id); BreakpointResponse response; @@ -2427,7 +2492,15 @@ void CdbEngine::attemptBreakpointSynchronization() } switch (handler->state(id)) { case BreakpointInsertRequested: - postCommand(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false), 0); + if (parameters.type == BreakpointByFileAndLine) { + if (lineCorrection.isNull()) + lineCorrection.reset(new BreakpointCorrectionContext(debuggerCore()->cppCodeModelSnapshot(), + CPlusPlus::CppModelManagerInterface::instance()->workingCopy())); + response.lineNumber = lineCorrection->fixLineNumber(parameters.fileName, parameters.lineNumber); + postCommand(cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false), 0); + } else { + postCommand(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false), 0); + } if (!parameters.enabled) postCommand("bd " + QByteArray::number(id), 0); handler->notifyBreakpointInsertProceeding(id); -- 2.11.0