Merge commit 'origin/1.3'

This commit is contained in:
con
2009-10-06 18:42:28 +02:00
36 changed files with 420 additions and 172 deletions

View File

@@ -1080,7 +1080,7 @@
\l{http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx}{32-bit} \l{http://www.microsoft.com/whdc/devtools/debugging/installx86.Mspx}{32-bit}
or or
\l{http://www.microsoft.com/whdc/devtools/debugging/install64bit.Mspx}{64-bit} \l{http://www.microsoft.com/whdc/devtools/debugging/install64bit.Mspx}{64-bit}
package (Version 6.10 for the 32-bit or the 64-bit version of Qt Creator, respectively), package (Version 6.11.1.404 for the 32-bit or the 64-bit version of Qt Creator, respectively),
which is freely available for download from the which is freely available for download from the
\l{http://msdn.microsoft.com/en-us/default.aspx} \l{http://msdn.microsoft.com/en-us/default.aspx}
{Microsoft Developer Network}. {Microsoft Developer Network}.

View File

@@ -108,3 +108,7 @@ linux-g++-* {
# to prevent checking in code that does not compile on other platforms. # to prevent checking in code that does not compile on other platforms.
QMAKE_LFLAGS += -Wl,--allow-shlib-undefined -Wl,--no-undefined QMAKE_LFLAGS += -Wl,--allow-shlib-undefined -Wl,--no-undefined
} }
# Handle S60 support: default on Windows, conditionally built on other platforms.
win32:SUPPORT_QT_S60=1
else:SUPPORT_QT_S60 = $$(QTCREATOR_WITH_S60)

View File

@@ -34,7 +34,6 @@
using namespace CPlusPlus; using namespace CPlusPlus;
TranslationUnit *_previousUnit;
FastMacroResolver::FastMacroResolver(TranslationUnit *unit, const Snapshot &snapshot) FastMacroResolver::FastMacroResolver(TranslationUnit *unit, const Snapshot &snapshot)
: _unit(unit), _snapshot(snapshot) : _unit(unit), _snapshot(snapshot)
{ {

View File

@@ -504,10 +504,29 @@ void LookupContext::expand(Scope *scope,
Symbol *LookupContext::canonicalSymbol(Symbol *symbol) Symbol *LookupContext::canonicalSymbol(Symbol *symbol)
{ {
Symbol *canonical = symbol; Symbol *canonical = symbol;
Class *canonicalClass = 0;
for (; symbol; symbol = symbol->next()) { for (; symbol; symbol = symbol->next()) {
if (symbol->name() == canonical->name()) if (symbol->identifier() == canonical->identifier()) {
canonical = symbol; canonical = symbol;
if (Class *klass = symbol->asClass())
canonicalClass = klass;
}
}
if (canonicalClass) {
Q_ASSERT(canonical != 0);
if (canonical->isForwardClassDeclaration())
return canonicalClass; // prefer class declarations when available.
}
if (canonical && canonical->scope()->isClassScope()) {
Class *enclosingClass = canonical->scope()->owner()->asClass();
if (enclosingClass->identifier() == canonical->identifier())
return enclosingClass;
} }
return canonical; return canonical;

View File

@@ -164,8 +164,6 @@ QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QStri
if (isCompleteStringLiteral(tk, index - 1)) if (isCompleteStringLiteral(tk, index - 1))
return QLatin1String("\""); return QLatin1String("\"");
qDebug() << "*** here";
return QString(); return QString();
} else if (text.at(0) == QLatin1Char('\'') && (token.is(T_CHAR_LITERAL) || token.is(T_WIDE_CHAR_LITERAL))) { } else if (text.at(0) == QLatin1Char('\'') && (token.is(T_CHAR_LITERAL) || token.is(T_WIDE_CHAR_LITERAL))) {
if (text.length() != 1) if (text.length() != 1)

View File

@@ -1146,10 +1146,12 @@ IEditor *EditorManager::openEditor(Core::Internal::EditorView *view, const QStri
return 0; return 0;
} }
addEditor(editor); addEditor(editor);
restoreEditorState(editor);
QApplication::restoreOverrideCursor();
return activateEditor(view, editor, flags); IEditor *result= activateEditor(view, editor, flags);
if (editor == result)
restoreEditorState(editor);
QApplication::restoreOverrideCursor();
return result;
} }
bool EditorManager::openExternalEditor(const QString &fileName, const QString &editorKind) bool EditorManager::openExternalEditor(const QString &fileName, const QString &editorKind)

View File

@@ -195,12 +195,10 @@ public:
// local and external uses. // local and external uses.
SemanticInfo::LocalUseMap localUses; SemanticInfo::LocalUseMap localUses;
SemanticInfo::ExternalUseMap externalUses;
void operator()(FunctionDefinitionAST *ast) void operator()(FunctionDefinitionAST *ast)
{ {
localUses.clear(); localUses.clear();
externalUses.clear();
if (ast && ast->symbol) { if (ast && ast->symbol) {
_functionScope = ast->symbol->members(); _functionScope = ast->symbol->members();
@@ -232,6 +230,18 @@ protected:
return false; return false;
} }
void searchUsesInTemplateArguments(NameAST *name)
{
if (! name)
return;
else if (TemplateIdAST *template_id = name->asTemplateId()) {
for (TemplateArgumentListAST *it = template_id->template_arguments; it; it = it->next) {
accept(it->template_argument);
}
}
}
virtual bool visit(SimpleNameAST *ast) virtual bool visit(SimpleNameAST *ast)
{ {
unsigned line, column; unsigned line, column;
@@ -258,14 +268,14 @@ protected:
scope = scope->enclosingScope(); scope = scope->enclosingScope();
} }
Identifier *id = identifier(ast->identifier_token);
externalUses[id].append(SemanticInfo::Use(line, column, id->size()));
return false; return false;
} }
virtual bool visit(TemplateIdAST *ast) virtual bool visit(TemplateIdAST *ast)
{ {
for (TemplateArgumentListAST *arg = ast->template_arguments; arg; arg = arg->next)
accept(arg->template_argument);
unsigned line, column; unsigned line, column;
getTokenStartPosition(ast->firstToken(), &line, &column); getTokenStartPosition(ast->firstToken(), &line, &column);
@@ -290,34 +300,15 @@ protected:
scope = scope->enclosingScope(); scope = scope->enclosingScope();
} }
Identifier *id = identifier(ast->identifier_token);
externalUses[id].append(SemanticInfo::Use(line, column, id->size()));
for (TemplateArgumentListAST *arg = ast->template_arguments; arg; arg = arg->next)
accept(arg);
return false; return false;
} }
virtual bool visit(QualifiedNameAST *ast) virtual bool visit(QualifiedNameAST *ast)
{ {
if (! ast->global_scope_token) { for (NestedNameSpecifierAST *it = ast->nested_name_specifier; it; it = it->next)
if (ast->nested_name_specifier) { searchUsesInTemplateArguments(it->class_or_namespace_name);
accept(ast->nested_name_specifier->class_or_namespace_name);
for (NestedNameSpecifierAST *it = ast->nested_name_specifier->next; it; it = it->next) {
if (NameAST *class_or_namespace_name = it->class_or_namespace_name) {
if (TemplateIdAST *template_id = class_or_namespace_name->asTemplateId()) {
for (TemplateArgumentListAST *arg = template_id->template_arguments; arg; arg = arg->next)
accept(arg);
}
}
}
}
accept(ast->unqualified_name);
}
searchUsesInTemplateArguments(ast->unqualified_name);
return false; return false;
} }
@@ -878,6 +869,16 @@ void CPPEditor::findUsages()
void CPPEditor::renameUsages() void CPPEditor::renameUsages()
{ {
Core::EditorManager::instance()->showEditorInfoBar(QLatin1String("CppEditor.Rename"),
tr("This change cannot be undone."),
tr("Yes, I know what I am doing."),
this, SLOT(renameUsagesNow()));
}
void CPPEditor::renameUsagesNow()
{
Core::EditorManager::instance()->hideEditorInfoBar(QLatin1String("CppEditor.Rename"));
m_currentRenameSelection = -1; m_currentRenameSelection = -1;
QList<QTextEdit::ExtraSelection> selections; QList<QTextEdit::ExtraSelection> selections;
@@ -2111,7 +2112,6 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
semanticInfo.snapshot = snapshot; semanticInfo.snapshot = snapshot;
semanticInfo.doc = doc; semanticInfo.doc = doc;
semanticInfo.localUses = useTable.localUses; semanticInfo.localUses = useTable.localUses;
semanticInfo.externalUses = useTable.externalUses;
return semanticInfo; return semanticInfo;
} }

View File

@@ -70,28 +70,21 @@ public:
unsigned column; unsigned column;
unsigned length; unsigned length;
Use() Use(unsigned line = 0, unsigned column = 0, unsigned length = 0)
: line(0), column(0), length(0) {} : line(line), column(column), length(length) {}
Use(unsigned line, unsigned column, unsigned length)
: line(line), column(column), length(length) {}
}; };
typedef QHash<CPlusPlus::Symbol *, QList<Use> > LocalUseMap; typedef QHash<CPlusPlus::Symbol *, QList<Use> > LocalUseMap;
typedef QHashIterator<CPlusPlus::Symbol *, QList<Use> > LocalUseIterator; typedef QHashIterator<CPlusPlus::Symbol *, QList<Use> > LocalUseIterator;
typedef QHash<CPlusPlus::Identifier *, QList<Use> > ExternalUseMap;
typedef QHashIterator<CPlusPlus::Identifier *, QList<Use> > ExternalUseIterator;
SemanticInfo() SemanticInfo()
: revision(-1) : revision(-1)
{ } { }
int revision; int revision;
CPlusPlus::Snapshot snapshot; CPlusPlus::Snapshot snapshot;
CPlusPlus::Document::Ptr doc; CPlusPlus::Document::Ptr doc;
LocalUseMap localUses; LocalUseMap localUses;
ExternalUseMap externalUses;
}; };
class SemanticHighlighter: public QThread class SemanticHighlighter: public QThread
@@ -199,6 +192,7 @@ public Q_SLOTS:
void renameSymbolUnderCursor(); void renameSymbolUnderCursor();
void renameUsages(); void renameUsages();
void findUsages(); void findUsages();
void renameUsagesNow();
void moveToPreviousToken(); void moveToPreviousToken();
void moveToNextToken(); void moveToNextToken();

View File

@@ -36,6 +36,7 @@
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/filesearch.h> #include <utils/filesearch.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <ASTVisitor.h> #include <ASTVisitor.h>
@@ -57,7 +58,7 @@
#include <QtCore/QTime> #include <QtCore/QTime>
#include <QtCore/QtConcurrentRun> #include <QtCore/QtConcurrentRun>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtGui/QApplication>
#include <qtconcurrent/runextensions.h> #include <qtconcurrent/runextensions.h>
using namespace CppTools::Internal; using namespace CppTools::Internal;
@@ -163,12 +164,20 @@ protected:
if (! symbol) if (! symbol)
return false; return false;
else if (symbol == _declSymbol) else if (symbol == _declSymbol) {
return true; return true;
else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) { } else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) {
if (! qstrcmp(symbol->fileName(), _declSymbol->fileName())) if (! qstrcmp(symbol->fileName(), _declSymbol->fileName()))
return true; return true;
} else if (symbol->isForwardClassDeclaration() && (_declSymbol->isClass() ||
_declSymbol->isForwardClassDeclaration())) {
return true;
} else if (_declSymbol->isForwardClassDeclaration() && (symbol->isClass() ||
symbol->isForwardClassDeclaration())) {
return true;
} }
return false; return false;
@@ -303,14 +312,22 @@ protected:
} }
} }
if (ast->unqualified_name) { if (NameAST *unqualified_name = ast->unqualified_name) {
SimpleNameAST *simple_name = ast->unqualified_name->asSimpleName(); unsigned identifier_token = 0;
if (SimpleNameAST *simple_name = unqualified_name->asSimpleName())
identifier_token = simple_name->identifier_token;
else if (DestructorNameAST *dtor_name = unqualified_name->asDestructorName())
identifier_token = dtor_name->identifier_token;
TemplateIdAST *template_id = 0; TemplateIdAST *template_id = 0;
if (! simple_name) { if (! identifier_token) {
template_id = ast->unqualified_name->asTemplateId(); template_id = unqualified_name->asTemplateId();
if (template_id) { if (template_id) {
identifier_token = template_id->identifier_token;
for (TemplateArgumentListAST *template_arguments = template_id->template_arguments; for (TemplateArgumentListAST *template_arguments = template_id->template_arguments;
template_arguments; template_arguments = template_arguments->next) { template_arguments; template_arguments = template_arguments->next) {
accept(template_arguments->template_argument); accept(template_arguments->template_argument);
@@ -318,14 +335,8 @@ protected:
} }
} }
if (simple_name || template_id) { if (identifier_token && identifier(identifier_token) == _id)
const unsigned identifier_token = simple_name checkExpression(ast->firstToken(), identifier_token);
? simple_name->identifier_token
: template_id->identifier_token;
if (identifier(identifier_token) == _id)
checkExpression(ast->firstToken(), identifier_token);
}
} }
return false; return false;
@@ -464,7 +475,21 @@ static void find_helper(QFutureInterface<Utils::FileSearchResult> &future,
const QString sourceFile = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()); const QString sourceFile = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
QStringList files(sourceFile); QStringList files(sourceFile);
files += snapshot.dependsOn(sourceFile);
if (symbol->isClass() || symbol->isForwardClassDeclaration()) {
foreach (const Document::Ptr &doc, snapshot) {
if (doc->fileName() == sourceFile)
continue;
Control *control = doc->control();
if (control->findIdentifier(symbolId->chars(), symbolId->size()))
files.append(doc->fileName());
}
} else {
files += snapshot.dependsOn(sourceFile);
}
qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size(); qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size();
future.setProgressRange(0, files.size()); future.setProgressRange(0, files.size());
@@ -544,15 +569,20 @@ void CppFindReferences::findUsages(Symbol *symbol)
void CppFindReferences::renameUsages(Symbol *symbol) void CppFindReferences::renameUsages(Symbol *symbol)
{ {
Find::SearchResult *search = _resultWindow->startNewSearch(Find::SearchResultWindow::SearchAndReplace); if (Identifier *id = symbol->identifier()) {
const QString textToReplace = QString::fromUtf8(id->chars(), id->size());
connect(search, SIGNAL(activated(Find::SearchResultItem)), Find::SearchResult *search = _resultWindow->startNewSearch(Find::SearchResultWindow::SearchAndReplace);
this, SLOT(openEditor(Find::SearchResultItem))); _resultWindow->setTextToReplace(textToReplace);
connect(search, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)), connect(search, SIGNAL(activated(Find::SearchResultItem)),
SLOT(onReplaceButtonClicked(QString,QList<Find::SearchResultItem>))); this, SLOT(openEditor(Find::SearchResultItem)));
findAll_helper(symbol); connect(search, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)),
SLOT(onReplaceButtonClicked(QString,QList<Find::SearchResultItem>)));
findAll_helper(symbol);
}
} }
void CppFindReferences::findAll_helper(Symbol *symbol) void CppFindReferences::findAll_helper(Symbol *symbol)
@@ -574,6 +604,23 @@ void CppFindReferences::findAll_helper(Symbol *symbol)
connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup())); connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup()));
} }
static void applyChanges(QTextDocument *doc, const QString &text, const QList<Find::SearchResultItem> &items)
{
QList<QTextCursor> cursors;
foreach (const Find::SearchResultItem &item, items) {
const int blockNumber = item.lineNumber - 1;
QTextCursor tc(doc->findBlockByNumber(blockNumber));
tc.setPosition(tc.position() + item.searchTermStart);
tc.setPosition(tc.position() + item.searchTermLength,
QTextCursor::KeepAnchor);
cursors.append(tc);
}
foreach (QTextCursor tc, cursors)
tc.insertText(text);
}
void CppFindReferences::onReplaceButtonClicked(const QString &text, void CppFindReferences::onReplaceButtonClicked(const QString &text,
const QList<Find::SearchResultItem> &items) const QList<Find::SearchResultItem> &items)
{ {
@@ -585,47 +632,55 @@ void CppFindReferences::onReplaceButtonClicked(const QString &text,
foreach (const Find::SearchResultItem &item, items) foreach (const Find::SearchResultItem &item, items)
changes[item.fileName].append(item); changes[item.fileName].append(item);
Core::EditorManager *editorManager = Core::EditorManager::instance();
QHashIterator<QString, QList<Find::SearchResultItem> > it(changes); QHashIterator<QString, QList<Find::SearchResultItem> > it(changes);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
const QString fileName = it.key(); const QString fileName = it.key();
QFile file(fileName); const QList<Find::SearchResultItem> items = it.value();
if (file.open(QFile::ReadOnly)) { const QList<Core::IEditor *> editors = editorManager->editorsForFileName(fileName);
QTextStream stream(&file); TextEditor::BaseTextEditor *textEditor = 0;
// ### set the encoding foreach (Core::IEditor *editor, editors) {
const QString plainText = stream.readAll(); textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
file.close(); if (textEditor != 0)
break;
}
QTextDocument doc; if (textEditor != 0) {
doc.setPlainText(plainText); QTextCursor tc = textEditor->textCursor();
tc.beginEditBlock();
applyChanges(textEditor->document(), text, items);
tc.endEditBlock();
} else {
QFile file(fileName);
QList<QTextCursor> cursors; if (file.open(QFile::ReadOnly)) {
const QList<Find::SearchResultItem> items = it.value(); QTextStream stream(&file);
foreach (const Find::SearchResultItem &item, items) {
const int blockNumber = item.lineNumber - 1;
QTextCursor tc(doc.findBlockByNumber(blockNumber));
tc.setPosition(tc.position() + item.searchTermStart);
tc.setPosition(tc.position() + item.searchTermLength,
QTextCursor::KeepAnchor);
cursors.append(tc);
}
foreach (QTextCursor tc, cursors)
tc.insertText(text);
QFile newFile(fileName);
if (newFile.open(QFile::WriteOnly)) {
QTextStream stream(&newFile);
// ### set the encoding // ### set the encoding
stream << doc.toPlainText(); const QString plainText = stream.readAll();
file.close();
QTextDocument doc;
doc.setPlainText(plainText);
applyChanges(&doc, text, items);
QFile newFile(fileName);
if (newFile.open(QFile::WriteOnly)) {
QTextStream stream(&newFile);
// ### set the encoding
stream << doc.toPlainText();
}
} }
} }
} }
const QStringList fileNames = changes.keys(); const QStringList fileNames = changes.keys();
_modelManager->updateSourceFiles(fileNames); _modelManager->updateSourceFiles(fileNames);
_resultWindow->hide();
} }
void CppFindReferences::displayResult(int index) void CppFindReferences::displayResult(int index)

View File

@@ -302,6 +302,7 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *manager,
m_dumper(new CdbDumperHelper(manager, &m_cif)), m_dumper(new CdbDumperHelper(manager, &m_cif)),
m_currentThreadId(-1), m_currentThreadId(-1),
m_eventThreadId(-1), m_eventThreadId(-1),
m_interrupted(false),
m_watchTimer(-1), m_watchTimer(-1),
m_debugEventCallBack(engine), m_debugEventCallBack(engine),
m_engine(engine), m_engine(engine),
@@ -445,6 +446,7 @@ void CdbDebugEnginePrivate::clearForRun()
m_breakEventMode = BreakEventHandle; m_breakEventMode = BreakEventHandle;
m_eventThreadId = -1; m_eventThreadId = -1;
m_interrupted = false;
cleanStackTrace(); cleanStackTrace();
} }
@@ -1026,6 +1028,9 @@ bool CdbDebugEngine::step(unsigned long executionStatus)
warning(msgStepFailed(executionStatus, m_d->m_currentThreadId, msgDebuggerCommandFailed(command, hr))); warning(msgStepFailed(executionStatus, m_d->m_currentThreadId, msgDebuggerCommandFailed(command, hr)));
} }
if (success) { if (success) {
// Oddity: Step into will first break at the calling function. Ignore
if (executionStatus == DEBUG_STATUS_STEP_INTO || executionStatus == DEBUG_STATUS_REVERSE_STEP_INTO)
m_d->m_breakEventMode = CdbDebugEnginePrivate::BreakEventIgnoreOnce;
startWatchTimer(); startWatchTimer();
setState(InferiorRunning, Q_FUNC_INFO, __LINE__); setState(InferiorRunning, Q_FUNC_INFO, __LINE__);
} else { } else {
@@ -1169,7 +1174,9 @@ bool CdbDebugEnginePrivate::interruptInterferiorProcess(QString *errorMessage)
qDebug() << Q_FUNC_INFO << "\n ex=" << executionStatus; qDebug() << Q_FUNC_INFO << "\n ex=" << executionStatus;
} }
if (!DebugBreakProcess(m_hDebuggeeProcess)) { if (DebugBreakProcess(m_hDebuggeeProcess)) {
m_interrupted = true;
} else {
*errorMessage = QString::fromLatin1("DebugBreakProcess failed: %1").arg(Utils::winErrorMessage(GetLastError())); *errorMessage = QString::fromLatin1("DebugBreakProcess failed: %1").arg(Utils::winErrorMessage(GetLastError()));
return false; return false;
} }
@@ -1704,12 +1711,34 @@ ULONG CdbDebugEnginePrivate::updateThreadList()
QList<ThreadData> threads; QList<ThreadData> threads;
ULONG currentThreadId; ULONG currentThreadId;
QString errorMessage; QString errorMessage;
// When interrupting, an artifical thread with a breakpoint is created.
if (!CdbStackTraceContext::getThreads(m_cif, true, &threads, &currentThreadId, &errorMessage)) if (!CdbStackTraceContext::getThreads(m_cif, true, &threads, &currentThreadId, &errorMessage))
m_engine->warning(errorMessage); m_engine->warning(errorMessage);
manager()->threadsHandler()->setThreads(threads); manager()->threadsHandler()->setThreads(threads);
return currentThreadId; return currentThreadId;
} }
// Figure out the thread to run the dumpers in (see notes on.
// CdbDumperHelper). Avoid the artifical threads created by interrupt
// and threads that are in waitFor().
// A stricter version could only use the thread if it is the event
// thread of a step or breakpoint hit (see CdbDebugEnginePrivate::m_interrupted).
static inline unsigned long dumperThreadId(const QList<StackFrame> &frames,
unsigned long currentThread)
{
if (frames.empty())
return CdbDumperHelper::InvalidDumperCallThread;
if (frames.at(0).function == QLatin1String(CdbStackTraceContext::winFuncDebugBreakPoint))
return CdbDumperHelper::InvalidDumperCallThread;
const int waitCheckDepth = qMin(frames.size(), 5);
static const QString waitForPrefix = QLatin1String(CdbStackTraceContext::winFuncWaitForPrefix);
for (int f = 0; f < waitCheckDepth; f++)
if (frames.at(f).function.startsWith(waitForPrefix))
return CdbDumperHelper::InvalidDumperCallThread;
return currentThread;
}
void CdbDebugEnginePrivate::updateStackTrace() void CdbDebugEnginePrivate::updateStackTrace()
{ {
if (debugCDB) if (debugCDB)
@@ -1750,11 +1779,19 @@ void CdbDebugEnginePrivate::updateStackTrace()
CdbDebugEngine::tr("Thread %1: No debug information available (%2).").arg(m_currentThreadId).arg(topFunction); CdbDebugEngine::tr("Thread %1: No debug information available (%2).").arg(m_currentThreadId).arg(topFunction);
m_engine->warning(msg); m_engine->warning(msg);
} }
// Set up dumper with a thread (or invalid)
const unsigned long dumperThread = dumperThreadId(stackFrames, m_currentThreadId);
if (debugCDB)
qDebug() << "updateStackTrace() current: " << m_currentThreadId << " dumper=" << dumperThread;
m_dumper->setDumperCallThread(dumperThread);
// Display frames
manager()->stackHandler()->setFrames(stackFrames); manager()->stackHandler()->setFrames(stackFrames);
m_firstActivatedFrame = true; m_firstActivatedFrame = true;
if (current >= 0) { if (current >= 0) {
manager()->stackHandler()->setCurrentIndex(current); manager()->stackHandler()->setCurrentIndex(current);
// First time : repaint
if (m_dumper->isEnabled() && m_dumper->state() != CdbDumperHelper::Initialized)
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
m_engine->activateFrame(current); m_engine->activateFrame(current);
} }
manager()->watchHandler()->updateWatchers(); manager()->watchHandler()->updateWatchers();

View File

@@ -156,6 +156,7 @@ struct CdbDebugEnginePrivate
const QSharedPointer<CdbOptions> m_options; const QSharedPointer<CdbOptions> m_options;
HANDLE m_hDebuggeeProcess; HANDLE m_hDebuggeeProcess;
HANDLE m_hDebuggeeThread; HANDLE m_hDebuggeeThread;
bool m_interrupted;
int m_currentThreadId; int m_currentThreadId;
int m_eventThreadId; int m_eventThreadId;
HandleBreakEventMode m_breakEventMode; HandleBreakEventMode m_breakEventMode;

View File

@@ -248,6 +248,7 @@ STDMETHODIMP CdbDebugEventCallback::Exception(
if (debugCDB) if (debugCDB)
qDebug() << Q_FUNC_INFO << "\nex=" << Exception->ExceptionCode << " fatal=" << fatal << msg; qDebug() << Q_FUNC_INFO << "\nex=" << Exception->ExceptionCode << " fatal=" << fatal << msg;
m_pEngine->manager()->showApplicationOutput(msg); m_pEngine->manager()->showApplicationOutput(msg);
m_pEngine->manager()->showDebuggerOutput(LogMisc, msg);
if (fatal) if (fatal)
m_pEngine->m_d->notifyCrashed(); m_pEngine->m_d->notifyCrashed();
return S_OK; return S_OK;

View File

@@ -41,8 +41,10 @@
#include <QtCore/QRegExp> #include <QtCore/QRegExp>
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QTextStream> #include <QtCore/QTextStream>
#include <QtCore/QTime>
enum { loadDebug = 0 }; enum { loadDebug = 0 };
enum { dumpDebug = 0 };
static const char *dumperModuleNameC = "gdbmacros"; static const char *dumperModuleNameC = "gdbmacros";
static const char *qtCoreModuleNameC = "QtCore"; static const char *qtCoreModuleNameC = "QtCore";
@@ -158,24 +160,25 @@ static bool debuggeeLoadLibrary(DebuggerManager *manager,
// We want to call "HMODULE LoadLibraryA(LPCTSTR lpFileName)" // We want to call "HMODULE LoadLibraryA(LPCTSTR lpFileName)"
// (void* LoadLibraryA(char*)). However, despite providing a symbol // (void* LoadLibraryA(char*)). However, despite providing a symbol
// server, the debugger refuses to recognize it as a function. // server, the debugger refuses to recognize it as a function.
// Set up the call stack with a function of same signature (qstrdup) // Call with a prototype of 'qstrdup', as it is the same
// and change the call register to LoadLibraryA() before executing "g".
// Prepare call: Locate 'qstrdup' in the (potentially namespaced) corelib. For some // Prepare call: Locate 'qstrdup' in the (potentially namespaced) corelib. For some
// reason, the symbol is present in QtGui as well without type information. // reason, the symbol is present in QtGui as well without type information.
QString dummyFunc = QLatin1String("*qstrdup"); QString dummyFunc = QLatin1String("*qstrdup");
if (resolveSymbol(cif->debugSymbols, QLatin1String("QtCore[d]*4!"), &dummyFunc, errorMessage) != ResolveSymbolOk) if (resolveSymbol(cif->debugSymbols, QLatin1String("QtCore[d]*4!"), &dummyFunc, errorMessage) != ResolveSymbolOk)
return false; return false;
QString callCmd = QLatin1String(".call ");
callCmd += dummyFunc; QString callCmd; {
callCmd += QLatin1String("(0x"); QTextStream str(&callCmd);
callCmd += QString::number(nameAddress, 16); str.setIntegerBase(16);
callCmd += QLatin1Char(')'); str << ".call /s " << dummyFunc << " Kernel32!LoadLibraryA(0x" << nameAddress << ')';
}
if (loadDebug)
qDebug() << "Calling" << callCmd;
if (!CdbDebugEnginePrivate::executeDebuggerCommand(cif->debugControl, callCmd, errorMessage)) if (!CdbDebugEnginePrivate::executeDebuggerCommand(cif->debugControl, callCmd, errorMessage))
return false; return false;
if (!CdbDebugEnginePrivate::executeDebuggerCommand(cif->debugControl, QLatin1String("r eip=Kernel32!LoadLibraryA"), errorMessage)) // Execute current thread. This will hit a breakpoint.
return false; if (!CdbDebugEnginePrivate::executeDebuggerCommand(cif->debugControl, QLatin1String("~. g"), errorMessage))
// This will hit a breakpoint.
if (!CdbDebugEnginePrivate::executeDebuggerCommand(cif->debugControl, QString(QLatin1Char('g')), errorMessage))
return false; return false;
const HRESULT hr = cif->debugControl->WaitForEvent(0, waitTimeOutMS); const HRESULT hr = cif->debugControl->WaitForEvent(0, waitTimeOutMS);
if (FAILED(hr)) { if (FAILED(hr)) {
@@ -185,6 +188,14 @@ static bool debuggeeLoadLibrary(DebuggerManager *manager,
return true; return true;
} }
// Format a "go" in a thread
static inline QString goCommand(unsigned long threadId)
{
QString rc;
QTextStream(&rc) << '~' << threadId << " g";
return rc;
}
// ---- Load messages // ---- Load messages
static inline QString msgMethod(bool injectOrCall) static inline QString msgMethod(bool injectOrCall)
{ {
@@ -226,7 +237,9 @@ CdbDumperHelper::CdbDumperHelper(DebuggerManager *manager,
m_inBufferSize(0), m_inBufferSize(0),
m_outBufferAddress(0), m_outBufferAddress(0),
m_outBufferSize(0), m_outBufferSize(0),
m_buffer(0) m_buffer(0),
m_dumperCallThread(0),
m_goCommand(goCommand(m_dumperCallThread))
{ {
} }
@@ -324,7 +337,7 @@ CdbDumperHelper::CallLoadResult CdbDumperHelper::initCallLoad(QString *errorMess
bool CdbDumperHelper::ensureInitialized(QString *errorMessage) bool CdbDumperHelper::ensureInitialized(QString *errorMessage)
{ {
if (loadDebug) if (loadDebug)
qDebug() << Q_FUNC_INFO << '\n' << m_state; qDebug() << "ensureInitialized thread: " << m_dumperCallThread << " state: " << m_state;
switch (m_state) { switch (m_state) {
case Disabled: case Disabled:
@@ -372,6 +385,9 @@ bool CdbDumperHelper::ensureInitialized(QString *errorMessage)
m_manager->showDebuggerOutput(LogMisc, *errorMessage); m_manager->showDebuggerOutput(LogMisc, *errorMessage);
m_manager->showQtDumperLibraryWarning(*errorMessage); m_manager->showQtDumperLibraryWarning(*errorMessage);
} }
if (loadDebug)
qDebug() << Q_FUNC_INFO << '\n' << ok;
return ok; return ok;
} }
@@ -451,7 +467,7 @@ bool CdbDumperHelper::initKnownTypes(QString *errorMessage)
*errorMessage = QtDumperHelper::msgDumperOutdated(dumperVersionRequired, m_helper.dumperVersion()); *errorMessage = QtDumperHelper::msgDumperOutdated(dumperVersionRequired, m_helper.dumperVersion());
return false; return false;
} }
if (loadDebug) if (loadDebug || dumpDebug)
qDebug() << Q_FUNC_INFO << m_helper.toString(true); qDebug() << Q_FUNC_INFO << m_helper.toString(true);
return true; return true;
} }
@@ -492,8 +508,11 @@ bool CdbDumperHelper::callDumper(const QString &callCmd, const QByteArray &inBuf
// by using 'gN' (go not handled -> pass handling to dumper __try/__catch block) // by using 'gN' (go not handled -> pass handling to dumper __try/__catch block)
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
const int oldExceptionCount = exLogger.exceptionCount(); const int oldExceptionCount = exLogger.exceptionCount();
// Go. If an exception occurs in loop 2, let the dumper handle it. // Go in current thread. If an exception occurs in loop 2,
const QString goCmd = i ? QString(QLatin1String("gN")) : QString(QLatin1Char('g')); // let the dumper handle it.
QString goCmd = m_goCommand;
if (i)
goCmd = QLatin1Char('N');
if (!CdbDebugEnginePrivate::executeDebuggerCommand(m_cif->debugControl, goCmd, errorMessage)) if (!CdbDebugEnginePrivate::executeDebuggerCommand(m_cif->debugControl, goCmd, errorMessage))
return false; return false;
HRESULT hr = m_cif->debugControl->WaitForEvent(0, waitTimeOutMS); HRESULT hr = m_cif->debugControl->WaitForEvent(0, waitTimeOutMS);
@@ -556,6 +575,18 @@ static inline QString msgNotHandled(const QString &type)
CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool dumpChildren, CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool dumpChildren,
QList<WatchData> *result, QString *errorMessage) QList<WatchData> *result, QString *errorMessage)
{ {
if (dumpDebug)
qDebug() << ">dumpType() thread: " << m_dumperCallThread << " state: " << m_state << wd.type << QTime::currentTime().toString();
const CdbDumperHelper::DumpResult rc = dumpTypeI(wd, dumpChildren, result, errorMessage);
if (dumpDebug)
qDebug() << "<dumpType() state: " << m_state << wd.type << " returns " << rc << *errorMessage << QTime::currentTime().toString();
return rc;
}
CdbDumperHelper::DumpResult CdbDumperHelper::dumpTypeI(const WatchData &wd, bool dumpChildren,
QList<WatchData> *result, QString *errorMessage)
{
errorMessage->clear();
// Check failure cache and supported types // Check failure cache and supported types
if (m_state == Disabled) { if (m_state == Disabled) {
*errorMessage = QLatin1String("Dumpers are disabled"); *errorMessage = QLatin1String("Dumpers are disabled");
@@ -570,6 +601,20 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool
return DumpNotHandled; return DumpNotHandled;
} }
// Do we have a thread
if (m_dumperCallThread == InvalidDumperCallThread) {
*errorMessage = QString::fromLatin1("No thread to call.");
if (loadDebug)
qDebug() << *errorMessage;
return DumpNotHandled;
}
// Delay initialization as much as possible
if (isIntOrFloatType(wd.type)) {
*errorMessage = QString::fromLatin1("Unhandled POD: " ) + wd.type;
return DumpNotHandled;
}
// Ensure types are parsed and known. // Ensure types are parsed and known.
if (!ensureInitialized(errorMessage)) { if (!ensureInitialized(errorMessage)) {
*errorMessage = msgDumpFailed(wd, errorMessage); *errorMessage = msgDumpFailed(wd, errorMessage);
@@ -722,5 +767,18 @@ bool CdbDumperHelper::runTypeSizeQuery(const QString &typeName, int *size, QStri
return true; return true;
} }
unsigned long CdbDumperHelper::dumperCallThread()
{
return m_dumperCallThread;
}
void CdbDumperHelper::setDumperCallThread(unsigned long t)
{
if (m_dumperCallThread != t) {
m_dumperCallThread = t;
m_goCommand = goCommand(m_dumperCallThread);
}
}
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger

View File

@@ -55,7 +55,17 @@ struct CdbComInterfaces;
* dumpType() is the main query function to obtain a list of WatchData from * dumpType() is the main query function to obtain a list of WatchData from
* WatchData item produced by the smbol context. * WatchData item produced by the smbol context.
* Call disable(), should the debuggee crash (as performing debuggee * Call disable(), should the debuggee crash (as performing debuggee
* calls is no longer possible, then).*/ * calls is no longer possible, then).
*
* dumperCallThread specifies the thread to use when making the calls.
* As of Debugging Tools v 6.11.1.404 (6.10.2009), calls cannot be executed
* when the current thread is in some WaitFor...() function. The call will
* then hang (regardless whether that thread or some other, non-blocking thread
* is used), and the debuggee will be in running state afterwards (causing errors
* from ReadVirtual, etc).
* The current thread can be used when stepping or a breakpoint was
* hit. When interrupting the inferior, an artifical thread is created,
* that is not usable, either. */
class CdbDumperHelper class CdbDumperHelper
{ {
@@ -93,6 +103,10 @@ public:
inline CdbComInterfaces *comInterfaces() const { return m_cif; } inline CdbComInterfaces *comInterfaces() const { return m_cif; }
enum { InvalidDumperCallThread = 0xFFFFFFFF };
unsigned long dumperCallThread();
void setDumperCallThread(unsigned long t);
private: private:
enum CallLoadResult { CallLoadOk, CallLoadError, CallLoadNoQtApp, CallLoadAlreadyLoaded }; enum CallLoadResult { CallLoadOk, CallLoadError, CallLoadNoQtApp, CallLoadAlreadyLoaded };
@@ -103,6 +117,9 @@ private:
bool initResolveSymbols(QString *errorMessage); bool initResolveSymbols(QString *errorMessage);
bool initKnownTypes(QString *errorMessage); bool initKnownTypes(QString *errorMessage);
inline DumpResult dumpTypeI(const WatchData &d, bool dumpChildren,
QList<WatchData> *result, QString *errorMessage);
bool getTypeSize(const QString &typeName, int *size, QString *errorMessage); bool getTypeSize(const QString &typeName, int *size, QString *errorMessage);
bool runTypeSizeQuery(const QString &typeName, int *size, QString *errorMessage); bool runTypeSizeQuery(const QString &typeName, int *size, QString *errorMessage);
bool callDumper(const QString &call, const QByteArray &inBuffer, const char **outputPtr, bool callDumper(const QString &call, const QByteArray &inBuffer, const char **outputPtr,
@@ -134,6 +151,8 @@ private:
QStringList m_failedTypes; QStringList m_failedTypes;
QtDumperHelper m_helper; QtDumperHelper m_helper;
unsigned long m_dumperCallThread;
QString m_goCommand;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -41,7 +41,11 @@ enum { debugExc = 0 };
// Special exception codes. // Special exception codes.
enum { cppExceptionCode = 0xe06d7363, startupCompleteTrap = 0x406d1388, enum { cppExceptionCode = 0xe06d7363, startupCompleteTrap = 0x406d1388,
rpcServerUnavailableExceptionCode = 0x6ba, rpcServerUnavailableExceptionCode = 0x6ba,
dllNotFoundExceptionCode = 0xc0000135 }; dllNotFoundExceptionCode = 0xc0000135,
dllInitFailed = 0xc0000142,
missingSystemFile = 0xc0000143,
appInitFailed = 0xc0000143
};
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -172,6 +176,12 @@ void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str)
case dllNotFoundExceptionCode: case dllNotFoundExceptionCode:
str << "DLL not found"; str << "DLL not found";
break; break;
case dllInitFailed:
str << "DLL failed to initialize";
break;
case missingSystemFile:
str << "System file is missing";
break;
case EXCEPTION_ACCESS_VIOLATION: { case EXCEPTION_ACCESS_VIOLATION: {
const bool writeOperation = e->ExceptionInformation[0]; const bool writeOperation = e->ExceptionInformation[0];
str << (writeOperation ? "write" : "read") str << (writeOperation ? "write" : "read")

View File

@@ -40,6 +40,10 @@
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
const char *CdbStackTraceContext::winFuncFastSystemCallRet = "ntdll!KiFastSystemCallRet";
const char *CdbStackTraceContext::winFuncDebugBreakPoint = "ntdll!DbgBreakPoint";
const char *CdbStackTraceContext::winFuncWaitForPrefix = "kernel32!WaitFor";
CdbStackTraceContext::CdbStackTraceContext(const QSharedPointer<CdbDumperHelper> &dumper) : CdbStackTraceContext::CdbStackTraceContext(const QSharedPointer<CdbDumperHelper> &dumper) :
m_dumper(dumper), m_dumper(dumper),
m_cif(dumper->comInterfaces()), m_cif(dumper->comInterfaces()),
@@ -232,6 +236,7 @@ static inline bool getStoppedThreadState(const CdbComInterfaces &cif,
ThreadData *t, ThreadData *t,
QString *errorMessage) QString *errorMessage)
{ {
enum { MaxFrames = 2 };
ULONG currentThread; ULONG currentThread;
HRESULT hr = cif.debugSystemObjects->GetCurrentThreadId(&currentThread); HRESULT hr = cif.debugSystemObjects->GetCurrentThreadId(&currentThread);
if (FAILED(hr)) { if (FAILED(hr)) {
@@ -246,29 +251,38 @@ static inline bool getStoppedThreadState(const CdbComInterfaces &cif,
} }
} }
ULONG frameCount; ULONG frameCount;
DEBUG_STACK_FRAME topFrame[1]; // Ignore the top frame if it is "ntdll!KiFastSystemCallRet", which is
hr = cif.debugControl->GetStackTrace(0, 0, 0, topFrame, 1, &frameCount); // not interesting for display.
DEBUG_STACK_FRAME frames[MaxFrames];
hr = cif.debugControl->GetStackTrace(0, 0, 0, frames, MaxFrames, &frameCount);
if (FAILED(hr)) { if (FAILED(hr)) {
*errorMessage = msgGetThreadStateFailed(t->id, msgComFailed("GetStackTrace", hr)); *errorMessage = msgGetThreadStateFailed(t->id, msgComFailed("GetStackTrace", hr));
return false; return false;
} }
// Ignore the top frame if it is "ntdll!KiFastSystemCallRet", which is
t->address = topFrame[0].InstructionOffset; // not interesting for display.
WCHAR wszBuf[MAX_PATH]; WCHAR wszBuf[MAX_PATH];
for (int frame = 0; frame < MaxFrames; frame++) {
cif.debugSymbols->GetNameByOffsetWide(topFrame[0].InstructionOffset, wszBuf, MAX_PATH, 0, 0); cif.debugSymbols->GetNameByOffsetWide(frames[frame].InstructionOffset, wszBuf, MAX_PATH, 0, 0);
t->function = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf)); t->function = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf));
ULONG ulLine; if (frame != 0 || t->function != QLatin1String(CdbStackTraceContext::winFuncFastSystemCallRet)) {
hr = cif.debugSymbols->GetLineByOffsetWide(topFrame[0].InstructionOffset, &ulLine, wszBuf, MAX_PATH, 0, 0); t->address = frames[frame].InstructionOffset;
if (SUCCEEDED(hr)) { cif.debugSymbols->GetNameByOffsetWide(frames[frame].InstructionOffset, wszBuf, MAX_PATH, 0, 0);
t->line = ulLine; t->function = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf));
// Just display base name ULONG ulLine;
t->file = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf)); hr = cif.debugSymbols->GetLineByOffsetWide(frames[frame].InstructionOffset, &ulLine, wszBuf, MAX_PATH, 0, 0);
if (!t->file.isEmpty()) { if (SUCCEEDED(hr)) {
const int slashPos = t->file.lastIndexOf(QLatin1Char('\\')); t->line = ulLine;
if (slashPos != -1) // Just display base name
t->file.remove(0, slashPos + 1); t->file = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf));
} if (!t->file.isEmpty()) {
const int slashPos = t->file.lastIndexOf(QLatin1Char('\\'));
if (slashPos != -1)
t->file.remove(0, slashPos + 1);
}
}
break;
} // was not "ntdll!KiFastSystemCallRet"
} }
return true; return true;
} }

View File

@@ -63,6 +63,13 @@ class CdbStackTraceContext
public: public:
enum { maxFrames = 100 }; enum { maxFrames = 100 };
// Some well known-functions
static const char *winFuncFastSystemCallRet;
// WaitFor...
static const char *winFuncWaitForPrefix;
// Dummy function used for interrupting a debuggee
static const char *winFuncDebugBreakPoint;
~CdbStackTraceContext(); ~CdbStackTraceContext();
static CdbStackTraceContext *create(const QSharedPointer<CdbDumperHelper> &dumper, static CdbStackTraceContext *create(const QSharedPointer<CdbDumperHelper> &dumper,
unsigned long threadid, unsigned long threadid,

View File

@@ -1,5 +1,10 @@
include(../../../shared/trk/trk.pri) include(../../../shared/trk/trk.pri)
!isEmpty(SUPPORT_QT_S60) {
message("Adding experimental support for Qt/S60 applications.")
DEFINES += QTCREATOR_WITH_S60
}
HEADERS += \ HEADERS += \
$$PWD/gdbmi.h \ $$PWD/gdbmi.h \
$$PWD/gdbengine.h \ $$PWD/gdbengine.h \

View File

@@ -4227,8 +4227,9 @@ void GdbEngine::handleAdapterShutdownFailed(const QString &msg)
void GdbEngine::addOptionPages(QList<Core::IOptionsPage*> *opts) const void GdbEngine::addOptionPages(QList<Core::IOptionsPage*> *opts) const
{ {
opts->push_back(new GdbOptionsPage); opts->push_back(new GdbOptionsPage);
if (!qgetenv("QTCREATOR_WITH_S60").isEmpty()) #ifdef QTCREATOR_WITH_S60
opts->push_back(new TrkOptionsPage(m_trkAdapter->options())); opts->push_back(new TrkOptionsPage(m_trkAdapter->options()));
#endif
} }
void GdbEngine::showMessageBox(int icon, const QString &title, const QString &text) void GdbEngine::showMessageBox(int icon, const QString &title, const QString &text)

View File

@@ -104,6 +104,17 @@ SearchResultWindow::~SearchResultWindow()
m_items.clear(); m_items.clear();
} }
void SearchResultWindow::setTextToReplace(const QString &textToReplace)
{
m_replaceTextEdit->setText(textToReplace);
m_replaceTextEdit->selectAll();
}
QString SearchResultWindow::textToReplace() const
{
return m_replaceTextEdit->text();
}
void SearchResultWindow::setShowReplaceUI(bool show) void SearchResultWindow::setShowReplaceUI(bool show)
{ {
m_searchResultTreeView->model()->setShowReplaceUI(show); m_searchResultTreeView->model()->setShowReplaceUI(show);
@@ -169,6 +180,7 @@ SearchResult *SearchResultWindow::startNewSearch(SearchMode searchOrSearchAndRep
void SearchResultWindow::clearContents() void SearchResultWindow::clearContents()
{ {
setReplaceUIEnabled(false); setReplaceUIEnabled(false);
m_replaceTextEdit->clear();
m_searchResultTreeView->clear(); m_searchResultTreeView->clear();
m_items.clear(); m_items.clear();
m_widget->setCurrentWidget(m_searchResultTreeView); m_widget->setCurrentWidget(m_searchResultTreeView);

View File

@@ -106,6 +106,9 @@ public:
void setShowReplaceUI(bool show); void setShowReplaceUI(bool show);
bool isShowingReplaceUI() const; bool isShowingReplaceUI() const;
void setTextToReplace(const QString &textToReplace);
QString textToReplace() const;
// search result object only lives till next startnewsearch call // search result object only lives till next startnewsearch call
SearchResult *startNewSearch(SearchMode searchOrSearchAndReplace = SearchOnly); SearchResult *startNewSearch(SearchMode searchOrSearchAndReplace = SearchOnly);

View File

@@ -341,9 +341,9 @@ void BuildManager::buildProjects(const QList<Project *> &projects, const QList<Q
} }
} }
} }
startBuildQueue();
if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput) if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput)
m_outputWindow->popup(false); m_outputWindow->popup(false);
startBuildQueue();
} }
void BuildManager::cleanProjects(const QList<Project *> &projects, const QList<QString> &configurations) void BuildManager::cleanProjects(const QList<Project *> &projects, const QList<QString> &configurations)
@@ -359,9 +359,9 @@ void BuildManager::cleanProjects(const QList<Project *> &projects, const QList<Q
buildQueueAppend(bs, *cit); buildQueueAppend(bs, *cit);
} }
} }
startBuildQueue();
if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput) if (ProjectExplorerPlugin::instance()->projectExplorerSettings().showCompilerOutput)
m_outputWindow->popup(false); m_outputWindow->popup(false);
startBuildQueue();
} }
void BuildManager::buildProject(Project *p, const QString &configuration) void BuildManager::buildProject(Project *p, const QString &configuration)

View File

@@ -335,7 +335,8 @@ QByteArray MSVCToolChain::predefinedMacros()
m_predefinedMacros += "#define __MSVCRT__\n" m_predefinedMacros += "#define __MSVCRT__\n"
"#define __WINNT__\n" "#define __WINNT__\n"
"#define __WINNT\n" "#define __WINNT\n"
"#define WINNT\n"; "#define WINNT\n"
"#define __int64 long long";
QString tmpFilePath; QString tmpFilePath;
{ {

View File

@@ -146,7 +146,6 @@ void ProjectLoadWizard::done(int result)
// This normally happens on showing the final page, but since we // This normally happens on showing the final page, but since we
// don't show it anymore, do it here // don't show it anymore, do it here
QString directory = QFileInfo(m_project->file()->fileName()).absolutePath();
if (m_importVersion && importCheckbox->isChecked()) { if (m_importVersion && importCheckbox->isChecked()) {
// Importing // Importing
if (m_temporaryVersion) if (m_temporaryVersion)

View File

@@ -1,5 +1,3 @@
win32:SUPPORT_QT_S60=1
else:SUPPORT_QT_S60 = $$(QTCREATOR_WITH_S60)
!isEmpty(SUPPORT_QT_S60) { !isEmpty(SUPPORT_QT_S60) {
message("Adding experimental support for Qt/S60 applications.") message("Adding experimental support for Qt/S60 applications.")
DEFINES += QTCREATOR_WITH_S60 DEFINES += QTCREATOR_WITH_S60

View File

@@ -209,9 +209,18 @@ static QString localExecutableFromPkgFile(const QString &pkgFileName, QString *e
// "<SDK>/foo.exe" - "!:\device_bin\foo.exe" // "<SDK>/foo.exe" - "!:\device_bin\foo.exe"
const QRegExp exePattern = QRegExp(QLatin1String("^\"([^\"]+\\.exe)\" +-.*$")); const QRegExp exePattern = QRegExp(QLatin1String("^\"([^\"]+\\.exe)\" +-.*$"));
Q_ASSERT(exePattern.isValid()); Q_ASSERT(exePattern.isValid());
foreach(const QString &line, QString::fromLocal8Bit(pkgFile.readAll()).split(QLatin1Char('\n')))
if (exePattern.exactMatch(line)) foreach(const QString &line, QString::fromLocal8Bit(pkgFile.readAll()).split(QLatin1Char('\n'))) {
return exePattern.cap(1); if (exePattern.exactMatch(line)) {
QString rc = exePattern.cap(1);
#ifdef Q_OS_WIN
// Sometimes, the drive letter is missing. Use that of the pkg file
if (rc.at(0) == QLatin1Char('/'))
rc.insert(0, pkgFileName.left(2));
#endif
return rc;
}
}
*errorMessage = S60DeviceRunConfiguration::tr("Unable to find the executable in the package file %1.").arg(pkgFileName); *errorMessage = S60DeviceRunConfiguration::tr("Unable to find the executable in the package file %1.").arg(pkgFileName);
return QString(); return QString();
} }
@@ -629,6 +638,7 @@ void S60DeviceRunControlBase::signsisProcessFinished()
connect(m_launcher, SIGNAL(copyingStarted()), this, SLOT(printCopyingNotice())); connect(m_launcher, SIGNAL(copyingStarted()), this, SLOT(printCopyingNotice()));
connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(printCreateFileFailed(QString,QString))); connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(printCreateFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(canNotWriteFile(QString,QString)), this, SLOT(printWriteFileFailed(QString,QString))); connect(m_launcher, SIGNAL(canNotWriteFile(QString,QString)), this, SLOT(printWriteFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(canNotCloseFile(QString,QString)), this, SLOT(printCloseFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(installingStarted()), this, SLOT(printInstallingNotice())); connect(m_launcher, SIGNAL(installingStarted()), this, SLOT(printInstallingNotice()));
connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(printInstallFailed(QString,QString))); connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(printInstallFailed(QString,QString)));
connect(m_launcher, SIGNAL(copyProgress(int)), this, SLOT(printCopyProgress(int))); connect(m_launcher, SIGNAL(copyProgress(int)), this, SLOT(printCopyProgress(int)));
@@ -662,6 +672,12 @@ void S60DeviceRunControlBase::printWriteFileFailed(const QString &filename, cons
emit addToOutputWindow(this, tr("Could not write to file %1 on device: %2").arg(filename, errorMessage)); emit addToOutputWindow(this, tr("Could not write to file %1 on device: %2").arg(filename, errorMessage));
} }
void S60DeviceRunControlBase::printCloseFileFailed(const QString &filename, const QString &errorMessage)
{
const QString msg = tr("Could not close file %1 on device: %2. It will be closed when App TRK is closed.");
emit addToOutputWindow(this, msg.arg(filename, errorMessage));
}
void S60DeviceRunControlBase::printCopyingNotice() void S60DeviceRunControlBase::printCopyingNotice()
{ {
emit addToOutputWindow(this, tr("Copying install file...")); emit addToOutputWindow(this, tr("Copying install file..."));

View File

@@ -173,6 +173,7 @@ private slots:
void printCopyingNotice(); void printCopyingNotice();
void printCreateFileFailed(const QString &filename, const QString &errorMessage); void printCreateFileFailed(const QString &filename, const QString &errorMessage);
void printWriteFileFailed(const QString &filename, const QString &errorMessage); void printWriteFileFailed(const QString &filename, const QString &errorMessage);
void printCloseFileFailed(const QString &filename, const QString &errorMessage);
void printCopyProgress(int progress); void printCopyProgress(int progress);
void printInstallingNotice(); void printInstallingNotice();
void printInstallFailed(const QString &filename, const QString &errorMessage); void printInstallFailed(const QString &filename, const QString &errorMessage);

View File

@@ -42,33 +42,15 @@ namespace {
const char * const USBSER = "Services/usbser/Enum"; const char * const USBSER = "Services/usbser/Enum";
} }
//#ifdef Q_OS_WIN
//GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72,
// 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
//#endif
SerialDeviceLister::SerialDeviceLister(QObject *parent) SerialDeviceLister::SerialDeviceLister(QObject *parent)
: QObject(parent), : QObject(parent),
m_initialized(false) m_initialized(false)
// , m_devNotifyHandle(0)
{ {
//#ifdef Q_OS_WIN
// // register for events
// DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
// ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
// NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
// NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// NotificationFilter.dbcc_classguid = WceusbshGUID;
// m_devNotifyHandle = RegisterDeviceNotification(QApplication::topLevelWidgets().at(0)->winId(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
//#endif
} }
SerialDeviceLister::~SerialDeviceLister() SerialDeviceLister::~SerialDeviceLister()
{ {
//#ifdef Q_OS_WIN
// if (m_devNotifyHandle)
// UnregisterDeviceNotification(m_devNotifyHandle);
//#endif
} }
QList<SerialDeviceLister::SerialDevice> SerialDeviceLister::serialDevices() const QList<SerialDeviceLister::SerialDevice> SerialDeviceLister::serialDevices() const

View File

@@ -69,11 +69,6 @@ private:
mutable bool m_initialized; mutable bool m_initialized;
mutable QList<SerialDevice> m_devices; mutable QList<SerialDevice> m_devices;
//#ifdef Q_OS_WIN
//private:
// HDEVNOTIFY m_devNotifyHandle;
//#endif
}; };
} // Internal } // Internal

View File

@@ -358,6 +358,7 @@ bool Qt4Project::restoreSettingsImpl(PersistentSettingsReader &settingsReader)
// Ensure that the qt version and tool chain in each build configuration is valid // Ensure that the qt version and tool chain in each build configuration is valid
// or if not, is reset to the default // or if not, is reset to the default
foreach (BuildConfiguration *bc, buildConfigurations()) { foreach (BuildConfiguration *bc, buildConfigurations()) {
qtVersionId(bc); qtVersionId(bc);
toolChainType(bc); toolChainType(bc);

View File

@@ -145,7 +145,7 @@ QString Qt4ProjectConfigWidget::displayName() const
void Qt4ProjectConfigWidget::init(const QString &buildConfiguration) void Qt4ProjectConfigWidget::init(const QString &buildConfiguration)
{ {
if (debug) if (debug)
qDebug() << "Qt4ProjectConfigWidget::init()"; qDebug() << "Qt4ProjectConfigWidget::init() for"<<buildConfiguration;
m_buildConfiguration = buildConfiguration; m_buildConfiguration = buildConfiguration;
ProjectExplorer::BuildConfiguration *bc = m_pro->buildConfiguration(buildConfiguration); ProjectExplorer::BuildConfiguration *bc = m_pro->buildConfiguration(buildConfiguration);
@@ -183,6 +183,7 @@ void Qt4ProjectConfigWidget::setupQtVersionsComboBox()
m_ui->qtVersionComboBox->addItem(tr("Default Qt Version (%1)").arg(vm->defaultVersion()->name()), 0); m_ui->qtVersionComboBox->addItem(tr("Default Qt Version (%1)").arg(vm->defaultVersion()->name()), 0);
int qtVersionId = m_pro->qtVersionId(m_pro->buildConfiguration(m_buildConfiguration)); int qtVersionId = m_pro->qtVersionId(m_pro->buildConfiguration(m_buildConfiguration));
if (qtVersionId == 0) { if (qtVersionId == 0) {
m_ui->qtVersionComboBox->setCurrentIndex(0); m_ui->qtVersionComboBox->setCurrentIndex(0);
m_ui->invalidQtWarningLabel->setVisible(false); m_ui->invalidQtWarningLabel->setVisible(false);

View File

@@ -159,6 +159,7 @@ QtVersionManager *QtVersionManager::instance()
void QtVersionManager::addVersion(QtVersion *version) void QtVersionManager::addVersion(QtVersion *version)
{ {
m_versions.append(version); m_versions.append(version);
m_uniqueIdToIndex.insert(version->uniqueId(), m_versions.count() - 1);
emit qtVersionsChanged(); emit qtVersionsChanged();
writeVersionsIntoSettings(); writeVersionsIntoSettings();
} }
@@ -528,7 +529,7 @@ void QtVersion::setName(const QString &name)
void QtVersion::setQMakeCommand(const QString& qmakeCommand) void QtVersion::setQMakeCommand(const QString& qmakeCommand)
{ {
m_qmakeCommand = qmakeCommand; m_qmakeCommand = QDir::fromNativeSeparators(qmakeCommand);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
m_qmakeCommand = m_qmakeCommand.toLower(); m_qmakeCommand = m_qmakeCommand.toLower();
#endif #endif
@@ -823,6 +824,7 @@ void QtVersion::updateVersionInfo() const
{ {
if (m_versionInfoUpToDate) if (m_versionInfoUpToDate)
return; return;
// extract data from qmake executable // extract data from qmake executable
m_versionInfo.clear(); m_versionInfo.clear();
m_notInstalled = false; m_notInstalled = false;
@@ -937,7 +939,7 @@ void QtVersion::updateMkSpec() const
mkspecPath = versionInfo().value("QT_INSTALL_DATA") + "/mkspecs/default"; mkspecPath = versionInfo().value("QT_INSTALL_DATA") + "/mkspecs/default";
else else
mkspecPath = mkspecPath + "/default"; mkspecPath = mkspecPath + "/default";
// qDebug() << "default mkspec is located at" << mkspecPath; // qDebug() << "default mkspec is located at" << mkspecPath;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QFile f2(mkspecPath + "/qmake.conf"); QFile f2(mkspecPath + "/qmake.conf");
if (f2.exists() && f2.open(QIODevice::ReadOnly)) { if (f2.exists() && f2.open(QIODevice::ReadOnly)) {

View File

@@ -332,6 +332,13 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
return false; return false;
} }
bool CheckDeclaration::visit(MemInitializerAST *ast)
{
(void) semantic()->check(ast->name, _scope);
FullySpecifiedType ty = semantic()->check(ast->expression, _scope);
return false;
}
bool CheckDeclaration::visit(LinkageBodyAST *ast) bool CheckDeclaration::visit(LinkageBodyAST *ast)
{ {
for (DeclarationListAST *decl = ast->declarations; decl; decl = decl->next) { for (DeclarationListAST *decl = ast->declarations; decl; decl = decl->next) {

View File

@@ -90,6 +90,7 @@ protected:
virtual bool visit(TemplateTypeParameterAST *ast); virtual bool visit(TemplateTypeParameterAST *ast);
virtual bool visit(UsingAST *ast); virtual bool visit(UsingAST *ast);
virtual bool visit(UsingDirectiveAST *ast); virtual bool visit(UsingDirectiveAST *ast);
virtual bool visit(MemInitializerAST *ast);
virtual bool visit(ObjCProtocolDeclarationAST *ast); virtual bool visit(ObjCProtocolDeclarationAST *ast);
virtual bool visit(ObjCProtocolForwardDeclarationAST *ast); virtual bool visit(ObjCProtocolForwardDeclarationAST *ast);

View File

@@ -297,8 +297,11 @@ void Launcher::handleResult(const TrkResult &result)
void Launcher::handleTrkVersion(const TrkResult &result) void Launcher::handleTrkVersion(const TrkResult &result)
{ {
if (result.errorCode() || result.data.size() < 5) if (result.errorCode() || result.data.size() < 5) {
if (d->m_startupActions == ActionPingOnly)
emit finished();
return; return;
}
const int trkMajor = result.data.at(1); const int trkMajor = result.data.at(1);
const int trkMinor = result.data.at(2); const int trkMinor = result.data.at(2);
const int protocolMajor = result.data.at(3); const int protocolMajor = result.data.at(3);
@@ -377,7 +380,8 @@ void Launcher::closeRemoteFile(bool failed)
void Launcher::handleFileCopied(const TrkResult &result) void Launcher::handleFileCopied(const TrkResult &result)
{ {
Q_UNUSED(result) if (result.errorCode())
emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString());
if (d->m_startupActions & ActionInstall) if (d->m_startupActions & ActionInstall)
installRemotePackageSilently(); installRemotePackageSilently();
else if (d->m_startupActions & ActionRun) else if (d->m_startupActions & ActionRun)

View File

@@ -71,6 +71,7 @@ signals:
void copyingStarted(); void copyingStarted();
void canNotCreateFile(const QString &filename, const QString &errorMessage); void canNotCreateFile(const QString &filename, const QString &errorMessage);
void canNotWriteFile(const QString &filename, const QString &errorMessage); void canNotWriteFile(const QString &filename, const QString &errorMessage);
void canNotCloseFile(const QString &filename, const QString &errorMessage);
void installingStarted(); void installingStarted();
void canNotInstall(const QString &packageFilename, const QString &errorMessage); void canNotInstall(const QString &packageFilename, const QString &errorMessage);
void startingApplication(); void startingApplication();