forked from qt-creator/qt-creator
Debugger: Clean up source utils
Change-Id: Ibfe20af9c4c413657b6a238337ff9af661857b3e Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -52,20 +52,6 @@ void AbstractEditorSupport::updateDocument()
|
|||||||
m_modelmanager->updateSourceFiles(QSet<QString>() << fileName());
|
m_modelmanager->updateSourceFiles(QSet<QString>() << fileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AbstractEditorSupport::functionAt(const CppModelManager *modelManager,
|
|
||||||
const QString &fileName,
|
|
||||||
int line, int column)
|
|
||||||
{
|
|
||||||
if (!modelManager)
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
const CPlusPlus::Snapshot snapshot = modelManager->snapshot();
|
|
||||||
if (const CPlusPlus::Document::Ptr document = snapshot.document(fileName))
|
|
||||||
return document->functionAt(line, column);
|
|
||||||
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractEditorSupport::licenseTemplate(const QString &file, const QString &className)
|
QString AbstractEditorSupport::licenseTemplate(const QString &file, const QString &className)
|
||||||
{
|
{
|
||||||
return Internal::CppFileSettings::licenseTemplate(file, className);
|
return Internal::CppFileSettings::licenseTemplate(file, className);
|
||||||
|
|||||||
@@ -52,11 +52,6 @@ public:
|
|||||||
void updateDocument();
|
void updateDocument();
|
||||||
unsigned revision() const { return m_revision; }
|
unsigned revision() const { return m_revision; }
|
||||||
|
|
||||||
// TODO: find a better place for common utility functions
|
|
||||||
static QString functionAt(const CppModelManager *mm,
|
|
||||||
const QString &fileName,
|
|
||||||
int line, int column);
|
|
||||||
|
|
||||||
static QString licenseTemplate(const QString &file = QString(), const QString &className = QString());
|
static QString licenseTemplate(const QString &file = QString(), const QString &className = QString());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <cpptools/abstracteditorsupport.h>
|
#include <cpptools/abstracteditorsupport.h>
|
||||||
#include <cpptools/cppprojectfile.h>
|
#include <cpptools/cppprojectfile.h>
|
||||||
#include <cpptools/cppmodelmanager.h>
|
#include <cpptools/cppmodelmanager.h>
|
||||||
|
#include <cplusplus/CppDocument.h>
|
||||||
#include <cplusplus/ExpressionUnderCursor.h>
|
#include <cplusplus/ExpressionUnderCursor.h>
|
||||||
#include <cplusplus/Overview.h>
|
#include <cplusplus/Overview.h>
|
||||||
|
|
||||||
@@ -48,7 +49,10 @@
|
|||||||
|
|
||||||
enum { debug = 0 };
|
enum { debug = 0 };
|
||||||
|
|
||||||
// Debug helpers for code model. @todo: Move to some CppTools library?
|
using namespace CppTools;
|
||||||
|
using namespace CPlusPlus;
|
||||||
|
using namespace TextEditor;
|
||||||
|
|
||||||
namespace CPlusPlus {
|
namespace CPlusPlus {
|
||||||
|
|
||||||
static void debugCppSymbolRecursion(QTextStream &str, const Overview &o,
|
static void debugCppSymbolRecursion(QTextStream &str, const Overview &o,
|
||||||
@@ -80,7 +84,7 @@ static void debugCppSymbolRecursion(QTextStream &str, const Overview &o,
|
|||||||
QDebug operator<<(QDebug d, const Symbol &s)
|
QDebug operator<<(QDebug d, const Symbol &s)
|
||||||
{
|
{
|
||||||
QString output;
|
QString output;
|
||||||
CPlusPlus::Overview o;
|
Overview o;
|
||||||
QTextStream str(&output);
|
QTextStream str(&output);
|
||||||
debugCppSymbolRecursion(str, o, s, true, 0);
|
debugCppSymbolRecursion(str, o, s, true, 0);
|
||||||
d.nospace() << output;
|
d.nospace() << output;
|
||||||
@@ -119,6 +123,7 @@ QDebug operator<<(QDebug d, const Scope &scope)
|
|||||||
d.nospace() << output;
|
d.nospace() << output;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace CPlusPlus
|
} // namespace CPlusPlus
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
@@ -144,8 +149,8 @@ if (true) {
|
|||||||
|
|
||||||
typedef QHash<QString, int> SeenHash;
|
typedef QHash<QString, int> SeenHash;
|
||||||
|
|
||||||
static void blockRecursion(const CPlusPlus::Overview &overview,
|
static void blockRecursion(const Overview &overview,
|
||||||
const CPlusPlus::Scope *scope,
|
const Scope *scope,
|
||||||
unsigned line,
|
unsigned line,
|
||||||
QStringList *uninitializedVariables,
|
QStringList *uninitializedVariables,
|
||||||
SeenHash *seenHash,
|
SeenHash *seenHash,
|
||||||
@@ -154,7 +159,7 @@ static void blockRecursion(const CPlusPlus::Overview &overview,
|
|||||||
// Go backwards in case someone has identical variables in the same scope.
|
// Go backwards in case someone has identical variables in the same scope.
|
||||||
// Fixme: loop variables or similar are currently seen in the outer scope
|
// Fixme: loop variables or similar are currently seen in the outer scope
|
||||||
for (int s = scope->memberCount() - 1; s >= 0; --s){
|
for (int s = scope->memberCount() - 1; s >= 0; --s){
|
||||||
const CPlusPlus::Symbol *symbol = scope->memberAt(s);
|
const Symbol *symbol = scope->memberAt(s);
|
||||||
if (symbol->isDeclaration()) {
|
if (symbol->isDeclaration()) {
|
||||||
// Find out about shadowed symbols by bookkeeping
|
// Find out about shadowed symbols by bookkeeping
|
||||||
// the already seen occurrences in a hash.
|
// the already seen occurrences in a hash.
|
||||||
@@ -171,13 +176,13 @@ static void blockRecursion(const CPlusPlus::Overview &overview,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Next block scope.
|
// Next block scope.
|
||||||
if (const CPlusPlus::Scope *enclosingScope = scope->enclosingBlock())
|
if (const Scope *enclosingScope = scope->enclosingBlock())
|
||||||
blockRecursion(overview, enclosingScope, line, uninitializedVariables, seenHash, level + 1);
|
blockRecursion(overview, enclosingScope, line, uninitializedVariables, seenHash, level + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inline helper with integer error return codes.
|
// Inline helper with integer error return codes.
|
||||||
static inline
|
static inline
|
||||||
int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
|
int getUninitializedVariablesI(const Snapshot &snapshot,
|
||||||
const QString &functionName,
|
const QString &functionName,
|
||||||
const QString &file,
|
const QString &file,
|
||||||
int line,
|
int line,
|
||||||
@@ -187,26 +192,26 @@ int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
|
|||||||
// Find document
|
// Find document
|
||||||
if (snapshot.isEmpty() || functionName.isEmpty() || file.isEmpty() || line < 1)
|
if (snapshot.isEmpty() || functionName.isEmpty() || file.isEmpty() || line < 1)
|
||||||
return 1;
|
return 1;
|
||||||
const CPlusPlus::Snapshot::const_iterator docIt = snapshot.find(file);
|
const Snapshot::const_iterator docIt = snapshot.find(file);
|
||||||
if (docIt == snapshot.end())
|
if (docIt == snapshot.end())
|
||||||
return 2;
|
return 2;
|
||||||
const CPlusPlus::Document::Ptr doc = docIt.value();
|
const Document::Ptr doc = docIt.value();
|
||||||
// Look at symbol at line and find its function. Either it is the
|
// Look at symbol at line and find its function. Either it is the
|
||||||
// function itself or some expression/variable.
|
// function itself or some expression/variable.
|
||||||
const CPlusPlus::Symbol *symbolAtLine = doc->lastVisibleSymbolAt(line, 0);
|
const Symbol *symbolAtLine = doc->lastVisibleSymbolAt(line, 0);
|
||||||
if (!symbolAtLine)
|
if (!symbolAtLine)
|
||||||
return 4;
|
return 4;
|
||||||
// First figure out the function to do a safety name check
|
// First figure out the function to do a safety name check
|
||||||
// and the innermost scope at cursor position
|
// and the innermost scope at cursor position
|
||||||
const CPlusPlus::Function *function = 0;
|
const Function *function = 0;
|
||||||
const CPlusPlus::Scope *innerMostScope = 0;
|
const Scope *innerMostScope = 0;
|
||||||
if (symbolAtLine->isFunction()) {
|
if (symbolAtLine->isFunction()) {
|
||||||
function = symbolAtLine->asFunction();
|
function = symbolAtLine->asFunction();
|
||||||
if (function->memberCount() == 1) // Skip over function block
|
if (function->memberCount() == 1) // Skip over function block
|
||||||
if (CPlusPlus::Block *block = function->memberAt(0)->asBlock())
|
if (Block *block = function->memberAt(0)->asBlock())
|
||||||
innerMostScope = block;
|
innerMostScope = block;
|
||||||
} else {
|
} else {
|
||||||
if (const CPlusPlus::Scope *functionScope = symbolAtLine->enclosingFunction()) {
|
if (const Scope *functionScope = symbolAtLine->enclosingFunction()) {
|
||||||
function = functionScope->asFunction();
|
function = functionScope->asFunction();
|
||||||
innerMostScope = symbolAtLine->isBlock() ?
|
innerMostScope = symbolAtLine->isBlock() ?
|
||||||
symbolAtLine->asBlock() :
|
symbolAtLine->asBlock() :
|
||||||
@@ -218,7 +223,7 @@ int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
|
|||||||
// Compare function names with a bit off fuzz,
|
// Compare function names with a bit off fuzz,
|
||||||
// skipping modules from a CDB symbol "lib!foo" or namespaces
|
// skipping modules from a CDB symbol "lib!foo" or namespaces
|
||||||
// that the code model does not show at this point
|
// that the code model does not show at this point
|
||||||
CPlusPlus::Overview overview;
|
Overview overview;
|
||||||
const QString name = overview.prettyName(function->name());
|
const QString name = overview.prettyName(function->name());
|
||||||
if (!functionName.endsWith(name))
|
if (!functionName.endsWith(name))
|
||||||
return 11;
|
return 11;
|
||||||
@@ -233,7 +238,7 @@ int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
|
bool getUninitializedVariables(const Snapshot &snapshot,
|
||||||
const QString &function,
|
const QString &function,
|
||||||
const QString &file,
|
const QString &file,
|
||||||
int line,
|
int line,
|
||||||
@@ -253,77 +258,32 @@ bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
|
|||||||
return rc == 0;
|
return rc == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//QByteArray gdbQuoteTypes(const QByteArray &type)
|
|
||||||
//{
|
|
||||||
// // gdb does not understand sizeof(Core::IDocument*).
|
|
||||||
// // "sizeof('Core::IDocument*')" is also not acceptable,
|
|
||||||
// // it needs to be "sizeof('Core::IDocument'*)"
|
|
||||||
// //
|
|
||||||
// // We never will have a perfect solution here (even if we had a full blown
|
|
||||||
// // C++ parser as we do not have information on what is a type and what is
|
|
||||||
// // a variable name. So "a<b>::c" could either be two comparisons of values
|
|
||||||
// // 'a', 'b' and '::c', or a nested type 'c' in a template 'a<b>'. We
|
|
||||||
// // assume here it is the latter.
|
|
||||||
// //return type;
|
|
||||||
|
|
||||||
// // (*('myns::QPointer<myns::QObject>*'*)0x684060)" is not acceptable
|
|
||||||
// // (*('myns::QPointer<myns::QObject>'**)0x684060)" is acceptable
|
|
||||||
// if (isPointerType(type))
|
|
||||||
// return gdbQuoteTypes(stripPointerType(type)) + '*';
|
|
||||||
|
|
||||||
// QByteArray accu;
|
|
||||||
// QByteArray result;
|
|
||||||
// int templateLevel = 0;
|
|
||||||
|
|
||||||
// const char colon = ':';
|
|
||||||
// const char singleQuote = '\'';
|
|
||||||
// const char lessThan = '<';
|
|
||||||
// const char greaterThan = '>';
|
|
||||||
// for (int i = 0; i != type.size(); ++i) {
|
|
||||||
// const char c = type.at(i);
|
|
||||||
// if (isLetterOrNumber(c) || c == '_' || c == colon || c == ' ') {
|
|
||||||
// accu += c;
|
|
||||||
// } else if (c == lessThan) {
|
|
||||||
// ++templateLevel;
|
|
||||||
// accu += c;
|
|
||||||
// } else if (c == greaterThan) {
|
|
||||||
// --templateLevel;
|
|
||||||
// accu += c;
|
|
||||||
// } else if (templateLevel > 0) {
|
|
||||||
// accu += c;
|
|
||||||
// } else {
|
|
||||||
// if (accu.contains(colon) || accu.contains(lessThan))
|
|
||||||
// result += singleQuote + accu + singleQuote;
|
|
||||||
// else
|
|
||||||
// result += accu;
|
|
||||||
// accu.clear();
|
|
||||||
// result += c;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (accu.contains(colon) || accu.contains(lessThan))
|
|
||||||
// result += singleQuote + accu + singleQuote;
|
|
||||||
// else
|
|
||||||
// result += accu;
|
|
||||||
// //qDebug() << "GDB_QUOTING" << type << " TO " << result;
|
|
||||||
|
|
||||||
// return result;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Utilities to decode string data returned by the dumper helpers.
|
|
||||||
|
|
||||||
|
|
||||||
// Editor tooltip support
|
// Editor tooltip support
|
||||||
bool isCppEditor(TextEditor::BaseTextEditorWidget *editorWidget)
|
bool isCppEditor(BaseTextEditorWidget *editorWidget)
|
||||||
{
|
{
|
||||||
const TextEditor::BaseTextDocument *document = editorWidget->textDocument();
|
const BaseTextDocument *document = editorWidget->textDocument();
|
||||||
return CppTools::ProjectFile::classify(document->filePath()) != CppTools::ProjectFile::Unclassified;
|
return ProjectFile::classify(document->filePath()) != ProjectFile::Unclassified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString cppFunctionAt(const QString &fileName, int line, int column)
|
||||||
|
{
|
||||||
|
CppModelManager *modelManager = CppModelManager::instance();
|
||||||
|
if (!modelManager)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
const Snapshot snapshot = modelManager->snapshot();
|
||||||
|
if (const Document::Ptr document = snapshot.document(fileName))
|
||||||
|
return document->functionAt(line, column);
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Return the Cpp expression, and, if desired, the function
|
// Return the Cpp expression, and, if desired, the function
|
||||||
QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos,
|
QString cppExpressionAt(BaseTextEditorWidget *editorWidget, int pos,
|
||||||
int *line, int *column, QString *function /* = 0 */)
|
int *line, int *column, QString *function /* = 0 */)
|
||||||
{
|
{
|
||||||
using namespace CppTools;
|
|
||||||
*line = *column = 0;
|
*line = *column = 0;
|
||||||
if (function)
|
if (function)
|
||||||
function->clear();
|
function->clear();
|
||||||
@@ -338,7 +298,7 @@ QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos,
|
|||||||
tc.movePosition(QTextCursor::EndOfWord);
|
tc.movePosition(QTextCursor::EndOfWord);
|
||||||
|
|
||||||
// Fetch the expression's code.
|
// Fetch the expression's code.
|
||||||
CPlusPlus::ExpressionUnderCursor expressionUnderCursor;
|
ExpressionUnderCursor expressionUnderCursor;
|
||||||
expr = expressionUnderCursor(tc);
|
expr = expressionUnderCursor(tc);
|
||||||
*column = tc.positionInBlock();
|
*column = tc.positionInBlock();
|
||||||
*line = tc.blockNumber();
|
*line = tc.blockNumber();
|
||||||
@@ -348,8 +308,7 @@ QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (function && !expr.isEmpty())
|
if (function && !expr.isEmpty())
|
||||||
*function = AbstractEditorSupport::functionAt(modelManager,
|
*function = cppFunctionAt(editorWidget->textDocument()->filePath(), *line, *column);
|
||||||
editorWidget->textDocument()->filePath(), *line, *column);
|
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
@@ -379,14 +338,5 @@ QString fixCppExpression(const QString &expIn)
|
|||||||
return removeObviousSideEffects(exp);
|
return removeObviousSideEffects(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString cppFunctionAt(const QString &fileName, int line)
|
|
||||||
{
|
|
||||||
using namespace CppTools;
|
|
||||||
using namespace CPlusPlus;
|
|
||||||
CppModelManager *modelManager = CppModelManager::instance();
|
|
||||||
return AbstractEditorSupport::functionAt(modelManager,
|
|
||||||
fileName, line, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ bool isCppEditor(TextEditor::BaseTextEditorWidget *editorWidget);
|
|||||||
QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos,
|
QString cppExpressionAt(TextEditor::BaseTextEditorWidget *editorWidget, int pos,
|
||||||
int *line, int *column, QString *function = 0);
|
int *line, int *column, QString *function = 0);
|
||||||
QString fixCppExpression(const QString &exp);
|
QString fixCppExpression(const QString &exp);
|
||||||
QString cppFunctionAt(const QString &fileName, int line);
|
QString cppFunctionAt(const QString &fileName, int line, int column = 0);
|
||||||
|
|
||||||
// Get variables that are not initialized at a certain line
|
// Get variables that are not initialized at a certain line
|
||||||
// of a function from the code model. Shadowed variables will
|
// of a function from the code model. Shadowed variables will
|
||||||
|
|||||||
Reference in New Issue
Block a user