forked from qt-creator/qt-creator
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
This commit is contained in:
@@ -117,6 +117,13 @@ Macro *Environment::bind(const Macro &__macro)
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Environment::addMacros(const QList<Macro> ¯os)
|
||||||
|
{
|
||||||
|
foreach (const Macro ¯o, macros) {
|
||||||
|
bind(macro);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Macro *Environment::remove(const QByteArray &name)
|
Macro *Environment::remove(const QByteArray &name)
|
||||||
{
|
{
|
||||||
Macro macro;
|
Macro macro;
|
||||||
@@ -127,6 +134,23 @@ Macro *Environment::remove(const QByteArray &name)
|
|||||||
return bind(macro);
|
return bind(macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Environment::reset()
|
||||||
|
{
|
||||||
|
if (_macros) {
|
||||||
|
qDeleteAll(firstMacro(), lastMacro());
|
||||||
|
free(_macros);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_hash)
|
||||||
|
free(_hash);
|
||||||
|
|
||||||
|
_macros = 0;
|
||||||
|
_allocated_macros = 0;
|
||||||
|
_macro_count = -1;
|
||||||
|
_hash = 0;
|
||||||
|
_hash_count = 401;
|
||||||
|
}
|
||||||
|
|
||||||
bool Environment::isBuiltinMacro(const QByteArray &s) const
|
bool Environment::isBuiltinMacro(const QByteArray &s) const
|
||||||
{
|
{
|
||||||
if (s.length() != 8)
|
if (s.length() != 8)
|
||||||
|
@@ -56,6 +56,7 @@
|
|||||||
#include "CPlusPlusForwardDeclarations.h"
|
#include "CPlusPlusForwardDeclarations.h"
|
||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <QList>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
|
||||||
namespace CPlusPlus {
|
namespace CPlusPlus {
|
||||||
@@ -89,6 +90,9 @@ public:
|
|||||||
Macro **lastMacro()
|
Macro **lastMacro()
|
||||||
{ return _macros + _macro_count + 1; }
|
{ return _macros + _macro_count + 1; }
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
void addMacros(const QList<Macro> ¯os);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static unsigned hashCode(const QByteArray &s);
|
static unsigned hashCode(const QByteArray &s);
|
||||||
void rehash();
|
void rehash();
|
||||||
|
@@ -54,6 +54,11 @@ bool SimpleToken::isKeyword() const
|
|||||||
return _kind >= T_FIRST_KEYWORD && _kind < T_FIRST_QT_KEYWORD;
|
return _kind >= T_FIRST_KEYWORD && _kind < T_FIRST_QT_KEYWORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SimpleToken::isComment() const
|
||||||
|
{
|
||||||
|
return _kind == T_COMMENT || _kind == T_DOXY_COMMENT;
|
||||||
|
}
|
||||||
|
|
||||||
SimpleLexer::SimpleLexer()
|
SimpleLexer::SimpleLexer()
|
||||||
: _lastState(0),
|
: _lastState(0),
|
||||||
_skipComments(false),
|
_skipComments(false),
|
||||||
|
@@ -69,6 +69,7 @@ public:
|
|||||||
bool isLiteral() const;
|
bool isLiteral() const;
|
||||||
bool isOperator() const;
|
bool isOperator() const;
|
||||||
bool isKeyword() const;
|
bool isKeyword() const;
|
||||||
|
bool isComment() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int _kind;
|
int _kind;
|
||||||
|
@@ -49,6 +49,9 @@ TokenUnderCursor::~TokenUnderCursor()
|
|||||||
SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor) const
|
SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor) const
|
||||||
{
|
{
|
||||||
SimpleLexer tokenize;
|
SimpleLexer tokenize;
|
||||||
|
tokenize.setObjCEnabled(true);
|
||||||
|
tokenize.setSkipComments(false);
|
||||||
|
|
||||||
QTextBlock block = cursor.block();
|
QTextBlock block = cursor.block();
|
||||||
int column = cursor.columnNumber();
|
int column = cursor.columnNumber();
|
||||||
|
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
<glob pattern="*.c++"/>
|
<glob pattern="*.c++"/>
|
||||||
<glob pattern="*.C"/>
|
<glob pattern="*.C"/>
|
||||||
<glob pattern="*.inl"/>
|
<glob pattern="*.inl"/>
|
||||||
|
<glob pattern="*.qdoc"/>
|
||||||
</mime-type>
|
</mime-type>
|
||||||
|
|
||||||
<mime-type type="text/x-objcsrc">
|
<mime-type type="text/x-objcsrc">
|
||||||
|
@@ -740,7 +740,9 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs)
|
|||||||
<< QLatin1String(TextEditor::Constants::C_OPERATOR)
|
<< QLatin1String(TextEditor::Constants::C_OPERATOR)
|
||||||
<< QLatin1String(TextEditor::Constants::C_PREPROCESSOR)
|
<< QLatin1String(TextEditor::Constants::C_PREPROCESSOR)
|
||||||
<< QLatin1String(TextEditor::Constants::C_LABEL)
|
<< QLatin1String(TextEditor::Constants::C_LABEL)
|
||||||
<< QLatin1String(TextEditor::Constants::C_COMMENT);
|
<< QLatin1String(TextEditor::Constants::C_COMMENT)
|
||||||
|
<< QLatin1String(TextEditor::Constants::C_DOXYGEN_COMMENT)
|
||||||
|
<< QLatin1String(TextEditor::Constants::C_DOXYGEN_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVector<QTextCharFormat> formats = fs.toTextCharFormats(categories);
|
const QVector<QTextCharFormat> formats = fs.toTextCharFormats(categories);
|
||||||
|
@@ -16,6 +16,7 @@ HEADERS += cppplugin.h \
|
|||||||
cppeditorenums.h \
|
cppeditorenums.h \
|
||||||
cppeditor_global.h \
|
cppeditor_global.h \
|
||||||
cppclasswizard.h
|
cppclasswizard.h
|
||||||
|
|
||||||
SOURCES += cppplugin.cpp \
|
SOURCES += cppplugin.cpp \
|
||||||
cppeditoractionhandler.cpp \
|
cppeditoractionhandler.cpp \
|
||||||
cppeditor.cpp \
|
cppeditor.cpp \
|
||||||
@@ -23,4 +24,5 @@ SOURCES += cppplugin.cpp \
|
|||||||
cpphoverhandler.cpp \
|
cpphoverhandler.cpp \
|
||||||
cppfilewizard.cpp \
|
cppfilewizard.cpp \
|
||||||
cppclasswizard.cpp
|
cppclasswizard.cpp
|
||||||
|
|
||||||
RESOURCES += cppeditor.qrc
|
RESOURCES += cppeditor.qrc
|
||||||
|
@@ -51,6 +51,8 @@ enum CppFormats {
|
|||||||
CppPreprocessorFormat,
|
CppPreprocessorFormat,
|
||||||
CppLabelFormat,
|
CppLabelFormat,
|
||||||
CppCommentFormat,
|
CppCommentFormat,
|
||||||
|
CppDoxygenCommentFormat,
|
||||||
|
CppDoxygenTagFormat,
|
||||||
NumCppFormats
|
NumCppFormats
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "cpphighlighter.h"
|
#include "cpphighlighter.h"
|
||||||
|
#include <cpptools/cppdoxygen.h>
|
||||||
|
|
||||||
#include <Token.h>
|
#include <Token.h>
|
||||||
#include <cplusplus/SimpleLexer.h>
|
#include <cplusplus/SimpleLexer.h>
|
||||||
@@ -115,23 +116,35 @@ void CppHighlighter::highlightBlock(const QString &text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool highlightCurrentWordAsPreprocessor = highlightAsPreprocessor;
|
bool highlightCurrentWordAsPreprocessor = highlightAsPreprocessor;
|
||||||
|
|
||||||
if (highlightAsPreprocessor)
|
if (highlightAsPreprocessor)
|
||||||
highlightAsPreprocessor = false;
|
highlightAsPreprocessor = false;
|
||||||
|
|
||||||
if (i == 0 && tk.is(T_POUND)) {
|
if (i == 0 && tk.is(T_POUND)) {
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
|
||||||
highlightAsPreprocessor = true;
|
highlightAsPreprocessor = true;
|
||||||
|
|
||||||
} else if (highlightCurrentWordAsPreprocessor &&
|
} else if (highlightCurrentWordAsPreprocessor &&
|
||||||
(tk.isKeyword() || tk.is(T_IDENTIFIER)) && isPPKeyword(tk.text()))
|
(tk.isKeyword() || tk.is(T_IDENTIFIER)) && isPPKeyword(tk.text()))
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
|
||||||
|
|
||||||
else if (tk.is(T_INT_LITERAL) || tk.is(T_FLOAT_LITERAL))
|
else if (tk.is(T_INT_LITERAL) || tk.is(T_FLOAT_LITERAL))
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppNumberFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppNumberFormat]);
|
||||||
|
|
||||||
else if (tk.is(T_STRING_LITERAL) || tk.is(T_CHAR_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL))
|
else if (tk.is(T_STRING_LITERAL) || tk.is(T_CHAR_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL))
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
|
||||||
|
|
||||||
else if (tk.is(T_WIDE_STRING_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL))
|
else if (tk.is(T_WIDE_STRING_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL))
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
|
||||||
else if (tk.is(T_COMMENT)) {
|
|
||||||
|
else if (tk.isComment()) {
|
||||||
|
|
||||||
|
if (tk.is(T_COMMENT))
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppCommentFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppCommentFormat]);
|
||||||
|
|
||||||
|
else // a doxygen comment
|
||||||
|
highlightDoxygenComment(text, tk.position(), tk.length());
|
||||||
|
|
||||||
// we need to insert a close comment parenthesis, if
|
// we need to insert a close comment parenthesis, if
|
||||||
// - the line starts in a C Comment (initalState != 0)
|
// - the line starts in a C Comment (initalState != 0)
|
||||||
// - the first token of the line is a T_COMMENT (i == 0 && tk.is(T_COMMENT))
|
// - the first token of the line is a T_COMMENT (i == 0 && tk.is(T_COMMENT))
|
||||||
@@ -145,12 +158,16 @@ void CppHighlighter::highlightBlock(const QString &text)
|
|||||||
// clear the initial state.
|
// clear the initial state.
|
||||||
initialState = 0;
|
initialState = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (tk.isKeyword() || isQtKeyword(tk.text()))
|
} else if (tk.isKeyword() || isQtKeyword(tk.text()))
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppKeywordFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppKeywordFormat]);
|
||||||
|
|
||||||
else if (tk.isOperator())
|
else if (tk.isOperator())
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppOperatorFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppOperatorFormat]);
|
||||||
|
|
||||||
else if (i == 0 && tokens.size() > 1 && tk.is(T_IDENTIFIER) && tokens.at(1).is(T_COLON))
|
else if (i == 0 && tokens.size() > 1 && tk.is(T_IDENTIFIER) && tokens.at(1).is(T_COLON))
|
||||||
setFormat(tk.position(), tk.length(), m_formats[CppLabelFormat]);
|
setFormat(tk.position(), tk.length(), m_formats[CppLabelFormat]);
|
||||||
|
|
||||||
else if (tk.is(T_IDENTIFIER))
|
else if (tk.is(T_IDENTIFIER))
|
||||||
highlightWord(tk.text(), tk.position(), tk.length());
|
highlightWord(tk.text(), tk.position(), tk.length());
|
||||||
}
|
}
|
||||||
@@ -304,3 +321,36 @@ void CppHighlighter::highlightWord(QStringRef word, int position, int length)
|
|||||||
setFormat(position, length, m_formats[CppTypeFormat]);
|
setFormat(position, length, m_formats[CppTypeFormat]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppHighlighter::highlightDoxygenComment(const QString &text, int position, int)
|
||||||
|
{
|
||||||
|
int initial = position;
|
||||||
|
|
||||||
|
const QChar *uc = text.unicode();
|
||||||
|
const QChar *it = uc + position;
|
||||||
|
|
||||||
|
const QTextCharFormat &format = m_formats[CppDoxygenCommentFormat];
|
||||||
|
const QTextCharFormat &kwFormat = m_formats[CppDoxygenTagFormat];
|
||||||
|
|
||||||
|
while (! it->isNull()) {
|
||||||
|
if (it->unicode() == QLatin1Char('\\') ||
|
||||||
|
it->unicode() == QLatin1Char('@')) {
|
||||||
|
++it;
|
||||||
|
|
||||||
|
const QChar *start = it;
|
||||||
|
while (it->isLetterOrNumber() || it->unicode() == '_')
|
||||||
|
++it;
|
||||||
|
|
||||||
|
int k = CppTools::classifyDoxygenTag(start, it - start);
|
||||||
|
if (k != CppTools::T_DOXY_IDENTIFIER) {
|
||||||
|
setFormat(initial, start - uc - initial, format);
|
||||||
|
setFormat(start - uc - 1, it - start + 1, kwFormat);
|
||||||
|
initial = it - uc;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
setFormat(initial, it - uc - initial, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -61,6 +61,10 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void highlightWord(QStringRef word, int position, int length);
|
void highlightWord(QStringRef word, int position, int length);
|
||||||
|
|
||||||
|
void highlightDoxygenComment(const QString &text, int position,
|
||||||
|
int length);
|
||||||
|
|
||||||
bool isPPKeyword(const QStringRef &text) const;
|
bool isPPKeyword(const QStringRef &text) const;
|
||||||
bool isQtKeyword(const QStringRef &text) const;
|
bool isQtKeyword(const QStringRef &text) const;
|
||||||
|
|
||||||
|
@@ -32,8 +32,8 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "cppcodecompletion.h"
|
#include "cppcodecompletion.h"
|
||||||
|
|
||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
|
#include "cppdoxygen.h"
|
||||||
|
|
||||||
#include <Control.h>
|
#include <Control.h>
|
||||||
#include <AST.h>
|
#include <AST.h>
|
||||||
@@ -371,45 +371,53 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
|
|||||||
const QChar ch3 = pos > 1 ? editor->characterAt(pos - 3) : QChar();
|
const QChar ch3 = pos > 1 ? editor->characterAt(pos - 3) : QChar();
|
||||||
|
|
||||||
int start = pos;
|
int start = pos;
|
||||||
|
int k = T_EOF_SYMBOL;
|
||||||
|
|
||||||
if (ch2 != QLatin1Char('.') && ch == QLatin1Char('.')) {
|
if (ch2 != QLatin1Char('.') && ch == QLatin1Char('.')) {
|
||||||
if (kind)
|
k = T_DOT;
|
||||||
*kind = T_DOT;
|
|
||||||
--start;
|
--start;
|
||||||
} else if (wantFunctionCall && ch == QLatin1Char('(')) {
|
} else if (wantFunctionCall && ch == QLatin1Char('(')) {
|
||||||
if (kind)
|
k = T_LPAREN;
|
||||||
*kind = T_LPAREN;
|
|
||||||
--start;
|
--start;
|
||||||
} else if (ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) {
|
} else if (ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) {
|
||||||
if (kind)
|
k = T_COLON_COLON;
|
||||||
*kind = T_COLON_COLON;
|
|
||||||
start -= 2;
|
start -= 2;
|
||||||
} else if (ch2 == QLatin1Char('-') && ch == QLatin1Char('>')) {
|
} else if (ch2 == QLatin1Char('-') && ch == QLatin1Char('>')) {
|
||||||
if (kind)
|
k = T_ARROW;
|
||||||
*kind = T_ARROW;
|
|
||||||
start -= 2;
|
start -= 2;
|
||||||
} else if (ch2 == QLatin1Char('.') && ch == QLatin1Char('*')) {
|
} else if (ch2 == QLatin1Char('.') && ch == QLatin1Char('*')) {
|
||||||
if (kind)
|
k = T_DOT_STAR;
|
||||||
*kind = T_DOT_STAR;
|
|
||||||
start -= 2;
|
start -= 2;
|
||||||
} else if (ch3 == QLatin1Char('-') && ch2 == QLatin1Char('>') && ch == QLatin1Char('*')) {
|
} else if (ch3 == QLatin1Char('-') && ch2 == QLatin1Char('>') && ch == QLatin1Char('*')) {
|
||||||
if (kind)
|
k = T_ARROW_STAR;
|
||||||
*kind = T_ARROW_STAR;
|
|
||||||
start -= 3;
|
start -= 3;
|
||||||
|
} else if (ch == QLatin1Char('@') || ch == QLatin1Char('\\')) {
|
||||||
|
k = T_DOXY_COMMENT;
|
||||||
|
--start;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start != pos) {
|
if (start == pos)
|
||||||
|
return start;
|
||||||
|
|
||||||
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
|
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
|
||||||
QTextCursor tc(edit->textCursor());
|
QTextCursor tc(edit->textCursor());
|
||||||
tc.setPosition(pos);
|
tc.setPosition(pos);
|
||||||
|
|
||||||
static CPlusPlus::TokenUnderCursor tokenUnderCursor;
|
static CPlusPlus::TokenUnderCursor tokenUnderCursor;
|
||||||
const SimpleToken tk = tokenUnderCursor(tc);
|
const SimpleToken tk = tokenUnderCursor(tc);
|
||||||
if (tk.is(T_COMMENT) || tk.isLiteral()) {
|
|
||||||
|
if (k == T_DOXY_COMMENT && tk.isNot(T_DOXY_COMMENT)) {
|
||||||
|
k = T_EOF_SYMBOL;
|
||||||
|
start = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (tk.is(T_COMMENT) || tk.isLiteral()) {
|
||||||
|
k = T_EOF_SYMBOL;
|
||||||
|
start = pos;
|
||||||
|
}
|
||||||
|
|
||||||
if (kind)
|
if (kind)
|
||||||
*kind = T_EOF_SYMBOL;
|
*kind = k;
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
@@ -457,15 +465,32 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
|
|||||||
ExpressionUnderCursor expressionUnderCursor;
|
ExpressionUnderCursor expressionUnderCursor;
|
||||||
QString expression;
|
QString expression;
|
||||||
|
|
||||||
|
|
||||||
|
if (m_completionOperator == T_DOXY_COMMENT) {
|
||||||
|
for (int i = 1; i < T_DOXY_LAST_TAG; ++i) {
|
||||||
|
TextEditor::CompletionItem item(this);
|
||||||
|
item.m_text.append(QString::fromLatin1(doxygenTagSpell(i)));
|
||||||
|
item.m_icon = m_icons.keywordIcon();
|
||||||
|
m_completions.append(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_startPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (m_completionOperator) {
|
if (m_completionOperator) {
|
||||||
QTextCursor tc(edit->document());
|
QTextCursor tc(edit->document());
|
||||||
tc.setPosition(endOfExpression);
|
tc.setPosition(endOfExpression);
|
||||||
|
|
||||||
expression = expressionUnderCursor(tc);
|
expression = expressionUnderCursor(tc);
|
||||||
|
|
||||||
if (m_completionOperator == T_LPAREN) {
|
if (m_completionOperator == T_LPAREN) {
|
||||||
if (expression.endsWith(QLatin1String("SIGNAL")))
|
if (expression.endsWith(QLatin1String("SIGNAL")))
|
||||||
m_completionOperator = T_SIGNAL;
|
m_completionOperator = T_SIGNAL;
|
||||||
|
|
||||||
else if (expression.endsWith(QLatin1String("SLOT")))
|
else if (expression.endsWith(QLatin1String("SLOT")))
|
||||||
m_completionOperator = T_SLOT;
|
m_completionOperator = T_SLOT;
|
||||||
|
|
||||||
else if (editor->position() != endOfOperator) {
|
else if (editor->position() != endOfOperator) {
|
||||||
// We don't want a function completion when the cursor isn't at the opening brace
|
// We don't want a function completion when the cursor isn't at the opening brace
|
||||||
expression.clear();
|
expression.clear();
|
||||||
|
3149
src/plugins/cpptools/cppdoxygen.cpp
Normal file
3149
src/plugins/cpptools/cppdoxygen.cpp
Normal file
File diff suppressed because it is too large
Load Diff
264
src/plugins/cpptools/cppdoxygen.h
Normal file
264
src/plugins/cpptools/cppdoxygen.h
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Non-Open Source Usage
|
||||||
|
**
|
||||||
|
** Licensees may use this file in accordance with the Qt Beta Version
|
||||||
|
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||||
|
** alternatively, in accordance with the terms contained in a written
|
||||||
|
** agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure GNU
|
||||||
|
** General Public Licensing requirements will be met:
|
||||||
|
**
|
||||||
|
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||||
|
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "cpptools_global.h"
|
||||||
|
|
||||||
|
namespace CppTools {
|
||||||
|
|
||||||
|
enum DoxygenReservedWord {
|
||||||
|
T_DOXY_IDENTIFIER,
|
||||||
|
T_DOXY_ARG,
|
||||||
|
T_DOXY_ATTENTION,
|
||||||
|
T_DOXY_AUTHOR,
|
||||||
|
T_DOXY_CALLGRAPH,
|
||||||
|
T_DOXY_CODE,
|
||||||
|
T_DOXY_DOT,
|
||||||
|
T_DOXY_ELSE,
|
||||||
|
T_DOXY_ENDCODE,
|
||||||
|
T_DOXY_ENDCOND,
|
||||||
|
T_DOXY_ENDDOT,
|
||||||
|
T_DOXY_ENDHTMLONLY,
|
||||||
|
T_DOXY_ENDIF,
|
||||||
|
T_DOXY_ENDLATEXONLY,
|
||||||
|
T_DOXY_ENDLINK,
|
||||||
|
T_DOXY_ENDMANONLY,
|
||||||
|
T_DOXY_ENDVERBATIM,
|
||||||
|
T_DOXY_ENDXMLONLY,
|
||||||
|
T_DOXY_HIDEINITIALIZER,
|
||||||
|
T_DOXY_HTMLONLY,
|
||||||
|
T_DOXY_INTERFACE,
|
||||||
|
T_DOXY_INTERNAL,
|
||||||
|
T_DOXY_INVARIANT,
|
||||||
|
T_DOXY_LATEXONLY,
|
||||||
|
T_DOXY_LI,
|
||||||
|
T_DOXY_MANONLY,
|
||||||
|
T_DOXY_N,
|
||||||
|
T_DOXY_NOSUBGROUPING,
|
||||||
|
T_DOXY_NOTE,
|
||||||
|
T_DOXY_ONLY,
|
||||||
|
T_DOXY_POST,
|
||||||
|
T_DOXY_PRE,
|
||||||
|
T_DOXY_REMARKS,
|
||||||
|
T_DOXY_RETURN,
|
||||||
|
T_DOXY_RETURNS,
|
||||||
|
T_DOXY_SA,
|
||||||
|
T_DOXY_SEE,
|
||||||
|
T_DOXY_SHOWINITIALIZER,
|
||||||
|
T_DOXY_SINCE,
|
||||||
|
T_DOXY_TEST,
|
||||||
|
T_DOXY_TODO,
|
||||||
|
T_DOXY_VERBATIM,
|
||||||
|
T_DOXY_WARNING,
|
||||||
|
T_DOXY_XMLONLY,
|
||||||
|
T_DOXY_A,
|
||||||
|
T_DOXY_ADDTOGROUP,
|
||||||
|
T_DOXY_ANCHOR,
|
||||||
|
T_DOXY_B,
|
||||||
|
T_DOXY_C,
|
||||||
|
T_DOXY_CLASS,
|
||||||
|
T_DOXY_COND,
|
||||||
|
T_DOXY_COPYDOC,
|
||||||
|
T_DOXY_DEF,
|
||||||
|
T_DOXY_DONTINCLUDE,
|
||||||
|
T_DOXY_DOTFILE,
|
||||||
|
T_DOXY_E,
|
||||||
|
T_DOXY_ELSEIF,
|
||||||
|
T_DOXY_EM,
|
||||||
|
T_DOXY_ENUM,
|
||||||
|
T_DOXY_EXAMPLE,
|
||||||
|
T_DOXY_EXCEPTION,
|
||||||
|
T_DOXY_EXCEPTIONS,
|
||||||
|
T_DOXY_FILE,
|
||||||
|
T_DOXY_HTMLINCLUDE,
|
||||||
|
T_DOXY_IF,
|
||||||
|
T_DOXY_IFNOT,
|
||||||
|
T_DOXY_INCLUDE,
|
||||||
|
T_DOXY_LINK,
|
||||||
|
T_DOXY_NAMESPACE,
|
||||||
|
T_DOXY_P,
|
||||||
|
T_DOXY_PACKAGE,
|
||||||
|
T_DOXY_REF,
|
||||||
|
T_DOXY_RELATES,
|
||||||
|
T_DOXY_RELATESALSO,
|
||||||
|
T_DOXY_RETVAL,
|
||||||
|
T_DOXY_THROW,
|
||||||
|
T_DOXY_THROWS,
|
||||||
|
T_DOXY_VERBINCLUDE,
|
||||||
|
T_DOXY_VERSION,
|
||||||
|
T_DOXY_XREFITEM,
|
||||||
|
T_DOXY_PARAM,
|
||||||
|
T_DOXY_IMAGE,
|
||||||
|
T_DOXY_DEFGROUP,
|
||||||
|
T_DOXY_PAGE,
|
||||||
|
T_DOXY_PARAGRAPH,
|
||||||
|
T_DOXY_SECTION,
|
||||||
|
T_DOXY_STRUCT,
|
||||||
|
T_DOXY_SUBSECTION,
|
||||||
|
T_DOXY_SUBSUBSECTION,
|
||||||
|
T_DOXY_UNION,
|
||||||
|
T_DOXY_WEAKGROUP,
|
||||||
|
T_DOXY_ADDINDEX,
|
||||||
|
T_DOXY_BRIEF,
|
||||||
|
T_DOXY_BUG,
|
||||||
|
T_DOXY_DATE,
|
||||||
|
T_DOXY_DEPRECATED,
|
||||||
|
T_DOXY_FN,
|
||||||
|
T_DOXY_INGROUP,
|
||||||
|
T_DOXY_LINE,
|
||||||
|
T_DOXY_MAINPAGE,
|
||||||
|
T_DOXY_NAME,
|
||||||
|
T_DOXY_OVERLOAD,
|
||||||
|
T_DOXY_PAR,
|
||||||
|
T_DOXY_SHORT,
|
||||||
|
T_DOXY_SKIP,
|
||||||
|
T_DOXY_SKIPLINE,
|
||||||
|
T_DOXY_TYPEDEF,
|
||||||
|
T_DOXY_UNTIL,
|
||||||
|
T_DOXY_VAR,
|
||||||
|
|
||||||
|
T_FIRST_QDOC_TAG,
|
||||||
|
|
||||||
|
T_DOXY_ABSTRACT = T_FIRST_QDOC_TAG,
|
||||||
|
T_DOXY_BADCODE,
|
||||||
|
T_DOXY_BASENAME,
|
||||||
|
T_DOXY_BOLD,
|
||||||
|
T_DOXY_CAPTION,
|
||||||
|
T_DOXY_CHAPTER,
|
||||||
|
T_DOXY_CODELINE,
|
||||||
|
T_DOXY_DOTS,
|
||||||
|
T_DOXY_ENDABSTRACT,
|
||||||
|
T_DOXY_ENDCHAPTER,
|
||||||
|
T_DOXY_ENDFOOTNOTE,
|
||||||
|
T_DOXY_ENDLEGALESE,
|
||||||
|
T_DOXY_ENDLIST,
|
||||||
|
T_DOXY_ENDOMIT,
|
||||||
|
T_DOXY_ENDPART,
|
||||||
|
T_DOXY_ENDQUOTATION,
|
||||||
|
T_DOXY_ENDRAW,
|
||||||
|
T_DOXY_ENDSECTION1,
|
||||||
|
T_DOXY_ENDSECTION2,
|
||||||
|
T_DOXY_ENDSECTION3,
|
||||||
|
T_DOXY_ENDSECTION4,
|
||||||
|
T_DOXY_ENDSIDEBAR,
|
||||||
|
T_DOXY_ENDTABLE,
|
||||||
|
T_DOXY_EXPIRE,
|
||||||
|
T_DOXY_FOOTNOTE,
|
||||||
|
T_DOXY_GENERATELIST,
|
||||||
|
T_DOXY_GRANULARITY,
|
||||||
|
T_DOXY_HEADER,
|
||||||
|
T_DOXY_I,
|
||||||
|
T_DOXY_INDEX,
|
||||||
|
T_DOXY_INLINEIMAGE,
|
||||||
|
T_DOXY_KEYWORD,
|
||||||
|
T_DOXY_L,
|
||||||
|
T_DOXY_LEGALESE,
|
||||||
|
T_DOXY_LIST,
|
||||||
|
T_DOXY_META,
|
||||||
|
T_DOXY_NEWCODE,
|
||||||
|
T_DOXY_O,
|
||||||
|
T_DOXY_OLDCODE,
|
||||||
|
T_DOXY_OMIT,
|
||||||
|
T_DOXY_OMITVALUE,
|
||||||
|
T_DOXY_PART,
|
||||||
|
T_DOXY_PRINTLINE,
|
||||||
|
T_DOXY_PRINTTO,
|
||||||
|
T_DOXY_PRINTUNTIL,
|
||||||
|
T_DOXY_QUOTATION,
|
||||||
|
T_DOXY_QUOTEFILE,
|
||||||
|
T_DOXY_QUOTEFROMFILE,
|
||||||
|
T_DOXY_QUOTEFUNCTION,
|
||||||
|
T_DOXY_RAW,
|
||||||
|
T_DOXY_ROW,
|
||||||
|
T_DOXY_SECTION1,
|
||||||
|
T_DOXY_SECTION2,
|
||||||
|
T_DOXY_SECTION3,
|
||||||
|
T_DOXY_SECTION4,
|
||||||
|
T_DOXY_SIDEBAR,
|
||||||
|
T_DOXY_SKIPTO,
|
||||||
|
T_DOXY_SKIPUNTIL,
|
||||||
|
T_DOXY_SNIPPET,
|
||||||
|
T_DOXY_SUB,
|
||||||
|
T_DOXY_SUP,
|
||||||
|
T_DOXY_TABLE,
|
||||||
|
T_DOXY_TABLEOFCONTENTS,
|
||||||
|
T_DOXY_TARGET,
|
||||||
|
T_DOXY_TT,
|
||||||
|
T_DOXY_UNDERLINE,
|
||||||
|
T_DOXY_UNICODE,
|
||||||
|
T_DOXY_VALUE,
|
||||||
|
T_DOXY_CONTENTSPAGE,
|
||||||
|
T_DOXY_EXTERNALPAGE,
|
||||||
|
T_DOXY_GROUP,
|
||||||
|
T_DOXY_HEADERFILE,
|
||||||
|
T_DOXY_INDEXPAGE,
|
||||||
|
T_DOXY_INHEADERFILE,
|
||||||
|
T_DOXY_MACRO,
|
||||||
|
T_DOXY_MODULE,
|
||||||
|
T_DOXY_NEXTPAGE,
|
||||||
|
T_DOXY_PREVIOUSPAGE,
|
||||||
|
T_DOXY_PROPERTY,
|
||||||
|
T_DOXY_REIMP,
|
||||||
|
T_DOXY_SERVICE,
|
||||||
|
T_DOXY_STARTPAGE,
|
||||||
|
T_DOXY_VARIABLE,
|
||||||
|
T_DOXY_COMPAT,
|
||||||
|
T_DOXY_INMODULE,
|
||||||
|
T_DOXY_MAINCLASS,
|
||||||
|
T_DOXY_NONREENTRANT,
|
||||||
|
T_DOXY_OBSOLETE,
|
||||||
|
T_DOXY_PRELIMINARY,
|
||||||
|
T_DOXY_INPUBLICGROUP,
|
||||||
|
T_DOXY_REENTRANT,
|
||||||
|
T_DOXY_SUBTITLE,
|
||||||
|
T_DOXY_THREADSAFE,
|
||||||
|
T_DOXY_TITLE,
|
||||||
|
T_DOXY_CORELIB,
|
||||||
|
T_DOXY_UITOOLS,
|
||||||
|
T_DOXY_GUI,
|
||||||
|
T_DOXY_NETWORK,
|
||||||
|
T_DOXY_OPENGL,
|
||||||
|
T_DOXY_QT3SUPPORT,
|
||||||
|
T_DOXY_SVG,
|
||||||
|
T_DOXY_SQL,
|
||||||
|
T_DOXY_QTESTLIB,
|
||||||
|
T_DOXY_WEBKIT,
|
||||||
|
T_DOXY_XML,
|
||||||
|
|
||||||
|
T_DOXY_LAST_TAG
|
||||||
|
};
|
||||||
|
|
||||||
|
CPPTOOLS_EXPORT int classifyDoxygenTag(const QChar *s, int n);
|
||||||
|
CPPTOOLS_EXPORT const char *doxygenTagSpell(int index);
|
||||||
|
|
||||||
|
} // namespace ::CppTools
|
||||||
|
|
@@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/uniqueidmanager.h>
|
#include <coreplugin/uniqueidmanager.h>
|
||||||
|
#include <coreplugin/mimedatabase.h>
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
|
|
||||||
@@ -140,6 +141,10 @@ static const char pp_configuration[] =
|
|||||||
"#define restrict\n"
|
"#define restrict\n"
|
||||||
"#define __restrict\n"
|
"#define __restrict\n"
|
||||||
|
|
||||||
|
"#define __complex__\n"
|
||||||
|
"#define __imag__\n"
|
||||||
|
"#define __real__\n"
|
||||||
|
|
||||||
// ### add macros for win32
|
// ### add macros for win32
|
||||||
"#define __cdecl\n"
|
"#define __cdecl\n"
|
||||||
"#define QT_WA(x) x\n"
|
"#define QT_WA(x) x\n"
|
||||||
@@ -164,9 +169,16 @@ public:
|
|||||||
void setIncludePaths(const QStringList &includePaths);
|
void setIncludePaths(const QStringList &includePaths);
|
||||||
void setFrameworkPaths(const QStringList &frameworkPaths);
|
void setFrameworkPaths(const QStringList &frameworkPaths);
|
||||||
void setProjectFiles(const QStringList &files);
|
void setProjectFiles(const QStringList &files);
|
||||||
|
void setTodo(const QStringList &files);
|
||||||
|
|
||||||
void run(QString &fileName);
|
void run(QString &fileName);
|
||||||
void operator()(QString &fileName);
|
void operator()(QString &fileName);
|
||||||
|
|
||||||
|
void resetEnvironment();
|
||||||
|
|
||||||
|
const QSet<QString> &todo() const
|
||||||
|
{ return m_todo; }
|
||||||
|
|
||||||
public: // attributes
|
public: // attributes
|
||||||
Snapshot snapshot;
|
Snapshot snapshot;
|
||||||
|
|
||||||
@@ -200,6 +212,7 @@ private:
|
|||||||
QStringList m_frameworkPaths;
|
QStringList m_frameworkPaths;
|
||||||
QSet<QString> m_included;
|
QSet<QString> m_included;
|
||||||
CPlusPlus::Document::Ptr m_currentDoc;
|
CPlusPlus::Document::Ptr m_currentDoc;
|
||||||
|
QSet<QString> m_todo;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -223,9 +236,15 @@ void CppPreprocessor::setFrameworkPaths(const QStringList &frameworkPaths)
|
|||||||
void CppPreprocessor::setProjectFiles(const QStringList &files)
|
void CppPreprocessor::setProjectFiles(const QStringList &files)
|
||||||
{ m_projectFiles = files; }
|
{ m_projectFiles = files; }
|
||||||
|
|
||||||
|
void CppPreprocessor::setTodo(const QStringList &files)
|
||||||
|
{ m_todo = QSet<QString>::fromList(files); }
|
||||||
|
|
||||||
void CppPreprocessor::run(QString &fileName)
|
void CppPreprocessor::run(QString &fileName)
|
||||||
{ sourceNeeded(fileName, IncludeGlobal, /*line = */ 0); }
|
{ sourceNeeded(fileName, IncludeGlobal, /*line = */ 0); }
|
||||||
|
|
||||||
|
void CppPreprocessor::resetEnvironment()
|
||||||
|
{ env.reset(); }
|
||||||
|
|
||||||
void CppPreprocessor::operator()(QString &fileName)
|
void CppPreprocessor::operator()(QString &fileName)
|
||||||
{ run(fileName); }
|
{ run(fileName); }
|
||||||
|
|
||||||
@@ -386,7 +405,7 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *process
|
|||||||
|
|
||||||
processed->insert(fn);
|
processed->insert(fn);
|
||||||
|
|
||||||
foreach (Document::Include incl, doc->includes()) {
|
foreach (const Document::Include &incl, doc->includes()) {
|
||||||
QString includedFile = incl.fileName();
|
QString includedFile = incl.fileName();
|
||||||
|
|
||||||
if (Document::Ptr includedDoc = snapshot.value(includedFile))
|
if (Document::Ptr includedDoc = snapshot.value(includedFile))
|
||||||
@@ -395,9 +414,7 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *process
|
|||||||
run(includedFile);
|
run(includedFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const Macro macro, doc->definedMacros()) {
|
env.addMacros(doc->definedMacros());
|
||||||
env.bind(macro);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppPreprocessor::startSkippingBlocks(unsigned offset)
|
void CppPreprocessor::startSkippingBlocks(unsigned offset)
|
||||||
@@ -424,55 +441,59 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type,
|
|||||||
|
|
||||||
if (m_currentDoc) {
|
if (m_currentDoc) {
|
||||||
m_currentDoc->addIncludeFile(fileName, line);
|
m_currentDoc->addIncludeFile(fileName, line);
|
||||||
|
|
||||||
if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
|
if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
|
||||||
QString msg;
|
QString msg;
|
||||||
|
|
||||||
msg += fileName;
|
msg += fileName;
|
||||||
msg += QLatin1String(": No such file or directory");
|
msg += QLatin1String(": No such file or directory");
|
||||||
|
|
||||||
Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
|
Document::DiagnosticMessage d(Document::DiagnosticMessage::Warning,
|
||||||
m_currentDoc->fileName(),
|
m_currentDoc->fileName(),
|
||||||
env.currentLine, /*column = */ 0,
|
env.currentLine, /*column = */ 0,
|
||||||
msg);
|
msg);
|
||||||
|
|
||||||
m_currentDoc->addDiagnosticMessage(d);
|
m_currentDoc->addDiagnosticMessage(d);
|
||||||
|
|
||||||
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
|
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! contents.isEmpty()) {
|
//qDebug() << "parse file:" << fileName << "contents:" << contents.size();
|
||||||
Document::Ptr cachedDoc = snapshot.value(fileName);
|
|
||||||
if (cachedDoc && m_currentDoc) {
|
|
||||||
mergeEnvironment(cachedDoc);
|
|
||||||
} else {
|
|
||||||
Document::Ptr previousDoc = switchDocument(Document::create(fileName));
|
|
||||||
|
|
||||||
const QByteArray previousFile = env.currentFile;
|
Document::Ptr doc = snapshot.value(fileName);
|
||||||
const unsigned previousLine = env.currentLine;
|
if (doc) {
|
||||||
|
mergeEnvironment(doc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TranslationUnit *unit = m_currentDoc->translationUnit();
|
doc = Document::create(fileName);
|
||||||
env.currentFile = QByteArray(unit->fileName(), unit->fileNameLength());
|
|
||||||
|
Document::Ptr previousDoc = switchDocument(doc);
|
||||||
|
|
||||||
QByteArray preprocessedCode;
|
QByteArray preprocessedCode;
|
||||||
m_proc(contents, &preprocessedCode);
|
m_proc(fileName.toUtf8(), contents, &preprocessedCode);
|
||||||
//qDebug() << preprocessedCode;
|
|
||||||
|
|
||||||
env.currentFile = previousFile;
|
doc->setSource(preprocessedCode);
|
||||||
env.currentLine = previousLine;
|
|
||||||
|
|
||||||
m_currentDoc->setSource(preprocessedCode);
|
doc->parse();
|
||||||
m_currentDoc->parse();
|
doc->check();
|
||||||
|
|
||||||
#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
|
#if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU)
|
||||||
DumpAST dump(m_currentDoc->control());
|
DumpAST dump(m_currentDoc->control());
|
||||||
dump(m_currentDoc->translationUnit()->ast());
|
dump(m_currentDoc->translationUnit()->ast());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_currentDoc->check();
|
doc->releaseTranslationUnit();
|
||||||
m_currentDoc->releaseTranslationUnit(); // release the AST and the token stream.
|
|
||||||
|
snapshot[fileName] = doc;
|
||||||
|
|
||||||
if (m_modelManager)
|
if (m_modelManager)
|
||||||
m_modelManager->emitDocumentUpdated(m_currentDoc);
|
m_modelManager->emitDocumentUpdated(m_currentDoc); // ### TODO: compress
|
||||||
|
|
||||||
(void) switchDocument(previousDoc);
|
(void) switchDocument(previousDoc);
|
||||||
}
|
m_todo.remove(fileName);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
|
Document::Ptr CppPreprocessor::switchDocument(Document::Ptr doc)
|
||||||
@@ -737,7 +758,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
|||||||
|
|
||||||
QList<TextEditor::BaseTextEditor::BlockRange> blockRanges;
|
QList<TextEditor::BaseTextEditor::BlockRange> blockRanges;
|
||||||
|
|
||||||
foreach (const Document::Block block, doc->skippedBlocks()) {
|
foreach (const Document::Block &block, doc->skippedBlocks()) {
|
||||||
blockRanges.append(TextEditor::BaseTextEditor::BlockRange(block.begin(), block.end()));
|
blockRanges.append(TextEditor::BaseTextEditor::BlockRange(block.begin(), block.end()));
|
||||||
}
|
}
|
||||||
ed->setIfdefedOutBlocks(blockRanges);
|
ed->setIfdefedOutBlocks(blockRanges);
|
||||||
@@ -750,7 +771,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
|||||||
macroFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
|
macroFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
|
||||||
|
|
||||||
QTextCursor c = ed->textCursor();
|
QTextCursor c = ed->textCursor();
|
||||||
foreach (const Document::Block block, doc->macroUses()) {
|
foreach (const Document::MacroUse &block, doc->macroUses()) {
|
||||||
QTextEdit::ExtraSelection sel;
|
QTextEdit::ExtraSelection sel;
|
||||||
sel.cursor = c;
|
sel.cursor = c;
|
||||||
sel.cursor.setPosition(block.begin());
|
sel.cursor.setPosition(block.begin());
|
||||||
@@ -771,7 +792,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
|||||||
warningFormat.setUnderlineColor(Qt::darkYellow);
|
warningFormat.setUnderlineColor(Qt::darkYellow);
|
||||||
|
|
||||||
QSet<int> lines;
|
QSet<int> lines;
|
||||||
foreach (const Document::DiagnosticMessage m, doc->diagnosticMessages()) {
|
foreach (const Document::DiagnosticMessage &m, doc->diagnosticMessages()) {
|
||||||
if (m.fileName() != fileName)
|
if (m.fileName() != fileName)
|
||||||
continue;
|
continue;
|
||||||
else if (lines.contains(m.line()))
|
else if (lines.contains(m.line()))
|
||||||
@@ -799,7 +820,7 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QList<Editor> todo;
|
QList<Editor> todo;
|
||||||
foreach (Editor e, todo) {
|
foreach (const Editor &e, todo) {
|
||||||
if (e.widget != ed)
|
if (e.widget != ed)
|
||||||
todo.append(e);
|
todo.append(e);
|
||||||
}
|
}
|
||||||
@@ -822,7 +843,7 @@ void CppModelManager::postEditorUpdate()
|
|||||||
|
|
||||||
void CppModelManager::updateEditorSelections()
|
void CppModelManager::updateEditorSelections()
|
||||||
{
|
{
|
||||||
foreach (Editor ed, m_todo) {
|
foreach (const Editor &ed, m_todo) {
|
||||||
if (! ed.widget)
|
if (! ed.widget)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -872,20 +893,40 @@ void CppModelManager::parse(QFutureInterface<void> &future,
|
|||||||
if (files.isEmpty())
|
if (files.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (QString file, files) {
|
Core::MimeDatabase *db = Core::ICore::instance()->mimeDatabase();
|
||||||
|
QStringList headers, sources;
|
||||||
|
Core::MimeType cSourceTy = db->findByType(QLatin1String("text/x-csrc"));
|
||||||
|
Core::MimeType cppSourceTy = db->findByType(QLatin1String("text/x-c++src"));
|
||||||
|
|
||||||
|
foreach (const QString &file, files) {
|
||||||
|
const QFileInfo fileInfo(file);
|
||||||
|
|
||||||
|
if (cSourceTy.matchesFile(fileInfo) || cppSourceTy.matchesFile(fileInfo))
|
||||||
|
sources.append(file);
|
||||||
|
|
||||||
|
else
|
||||||
|
headers.append(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const QString &file, files) {
|
||||||
preproc->snapshot.remove(file);
|
preproc->snapshot.remove(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
files = sources;
|
||||||
|
files += headers;
|
||||||
|
|
||||||
|
preproc->setTodo(files);
|
||||||
|
|
||||||
// Change the priority of the background parser thread to idle.
|
// Change the priority of the background parser thread to idle.
|
||||||
QThread::currentThread()->setPriority(QThread::IdlePriority);
|
QThread::currentThread()->setPriority(QThread::IdlePriority);
|
||||||
|
|
||||||
future.setProgressRange(0, files.size());
|
future.setProgressRange(0, files.size());
|
||||||
|
|
||||||
QString conf = QLatin1String(pp_configuration_file);
|
QString conf = QLatin1String(pp_configuration_file);
|
||||||
(void) preproc->run(conf);
|
|
||||||
|
|
||||||
const int STEP = 10;
|
const int STEP = 10;
|
||||||
|
|
||||||
|
bool processingHeaders = false;
|
||||||
|
|
||||||
for (int i = 0; i < files.size(); ++i) {
|
for (int i = 0; i < files.size(); ++i) {
|
||||||
if (future.isPaused())
|
if (future.isPaused())
|
||||||
future.waitForResume();
|
future.waitForResume();
|
||||||
@@ -893,16 +934,33 @@ void CppModelManager::parse(QFutureInterface<void> &future,
|
|||||||
if (future.isCanceled())
|
if (future.isCanceled())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
future.setProgressValue(i);
|
|
||||||
|
|
||||||
#ifdef CPPTOOLS_DEBUG_PARSING_TIME
|
#ifdef CPPTOOLS_DEBUG_PARSING_TIME
|
||||||
QTime tm;
|
QTime tm;
|
||||||
tm.start();
|
tm.start();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QString fileName = files.at(i);
|
QString fileName = files.at(i);
|
||||||
|
|
||||||
|
bool isSourceFile = false;
|
||||||
|
if (cppSourceTy.matchesFile(fileName) || cSourceTy.matchesFile(fileName))
|
||||||
|
isSourceFile = true;
|
||||||
|
|
||||||
|
if (isSourceFile)
|
||||||
|
(void) preproc->run(conf);
|
||||||
|
|
||||||
|
else if (! processingHeaders) {
|
||||||
|
(void) preproc->run(conf);
|
||||||
|
|
||||||
|
processingHeaders = true;
|
||||||
|
}
|
||||||
|
|
||||||
preproc->run(fileName);
|
preproc->run(fileName);
|
||||||
|
|
||||||
|
future.setProgressValue(files.size() - preproc->todo().size());
|
||||||
|
|
||||||
|
if (isSourceFile)
|
||||||
|
preproc->resetEnvironment();
|
||||||
|
|
||||||
if (! (i % STEP)) // Yields execution of the current thread.
|
if (! (i % STEP)) // Yields execution of the current thread.
|
||||||
QThread::yieldCurrentThread();
|
QThread::yieldCurrentThread();
|
||||||
|
|
||||||
|
@@ -8,27 +8,29 @@ include(cpptools_dependencies.pri)
|
|||||||
DEFINES += QT_NO_CAST_TO_ASCII
|
DEFINES += QT_NO_CAST_TO_ASCII
|
||||||
INCLUDEPATH += .
|
INCLUDEPATH += .
|
||||||
DEFINES += CPPTOOLS_LIBRARY
|
DEFINES += CPPTOOLS_LIBRARY
|
||||||
HEADERS += cpptools_global.h \
|
HEADERS += completionsettingspage.h \
|
||||||
cppquickopenfilter.h \
|
|
||||||
cppclassesfilter.h \
|
cppclassesfilter.h \
|
||||||
searchsymbols.h \
|
|
||||||
cppfunctionsfilter.h \
|
|
||||||
completionsettingspage.h
|
|
||||||
SOURCES += cppquickopenfilter.cpp \
|
|
||||||
cpptoolseditorsupport.cpp \
|
|
||||||
cppclassesfilter.cpp \
|
|
||||||
searchsymbols.cpp \
|
|
||||||
cppfunctionsfilter.cpp \
|
|
||||||
completionsettingspage.cpp
|
|
||||||
|
|
||||||
# Input
|
|
||||||
SOURCES += cpptoolsplugin.cpp \
|
|
||||||
cppmodelmanager.cpp \
|
|
||||||
cppcodecompletion.cpp
|
|
||||||
HEADERS += cpptoolsplugin.h \
|
|
||||||
cppmodelmanager.h \
|
|
||||||
cppcodecompletion.h \
|
cppcodecompletion.h \
|
||||||
|
cppfunctionsfilter.h \
|
||||||
|
cppmodelmanager.h \
|
||||||
cppmodelmanagerinterface.h \
|
cppmodelmanagerinterface.h \
|
||||||
|
cppquickopenfilter.h \
|
||||||
|
cpptools_global.h \
|
||||||
|
cpptoolsconstants.h \
|
||||||
cpptoolseditorsupport.h \
|
cpptoolseditorsupport.h \
|
||||||
cpptoolsconstants.h
|
cpptoolsplugin.h \
|
||||||
|
searchsymbols.h \
|
||||||
|
cppdoxygen.h
|
||||||
|
|
||||||
|
SOURCES += completionsettingspage.cpp \
|
||||||
|
cppclassesfilter.cpp \
|
||||||
|
cppcodecompletion.cpp \
|
||||||
|
cppfunctionsfilter.cpp \
|
||||||
|
cppmodelmanager.cpp \
|
||||||
|
cppquickopenfilter.cpp \
|
||||||
|
cpptoolseditorsupport.cpp \
|
||||||
|
cpptoolsplugin.cpp \
|
||||||
|
searchsymbols.cpp \
|
||||||
|
cppdoxygen.cpp
|
||||||
|
|
||||||
FORMS += completionsettingspage.ui
|
FORMS += completionsettingspage.ui
|
||||||
|
@@ -34,6 +34,8 @@
|
|||||||
#ifndef CPPTOOLS_GLOBAL_H
|
#ifndef CPPTOOLS_GLOBAL_H
|
||||||
#define CPPTOOLS_GLOBAL_H
|
#define CPPTOOLS_GLOBAL_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
#if defined(CPPTOOLS_LIBRARY)
|
#if defined(CPPTOOLS_LIBRARY)
|
||||||
# define CPPTOOLS_EXPORT Q_DECL_EXPORT
|
# define CPPTOOLS_EXPORT Q_DECL_EXPORT
|
||||||
#else
|
#else
|
||||||
|
34
src/plugins/debugger/cdb/cdb.pri
Normal file
34
src/plugins/debugger/cdb/cdb.pri
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
win32 {
|
||||||
|
# ---- Detect Debugging Tools For Windows
|
||||||
|
|
||||||
|
CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows/sdk"
|
||||||
|
|
||||||
|
exists ($$CDB_PATH) {
|
||||||
|
message("Experimental: Adding support for $$CDB_PATH")
|
||||||
|
|
||||||
|
DEFINES+=CDB_ENABLED
|
||||||
|
|
||||||
|
CDB_PLATFORM=i386
|
||||||
|
|
||||||
|
INCLUDEPATH*=$$CDB_PATH
|
||||||
|
INCLUDEPATH*=$$PWD
|
||||||
|
|
||||||
|
CDB_LIBPATH=$$CDB_PATH/lib/$$CDB_PLATFORM
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/cdbdebugengine.h \
|
||||||
|
$$PWD/cdbdebugengine_p.h \
|
||||||
|
$$PWD/cdbdebugeventcallback.h \
|
||||||
|
$$PWD/cdbdebugoutput.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/cdbdebugengine.cpp \
|
||||||
|
$$PWD/cdbdebugeventcallback.cpp \
|
||||||
|
$$PWD/cdbdebugoutput.cpp
|
||||||
|
|
||||||
|
LIBS += -L$$CDB_LIBPATH Dbghelp.lib dbgeng.lib
|
||||||
|
|
||||||
|
} else {
|
||||||
|
error("Debugging Tools for Windows could not be found in $$CDB_PATH")
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,38 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Non-Open Source Usage
|
||||||
|
**
|
||||||
|
** Licensees may use this file in accordance with the Qt Beta Version
|
||||||
|
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||||
|
** alternatively, in accordance with the terms contained in a written
|
||||||
|
** agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure GNU
|
||||||
|
** General Public Licensing requirements will be met:
|
||||||
|
**
|
||||||
|
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||||
|
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
#include "cdbdebugengine.h"
|
#include "cdbdebugengine.h"
|
||||||
|
#include "cdbdebugengine_p.h"
|
||||||
|
|
||||||
#include "debuggermanager.h"
|
#include "debuggermanager.h"
|
||||||
#include "breakhandler.h"
|
#include "breakhandler.h"
|
||||||
@@ -6,30 +40,28 @@
|
|||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QTimerEvent>
|
#include <QtCore/QTimerEvent>
|
||||||
#include <QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
#define DBGHELP_TRANSLATE_TCHAR
|
#define DBGHELP_TRANSLATE_TCHAR
|
||||||
#include <Dbghelp.h>
|
#include <inc/Dbghelp.h>
|
||||||
|
|
||||||
using namespace Debugger;
|
using namespace Debugger;
|
||||||
using namespace Debugger::Internal;
|
using namespace Debugger::Internal;
|
||||||
|
|
||||||
|
CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEngine* engine) :
|
||||||
CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent)
|
|
||||||
: IDebuggerEngine(parent),
|
|
||||||
m_hDebuggeeProcess(0),
|
m_hDebuggeeProcess(0),
|
||||||
m_hDebuggeeThread(0),
|
m_hDebuggeeThread(0),
|
||||||
//m_hDebuggeeImage(0),
|
|
||||||
m_bIgnoreNextDebugEvent(false),
|
m_bIgnoreNextDebugEvent(false),
|
||||||
m_watchTimer(-1),
|
m_watchTimer(-1),
|
||||||
m_debugEventCallBack(this),
|
m_debugEventCallBack(engine),
|
||||||
m_debugOutputCallBack(this)
|
m_debugOutputCallBack(engine),
|
||||||
|
m_engine(engine),
|
||||||
|
m_debuggerManager(parent),
|
||||||
|
m_debuggerManagerAccess(parent->engineInterface())
|
||||||
{
|
{
|
||||||
q = parent;
|
|
||||||
qq = parent->engineInterface();
|
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
hr = DebugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient));
|
hr = DebugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient));
|
||||||
if (FAILED(hr)) m_pDebugClient = 0;
|
if (FAILED(hr)) m_pDebugClient = 0;
|
||||||
@@ -51,7 +83,7 @@ CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CdbDebugEngine::~CdbDebugEngine()
|
CdbDebugEnginePrivate::~CdbDebugEnginePrivate()
|
||||||
{
|
{
|
||||||
if (m_pDebugClient)
|
if (m_pDebugClient)
|
||||||
m_pDebugClient->Release();
|
m_pDebugClient->Release();
|
||||||
@@ -65,17 +97,28 @@ CdbDebugEngine::~CdbDebugEngine()
|
|||||||
m_pDebugRegisters->Release();
|
m_pDebugRegisters->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent)
|
||||||
|
: IDebuggerEngine(parent),
|
||||||
|
m_d(new CdbDebugEnginePrivate(parent, this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CdbDebugEngine::~CdbDebugEngine()
|
||||||
|
{
|
||||||
|
delete m_d;
|
||||||
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::startWatchTimer()
|
void CdbDebugEngine::startWatchTimer()
|
||||||
{
|
{
|
||||||
if (m_watchTimer == -1)
|
if (m_d->m_watchTimer == -1)
|
||||||
m_watchTimer = startTimer(0);
|
m_d->m_watchTimer = startTimer(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::killWatchTimer()
|
void CdbDebugEngine::killWatchTimer()
|
||||||
{
|
{
|
||||||
if (m_watchTimer != -1) {
|
if (m_d->m_watchTimer != -1) {
|
||||||
killTimer(m_watchTimer);
|
killTimer(m_d->m_watchTimer);
|
||||||
m_watchTimer = -1;
|
m_d->m_watchTimer = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,13 +127,13 @@ void CdbDebugEngine::shutdown()
|
|||||||
exitDebugger();
|
exitDebugger();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::setToolTipExpression(const QPoint &pos, const QString &exp)
|
void CdbDebugEngine::setToolTipExpression(const QPoint & /*pos*/, const QString & /*exp*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdbDebugEngine::startDebugger()
|
bool CdbDebugEngine::startDebugger()
|
||||||
{
|
{
|
||||||
q->showStatusMessage("Starting Debugger", -1);
|
m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
|
||||||
|
|
||||||
//if (!q->m_workingDir.isEmpty())
|
//if (!q->m_workingDir.isEmpty())
|
||||||
// m_gdbProc.setWorkingDirectory(q->m_workingDir);
|
// m_gdbProc.setWorkingDirectory(q->m_workingDir);
|
||||||
@@ -101,19 +144,21 @@ bool CdbDebugEngine::startDebugger()
|
|||||||
memset(&dbgopts, 0, sizeof(dbgopts));
|
memset(&dbgopts, 0, sizeof(dbgopts));
|
||||||
dbgopts.CreateFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
|
dbgopts.CreateFlags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
|
||||||
|
|
||||||
HRESULT hr;
|
const QString filename(m_d->m_debuggerManager->m_executable);
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO <<filename;
|
||||||
|
|
||||||
QString filename(q->m_executable);
|
const QFileInfo fi(filename);
|
||||||
QFileInfo fi(filename);
|
m_d->m_pDebugSymbols->AppendImagePathWide(QDir::toNativeSeparators(fi.absolutePath()).utf16());
|
||||||
m_pDebugSymbols->AppendImagePathWide(fi.absolutePath().replace('/','\\').utf16());
|
|
||||||
//m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
//m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
||||||
m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
m_d->m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
|
||||||
//m_pDebugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH);
|
//m_pDebugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH);
|
||||||
|
|
||||||
if (q->startMode() == q->attachExternal) {
|
if (m_d->m_debuggerManager->startMode() == DebuggerManager::AttachExternal) {
|
||||||
qWarning("CdbDebugEngine: attach to process not yet implemented!");
|
qWarning("CdbDebugEngine: attach to process not yet implemented!");
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
hr = m_pDebugClient->CreateProcess2Wide(NULL,
|
HRESULT hr = m_d->m_pDebugClient->CreateProcess2Wide(NULL,
|
||||||
const_cast<PWSTR>(filename.utf16()),
|
const_cast<PWSTR>(filename.utf16()),
|
||||||
&dbgopts,
|
&dbgopts,
|
||||||
sizeof(dbgopts),
|
sizeof(dbgopts),
|
||||||
@@ -121,19 +166,22 @@ bool CdbDebugEngine::startDebugger()
|
|||||||
NULL); // TODO: think about setting the environment
|
NULL); // TODO: think about setting the environment
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
//qWarning("CreateProcess2Wide failed");
|
//qWarning("CreateProcess2Wide failed");
|
||||||
qq->notifyInferiorExited();
|
m_d->m_debuggerManagerAccess->notifyInferiorExited();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
q->showStatusMessage(tr("Debugger Running"), -1);
|
m_d->m_debuggerManager->showStatusMessage(tr("Debugger Running"), -1);
|
||||||
startWatchTimer();
|
startWatchTimer();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::exitDebugger()
|
void CdbDebugEngine::exitDebugger()
|
||||||
{
|
{
|
||||||
m_pDebugClient->TerminateCurrentProcess();
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
m_d->m_pDebugClient->TerminateCurrentProcess();
|
||||||
killWatchTimer();
|
killWatchTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,18 +191,22 @@ void CdbDebugEngine::updateWatchModel()
|
|||||||
|
|
||||||
void CdbDebugEngine::stepExec()
|
void CdbDebugEngine::stepExec()
|
||||||
{
|
{
|
||||||
//qDebug() << "CdbDebugEngine::stepExec()";
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
//m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
//m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
hr = m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
|
hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
|
||||||
m_bIgnoreNextDebugEvent = true;
|
m_d->m_bIgnoreNextDebugEvent = true;
|
||||||
startWatchTimer();
|
startWatchTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::stepOutExec()
|
void CdbDebugEngine::stepOutExec()
|
||||||
{
|
{
|
||||||
//qDebug() << "CdbDebugEngine::stepOutExec()";
|
if (debugCDB)
|
||||||
StackHandler* sh = qq->stackHandler();
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
StackHandler* sh = m_d->m_debuggerManagerAccess->stackHandler();
|
||||||
const int idx = sh->currentIndex() + 1;
|
const int idx = sh->currentIndex() + 1;
|
||||||
QList<StackFrame> stackframes = sh->frames();
|
QList<StackFrame> stackframes = sh->frames();
|
||||||
if (idx < 0 || idx >= stackframes.size()) {
|
if (idx < 0 || idx >= stackframes.size()) {
|
||||||
@@ -171,7 +223,7 @@ void CdbDebugEngine::stepOutExec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
IDebugBreakpoint2* pBP;
|
IDebugBreakpoint2* pBP;
|
||||||
HRESULT hr = m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
|
HRESULT hr = m_d->m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
|
||||||
if (FAILED(hr) || !pBP) {
|
if (FAILED(hr) || !pBP) {
|
||||||
qWarning("stepOutExec: cannot create temporary breakpoint");
|
qWarning("stepOutExec: cannot create temporary breakpoint");
|
||||||
return;
|
return;
|
||||||
@@ -194,9 +246,11 @@ void CdbDebugEngine::stepOutExec()
|
|||||||
|
|
||||||
void CdbDebugEngine::nextExec()
|
void CdbDebugEngine::nextExec()
|
||||||
{
|
{
|
||||||
//qDebug() << "CdbDebugEngine::nextExec()";
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
hr = m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
|
hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
|
||||||
startWatchTimer();
|
startWatchTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,68 +261,85 @@ void CdbDebugEngine::stepIExec()
|
|||||||
|
|
||||||
void CdbDebugEngine::nextIExec()
|
void CdbDebugEngine::nextIExec()
|
||||||
{
|
{
|
||||||
m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
m_d->m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
|
||||||
startWatchTimer();
|
startWatchTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::continueInferior()
|
void CdbDebugEngine::continueInferior()
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
killWatchTimer();
|
killWatchTimer();
|
||||||
q->resetLocation();
|
m_d->m_debuggerManager->resetLocation();
|
||||||
|
|
||||||
ULONG executionStatus;
|
ULONG executionStatus;
|
||||||
HRESULT hr = m_pDebugControl->GetExecutionStatus(&executionStatus);
|
HRESULT hr = m_d->m_pDebugControl->GetExecutionStatus(&executionStatus);
|
||||||
if (SUCCEEDED(hr) && executionStatus != DEBUG_STATUS_GO)
|
if (SUCCEEDED(hr) && executionStatus != DEBUG_STATUS_GO)
|
||||||
m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
|
m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
|
||||||
|
|
||||||
startWatchTimer();
|
startWatchTimer();
|
||||||
qq->notifyInferiorRunning();
|
m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||||
}
|
|
||||||
|
|
||||||
void CdbDebugEngine::runInferior()
|
|
||||||
{
|
|
||||||
continueInferior();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::interruptInferior()
|
void CdbDebugEngine::interruptInferior()
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
//TODO: better use IDebugControl::SetInterrupt?
|
//TODO: better use IDebugControl::SetInterrupt?
|
||||||
if (!m_hDebuggeeProcess)
|
if (!m_d->m_hDebuggeeProcess)
|
||||||
return;
|
return;
|
||||||
if (!DebugBreakProcess(m_hDebuggeeProcess)) {
|
if (!DebugBreakProcess(m_d->m_hDebuggeeProcess)) {
|
||||||
qWarning("DebugBreakProcess failed.");
|
qWarning("DebugBreakProcess failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qq->notifyInferiorStopped();
|
m_d->m_debuggerManagerAccess->notifyInferiorStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::runToLineExec(const QString &fileName, int lineNumber)
|
void CdbDebugEngine::runToLineExec(const QString &fileName, int lineNumber)
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::runToFunctionExec(const QString &functionName)
|
void CdbDebugEngine::runToFunctionExec(const QString &functionName)
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << functionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::jumpToLineExec(const QString &fileName, int lineNumber)
|
void CdbDebugEngine::jumpToLineExec(const QString &fileName, int lineNumber)
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << fileName << lineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &value)
|
void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &value)
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << expr << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::executeDebuggerCommand(const QString &/*command*/)
|
void CdbDebugEngine::executeDebuggerCommand(const QString &command)
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << command;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::activateFrame(int frameIndex)
|
void CdbDebugEngine::activateFrame(int frameIndex)
|
||||||
{
|
{
|
||||||
if (q->status() != DebuggerInferiorStopped)
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << frameIndex;
|
||||||
|
|
||||||
|
if (m_d->m_debuggerManager->status() != DebuggerInferiorStopped)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
StackHandler *stackHandler = qq->stackHandler();
|
StackHandler *stackHandler = m_d->m_debuggerManagerAccess->stackHandler();
|
||||||
int oldIndex = stackHandler->currentIndex();
|
const int oldIndex = stackHandler->currentIndex();
|
||||||
//qDebug() << "ACTIVATE FRAME: " << frameIndex << oldIndex
|
//qDebug() << "ACTIVATE FRAME: " << frameIndex << oldIndex
|
||||||
// << stackHandler->currentIndex();
|
// << stackHandler->currentIndex();
|
||||||
|
|
||||||
@@ -281,42 +352,63 @@ void CdbDebugEngine::activateFrame(int frameIndex)
|
|||||||
|
|
||||||
const StackFrame &frame = stackHandler->currentFrame();
|
const StackFrame &frame = stackHandler->currentFrame();
|
||||||
|
|
||||||
bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
|
const bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
|
||||||
if (usable)
|
if (usable)
|
||||||
q->gotoLocation(frame.file, frame.line, true);
|
m_d->m_debuggerManager->gotoLocation(frame.file, frame.line, true);
|
||||||
else
|
else
|
||||||
qDebug() << "FULL NAME NOT USABLE: " << frame.file;
|
qDebug() << "FULL NAME NOT USABLE: " << frame.file;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::selectThread(int index)
|
void CdbDebugEngine::selectThread(int index)
|
||||||
{
|
{
|
||||||
//reset location arrow
|
if (debugCDB)
|
||||||
q->resetLocation();
|
qDebug() << Q_FUNC_INFO << index;
|
||||||
|
|
||||||
ThreadsHandler *threadsHandler = qq->threadsHandler();
|
//reset location arrow
|
||||||
|
m_d->m_debuggerManager->resetLocation();
|
||||||
|
|
||||||
|
ThreadsHandler *threadsHandler = m_d->m_debuggerManagerAccess->threadsHandler();
|
||||||
threadsHandler->setCurrentThread(index);
|
threadsHandler->setCurrentThread(index);
|
||||||
m_currentThreadId = index;
|
m_d->m_currentThreadId = index;
|
||||||
updateStackTrace();
|
m_d->updateStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QString breakPointExpression(const QString &fileName, const QString &lineNumber)
|
||||||
|
{
|
||||||
|
QString str;
|
||||||
|
str += QLatin1Char('`');
|
||||||
|
str += QDir::toNativeSeparators(fileName);
|
||||||
|
str += QLatin1Char(':');
|
||||||
|
str += lineNumber;
|
||||||
|
str += QLatin1Char('`');
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::attemptBreakpointSynchronization()
|
void CdbDebugEngine::attemptBreakpointSynchronization()
|
||||||
{
|
{
|
||||||
BreakHandler *handler = qq->breakHandler();
|
if (debugCDB)
|
||||||
//qDebug() << "attemptBreakpointSynchronization";
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
if (!m_d->m_hDebuggeeProcess) {
|
||||||
|
qWarning("attemptBreakpointSynchronization() called while debugger is not running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BreakHandler *handler = m_d->m_debuggerManagerAccess->breakHandler();
|
||||||
for (int i=0; i < handler->size(); ++i) {
|
for (int i=0; i < handler->size(); ++i) {
|
||||||
BreakpointData* breakpoint = handler->at(i);
|
BreakpointData* breakpoint = handler->at(i);
|
||||||
if (breakpoint->pending) {
|
if (breakpoint->pending) {
|
||||||
|
const QString expr = breakPointExpression(breakpoint->fileName, breakpoint->lineNumber);
|
||||||
IDebugBreakpoint2* pBP = 0;
|
IDebugBreakpoint2* pBP = 0;
|
||||||
HRESULT hr = m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
|
HRESULT hr = m_d->m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
|
||||||
if (FAILED(hr) || !pBP) {
|
if (FAILED(hr) || !pBP) {
|
||||||
qWarning("m_pDebugControl->AddBreakpoint2 failed");
|
qWarning("m_pDebugControl->AddBreakpoint2 %s failed.", qPrintable(expr));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString str = '`' + breakpoint->fileName + ':' + breakpoint->lineNumber + '`';
|
hr = pBP->SetOffsetExpressionWide(expr.utf16());
|
||||||
hr = pBP->SetOffsetExpressionWide(str.utf16());
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
qWarning("SetOffsetExpressionWide failed");
|
qWarning("SetOffsetExpressionWide %s failed", qPrintable(expr));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,10 +444,14 @@ void CdbDebugEngine::reloadModules()
|
|||||||
|
|
||||||
void CdbDebugEngine::loadSymbols(const QString &moduleName)
|
void CdbDebugEngine::loadSymbols(const QString &moduleName)
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << moduleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::loadAllSymbols()
|
void CdbDebugEngine::loadAllSymbols()
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::reloadRegisters()
|
void CdbDebugEngine::reloadRegisters()
|
||||||
@@ -364,41 +460,52 @@ void CdbDebugEngine::reloadRegisters()
|
|||||||
|
|
||||||
void CdbDebugEngine::timerEvent(QTimerEvent* te)
|
void CdbDebugEngine::timerEvent(QTimerEvent* te)
|
||||||
{
|
{
|
||||||
if (te->timerId() != m_watchTimer)
|
if (te->timerId() != m_d->m_watchTimer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (debugCDB > 1)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
hr = m_pDebugControl->WaitForEvent(0, 1);
|
hr = m_d->m_pDebugControl->WaitForEvent(0, 1);
|
||||||
switch (hr) {
|
switch (hr) {
|
||||||
case S_OK:
|
case S_OK:
|
||||||
//qDebug() << "WaitForEvent S_OK";
|
if (debugCDB > 1)
|
||||||
|
qDebug() << "WaitForEvent S_OK";
|
||||||
|
|
||||||
killWatchTimer();
|
killWatchTimer();
|
||||||
handleDebugEvent();
|
m_d->handleDebugEvent();
|
||||||
break;
|
break;
|
||||||
case S_FALSE:
|
case S_FALSE:
|
||||||
//qDebug() << "S_FALSE";
|
if (debugCDB > 1)
|
||||||
|
qDebug() << "WaitForEvent S_FALSE";
|
||||||
break;
|
break;
|
||||||
case E_PENDING:
|
case E_PENDING:
|
||||||
qDebug() << "S_PENDING";
|
if (debugCDB > 1)
|
||||||
|
qDebug() << "WaitForEvent E_PENDING";
|
||||||
break;
|
break;
|
||||||
case E_UNEXPECTED:
|
case E_UNEXPECTED:
|
||||||
|
if (debugCDB > 1)
|
||||||
|
qDebug() << "WaitForEvent E_UNEXPECTED";
|
||||||
killWatchTimer();
|
killWatchTimer();
|
||||||
break;
|
break;
|
||||||
case E_FAIL:
|
case E_FAIL:
|
||||||
qDebug() << "E_FAIL";
|
if (debugCDB > 1)
|
||||||
|
qDebug() << "WaitForEvent E_FAIL";
|
||||||
break;
|
break;
|
||||||
//default:
|
|
||||||
// qDebug() << "asser welljuh, schuddnt heppn";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::handleDebugEvent()
|
void CdbDebugEnginePrivate::handleDebugEvent()
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
if (m_bIgnoreNextDebugEvent) {
|
if (m_bIgnoreNextDebugEvent) {
|
||||||
startWatchTimer();
|
m_engine->startWatchTimer();
|
||||||
m_bIgnoreNextDebugEvent = false;
|
m_bIgnoreNextDebugEvent = false;
|
||||||
} else {
|
} else {
|
||||||
qq->notifyInferiorStopped();
|
m_debuggerManagerAccess->notifyInferiorStopped();
|
||||||
updateThreadList();
|
updateThreadList();
|
||||||
updateStackTrace();
|
updateStackTrace();
|
||||||
}
|
}
|
||||||
@@ -415,9 +522,12 @@ void CdbDebugEngine::handleDebugEvent()
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::updateThreadList()
|
void CdbDebugEnginePrivate::updateThreadList()
|
||||||
{
|
{
|
||||||
ThreadsHandler* th = qq->threadsHandler();
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
ThreadsHandler* th = m_debuggerManagerAccess->threadsHandler();
|
||||||
QList<ThreadData> threads;
|
QList<ThreadData> threads;
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@@ -436,11 +546,13 @@ void CdbDebugEngine::updateThreadList()
|
|||||||
th->setThreads(threads);
|
th->setThreads(threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::updateStackTrace()
|
void CdbDebugEnginePrivate::updateStackTrace()
|
||||||
{
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
//qDebug() << "updateStackTrace()";
|
//qDebug() << "updateStackTrace()";
|
||||||
HRESULT hr;
|
HRESULT hr = m_pDebugSystemObjects->SetCurrentThreadId(m_currentThreadId);
|
||||||
hr = m_pDebugSystemObjects->SetCurrentThreadId(m_currentThreadId);
|
|
||||||
|
|
||||||
//ULONG64 frameOffset, instructionOffset, stackOffset;
|
//ULONG64 frameOffset, instructionOffset, stackOffset;
|
||||||
//if (FAILED(m_pDebugRegisters->GetFrameOffset2(DEBUG_REGSRC_DEBUGGEE, &frameOffset)) ||
|
//if (FAILED(m_pDebugRegisters->GetFrameOffset2(DEBUG_REGSRC_DEBUGGEE, &frameOffset)) ||
|
||||||
@@ -466,7 +578,7 @@ void CdbDebugEngine::updateStackTrace()
|
|||||||
StackFrame frame;
|
StackFrame frame;
|
||||||
frame.line = 0;
|
frame.line = 0;
|
||||||
frame.level = i;
|
frame.level = i;
|
||||||
frame.address = QString("0x%1").arg(frames[i].InstructionOffset, 0, 16);
|
frame.address = QString::fromLatin1("0x%1").arg(frames[i].InstructionOffset, 0, 16);
|
||||||
|
|
||||||
m_pDebugSymbols->GetNameByOffsetWide(frames[i].InstructionOffset, wszBuf, MAX_PATH, 0, 0);
|
m_pDebugSymbols->GetNameByOffsetWide(frames[i].InstructionOffset, wszBuf, MAX_PATH, 0, 0);
|
||||||
frame.function = QString::fromUtf16(wszBuf);
|
frame.function = QString::fromUtf16(wszBuf);
|
||||||
@@ -482,15 +594,15 @@ void CdbDebugEngine::updateStackTrace()
|
|||||||
stackFrames.append(frame);
|
stackFrames.append(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
qq->stackHandler()->setFrames(stackFrames);
|
m_debuggerManagerAccess->stackHandler()->setFrames(stackFrames);
|
||||||
|
|
||||||
// find the first usable frame and select it
|
// find the first usable frame and select it
|
||||||
for (int i=0; i < stackFrames.count(); ++i) {
|
for (int i=0; i < stackFrames.count(); ++i) {
|
||||||
const StackFrame &frame = stackFrames.at(i);
|
const StackFrame &frame = stackFrames.at(i);
|
||||||
bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
|
const bool usable = !frame.file.isEmpty() && QFileInfo(frame.file).isReadable();
|
||||||
if (usable) {
|
if (usable) {
|
||||||
qq->stackHandler()->setCurrentIndex(i);
|
m_debuggerManagerAccess->stackHandler()->setCurrentIndex(i);
|
||||||
q->gotoLocation(frame.file, frame.line, true);
|
m_debuggerManager->gotoLocation(frame.file, frame.line, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -504,17 +616,33 @@ void CdbDebugEngine::updateStackTrace()
|
|||||||
//m_pDebugControl->OutputStackTrace(DEBUG_OUTCTL_THIS_CLIENT, frames, numFramesFilled, DEBUG_STACK_SOURCE_LINE);
|
//m_pDebugControl->OutputStackTrace(DEBUG_OUTCTL_THIS_CLIENT, frames, numFramesFilled, DEBUG_STACK_SOURCE_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::handleDebugOutput(const char* szOutputString)
|
void CdbDebugEnginePrivate::handleDebugOutput(const char* szOutputString)
|
||||||
{
|
{
|
||||||
qq->showApplicationOutput("app-dbgoutput", QString::fromLocal8Bit(szOutputString));
|
m_debuggerManagerAccess->showApplicationOutput(QString::fromLocal8Bit(szOutputString));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbDebugEngine::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP)
|
void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP)
|
||||||
{
|
{
|
||||||
qDebug() << "CdbDebugEngine::handleBreakpointEvent()";
|
Q_UNUSED(pBP)
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDebuggerEngine *createWinEngine(DebuggerManager *parent)
|
IDebuggerEngine *createWinEngine(DebuggerManager *parent)
|
||||||
{
|
{
|
||||||
return new CdbDebugEngine(parent);
|
return new CdbDebugEngine(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CdbDebugEngine::setDebugDumpers(bool on)
|
||||||
|
{
|
||||||
|
Q_UNUSED(on)
|
||||||
|
}
|
||||||
|
|
||||||
|
void CdbDebugEngine::setUseCustomDumpers(bool on)
|
||||||
|
{
|
||||||
|
Q_UNUSED(on)
|
||||||
|
}
|
||||||
|
|
||||||
|
void CdbDebugEngine::reloadSourceFiles()
|
||||||
|
{
|
||||||
|
}
|
@@ -1,17 +1,48 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Non-Open Source Usage
|
||||||
|
**
|
||||||
|
** Licensees may use this file in accordance with the Qt Beta Version
|
||||||
|
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||||
|
** alternatively, in accordance with the terms contained in a written
|
||||||
|
** agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure GNU
|
||||||
|
** General Public Licensing requirements will be met:
|
||||||
|
**
|
||||||
|
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||||
|
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef DEBUGGER_CDBENGINE_H
|
#ifndef DEBUGGER_CDBENGINE_H
|
||||||
#define DEBUGGER_CDBENGINE_H
|
#define DEBUGGER_CDBENGINE_H
|
||||||
|
|
||||||
#include "idebuggerengine.h"
|
#include "idebuggerengine.h"
|
||||||
#include "cdbdebugeventcallback.h"
|
|
||||||
#include "cdbdebugoutput.h"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class DebuggerManager;
|
class DebuggerManager;
|
||||||
class IDebuggerManagerAccessForEngines;
|
class CdbDebugEventCallback;
|
||||||
|
class CdbDebugOutput;
|
||||||
|
struct CdbDebugEnginePrivate;
|
||||||
|
|
||||||
class CdbDebugEngine : public IDebuggerEngine
|
class CdbDebugEngine : public IDebuggerEngine
|
||||||
{
|
{
|
||||||
@@ -33,7 +64,6 @@ public:
|
|||||||
virtual void nextIExec();
|
virtual void nextIExec();
|
||||||
|
|
||||||
virtual void continueInferior();
|
virtual void continueInferior();
|
||||||
virtual void runInferior();
|
|
||||||
virtual void interruptInferior();
|
virtual void interruptInferior();
|
||||||
|
|
||||||
virtual void runToLineExec(const QString &fileName, int lineNumber);
|
virtual void runToLineExec(const QString &fileName, int lineNumber);
|
||||||
@@ -58,37 +88,21 @@ public:
|
|||||||
|
|
||||||
virtual void reloadRegisters();
|
virtual void reloadRegisters();
|
||||||
|
|
||||||
|
virtual void setDebugDumpers(bool on);
|
||||||
|
virtual void setUseCustomDumpers(bool on);
|
||||||
|
|
||||||
|
virtual void reloadSourceFiles();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent*);
|
void timerEvent(QTimerEvent*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startWatchTimer();
|
void startWatchTimer();
|
||||||
void killWatchTimer();
|
void killWatchTimer();
|
||||||
bool isDebuggeeRunning() const { return m_watchTimer != -1; }
|
|
||||||
void handleDebugEvent();
|
|
||||||
void updateThreadList();
|
|
||||||
void updateStackTrace();
|
|
||||||
void handleDebugOutput(const char* szOutputString);
|
|
||||||
void handleBreakpointEvent(PDEBUG_BREAKPOINT pBP);
|
|
||||||
|
|
||||||
private:
|
CdbDebugEnginePrivate *m_d;
|
||||||
HANDLE m_hDebuggeeProcess;
|
|
||||||
HANDLE m_hDebuggeeThread;
|
|
||||||
int m_currentThreadId;
|
|
||||||
bool m_bIgnoreNextDebugEvent;
|
|
||||||
|
|
||||||
int m_watchTimer;
|
|
||||||
IDebugClient5* m_pDebugClient;
|
|
||||||
IDebugControl4* m_pDebugControl;
|
|
||||||
IDebugSystemObjects4* m_pDebugSystemObjects;
|
|
||||||
IDebugSymbols3* m_pDebugSymbols;
|
|
||||||
IDebugRegisters2* m_pDebugRegisters;
|
|
||||||
CdbDebugEventCallback m_debugEventCallBack;
|
|
||||||
CdbDebugOutput m_debugOutputCallBack;
|
|
||||||
|
|
||||||
DebuggerManager *q;
|
|
||||||
IDebuggerManagerAccessForEngines *qq;
|
|
||||||
|
|
||||||
|
friend struct CdbDebugEnginePrivate;
|
||||||
friend class CdbDebugEventCallback;
|
friend class CdbDebugEventCallback;
|
||||||
friend class CdbDebugOutput;
|
friend class CdbDebugOutput;
|
||||||
};
|
};
|
82
src/plugins/debugger/cdb/cdbdebugengine_p.h
Normal file
82
src/plugins/debugger/cdb/cdbdebugengine_p.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Non-Open Source Usage
|
||||||
|
**
|
||||||
|
** Licensees may use this file in accordance with the Qt Beta Version
|
||||||
|
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||||
|
** alternatively, in accordance with the terms contained in a written
|
||||||
|
** agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure GNU
|
||||||
|
** General Public Licensing requirements will be met:
|
||||||
|
**
|
||||||
|
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||||
|
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef DEBUGGER_CDBENGINEPRIVATE_H
|
||||||
|
#define DEBUGGER_CDBENGINEPRIVATE_H
|
||||||
|
|
||||||
|
#include "cdbdebugeventcallback.h"
|
||||||
|
#include "cdbdebugoutput.h"
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class DebuggerManager;
|
||||||
|
class IDebuggerManagerAccessForEngines;
|
||||||
|
|
||||||
|
struct CdbDebugEnginePrivate
|
||||||
|
{
|
||||||
|
explicit CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEngine* engine);
|
||||||
|
~CdbDebugEnginePrivate();
|
||||||
|
|
||||||
|
bool isDebuggeeRunning() const { return m_watchTimer != -1; }
|
||||||
|
void handleDebugEvent();
|
||||||
|
void updateThreadList();
|
||||||
|
void updateStackTrace();
|
||||||
|
void handleDebugOutput(const char* szOutputString);
|
||||||
|
void handleBreakpointEvent(PDEBUG_BREAKPOINT pBP);
|
||||||
|
|
||||||
|
HANDLE m_hDebuggeeProcess;
|
||||||
|
HANDLE m_hDebuggeeThread;
|
||||||
|
int m_currentThreadId;
|
||||||
|
bool m_bIgnoreNextDebugEvent;
|
||||||
|
|
||||||
|
int m_watchTimer;
|
||||||
|
IDebugClient5* m_pDebugClient;
|
||||||
|
IDebugControl4* m_pDebugControl;
|
||||||
|
IDebugSystemObjects4* m_pDebugSystemObjects;
|
||||||
|
IDebugSymbols3* m_pDebugSymbols;
|
||||||
|
IDebugRegisters2* m_pDebugRegisters;
|
||||||
|
CdbDebugEventCallback m_debugEventCallBack;
|
||||||
|
CdbDebugOutput m_debugOutputCallBack;
|
||||||
|
|
||||||
|
CdbDebugEngine* m_engine;
|
||||||
|
DebuggerManager *m_debuggerManager;
|
||||||
|
IDebuggerManagerAccessForEngines *m_debuggerManagerAccess;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { debugCDB = 0 };
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
||||||
|
|
||||||
|
#endif // DEBUGGER_CDBENGINEPRIVATE_H
|
288
src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
Normal file
288
src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Non-Open Source Usage
|
||||||
|
**
|
||||||
|
** Licensees may use this file in accordance with the Qt Beta Version
|
||||||
|
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||||
|
** alternatively, in accordance with the terms contained in a written
|
||||||
|
** agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure GNU
|
||||||
|
** General Public Licensing requirements will be met:
|
||||||
|
**
|
||||||
|
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||||
|
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "cdbdebugeventcallback.h"
|
||||||
|
#include "cdbdebugengine.h"
|
||||||
|
#include "cdbdebugengine_p.h"
|
||||||
|
#include "debuggermanager.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
CdbDebugEventCallback::CdbDebugEventCallback(CdbDebugEngine* dbg) :
|
||||||
|
m_pEngine(dbg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::QueryInterface(
|
||||||
|
THIS_
|
||||||
|
IN REFIID InterfaceId,
|
||||||
|
OUT PVOID* Interface)
|
||||||
|
{
|
||||||
|
*Interface = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
||||||
|
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks))) {
|
||||||
|
*Interface = (IDebugOutputCallbacks *)this;
|
||||||
|
AddRef();
|
||||||
|
return S_OK;
|
||||||
|
} else {
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP_(ULONG) CdbDebugEventCallback::AddRef(THIS)
|
||||||
|
{
|
||||||
|
// This class is designed to be static so
|
||||||
|
// there's no true refcount.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP_(ULONG) CdbDebugEventCallback::Release(THIS)
|
||||||
|
{
|
||||||
|
// This class is designed to be static so
|
||||||
|
// there's no true refcount.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
|
||||||
|
{
|
||||||
|
*mask = DEBUG_EVENT_CREATE_PROCESS | DEBUG_EVENT_EXIT_PROCESS
|
||||||
|
//| DEBUG_EVENT_CREATE_THREAD | DEBUG_EVENT_EXIT_THREAD
|
||||||
|
| DEBUG_EVENT_BREAKPOINT
|
||||||
|
| DEBUG_EVENT_EXCEPTION
|
||||||
|
;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT Bp)
|
||||||
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
m_pEngine->m_d->handleBreakpointEvent(Bp);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::Exception(
|
||||||
|
THIS_
|
||||||
|
__in PEXCEPTION_RECORD64 Exception,
|
||||||
|
__in ULONG FirstChance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(Exception)
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << FirstChance;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::CreateThread(
|
||||||
|
THIS_
|
||||||
|
__in ULONG64 Handle,
|
||||||
|
__in ULONG64 DataOffset,
|
||||||
|
__in ULONG64 StartOffset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(Handle)
|
||||||
|
Q_UNUSED(DataOffset)
|
||||||
|
Q_UNUSED(StartOffset)
|
||||||
|
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
//Debugger::ThreadInfo ti;
|
||||||
|
//ti.handle = Handle;
|
||||||
|
//ti.dataOffset = DataOffset;
|
||||||
|
//ti.startOffset = StartOffset;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::ExitThread(
|
||||||
|
THIS_
|
||||||
|
__in ULONG ExitCode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << ExitCode;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::CreateProcess(
|
||||||
|
THIS_
|
||||||
|
__in ULONG64 ImageFileHandle,
|
||||||
|
__in ULONG64 Handle,
|
||||||
|
__in ULONG64 BaseOffset,
|
||||||
|
__in ULONG ModuleSize,
|
||||||
|
__in_opt PCSTR ModuleName,
|
||||||
|
__in_opt PCSTR ImageName,
|
||||||
|
__in ULONG CheckSum,
|
||||||
|
__in ULONG TimeDateStamp,
|
||||||
|
__in ULONG64 InitialThreadHandle,
|
||||||
|
__in ULONG64 ThreadDataOffset,
|
||||||
|
__in ULONG64 StartOffset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(ImageFileHandle)
|
||||||
|
Q_UNUSED(BaseOffset)
|
||||||
|
Q_UNUSED(ModuleSize)
|
||||||
|
Q_UNUSED(ModuleName)
|
||||||
|
Q_UNUSED(ImageName)
|
||||||
|
Q_UNUSED(CheckSum)
|
||||||
|
Q_UNUSED(TimeDateStamp)
|
||||||
|
Q_UNUSED(ThreadDataOffset)
|
||||||
|
Q_UNUSED(StartOffset)
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << ModuleName;
|
||||||
|
|
||||||
|
m_pEngine->m_d->m_hDebuggeeProcess = (HANDLE)Handle;
|
||||||
|
m_pEngine->m_d->m_hDebuggeeThread = (HANDLE)InitialThreadHandle;
|
||||||
|
m_pEngine->m_d->m_debuggerManagerAccess->notifyInferiorRunning();
|
||||||
|
|
||||||
|
ULONG currentThreadId;
|
||||||
|
if (SUCCEEDED(m_pEngine->m_d->m_pDebugSystemObjects->GetThreadIdByHandle(InitialThreadHandle, ¤tThreadId)))
|
||||||
|
m_pEngine->m_d->m_currentThreadId = currentThreadId;
|
||||||
|
else
|
||||||
|
m_pEngine->m_d->m_currentThreadId = 0;
|
||||||
|
|
||||||
|
m_pEngine->attemptBreakpointSynchronization();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::ExitProcess(
|
||||||
|
THIS_
|
||||||
|
__in ULONG ExitCode
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << ExitCode;
|
||||||
|
|
||||||
|
m_pEngine->m_d->m_hDebuggeeProcess = 0;
|
||||||
|
m_pEngine->m_d->m_hDebuggeeThread = 0;
|
||||||
|
m_pEngine->m_d->m_debuggerManagerAccess->notifyInferiorExited();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::LoadModule(
|
||||||
|
THIS_
|
||||||
|
__in ULONG64 ImageFileHandle,
|
||||||
|
__in ULONG64 BaseOffset,
|
||||||
|
__in ULONG ModuleSize,
|
||||||
|
__in_opt PCSTR ModuleName,
|
||||||
|
__in_opt PCSTR ImageName,
|
||||||
|
__in ULONG CheckSum,
|
||||||
|
__in ULONG TimeDateStamp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(ImageFileHandle)
|
||||||
|
Q_UNUSED(BaseOffset)
|
||||||
|
Q_UNUSED(ModuleSize)
|
||||||
|
Q_UNUSED(ModuleName)
|
||||||
|
Q_UNUSED(ImageName)
|
||||||
|
Q_UNUSED(CheckSum)
|
||||||
|
Q_UNUSED(TimeDateStamp)
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << ModuleName;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::UnloadModule(
|
||||||
|
THIS_
|
||||||
|
__in_opt PCSTR ImageBaseName,
|
||||||
|
__in ULONG64 BaseOffset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(ImageBaseName)
|
||||||
|
Q_UNUSED(BaseOffset)
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << ImageBaseName;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::SystemError(
|
||||||
|
THIS_
|
||||||
|
__in ULONG Error,
|
||||||
|
__in ULONG Level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (debugCDB)
|
||||||
|
qDebug() << Q_FUNC_INFO << Error << Level;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::SessionStatus(
|
||||||
|
THIS_
|
||||||
|
__in ULONG Status
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(Status)
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::ChangeDebuggeeState(
|
||||||
|
THIS_
|
||||||
|
__in ULONG Flags,
|
||||||
|
__in ULONG64 Argument
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(Flags)
|
||||||
|
Q_UNUSED(Argument)
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::ChangeEngineState(
|
||||||
|
THIS_
|
||||||
|
__in ULONG Flags,
|
||||||
|
__in ULONG64 Argument
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(Flags)
|
||||||
|
Q_UNUSED(Argument)
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugEventCallback::ChangeSymbolState(
|
||||||
|
THIS_
|
||||||
|
__in ULONG Flags,
|
||||||
|
__in ULONG64 Argument
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_UNUSED(Flags)
|
||||||
|
Q_UNUSED(Argument)
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
@@ -1,8 +1,41 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Non-Open Source Usage
|
||||||
|
**
|
||||||
|
** Licensees may use this file in accordance with the Qt Beta Version
|
||||||
|
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||||
|
** alternatively, in accordance with the terms contained in a written
|
||||||
|
** agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure GNU
|
||||||
|
** General Public Licensing requirements will be met:
|
||||||
|
**
|
||||||
|
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||||
|
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
#ifndef DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
||||||
#define DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
#define DEBUGGER_CDBDEBUGEVENTCALLBACK_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <dbgeng.h>
|
#include <inc/dbgeng.h>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -12,9 +45,7 @@ class CdbDebugEngine;
|
|||||||
class CdbDebugEventCallback : public IDebugEventCallbacks
|
class CdbDebugEventCallback : public IDebugEventCallbacks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CdbDebugEventCallback(CdbDebugEngine* dbg)
|
explicit CdbDebugEventCallback(CdbDebugEngine* dbg);
|
||||||
: m_pEngine(dbg)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// IUnknown.
|
// IUnknown.
|
||||||
STDMETHOD(QueryInterface)(
|
STDMETHOD(QueryInterface)(
|
95
src/plugins/debugger/cdb/cdbdebugoutput.cpp
Normal file
95
src/plugins/debugger/cdb/cdbdebugoutput.cpp
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Non-Open Source Usage
|
||||||
|
**
|
||||||
|
** Licensees may use this file in accordance with the Qt Beta Version
|
||||||
|
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||||
|
** alternatively, in accordance with the terms contained in a written
|
||||||
|
** agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure GNU
|
||||||
|
** General Public Licensing requirements will be met:
|
||||||
|
**
|
||||||
|
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||||
|
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "cdbdebugoutput.h"
|
||||||
|
#include "cdbdebugengine.h"
|
||||||
|
#include "cdbdebugengine_p.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <inc/dbgeng.h>
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
CdbDebugOutput::CdbDebugOutput(CdbDebugEngine* engine) :
|
||||||
|
m_pEngine(engine)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugOutput::QueryInterface(
|
||||||
|
THIS_
|
||||||
|
IN REFIID InterfaceId,
|
||||||
|
OUT PVOID* Interface
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*Interface = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
||||||
|
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
|
||||||
|
{
|
||||||
|
*Interface = (IDebugOutputCallbacks *)this;
|
||||||
|
AddRef();
|
||||||
|
return S_OK;
|
||||||
|
} else {
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP_(ULONG) CdbDebugOutput::AddRef(THIS)
|
||||||
|
{
|
||||||
|
// This class is designed to be static so
|
||||||
|
// there's no true refcount.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP_(ULONG) CdbDebugOutput::Release(THIS)
|
||||||
|
{
|
||||||
|
// This class is designed to be static so
|
||||||
|
// there's no true refcount.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CdbDebugOutput::Output(
|
||||||
|
THIS_
|
||||||
|
IN ULONG mask,
|
||||||
|
IN PCSTR text
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(mask);
|
||||||
|
m_pEngine->m_d->handleDebugOutput(text);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
77
src/plugins/debugger/cdb/cdbdebugoutput.h
Normal file
77
src/plugins/debugger/cdb/cdbdebugoutput.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Qt Software Information (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** Non-Open Source Usage
|
||||||
|
**
|
||||||
|
** Licensees may use this file in accordance with the Qt Beta Version
|
||||||
|
** License Agreement, Agreement version 2.2 provided with the Software or,
|
||||||
|
** alternatively, in accordance with the terms contained in a written
|
||||||
|
** agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU General
|
||||||
|
** Public License versions 2.0 or 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the packaging
|
||||||
|
** of this file. Please review the following information to ensure GNU
|
||||||
|
** General Public Licensing requirements will be met:
|
||||||
|
**
|
||||||
|
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
|
||||||
|
** http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt GPL Exception
|
||||||
|
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef DEBUGGER_CDBOUTPUT_H
|
||||||
|
#define DEBUGGER_CDBOUTPUT_H
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <inc/dbgeng.h>
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class CdbDebugEngine;
|
||||||
|
|
||||||
|
class CdbDebugOutput : public IDebugOutputCallbacks
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CdbDebugOutput(CdbDebugEngine* engine);
|
||||||
|
|
||||||
|
// IUnknown.
|
||||||
|
STDMETHOD(QueryInterface)(
|
||||||
|
THIS_
|
||||||
|
IN REFIID InterfaceId,
|
||||||
|
OUT PVOID* Interface
|
||||||
|
);
|
||||||
|
STDMETHOD_(ULONG, AddRef)(
|
||||||
|
THIS
|
||||||
|
);
|
||||||
|
STDMETHOD_(ULONG, Release)(
|
||||||
|
THIS
|
||||||
|
);
|
||||||
|
|
||||||
|
// IDebugOutputCallbacks.
|
||||||
|
STDMETHOD(Output)(
|
||||||
|
THIS_
|
||||||
|
IN ULONG mask,
|
||||||
|
IN PCSTR text
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CdbDebugEngine* m_pEngine;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Debugger
|
||||||
|
|
||||||
|
#endif // DEBUGGER_CDBOUTPUT_H
|
@@ -1,203 +0,0 @@
|
|||||||
#include "cdbdebugeventcallback.h"
|
|
||||||
#include "cdbcdebugengine.h"
|
|
||||||
#include "debuggermanager.h"
|
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
namespace Debugger {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::QueryInterface(
|
|
||||||
THIS_
|
|
||||||
IN REFIID InterfaceId,
|
|
||||||
OUT PVOID* Interface)
|
|
||||||
{
|
|
||||||
*Interface = NULL;
|
|
||||||
|
|
||||||
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
|
||||||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
|
|
||||||
{
|
|
||||||
*Interface = (IDebugOutputCallbacks *)this;
|
|
||||||
AddRef();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP_(ULONG) MSVCDebugEventCallback::AddRef(THIS)
|
|
||||||
{
|
|
||||||
// This class is designed to be static so
|
|
||||||
// there's no true refcount.
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP_(ULONG) MSVCDebugEventCallback::Release(THIS)
|
|
||||||
{
|
|
||||||
// This class is designed to be static so
|
|
||||||
// there's no true refcount.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
|
|
||||||
{
|
|
||||||
*mask = DEBUG_EVENT_CREATE_PROCESS | DEBUG_EVENT_EXIT_PROCESS
|
|
||||||
//| DEBUG_EVENT_CREATE_THREAD | DEBUG_EVENT_EXIT_THREAD
|
|
||||||
| DEBUG_EVENT_BREAKPOINT
|
|
||||||
| DEBUG_EVENT_EXCEPTION
|
|
||||||
;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT Bp)
|
|
||||||
{
|
|
||||||
qDebug() << "MSVCDebugEventCallback::Breakpoint";
|
|
||||||
m_pEngine->handleBreakpointEvent(Bp);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::Exception(
|
|
||||||
THIS_
|
|
||||||
__in PEXCEPTION_RECORD64 Exception,
|
|
||||||
__in ULONG FirstChance
|
|
||||||
)
|
|
||||||
{
|
|
||||||
qDebug() << "MSVCDebugEventCallback::Exception";
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::CreateThread(
|
|
||||||
THIS_
|
|
||||||
__in ULONG64 Handle,
|
|
||||||
__in ULONG64 DataOffset,
|
|
||||||
__in ULONG64 StartOffset
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//Debugger::ThreadInfo ti;
|
|
||||||
//ti.handle = Handle;
|
|
||||||
//ti.dataOffset = DataOffset;
|
|
||||||
//ti.startOffset = StartOffset;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::ExitThread(
|
|
||||||
THIS_
|
|
||||||
__in ULONG ExitCode
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::CreateProcess(
|
|
||||||
THIS_
|
|
||||||
__in ULONG64 ImageFileHandle,
|
|
||||||
__in ULONG64 Handle,
|
|
||||||
__in ULONG64 BaseOffset,
|
|
||||||
__in ULONG ModuleSize,
|
|
||||||
__in_opt PCSTR ModuleName,
|
|
||||||
__in_opt PCSTR ImageName,
|
|
||||||
__in ULONG CheckSum,
|
|
||||||
__in ULONG TimeDateStamp,
|
|
||||||
__in ULONG64 InitialThreadHandle,
|
|
||||||
__in ULONG64 ThreadDataOffset,
|
|
||||||
__in ULONG64 StartOffset
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_pEngine->m_hDebuggeeProcess = (HANDLE)Handle;
|
|
||||||
m_pEngine->m_hDebuggeeThread = (HANDLE)InitialThreadHandle;
|
|
||||||
//m_pEngine->qq->notifyStartupFinished();
|
|
||||||
m_pEngine->qq->notifyInferiorRunning();
|
|
||||||
|
|
||||||
ULONG currentThreadId;
|
|
||||||
if (SUCCEEDED(m_pEngine->m_pDebugSystemObjects->GetThreadIdByHandle(InitialThreadHandle, ¤tThreadId)))
|
|
||||||
m_pEngine->m_currentThreadId = currentThreadId;
|
|
||||||
else
|
|
||||||
m_pEngine->m_currentThreadId = 0;
|
|
||||||
|
|
||||||
m_pEngine->attemptBreakpointSynchronization();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::ExitProcess(
|
|
||||||
THIS_
|
|
||||||
__in ULONG ExitCode
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UNREFERENCED_PARAMETER(ExitCode);
|
|
||||||
m_pEngine->m_hDebuggeeProcess = 0;
|
|
||||||
m_pEngine->m_hDebuggeeThread = 0;
|
|
||||||
m_pEngine->qq->notifyInferiorExited();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::LoadModule(
|
|
||||||
THIS_
|
|
||||||
__in ULONG64 ImageFileHandle,
|
|
||||||
__in ULONG64 BaseOffset,
|
|
||||||
__in ULONG ModuleSize,
|
|
||||||
__in_opt PCSTR ModuleName,
|
|
||||||
__in_opt PCSTR ImageName,
|
|
||||||
__in ULONG CheckSum,
|
|
||||||
__in ULONG TimeDateStamp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::UnloadModule(
|
|
||||||
THIS_
|
|
||||||
__in_opt PCSTR ImageBaseName,
|
|
||||||
__in ULONG64 BaseOffset
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::SystemError(
|
|
||||||
THIS_
|
|
||||||
__in ULONG Error,
|
|
||||||
__in ULONG Level
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::SessionStatus(
|
|
||||||
THIS_
|
|
||||||
__in ULONG Status
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::ChangeDebuggeeState(
|
|
||||||
THIS_
|
|
||||||
__in ULONG Flags,
|
|
||||||
__in ULONG64 Argument
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::ChangeEngineState(
|
|
||||||
THIS_
|
|
||||||
__in ULONG Flags,
|
|
||||||
__in ULONG64 Argument
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugEventCallback::ChangeSymbolState(
|
|
||||||
THIS_
|
|
||||||
__in ULONG Flags,
|
|
||||||
__in ULONG64 Argument
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Debugger
|
|
@@ -1,57 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#include <dbgeng.h>
|
|
||||||
|
|
||||||
#include "cdbdebugoutput.h"
|
|
||||||
#include "cdbdebugengine.h"
|
|
||||||
|
|
||||||
namespace Debugger {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugOutput::QueryInterface(
|
|
||||||
THIS_
|
|
||||||
IN REFIID InterfaceId,
|
|
||||||
OUT PVOID* Interface
|
|
||||||
)
|
|
||||||
{
|
|
||||||
*Interface = NULL;
|
|
||||||
|
|
||||||
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
|
||||||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
|
|
||||||
{
|
|
||||||
*Interface = (IDebugOutputCallbacks *)this;
|
|
||||||
AddRef();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP_(ULONG) MSVCDebugOutput::AddRef(THIS)
|
|
||||||
{
|
|
||||||
// This class is designed to be static so
|
|
||||||
// there's no true refcount.
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP_(ULONG) MSVCDebugOutput::Release(THIS)
|
|
||||||
{
|
|
||||||
// This class is designed to be static so
|
|
||||||
// there's no true refcount.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP MSVCDebugOutput::Output(
|
|
||||||
THIS_
|
|
||||||
IN ULONG mask,
|
|
||||||
IN PCSTR text
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UNREFERENCED_PARAMETER(mask);
|
|
||||||
m_pEngine->handleDebugOutput(text);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Debugger
|
|
@@ -1,43 +0,0 @@
|
|||||||
#ifndef DEBUGGER_CDBOUTPUT_H
|
|
||||||
#define DEBUGGER_CDBOUTPUT_H
|
|
||||||
|
|
||||||
namespace Debugger {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class CdbDebugEngine;
|
|
||||||
|
|
||||||
class CdbDebugOutput : public IDebugOutputCallbacks
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CdbDebugOutput(CdbDebugEngine* engine)
|
|
||||||
: m_pEngine(engine)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// IUnknown.
|
|
||||||
STDMETHOD(QueryInterface)(
|
|
||||||
THIS_
|
|
||||||
IN REFIID InterfaceId,
|
|
||||||
OUT PVOID* Interface
|
|
||||||
);
|
|
||||||
STDMETHOD_(ULONG, AddRef)(
|
|
||||||
THIS
|
|
||||||
);
|
|
||||||
STDMETHOD_(ULONG, Release)(
|
|
||||||
THIS
|
|
||||||
);
|
|
||||||
|
|
||||||
// IDebugOutputCallbacks.
|
|
||||||
STDMETHOD(Output)(
|
|
||||||
THIS_
|
|
||||||
IN ULONG mask,
|
|
||||||
IN PCSTR text
|
|
||||||
);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CdbDebugEngine* m_pEngine;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
} // namespace Debugger
|
|
||||||
|
|
||||||
#endif // DEBUGGER_CDBOUTPUT_H
|
|
@@ -85,19 +85,4 @@ HEADERS += $$PWD/modeltest.h
|
|||||||
DEFINES += USE_MODEL_TEST=1
|
DEFINES += USE_MODEL_TEST=1
|
||||||
}
|
}
|
||||||
|
|
||||||
false {
|
CONFIG(cdbdebugger):include(cdb\cdb.pri)
|
||||||
|
|
||||||
HEADERS += \
|
|
||||||
cdbdebugengine.h \
|
|
||||||
cdbdebugeventcallback.h \
|
|
||||||
cdbdebugoutput.h
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
cdbdebugengine.cpp \
|
|
||||||
cdbdebugeventcallback.cpp \
|
|
||||||
cdbdebugoutput.cpp
|
|
||||||
|
|
||||||
LIBS += dbgeng.lib
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -132,7 +132,12 @@ static IDebuggerEngine *winEngine = 0;
|
|||||||
static IDebuggerEngine *scriptEngine = 0;
|
static IDebuggerEngine *scriptEngine = 0;
|
||||||
|
|
||||||
extern IDebuggerEngine *createGdbEngine(DebuggerManager *parent);
|
extern IDebuggerEngine *createGdbEngine(DebuggerManager *parent);
|
||||||
extern IDebuggerEngine *createWinEngine(DebuggerManager *) { return 0; }
|
extern IDebuggerEngine *createWinEngine(DebuggerManager *)
|
||||||
|
#ifdef CDB_ENABLED
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
{ return 0; }
|
||||||
|
#endif
|
||||||
extern IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
|
extern IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
|
||||||
|
|
||||||
DebuggerManager::DebuggerManager()
|
DebuggerManager::DebuggerManager()
|
||||||
|
@@ -106,11 +106,11 @@ enum DebuggerStatus
|
|||||||
DebuggerInferiorStopped, // Debuggee stopped
|
DebuggerInferiorStopped, // Debuggee stopped
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class IDebuggerEngine;
|
class IDebuggerEngine;
|
||||||
class GdbEngine;
|
class GdbEngine;
|
||||||
class ScriptEngine;
|
class ScriptEngine;
|
||||||
class WinEngine;
|
class CdbDebugEngine;
|
||||||
|
struct CdbDebugEnginePrivate;
|
||||||
|
|
||||||
// The construct below is not nice but enforces a bit of order. The
|
// The construct below is not nice but enforces a bit of order. The
|
||||||
// DebuggerManager interfaces a lots of thing: The DebuggerPlugin,
|
// DebuggerManager interfaces a lots of thing: The DebuggerPlugin,
|
||||||
@@ -131,10 +131,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// This is the part of the interface that's exclusively seen by the
|
// This is the part of the interface that's exclusively seen by the
|
||||||
// debugger engines.
|
// debugger engines
|
||||||
friend class GdbEngine;
|
friend class GdbEngine;
|
||||||
|
friend class CdbDebugEngine;
|
||||||
|
friend class CdbDebugEventCallback;
|
||||||
friend class ScriptEngine;
|
friend class ScriptEngine;
|
||||||
friend class WinEngine;
|
friend struct CdbDebugEnginePrivate;
|
||||||
|
|
||||||
// called from the engines after successful startup
|
// called from the engines after successful startup
|
||||||
virtual void notifyInferiorStopRequested() = 0;
|
virtual void notifyInferiorStopRequested() = 0;
|
||||||
|
@@ -234,15 +234,6 @@ static bool isLeavableFunction(const QString &funcName, const QString &fileName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString startSymbolName()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
return "WinMainCRTStartup";
|
|
||||||
#else
|
|
||||||
return "_start";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -1555,9 +1546,7 @@ bool GdbEngine::startDebugger()
|
|||||||
qDebug() << "ExeFile: " << q->m_executable;
|
qDebug() << "ExeFile: " << q->m_executable;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
q->showStatusMessage(tr("Starting Debugger"));
|
q->showStatusMessage(tr("Starting Debugger: ") + q->settings()->m_gdbCmd + ' ' + gdbArgs.join(" "));
|
||||||
emit gdbInputAvailable(QString(), q->settings()->m_gdbCmd + ' ' + gdbArgs.join(" "));
|
|
||||||
|
|
||||||
m_gdbProc.start(q->settings()->m_gdbCmd, gdbArgs);
|
m_gdbProc.start(q->settings()->m_gdbCmd, gdbArgs);
|
||||||
m_gdbProc.waitForStarted();
|
m_gdbProc.waitForStarted();
|
||||||
|
|
||||||
@@ -1655,7 +1644,7 @@ bool GdbEngine::startDebugger()
|
|||||||
if (!q->m_processArgs.isEmpty())
|
if (!q->m_processArgs.isEmpty())
|
||||||
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
|
||||||
sendCommand("set auto-solib-add off");
|
sendCommand("set auto-solib-add off");
|
||||||
sendCommand("x/2i " + startSymbolName(), GdbStart);
|
sendCommand("info target", GdbStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set all to "pending"
|
// set all to "pending"
|
||||||
@@ -1678,14 +1667,14 @@ void GdbEngine::continueInferior()
|
|||||||
void GdbEngine::handleStart(const GdbResultRecord &response)
|
void GdbEngine::handleStart(const GdbResultRecord &response)
|
||||||
{
|
{
|
||||||
if (response.resultClass == GdbResultDone) {
|
if (response.resultClass == GdbResultDone) {
|
||||||
// stdout:&"x/2i _start\n"
|
// [some leading stdout here]
|
||||||
// stdout:~"0x404540 <_start>:\txor %ebp,%ebp\n"
|
// stdout:&" Entry point: 0x80831f0 0x08048134 - 0x08048147 is .interp\n"
|
||||||
// stdout:~"0x404542 <_start+2>:\tmov %rdx,%r9\n"
|
// [some trailing stdout here]
|
||||||
QString msg = response.data.findChild("consolestreamoutput").data();
|
QString msg = response.data.findChild("consolestreamoutput").data();
|
||||||
QRegExp needle("0x([0-9a-f]+) <" + startSymbolName() + "\\+.*>:");
|
QRegExp needle("\\bEntry point: (0x[0-9a-f]+)\\b");
|
||||||
if (needle.indexIn(msg) != -1) {
|
if (needle.indexIn(msg) != -1) {
|
||||||
//debugMessage("STREAM: " + msg + " " + needle.cap(1));
|
//debugMessage("STREAM: " + msg + " " + needle.cap(1));
|
||||||
sendCommand("tbreak *0x" + needle.cap(1));
|
sendCommand("tbreak *" + needle.cap(1));
|
||||||
m_waitingForFirstBreakpointToBeHit = true;
|
m_waitingForFirstBreakpointToBeHit = true;
|
||||||
qq->notifyInferiorRunningRequested();
|
qq->notifyInferiorRunningRequested();
|
||||||
sendCommand("-exec-run");
|
sendCommand("-exec-run");
|
||||||
@@ -1693,7 +1682,7 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
|
|||||||
debugMessage("PARSING START ADDRESS FAILED: " + msg);
|
debugMessage("PARSING START ADDRESS FAILED: " + msg);
|
||||||
}
|
}
|
||||||
} else if (response.resultClass == GdbResultError) {
|
} else if (response.resultClass == GdbResultError) {
|
||||||
debugMessage("PARSING START ADDRESS FAILED: " + response.toString());
|
debugMessage("FETCHING START ADDRESS FAILED: " + response.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,6 +39,8 @@
|
|||||||
#include <QtNetwork/QLocalSocket>
|
#include <QtNetwork/QLocalSocket>
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
@@ -80,7 +82,9 @@ bool OutputCollector::listen()
|
|||||||
return m_server->isListening();
|
return m_server->isListening();
|
||||||
m_server = new QLocalServer(this);
|
m_server = new QLocalServer(this);
|
||||||
connect(m_server, SIGNAL(newConnection()), SLOT(newConnectionAvailable()));
|
connect(m_server, SIGNAL(newConnection()), SLOT(newConnectionAvailable()));
|
||||||
return m_server->listen(QString::fromLatin1("creator-%1").arg(QCoreApplication::applicationPid())); // XXX how to make that secure?
|
return m_server->listen(QString::fromLatin1("creator-%1-%2")
|
||||||
|
.arg(QCoreApplication::applicationPid())
|
||||||
|
.arg(rand()));
|
||||||
#else
|
#else
|
||||||
if (!m_serverPath.isEmpty())
|
if (!m_serverPath.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
@@ -156,7 +160,7 @@ void OutputCollector::newConnectionAvailable()
|
|||||||
if (m_socket)
|
if (m_socket)
|
||||||
return;
|
return;
|
||||||
m_socket = m_server->nextPendingConnection();
|
m_socket = m_server->nextPendingConnection();
|
||||||
connect(m_socket, SIGNAL(bytesAvailable()), SLOT(bytesAvailable()));
|
connect(m_socket, SIGNAL(readyRead()), SLOT(bytesAvailable()));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -111,7 +111,7 @@ QWidget *ApplicationRunConfigurationRunner::configurationWidget(QSharedPointer<R
|
|||||||
// ApplicationRunControl
|
// ApplicationRunControl
|
||||||
|
|
||||||
ApplicationRunControl::ApplicationRunControl(QSharedPointer<ApplicationRunConfiguration> runConfiguration)
|
ApplicationRunControl::ApplicationRunControl(QSharedPointer<ApplicationRunConfiguration> runConfiguration)
|
||||||
: RunControl(runConfiguration), m_applicationLauncher()
|
: RunControl(runConfiguration)
|
||||||
{
|
{
|
||||||
connect(&m_applicationLauncher, SIGNAL(applicationError(QString)),
|
connect(&m_applicationLauncher, SIGNAL(applicationError(QString)),
|
||||||
this, SLOT(slotError(QString)));
|
this, SLOT(slotError(QString)));
|
||||||
|
@@ -84,6 +84,9 @@ const char * const C_OPERATOR = "Operator";
|
|||||||
const char * const C_PREPROCESSOR = "Preprocessor";
|
const char * const C_PREPROCESSOR = "Preprocessor";
|
||||||
const char * const C_LABEL = "Label";
|
const char * const C_LABEL = "Label";
|
||||||
const char * const C_COMMENT = "Comment";
|
const char * const C_COMMENT = "Comment";
|
||||||
|
const char * const C_DOXYGEN_COMMENT = "Doxygen.Comment";
|
||||||
|
const char * const C_DOXYGEN_TAG = "Doxygen.Tag";
|
||||||
|
|
||||||
const char * const C_DISABLED_CODE = "DisabledCode";
|
const char * const C_DISABLED_CODE = "DisabledCode";
|
||||||
|
|
||||||
const char * const C_ADDED_LINE = "AddedLine";
|
const char * const C_ADDED_LINE = "AddedLine";
|
||||||
|
@@ -84,6 +84,8 @@ TextEditorSettings::TextEditorSettings(QObject *parent)
|
|||||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_PREPROCESSOR), tr("Preprocessor"), Qt::darkBlue));
|
formatDescriptions.push_back(FormatDescription(QLatin1String(C_PREPROCESSOR), tr("Preprocessor"), Qt::darkBlue));
|
||||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_LABEL), tr("Label"), Qt::darkRed));
|
formatDescriptions.push_back(FormatDescription(QLatin1String(C_LABEL), tr("Label"), Qt::darkRed));
|
||||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_COMMENT), tr("Comment"), Qt::darkGreen));
|
formatDescriptions.push_back(FormatDescription(QLatin1String(C_COMMENT), tr("Comment"), Qt::darkGreen));
|
||||||
|
formatDescriptions.push_back(FormatDescription(QLatin1String(C_DOXYGEN_COMMENT), tr("Doxygen Comment"), Qt::darkBlue));
|
||||||
|
formatDescriptions.push_back(FormatDescription(QLatin1String(C_DOXYGEN_TAG), tr("Doxygen Tag"), Qt::blue));
|
||||||
formatDescriptions.push_back(FormatDescription(QLatin1String(C_DISABLED_CODE), tr("Disabled Code"), Qt::gray));
|
formatDescriptions.push_back(FormatDescription(QLatin1String(C_DISABLED_CODE), tr("Disabled Code"), Qt::gray));
|
||||||
|
|
||||||
// Diff categories
|
// Diff categories
|
||||||
|
@@ -60,7 +60,7 @@ CPLUSPLUS_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
Lexer::Lexer(TranslationUnit *unit)
|
Lexer::Lexer(TranslationUnit *unit)
|
||||||
: _translationUnit(unit),
|
: _translationUnit(unit),
|
||||||
_state(Lexer::DefaultState),
|
_state(State_Default),
|
||||||
_flags(0),
|
_flags(0),
|
||||||
_currentLine(1)
|
_currentLine(1)
|
||||||
{
|
{
|
||||||
@@ -71,7 +71,7 @@ Lexer::Lexer(TranslationUnit *unit)
|
|||||||
|
|
||||||
Lexer::Lexer(const char *firstChar, const char *lastChar)
|
Lexer::Lexer(const char *firstChar, const char *lastChar)
|
||||||
: _translationUnit(0),
|
: _translationUnit(0),
|
||||||
_state(Lexer::DefaultState),
|
_state(State_Default),
|
||||||
_flags(0),
|
_flags(0),
|
||||||
_currentLine(1)
|
_currentLine(1)
|
||||||
{
|
{
|
||||||
@@ -196,7 +196,9 @@ void Lexer::scan_helper(Token *tok)
|
|||||||
_tokenStart = _currentChar;
|
_tokenStart = _currentChar;
|
||||||
tok->offset = _currentChar - _firstChar;
|
tok->offset = _currentChar - _firstChar;
|
||||||
|
|
||||||
if (_state == MultiLineCommentState) {
|
if (_state == State_MultiLineComment || _state == State_MultiLineDoxyComment) {
|
||||||
|
const int originalState = _state;
|
||||||
|
|
||||||
if (! _yychar) {
|
if (! _yychar) {
|
||||||
tok->kind = T_EOF_SYMBOL;
|
tok->kind = T_EOF_SYMBOL;
|
||||||
return;
|
return;
|
||||||
@@ -209,7 +211,7 @@ void Lexer::scan_helper(Token *tok)
|
|||||||
yyinp();
|
yyinp();
|
||||||
if (_yychar == '/') {
|
if (_yychar == '/') {
|
||||||
yyinp();
|
yyinp();
|
||||||
_state = DefaultState;
|
_state = State_Default;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +220,10 @@ void Lexer::scan_helper(Token *tok)
|
|||||||
if (! _scanCommentTokens)
|
if (! _scanCommentTokens)
|
||||||
goto _Lagain;
|
goto _Lagain;
|
||||||
|
|
||||||
|
else if (originalState == State_MultiLineComment)
|
||||||
tok->kind = T_COMMENT;
|
tok->kind = T_COMMENT;
|
||||||
|
else
|
||||||
|
tok->kind = T_DOXY_COMMENT;
|
||||||
return; // done
|
return; // done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,14 +407,30 @@ void Lexer::scan_helper(Token *tok)
|
|||||||
|
|
||||||
case '/':
|
case '/':
|
||||||
if (_yychar == '/') {
|
if (_yychar == '/') {
|
||||||
do {
|
|
||||||
yyinp();
|
yyinp();
|
||||||
} while (_yychar && _yychar != '\n');
|
|
||||||
|
bool doxy = false;
|
||||||
|
|
||||||
|
if (_yychar == '/' || _yychar == '!') {
|
||||||
|
yyinp();
|
||||||
|
|
||||||
|
if (_yychar != '\n' && std::isspace(_yychar))
|
||||||
|
doxy = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (_yychar && _yychar != '\n')
|
||||||
|
yyinp();
|
||||||
|
|
||||||
if (! _scanCommentTokens)
|
if (! _scanCommentTokens)
|
||||||
goto _Lagain;
|
goto _Lagain;
|
||||||
tok->kind = T_COMMENT;
|
|
||||||
|
tok->kind = doxy ? T_DOXY_COMMENT : T_COMMENT;
|
||||||
|
|
||||||
} else if (_yychar == '*') {
|
} else if (_yychar == '*') {
|
||||||
yyinp();
|
yyinp();
|
||||||
|
|
||||||
|
const bool doxy = _yychar == '*' || _yychar == '!';
|
||||||
|
|
||||||
while (_yychar) {
|
while (_yychar) {
|
||||||
if (_yychar != '*') {
|
if (_yychar != '*') {
|
||||||
yyinp();
|
yyinp();
|
||||||
@@ -423,11 +444,13 @@ void Lexer::scan_helper(Token *tok)
|
|||||||
if (_yychar)
|
if (_yychar)
|
||||||
yyinp();
|
yyinp();
|
||||||
else
|
else
|
||||||
_state = MultiLineCommentState;
|
_state = doxy ? State_MultiLineDoxyComment : State_MultiLineComment;
|
||||||
|
|
||||||
if (! _scanCommentTokens)
|
if (! _scanCommentTokens)
|
||||||
goto _Lagain;
|
goto _Lagain;
|
||||||
tok->kind = T_COMMENT;
|
|
||||||
|
tok->kind = doxy ? T_DOXY_COMMENT : T_COMMENT;
|
||||||
|
|
||||||
} else if (_yychar == '=') {
|
} else if (_yychar == '=') {
|
||||||
yyinp();
|
yyinp();
|
||||||
tok->kind = T_SLASH_EQUAL;
|
tok->kind = T_SLASH_EQUAL;
|
||||||
|
@@ -66,8 +66,9 @@ class CPLUSPLUS_EXPORT Lexer
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum State {
|
enum State {
|
||||||
DefaultState,
|
State_Default,
|
||||||
MultiLineCommentState
|
State_MultiLineComment,
|
||||||
|
State_MultiLineDoxyComment
|
||||||
};
|
};
|
||||||
|
|
||||||
Lexer(TranslationUnit *unit);
|
Lexer(TranslationUnit *unit);
|
||||||
|
@@ -58,7 +58,7 @@ CPLUSPLUS_BEGIN_NAMESPACE
|
|||||||
static const char *token_names[] = {
|
static const char *token_names[] = {
|
||||||
(""), ("<error>"),
|
(""), ("<error>"),
|
||||||
|
|
||||||
("<comment>"),
|
("<comment>"), ("<doxy comment>"),
|
||||||
|
|
||||||
("<identifier>"), ("<int literal>"), ("<float literal>"), ("<char literal>"),
|
("<identifier>"), ("<int literal>"), ("<float literal>"), ("<char literal>"),
|
||||||
("<wide char literal>"), ("<string literal>"), ("<wide char literal>"),
|
("<wide char literal>"), ("<string literal>"), ("<wide char literal>"),
|
||||||
|
@@ -64,6 +64,7 @@ enum Kind {
|
|||||||
T_ERROR,
|
T_ERROR,
|
||||||
|
|
||||||
T_COMMENT,
|
T_COMMENT,
|
||||||
|
T_DOXY_COMMENT,
|
||||||
T_IDENTIFIER,
|
T_IDENTIFIER,
|
||||||
|
|
||||||
T_FIRST_LITERAL,
|
T_FIRST_LITERAL,
|
||||||
@@ -297,6 +298,9 @@ public:
|
|||||||
inline bool isKeyword() const
|
inline bool isKeyword() const
|
||||||
{ return kind >= T_FIRST_KEYWORD && kind < T_FIRST_QT_KEYWORD; }
|
{ return kind >= T_FIRST_KEYWORD && kind < T_FIRST_QT_KEYWORD; }
|
||||||
|
|
||||||
|
inline bool isComment() const
|
||||||
|
{ return kind == T_COMMENT || kind == T_DOXY_COMMENT; }
|
||||||
|
|
||||||
inline bool isObjCAtKeyword() const
|
inline bool isObjCAtKeyword() const
|
||||||
{ return kind >= T_FIRST_OBJC_AT_KEYWORD && kind < T_LAST_OBJC_AT_KEYWORD; }
|
{ return kind >= T_FIRST_OBJC_AT_KEYWORD && kind < T_LAST_OBJC_AT_KEYWORD; }
|
||||||
|
|
||||||
|
@@ -5,4 +5,3 @@ echo "Generating $t"
|
|||||||
${CPP-gcc} -xc++ -E -include $me/conf.c++ $* > $t
|
${CPP-gcc} -xc++ -E -include $me/conf.c++ $* > $t
|
||||||
echo "Parsing $t"
|
echo "Parsing $t"
|
||||||
$me/cplusplus0 $t
|
$me/cplusplus0 $t
|
||||||
|
|
||||||
|
@@ -6,3 +6,6 @@
|
|||||||
#define restrict
|
#define restrict
|
||||||
#define __restrict
|
#define __restrict
|
||||||
#define __weak
|
#define __weak
|
||||||
|
#define __complex__
|
||||||
|
#define __imag__
|
||||||
|
#define __real__
|
||||||
|
Reference in New Issue
Block a user