Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

This commit is contained in:
mae
2009-02-16 18:44:36 +01:00
41 changed files with 649 additions and 224 deletions

View File

@@ -100,7 +100,7 @@ QIcon Icons::iconForSymbol(const Symbol *symbol) const
} }
} else if (symbol->isEnum()) { } else if (symbol->isEnum()) {
return _enumIcon; return _enumIcon;
} else if (symbol->isClass()) { } else if (symbol->isClass() || symbol->isForwardClassDeclaration()) {
return _classIcon; return _classIcon;
} else if (symbol->isNamespace()) { } else if (symbol->isNamespace()) {
return _namespaceIcon; return _namespaceIcon;

View File

@@ -42,7 +42,8 @@ Overview::Overview()
: _markArgument(0), : _markArgument(0),
_showArgumentNames(false), _showArgumentNames(false),
_showReturnTypes(false), _showReturnTypes(false),
_showFunctionSignatures(true) _showFunctionSignatures(true),
_showFullyQualifiedNames(false)
{ } { }
Overview::~Overview() Overview::~Overview()
@@ -88,6 +89,16 @@ void Overview::setShowFunctionSignatures(bool showFunctionSignatures)
_showFunctionSignatures = showFunctionSignatures; _showFunctionSignatures = showFunctionSignatures;
} }
bool Overview::showFullyQualifiedNames() const
{
return _showFullyQualifiedNames;
}
void Overview::setShowFullyQualifiedNamed(bool showFullyQualifiedNames)
{
_showFullyQualifiedNames = showFullyQualifiedNames;
}
QString Overview::prettyName(Name *name) const QString Overview::prettyName(Name *name) const
{ {
NamePrettyPrinter pp(this); NamePrettyPrinter pp(this);

View File

@@ -57,6 +57,9 @@ public:
bool showFunctionSignatures() const; bool showFunctionSignatures() const;
void setShowFunctionSignatures(bool showFunctionSignatures); void setShowFunctionSignatures(bool showFunctionSignatures);
bool showFullyQualifiedNames() const;
void setShowFullyQualifiedNamed(bool showFullyQualifiedNames);
// 1-based // 1-based
// ### rename // ### rename
unsigned markArgument() const; unsigned markArgument() const;
@@ -77,6 +80,7 @@ private:
bool _showArgumentNames: 1; bool _showArgumentNames: 1;
bool _showReturnTypes: 1; bool _showReturnTypes: 1;
bool _showFunctionSignatures: 1; bool _showFunctionSignatures: 1;
bool _showFullyQualifiedNames: 1;
}; };
} // end of namespace CPlusPlus } // end of namespace CPlusPlus

View File

@@ -37,9 +37,41 @@
#include <CoreTypes.h> #include <CoreTypes.h>
#include <Symbols.h> #include <Symbols.h>
#include <Scope.h> #include <Scope.h>
#include <QStringList>
#include <QtDebug>
using namespace CPlusPlus; using namespace CPlusPlus;
static QString fullyQualifiedName(Symbol *symbol, const Overview *overview)
{
QStringList nestedNameSpecifier;
for (Scope *scope = symbol->scope(); scope && scope->enclosingScope();
scope = scope->enclosingScope())
{
Symbol *owner = scope->owner();
if (! owner) {
qWarning() << "invalid scope."; // ### better message.
continue;
}
if (! owner->name())
nestedNameSpecifier.prepend(QLatin1String("<anonymous>"));
else {
const QString name = overview->prettyName(owner->name());
nestedNameSpecifier.prepend(name);
}
}
nestedNameSpecifier.append(overview->prettyName(symbol->name()));
return nestedNameSpecifier.join(QLatin1String("::"));
}
TypePrettyPrinter::TypePrettyPrinter(const Overview *overview) TypePrettyPrinter::TypePrettyPrinter(const Overview *overview)
: _overview(overview), : _overview(overview),
_name(0) _name(0)
@@ -150,16 +182,26 @@ void TypePrettyPrinter::visit(Namespace *type)
applyPtrOperators(); applyPtrOperators();
} }
void TypePrettyPrinter::visit(Class *type) void TypePrettyPrinter::visit(Class *classTy)
{ {
_text += overview()->prettyName(type->name()); if (overview()->showFullyQualifiedNames())
_text += fullyQualifiedName(classTy, overview());
else
_text += overview()->prettyName(classTy->name());
applyPtrOperators(); applyPtrOperators();
} }
void TypePrettyPrinter::visit(Enum *type) void TypePrettyPrinter::visit(Enum *type)
{ {
if (overview()->showFullyQualifiedNames())
_text += fullyQualifiedName(type, overview());
else
_text += overview()->prettyName(type->name()); _text += overview()->prettyName(type->name());
applyPtrOperators(); applyPtrOperators();
} }
@@ -259,11 +301,14 @@ void TypePrettyPrinter::visit(Function *type)
if (! _ptrOperators.isEmpty()) { if (! _ptrOperators.isEmpty()) {
out(QLatin1Char('(')); out(QLatin1Char('('));
applyPtrOperators(false); applyPtrOperators(false);
if (! _name.isEmpty()) { if (! _name.isEmpty()) {
_text += _name; _text += _name;
_name.clear(); _name.clear();
} }
out(QLatin1Char(')')); out(QLatin1Char(')'));
} else if (! _name.isEmpty() && _overview->showFunctionSignatures()) { } else if (! _name.isEmpty() && _overview->showFunctionSignatures()) {
space(); space();
out(_name); out(_name);

View File

@@ -40,6 +40,7 @@
#include "cmakestep.h" #include "cmakestep.h"
#include "makestep.h" #include "makestep.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <cpptools/cppmodelmanagerinterface.h> #include <cpptools/cppmodelmanagerinterface.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -103,7 +104,7 @@ void CMakeProject::parseCMakeLists()
} else { } else {
// TODO hmm? // TODO hmm?
} }
if (newToolChain == m_toolChain) { if (ProjectExplorer::ToolChain::equals(newToolChain, m_toolChain)) {
delete newToolChain; delete newToolChain;
newToolChain = 0; newToolChain = 0;
} else { } else {
@@ -158,6 +159,21 @@ void CMakeProject::parseCMakeLists()
} }
} }
QString CMakeProject::buildParser(const QString &buildConfiguration) const
{
if (!m_toolChain)
return QString::null;
if (m_toolChain->type() == ProjectExplorer::ToolChain::GCC
|| m_toolChain->type() == ProjectExplorer::ToolChain::LinuxICC
|| m_toolChain->type() == ProjectExplorer::ToolChain::MinGW) {
return ProjectExplorer::Constants::BUILD_PARSER_GCC;
} else if (m_toolChain->type() == ProjectExplorer::ToolChain::MSVC
|| m_toolChain->type() == ProjectExplorer::ToolChain::WINCE) {
return ProjectExplorer::Constants::BUILD_PARSER_MSVC;
}
return QString::null;
}
QStringList CMakeProject::targets() const QStringList CMakeProject::targets() const
{ {
QStringList results; QStringList results;

View File

@@ -105,6 +105,7 @@ public:
MakeStep *makeStep() const; MakeStep *makeStep() const;
CMakeStep *cmakeStep() const; CMakeStep *cmakeStep() const;
QStringList targets() const; QStringList targets() const;
QString buildParser(const QString &buildConfiguration) const;
private: private:
void parseCMakeLists(); void parseCMakeLists();

View File

@@ -34,6 +34,7 @@
#include "makestep.h" #include "makestep.h"
#include "cmakeprojectconstants.h" #include "cmakeprojectconstants.h"
#include "cmakeproject.h" #include "cmakeproject.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QtGui/QFormLayout> #include <QtGui/QFormLayout>
@@ -42,6 +43,11 @@
#include <QtGui/QLineEdit> #include <QtGui/QLineEdit>
#include <QtGui/QListWidget> #include <QtGui/QListWidget>
namespace {
bool debug = false;
}
using namespace CMakeProjectManager; using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal; using namespace CMakeProjectManager::Internal;
@@ -52,10 +58,42 @@ MakeStep::MakeStep(CMakeProject *pro)
MakeStep::~MakeStep() MakeStep::~MakeStep()
{ {
delete m_buildParser;
m_buildParser = 0;
} }
bool MakeStep::init(const QString &buildConfiguration) bool MakeStep::init(const QString &buildConfiguration)
{ {
// TODO figure out the correct build parser
delete m_buildParser;
m_buildParser = 0;
QString buildParser = m_pro->buildParser(buildConfiguration);
QList<ProjectExplorer::IBuildParserFactory *> buildParserFactories =
ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();
foreach (ProjectExplorer::IBuildParserFactory * factory, buildParserFactories)
if (factory->canCreate(buildParser)) {
m_buildParser = factory->create(buildParser);
break;
}
if (m_buildParser) {
connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)),
this, SIGNAL(addToOutputWindow(const QString &)),
Qt::DirectConnection);
connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)),
this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)),
Qt::DirectConnection);
connect(m_buildParser, SIGNAL(enterDirectory(const QString &)),
this, SLOT(addDirectory(const QString &)),
Qt::DirectConnection);
connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)),
this, SLOT(removeDirectory(const QString &)),
Qt::DirectConnection);
}
m_openDirectories.clear();
addDirectory(m_pro->buildDirectory(buildConfiguration));
setEnabled(buildConfiguration, true); setEnabled(buildConfiguration, true);
setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration)); setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
setCommand(buildConfiguration, "make"); // TODO give full path here? setCommand(buildConfiguration, "make"); // TODO give full path here?
@@ -89,6 +127,79 @@ bool MakeStep::immutable() const
return true; return true;
} }
void MakeStep::stdOut(const QString &line)
{
if (m_buildParser)
m_buildParser->stdOutput(line);
AbstractProcessStep::stdOut(line);
}
void MakeStep::stdError(const QString &line)
{
if (m_buildParser)
m_buildParser->stdError(line);
AbstractProcessStep::stdError(line);
}
void MakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description)
{
QString filePath = fn;
if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
// We have no save way to decide which file in which subfolder
// is meant. Therefore we apply following heuristics:
// 1. Search for unique file in directories currently indicated as open by GNU make
// (Enter directory xxx, Leave directory xxx...) + current directory
// 3. Check if file is unique in whole project
// 4. Otherwise give up
filePath = filePath.trimmed();
QList<QFileInfo> possibleFiles;
foreach (const QString &dir, m_openDirectories) {
QFileInfo candidate(dir + QLatin1Char('/') + filePath);
if (debug)
qDebug() << "Checking path " << candidate.filePath();
if (candidate.exists()
&& !possibleFiles.contains(candidate)) {
if (debug)
qDebug() << candidate.filePath() << "exists!";
possibleFiles << candidate;
}
}
if (possibleFiles.count() == 0) {
if (debug)
qDebug() << "No success. Trying all files in project ...";
QString fileName = QFileInfo(filePath).fileName();
foreach (const QString &file, project()->files(ProjectExplorer::Project::AllFiles)) {
QFileInfo candidate(file);
if (candidate.fileName() == fileName) {
if (debug)
qDebug() << "Found " << file;
possibleFiles << candidate;
}
}
}
if (possibleFiles.count() == 1)
filePath = possibleFiles.first().filePath();
else
qWarning() << "Could not find absolute location of file " << filePath;
}
emit addToTaskWindow(filePath, type, linenumber, description);
}
void MakeStep::addDirectory(const QString &dir)
{
if (!m_openDirectories.contains(dir))
m_openDirectories.insert(dir);
}
void MakeStep::removeDirectory(const QString &dir)
{
if (m_openDirectories.contains(dir))
m_openDirectories.remove(dir);
}
CMakeProject *MakeStep::project() const CMakeProject *MakeStep::project() const
{ {
return m_pro; return m_pro;
@@ -154,7 +265,6 @@ void MakeBuildStepConfigWidget::init(const QString &buildConfiguration)
} }
// and connect again // and connect again
connect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); connect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
} }
// //

View File

@@ -64,8 +64,17 @@ public:
CMakeProject *project() const; CMakeProject *project() const;
bool buildsTarget(const QString &buildConfiguration, const QString &target) const; bool buildsTarget(const QString &buildConfiguration, const QString &target) const;
void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on); void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on);
private slots:
void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description);
void addDirectory(const QString &dir);
void removeDirectory(const QString &dir);
protected:
virtual void stdOut(const QString &line);
virtual void stdError(const QString &line);
private: private:
CMakeProject *m_pro; CMakeProject *m_pro;
ProjectExplorer::BuildParserInterface *m_buildParser;
QSet<QString> m_openDirectories;
}; };
class MakeBuildStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget class MakeBuildStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget

View File

@@ -47,6 +47,7 @@
#include <CoreTypes.h> #include <CoreTypes.h>
#include <FullySpecifiedType.h> #include <FullySpecifiedType.h>
#include <Literals.h> #include <Literals.h>
#include <Control.h>
#include <Names.h> #include <Names.h>
#include <Scope.h> #include <Scope.h>
#include <Symbol.h> #include <Symbol.h>
@@ -141,30 +142,13 @@ void CppHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint
} }
} }
static QString buildHelpId(const FullySpecifiedType &type, static QString buildHelpId(Symbol *symbol, Name *name)
const Symbol *symbol)
{ {
Name *name = 0;
Scope *scope = 0; Scope *scope = 0;
if (const Function *f = type->asFunctionType()) { if (symbol) {
name = f->name(); scope = symbol->scope();
scope = f->scope(); name = symbol->name();
} else if (const Class *c = type->asClassType()) {
name = c->name();
scope = c->scope();
} else if (const Enum *e = type->asEnumType()) {
name = e->name();
scope = e->scope();
} else if (const NamedType *t = type->asNamedType()) {
name = t->name();
} else if (symbol && symbol->isDeclaration()) {
const Declaration *d = symbol->asDeclaration();
if (d->scope() && d->scope()->isEnumScope()) {
name = d->name();
scope = d->scope();
}
} }
if (! name) if (! name)
@@ -178,14 +162,18 @@ static QString buildHelpId(const FullySpecifiedType &type,
qualifiedNames.prepend(overview.prettyName(name)); qualifiedNames.prepend(overview.prettyName(name));
for (; scope; scope = scope->enclosingScope()) { for (; scope; scope = scope->enclosingScope()) {
if (scope->owner() && scope->owner()->name() && !scope->isEnumScope()) { Symbol *owner = scope->owner();
Name *name = scope->owner()->name();
if (owner && owner->name() && ! scope->isEnumScope()) {
Name *name = owner->name();
Identifier *id = 0; Identifier *id = 0;
if (NameId *nameId = name->asNameId()) {
if (NameId *nameId = name->asNameId())
id = nameId->identifier(); id = nameId->identifier();
} else if (TemplateNameId *nameId = name->asTemplateNameId()) {
else if (TemplateNameId *nameId = name->asTemplateNameId())
id = nameId->identifier(); id = nameId->identifier();
}
if (id) if (id)
qualifiedNames.prepend(QString::fromLatin1(id->chars(), id->size())); qualifiedNames.prepend(QString::fromLatin1(id->chars(), id->size()));
} }
@@ -194,6 +182,70 @@ static QString buildHelpId(const FullySpecifiedType &type,
return qualifiedNames.join(QLatin1String("::")); return qualifiedNames.join(QLatin1String("::"));
} }
// ### move me
static FullySpecifiedType resolve(const FullySpecifiedType &ty,
const LookupContext &context,
Symbol **resolvedSymbol,
Name **resolvedName)
{
Control *control = context.control();
if (const PointerType *ptrTy = ty->asPointerType()) {
return control->pointerType(resolve(ptrTy->elementType(), context,
resolvedSymbol, resolvedName));
} else if (const ReferenceType *refTy = ty->asReferenceType()) {
return control->referenceType(resolve(refTy->elementType(), context,
resolvedSymbol, resolvedName));
} else if (const PointerToMemberType *ptrToMemTy = ty->asPointerToMemberType()) {
return control->pointerToMemberType(ptrToMemTy->memberName(),
resolve(ptrToMemTy->elementType(), context,
resolvedSymbol, resolvedName));
} else if (const NamedType *namedTy = ty->asNamedType()) {
if (resolvedName)
*resolvedName = namedTy->name();
const QList<Symbol *> candidates = context.resolve(namedTy->name());
foreach (Symbol *c, candidates) {
if (c->isClass() || c->isEnum()) {
if (resolvedSymbol)
*resolvedSymbol = c;
return c->type();
}
}
} else if (const Namespace *nsTy = ty->asNamespaceType()) {
if (resolvedName)
*resolvedName = nsTy->name();
} else if (const Class *classTy = ty->asClassType()) {
if (resolvedName)
*resolvedName = classTy->name();
if (resolvedSymbol)
*resolvedSymbol = const_cast<Class *>(classTy);
} else if (const ForwardClassDeclaration *fwdClassTy = ty->asForwardClassDeclarationType()) {
if (resolvedName)
*resolvedName = fwdClassTy->name();
} else if (const Enum *enumTy = ty->asEnumType()) {
if (resolvedName)
*resolvedName = enumTy->name();
} else if (const Function *funTy = ty->asFunctionType()) {
if (resolvedName)
*resolvedName = funTy->name();
}
return ty;
}
void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos) void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos)
{ {
m_helpId.clear(); m_helpId.clear();
@@ -262,26 +314,38 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
typeOfExpression(expression, doc, lastSymbol); typeOfExpression(expression, doc, lastSymbol);
if (!types.isEmpty()) { if (!types.isEmpty()) {
FullySpecifiedType firstType = types.first().first; const TypeOfExpression::Result result = types.first();
Symbol *symbol = types.first().second;
FullySpecifiedType docType = firstType;
if (const PointerType *pt = firstType->asPointerType()) { FullySpecifiedType firstType = result.first; // result of `type of expression'.
docType = pt->elementType(); Symbol *lookupSymbol = result.second; // lookup symbol
} else if (const ReferenceType *rt = firstType->asReferenceType()) {
docType = rt->elementType();
}
m_helpId = buildHelpId(docType, symbol); Symbol *resolvedSymbol = 0;
QString displayName = buildHelpId(firstType, symbol); Name *resolvedName = 0;
firstType = resolve(firstType, typeOfExpression.lookupContext(),
&resolvedSymbol, &resolvedName);
m_helpId = buildHelpId(resolvedSymbol, resolvedName);
Symbol *symbol = result.second;
if (resolvedSymbol)
symbol = resolvedSymbol;
if (!firstType->isClassType() && !firstType->isNamedType()) {
Overview overview; Overview overview;
overview.setShowArgumentNames(true); overview.setShowArgumentNames(true);
overview.setShowReturnTypes(true); overview.setShowReturnTypes(true);
m_toolTip = overview.prettyType(firstType, displayName); overview.setShowFullyQualifiedNamed(true);
} else {
if (lookupSymbol && lookupSymbol->isDeclaration()) {
Declaration *decl = lookupSymbol->asDeclaration();
m_toolTip = overview.prettyType(firstType, decl->name());
} else if (firstType->isClassType() || firstType->isEnumType() ||
firstType->isForwardClassDeclarationType()) {
m_toolTip = m_helpId; m_toolTip = m_helpId;
} else {
m_toolTip = overview.prettyType(firstType, m_helpId);
} }
} }
} }

View File

@@ -150,10 +150,9 @@ void DebuggerManager::init()
{ {
m_status = -1; m_status = -1;
m_busy = false; m_busy = false;
m_shutdown = false;
m_attachedPID = 0; m_attachedPID = 0;
m_startMode = startInternal; m_startMode = StartInternal;
m_disassemblerHandler = 0; m_disassemblerHandler = 0;
m_modulesHandler = 0; m_modulesHandler = 0;
@@ -544,6 +543,12 @@ void DebuggerManager::notifyStartupFinished()
showStatusMessage(tr("Startup finished. Debugger ready."), -1); showStatusMessage(tr("Startup finished. Debugger ready."), -1);
} }
void DebuggerManager::notifyInferiorStopRequested()
{
setStatus(DebuggerInferiorStopRequested);
showStatusMessage(tr("Stop requested..."), 5000);
}
void DebuggerManager::notifyInferiorStopped() void DebuggerManager::notifyInferiorStopped()
{ {
resetLocation(); resetLocation();
@@ -578,7 +583,7 @@ void DebuggerManager::notifyInferiorExited()
void DebuggerManager::notifyInferiorPidChanged(int pid) void DebuggerManager::notifyInferiorPidChanged(int pid)
{ {
//QMessageBox::warning(0, "PID", "PID: " + QString::number(pid)); //QMessageBox::warning(0, "PID", "PID: " + QString::number(pid));
qDebug() << "PID: " << pid; //qDebug() << "PID: " << pid;
emit inferiorPidChanged(pid); emit inferiorPidChanged(pid);
} }
@@ -590,9 +595,10 @@ void DebuggerManager::showApplicationOutput(const QString &str)
void DebuggerManager::shutdown() void DebuggerManager::shutdown()
{ {
//qDebug() << "DEBUGGER_MANAGER SHUTDOWN START"; //qDebug() << "DEBUGGER_MANAGER SHUTDOWN START";
m_shutdown = true; if (m_engine) {
if (m_engine) //qDebug() << "SHUTTING DOWN ENGINE" << m_engine;
m_engine->shutdown(); m_engine->shutdown();
}
m_engine = 0; m_engine = 0;
delete scriptEngine; delete scriptEngine;
@@ -657,6 +663,12 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber)
{ {
QTC_ASSERT(m_engine, return); QTC_ASSERT(m_engine, return);
QTC_ASSERT(m_breakHandler, return); QTC_ASSERT(m_breakHandler, return);
if (status() != DebuggerInferiorRunning && status() != DebuggerInferiorStopped) {
showStatusMessage(tr("Changing breakpoint state requires either a "
"fully running or fully stopped application."));
return;
}
int index = m_breakHandler->indexOf(fileName, lineNumber); int index = m_breakHandler->indexOf(fileName, lineNumber);
if (index == -1) if (index == -1)
m_breakHandler->setBreakpoint(fileName, lineNumber); m_breakHandler->setBreakpoint(fileName, lineNumber);
@@ -737,13 +749,13 @@ void DebuggerManager::setConfigValue(const QString &name, const QVariant &value)
void DebuggerManager::startExternalApplication() void DebuggerManager::startExternalApplication()
{ {
if (!startNewDebugger(startExternal)) if (!startNewDebugger(StartExternal))
emit debuggingFinished(); emit debuggingFinished();
} }
void DebuggerManager::attachExternalApplication() void DebuggerManager::attachExternalApplication()
{ {
if (!startNewDebugger(attachExternal)) if (!startNewDebugger(AttachExternal))
emit debuggingFinished(); emit debuggingFinished();
} }
@@ -752,7 +764,7 @@ bool DebuggerManager::startNewDebugger(StartMode mode)
m_startMode = mode; m_startMode = mode;
// FIXME: Clean up // FIXME: Clean up
if (startMode() == startExternal) { if (startMode() == StartExternal) {
StartExternalDialog dlg(mainWindow()); StartExternalDialog dlg(mainWindow());
dlg.setExecutableFile( dlg.setExecutableFile(
configValue(QLatin1String("LastExternalExecutableFile")).toString()); configValue(QLatin1String("LastExternalExecutableFile")).toString());
@@ -768,7 +780,7 @@ bool DebuggerManager::startNewDebugger(StartMode mode)
m_processArgs = dlg.executableArguments().split(' '); m_processArgs = dlg.executableArguments().split(' ');
m_workingDir = QString(); m_workingDir = QString();
m_attachedPID = -1; m_attachedPID = -1;
} else if (startMode() == attachExternal) { } else if (startMode() == AttachExternal) {
AttachExternalDialog dlg(mainWindow()); AttachExternalDialog dlg(mainWindow());
if (dlg.exec() != QDialog::Accepted) if (dlg.exec() != QDialog::Accepted)
return false; return false;
@@ -781,7 +793,7 @@ bool DebuggerManager::startNewDebugger(StartMode mode)
tr("Cannot attach to PID 0")); tr("Cannot attach to PID 0"));
return false; return false;
} }
} else if (startMode() == startInternal) { } else if (startMode() == StartInternal) {
if (m_executable.isEmpty()) { if (m_executable.isEmpty()) {
QString startDirectory = m_executable; QString startDirectory = m_executable;
if (m_executable.isEmpty()) { if (m_executable.isEmpty()) {
@@ -835,9 +847,8 @@ void DebuggerManager::cleanupViews()
void DebuggerManager::exitDebugger() void DebuggerManager::exitDebugger()
{ {
if (m_shutdown) //qDebug() << "DebuggerManager::exitDebugger";
return; if (m_engine)
QTC_ASSERT(m_engine, return);
m_engine->exitDebugger(); m_engine->exitDebugger();
cleanupViews(); cleanupViews();
setStatus(DebuggerProcessNotReady); setStatus(DebuggerProcessNotReady);
@@ -960,33 +971,6 @@ void DebuggerManager::dumpLog()
ts << m_outputWindow->combinedContents(); ts << m_outputWindow->combinedContents();
} }
#if 0
// call after m_gdbProc exited.
void GdbEngine::procFinished()
{
//qDebug() << "GDB PROCESS FINISHED";
setStatus(DebuggerProcessNotReady);
showStatusMessage(tr("Done"), 5000);
q->m_breakHandler->procFinished();
q->m_watchHandler->cleanup();
m_stackHandler->m_stackFrames.clear();
m_stackHandler->resetModel();
m_threadsHandler->resetModel();
if (q->m_modulesHandler)
q->m_modulesHandler->procFinished();
q->resetLocation();
setStatus(DebuggerProcessNotReady);
emit q->previousModeRequested();
emit q->debuggingFinished();
//exitDebugger();
//showStatusMessage("Gdb killed");
m_shortToFullName.clear();
m_fullToShortName.clear();
m_shared = 0;
q->m_busy = false;
}
#endif
void DebuggerManager::addToWatchWindow() void DebuggerManager::addToWatchWindow()
{ {
// requires a selection, but that's the only case we want... // requires a selection, but that's the only case we want...

View File

@@ -151,6 +151,7 @@ private:
// called from the engines after successful startup // called from the engines after successful startup
virtual void notifyStartupFinished() = 0; virtual void notifyStartupFinished() = 0;
virtual void notifyInferiorStopRequested() = 0;
virtual void notifyInferiorStopped() = 0; virtual void notifyInferiorStopped() = 0;
virtual void notifyInferiorUpdateFinished() = 0; virtual void notifyInferiorUpdateFinished() = 0;
virtual void notifyInferiorRunningRequested() = 0; virtual void notifyInferiorRunningRequested() = 0;
@@ -229,7 +230,7 @@ public:
QLabel *statusLabel() const { return m_statusLabel; } QLabel *statusLabel() const { return m_statusLabel; }
DebuggerSettings *settings() { return &m_settings; } DebuggerSettings *settings() { return &m_settings; }
enum StartMode { startInternal, startExternal, attachExternal }; enum StartMode { StartInternal, StartExternal, AttachExternal };
enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger }; enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger };
public slots: public slots:
@@ -339,6 +340,7 @@ private:
void notifyInferiorStopped(); void notifyInferiorStopped();
void notifyInferiorUpdateFinished(); void notifyInferiorUpdateFinished();
void notifyInferiorRunningRequested(); void notifyInferiorRunningRequested();
void notifyInferiorStopRequested();
void notifyInferiorRunning(); void notifyInferiorRunning();
void notifyInferiorExited(); void notifyInferiorExited();
void notifyInferiorPidChanged(int); void notifyInferiorPidChanged(int);
@@ -466,8 +468,6 @@ private:
IDebuggerEngine *engine(); IDebuggerEngine *engine();
IDebuggerEngine *m_engine; IDebuggerEngine *m_engine;
DebuggerSettings m_settings; DebuggerSettings m_settings;
// set during application shutdown
bool m_shutdown;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -115,6 +115,8 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
connect(m_manager, SIGNAL(inferiorPidChanged(qint64)), connect(m_manager, SIGNAL(inferiorPidChanged(qint64)),
this, SLOT(bringApplicationToForeground(qint64)), this, SLOT(bringApplicationToForeground(qint64)),
Qt::QueuedConnection); Qt::QueuedConnection);
connect(this, SIGNAL(stopRequested()),
m_manager, SLOT(exitDebugger()));
} }
void DebuggerRunControl::start() void DebuggerRunControl::start()
@@ -135,7 +137,7 @@ void DebuggerRunControl::start()
//<daniel> andre: + "\qtc-gdbmacros\" //<daniel> andre: + "\qtc-gdbmacros\"
//emit addToOutputWindow(this, tr("Debugging %1").arg(m_executable)); //emit addToOutputWindow(this, tr("Debugging %1").arg(m_executable));
if (m_manager->startNewDebugger(DebuggerManager::startInternal)) if (m_manager->startNewDebugger(DebuggerManager::StartInternal))
emit started(); emit started();
else else
debuggingFinished(); debuggingFinished();
@@ -148,17 +150,21 @@ void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data)
void DebuggerRunControl::stop() void DebuggerRunControl::stop()
{ {
m_manager->exitDebugger(); //qDebug() << "DebuggerRunControl::stop";
m_running = false;
emit stopRequested();
} }
void DebuggerRunControl::debuggingFinished() void DebuggerRunControl::debuggingFinished()
{ {
m_running = false; m_running = false;
//qDebug() << "DebuggerRunControl::finished";
//emit addToOutputWindow(this, tr("Debugging %1 finished").arg(m_executable)); //emit addToOutputWindow(this, tr("Debugging %1 finished").arg(m_executable));
emit finished(); emit finished();
} }
bool DebuggerRunControl::isRunning() const bool DebuggerRunControl::isRunning() const
{ {
//qDebug() << "DebuggerRunControl::isRunning" << m_running;
return m_running; return m_running;
} }

View File

@@ -82,6 +82,9 @@ public:
virtual void stop(); virtual void stop();
virtual bool isRunning() const; virtual bool isRunning() const;
signals:
void stopRequested();
private slots: private slots:
void debuggingFinished(); void debuggingFinished();
void slotAddToOutputWindowInline(const QString &output); void slotAddToOutputWindowInline(const QString &output);

View File

@@ -115,6 +115,7 @@ enum GdbCommandType
GdbInfoThreads, GdbInfoThreads,
GdbQueryDataDumper1, GdbQueryDataDumper1,
GdbQueryDataDumper2, GdbQueryDataDumper2,
GdbTemporaryContinue,
BreakCondition = 200, BreakCondition = 200,
BreakEnablePending, BreakEnablePending,
@@ -257,6 +258,8 @@ GdbEngine::GdbEngine(DebuggerManager *parent)
GdbEngine::~GdbEngine() GdbEngine::~GdbEngine()
{ {
// prevent sending error messages afterwards
m_gdbProc.disconnect(this);
} }
void GdbEngine::initializeConnections() void GdbEngine::initializeConnections()
@@ -303,6 +306,7 @@ void GdbEngine::initializeVariables()
m_pendingRequests = 0; m_pendingRequests = 0;
m_waitingForBreakpointSynchronizationToContinue = false; m_waitingForBreakpointSynchronizationToContinue = false;
m_waitingForFirstBreakpointToBeHit = false; m_waitingForFirstBreakpointToBeHit = false;
m_commandsToRunOnTemporaryBreak.clear();
} }
void GdbEngine::gdbProcError(QProcess::ProcessError error) void GdbEngine::gdbProcError(QProcess::ProcessError error)
@@ -386,6 +390,11 @@ void GdbEngine::readDebugeeOutput(const QByteArray &data)
data.constData(), data.length(), &m_outputCodecState)); data.constData(), data.length(), &m_outputCodecState));
} }
void GdbEngine::debugMessage(const QString &msg)
{
emit gdbOutputAvailable("debug:", msg);
}
// called asyncronously as response to Gdb stdout output in // called asyncronously as response to Gdb stdout output in
// gdbResponseAvailable() // gdbResponseAvailable()
void GdbEngine::handleResponse() void GdbEngine::handleResponse()
@@ -643,22 +652,29 @@ void GdbEngine::readGdbStandardOutput()
void GdbEngine::interruptInferior() void GdbEngine::interruptInferior()
{ {
if (m_gdbProc.state() == QProcess::NotRunning) qq->notifyInferiorStopRequested();
if (m_gdbProc.state() == QProcess::NotRunning) {
debugMessage("TRYING TO INTERRUPT INFERIOR WITHOUT RUNNING GDB");
qq->notifyInferiorExited();
return; return;
}
if (q->m_attachedPID > 0) { if (q->m_attachedPID > 0) {
if (interruptProcess(q->m_attachedPID)) if (!interruptProcess(q->m_attachedPID))
qq->notifyInferiorStopped(); // qq->notifyInferiorStopped();
//else
debugMessage(QString("CANNOT INTERRUPT %1").arg(q->m_attachedPID));
return; return;
} }
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
sendCommand("-exec-interrupt", GdbExecInterrupt); sendCommand("-exec-interrupt", GdbExecInterrupt);
qq->notifyInferiorStopped(); //qq->notifyInferiorStopped();
#else #else
qDebug() << "CANNOT STOP INFERIOR" << m_gdbProc.pid(); if (!interruptChildProcess(m_gdbProc.pid()))
if (interruptChildProcess(m_gdbProc.pid())) // qq->notifyInferiorStopped();
qq->notifyInferiorStopped(); //else
debugMessage(QString("CANNOT STOP INFERIOR"));
#endif #endif
} }
@@ -666,38 +682,30 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
{ {
int pid = pid0.toInt(); int pid = pid0.toInt();
if (pid == 0) { if (pid == 0) {
qDebug() << "Cannot parse PID from " << pid0; debugMessage(QString("Cannot parse PID from %1").arg(pid0));
return; return;
} }
if (pid == q->m_attachedPID) if (pid == q->m_attachedPID)
return; return;
qDebug() << "FOUND PID " << pid; debugMessage(QString("FOUND PID %1").arg(pid));
q->m_attachedPID = pid; q->m_attachedPID = pid;
qq->notifyInferiorPidChanged(pid); qq->notifyInferiorPidChanged(pid);
} }
void GdbEngine::sendSynchronizedCommand(const QString & command, void GdbEngine::sendSynchronizedCommand(const QString & command,
int type, const QVariant &cookie, bool needStop) int type, const QVariant &cookie, StopNeeded needStop)
{ {
sendCommand(command, type, cookie, needStop, true); sendCommand(command, type, cookie, needStop, Synchronized);
} }
void GdbEngine::sendCommand(const QString &command, int type, void GdbEngine::sendCommand(const QString &command, int type,
const QVariant &cookie, bool needStop, bool synchronized) const QVariant &cookie, StopNeeded needStop, Synchronization synchronized)
{ {
if (m_gdbProc.state() == QProcess::NotRunning) { if (m_gdbProc.state() == QProcess::NotRunning) {
//qDebug() << "NO GDB PROCESS RUNNING, CMD IGNORED:" << command; debugMessage("NO GDB PROCESS RUNNING, CMD IGNORED: " + command);
return; return;
} }
bool temporarilyStopped = false;
if (needStop && q->status() == DebuggerInferiorRunning) {
q->showStatusMessage(tr("Temporarily stopped"));
interruptInferior();
temporarilyStopped = true;
}
++currentToken();
if (synchronized) { if (synchronized) {
++m_pendingRequests; ++m_pendingRequests;
PENDING_DEBUG(" TYPE " << type << " INCREMENTS PENDING TO: " PENDING_DEBUG(" TYPE " << type << " INCREMENTS PENDING TO: "
@@ -710,28 +718,30 @@ void GdbEngine::sendCommand(const QString &command, int type,
GdbCookie cmd; GdbCookie cmd;
cmd.synchronized = synchronized; cmd.synchronized = synchronized;
cmd.command = command; cmd.command = command;
cmd.command = QString::number(currentToken()) + cmd.command;
if (cmd.command.contains("%1"))
cmd.command = cmd.command.arg(currentToken());
cmd.type = type; cmd.type = type;
cmd.cookie = cookie; cmd.cookie = cookie;
if (needStop && q->status() != DebuggerInferiorStopped
&& q->status() != DebuggerProcessStartingUp) {
// queue the commands that we cannot send at once
QTC_ASSERT(q->status() == DebuggerInferiorRunning,
qDebug() << "STATUS: " << q->status());
q->showStatusMessage(tr("Stopping temporarily."));
debugMessage("QUEUING COMMAND " + cmd.command);
m_commandsToRunOnTemporaryBreak.append(cmd);
interruptInferior();
} else if (!command.isEmpty()) {
++currentToken();
m_cookieForToken[currentToken()] = cmd; m_cookieForToken[currentToken()] = cmd;
cmd.command = QString::number(currentToken()) + cmd.command;
if (cmd.command.contains("%1"))
cmd.command = cmd.command.arg(currentToken());
//qDebug() << "";
if (!command.isEmpty()) {
//qDebug() << qPrintable(currentTime()) << "RUNNING" << cmd.command;
m_gdbProc.write(cmd.command.toLatin1() + "\r\n"); m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
//emit gdbInputAvailable(QString(), " " + currentTime()); //emit gdbInputAvailable(QString(), " " + currentTime());
//emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command); //emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
emit gdbInputAvailable(QString(), cmd.command); emit gdbInputAvailable(QString(), cmd.command);
} }
if (temporarilyStopped)
sendCommand("-exec-continue");
// slows down
//qApp->processEvents();
} }
void GdbEngine::handleResultRecord(const GdbResultRecord &record) void GdbEngine::handleResultRecord(const GdbResultRecord &record)
@@ -817,6 +827,7 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
//handleExecRunToFunction(record); //handleExecRunToFunction(record);
break; break;
case GdbExecInterrupt: case GdbExecInterrupt:
qq->notifyInferiorStopped();
break; break;
case GdbExecJumpToLine: case GdbExecJumpToLine:
handleExecJumpToLine(record); handleExecJumpToLine(record);
@@ -839,6 +850,10 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
case GdbQueryDataDumper2: case GdbQueryDataDumper2:
handleQueryDataDumper2(record); handleQueryDataDumper2(record);
break; break;
case GdbTemporaryContinue:
continueInferior();
q->showStatusMessage(tr("Continuing after temporary stop."));
break;
case BreakList: case BreakList:
handleBreakList(record); handleBreakList(record);
@@ -920,8 +935,8 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
break; break;
default: default:
qDebug() << "FIXME: GdbEngine::handleResult: " debugMessage(QString("FIXME: GdbEngine::handleResult: "
"should not happen" << type; "should not happen %1").arg(type));
break; break;
} }
} }
@@ -930,7 +945,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
{ {
//createGdbProcessIfNeeded(); //createGdbProcessIfNeeded();
if (m_gdbProc.state() == QProcess::NotRunning) { if (m_gdbProc.state() == QProcess::NotRunning) {
qDebug() << "NO GDB PROCESS RUNNING, PLAIN CMD IGNORED: " << command; debugMessage("NO GDB PROCESS RUNNING, PLAIN CMD IGNORED: " + command);
return; return;
} }
@@ -938,11 +953,6 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
cmd.command = command; cmd.command = command;
cmd.type = -1; cmd.type = -1;
//m_cookieForToken[currentToken()] = cmd;
//++currentToken();
//qDebug() << "";
//qDebug() << currentTime() << "Running command: " << cmd.command;
emit gdbInputAvailable(QString(), cmd.command); emit gdbInputAvailable(QString(), cmd.command);
m_gdbProc.write(cmd.command.toLatin1() + "\r\n"); m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
} }
@@ -969,7 +979,7 @@ void GdbEngine::handleQueryPwd(const GdbResultRecord &record)
m_pwd = record.data.findChild("consolestreamoutput").data(); m_pwd = record.data.findChild("consolestreamoutput").data();
m_pwd = m_pwd.trimmed(); m_pwd = m_pwd.trimmed();
#endif #endif
//qDebug() << "PWD RESULT:" << m_pwd; debugMessage("PWD RESULT: " + m_pwd);
} }
} }
@@ -1104,6 +1114,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
//MAC: bool isFirstStop = data.findChild("bkptno").data() == "1"; //MAC: bool isFirstStop = data.findChild("bkptno").data() == "1";
//!MAC: startSymbolName == data.findChild("frame").findChild("func") //!MAC: startSymbolName == data.findChild("frame").findChild("func")
if (m_waitingForFirstBreakpointToBeHit) { if (m_waitingForFirstBreakpointToBeHit) {
qq->notifyInferiorStopped();
m_waitingForFirstBreakpointToBeHit = false; m_waitingForFirstBreakpointToBeHit = false;
// //
// that's the "early stop" // that's the "early stop"
@@ -1143,11 +1154,28 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
return; return;
} }
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
QTC_ASSERT(q->status() == DebuggerInferiorStopRequested,
qDebug() << "STATUS: " << q->status())
qq->notifyInferiorStopped();
q->showStatusMessage(tr("Temporarily stopped."));
// FIXME: racy
foreach (const GdbCookie &cmd, m_commandsToRunOnTemporaryBreak) {
debugMessage(QString("RUNNING QUEUED COMMAND %1 %2")
.arg(cmd.command).arg(cmd.type));
sendCommand(cmd.command, cmd.type, cmd.cookie);
}
sendCommand("p temporaryStop", GdbTemporaryContinue);
m_commandsToRunOnTemporaryBreak.clear();
q->showStatusMessage(tr("Handling queued commands."));
return;
}
QString msg = data.findChild("consolestreamoutput").data(); QString msg = data.findChild("consolestreamoutput").data();
if (msg.contains("Stopped due to shared library event") || reason.isEmpty()) { if (msg.contains("Stopped due to shared library event") || reason.isEmpty()) {
if (qq->wantsSelectedPluginBreakpoints()) { if (qq->wantsSelectedPluginBreakpoints()) {
qDebug() << "SHARED LIBRARY EVENT " << data.toString(); debugMessage("SHARED LIBRARY EVENT: " + data.toString());
qDebug() << "PATTERN" << qq->selectedPluginBreakpointsPattern(); debugMessage("PATTERN: " + qq->selectedPluginBreakpointsPattern());
sendCommand("sharedlibrary " + qq->selectedPluginBreakpointsPattern()); sendCommand("sharedlibrary " + qq->selectedPluginBreakpointsPattern());
continueInferior(); continueInferior();
q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString()))); q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString())));
@@ -1182,6 +1210,8 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
+ data.findChild("signal-name").toString(); + data.findChild("signal-name").toString();
} }
q->showStatusMessage(msg); q->showStatusMessage(msg);
// FIXME: shouldn't this use a statis change?
debugMessage("CALLING PARENT EXITDEBUGGER");
q->exitDebugger(); q->exitDebugger();
return; return;
} }
@@ -1193,21 +1223,21 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
if (qq->skipKnownFrames()) { if (qq->skipKnownFrames()) {
if (reason == "end-stepping-range" || reason == "function-finished") { if (reason == "end-stepping-range" || reason == "function-finished") {
GdbMi frame = data.findChild("frame"); GdbMi frame = data.findChild("frame");
//qDebug() << frame.toString(); //debugMessage(frame.toString());
m_currentFrame = frame.findChild("addr").data() + '%' + m_currentFrame = frame.findChild("addr").data() + '%' +
frame.findChild("func").data() + '%'; frame.findChild("func").data() + '%';
QString funcName = frame.findChild("func").data(); QString funcName = frame.findChild("func").data();
QString fileName = frame.findChild("file").data(); QString fileName = frame.findChild("file").data();
if (isLeavableFunction(funcName, fileName)) { if (isLeavableFunction(funcName, fileName)) {
//qDebug() << "LEAVING" << funcName; //debugMessage("LEAVING" + funcName);
++stepCounter; ++stepCounter;
q->stepOutExec(); q->stepOutExec();
//stepExec(); //stepExec();
return; return;
} }
if (isSkippableFunction(funcName, fileName)) { if (isSkippableFunction(funcName, fileName)) {
//qDebug() << "SKIPPING" << funcName; //debugMessage("SKIPPING" + funcName);
++stepCounter; ++stepCounter;
q->stepExec(); q->stepExec();
return; return;
@@ -1227,7 +1257,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
if (reason == "breakpoint-hit") { if (reason == "breakpoint-hit") {
q->showStatusMessage(tr("Stopped at breakpoint")); q->showStatusMessage(tr("Stopped at breakpoint"));
GdbMi frame = data.findChild("frame"); GdbMi frame = data.findChild("frame");
//qDebug() << "HIT BREAKPOINT: " << frame.toString(); //debugMessage("HIT BREAKPOINT: " + frame.toString());
m_currentFrame = frame.findChild("addr").data() + '%' + m_currentFrame = frame.findChild("addr").data() + '%' +
frame.findChild("func").data() + '%'; frame.findChild("func").data() + '%';
@@ -1243,7 +1273,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
return; return;
} }
qDebug() << "STOPPED FOR UNKNOWN REASON" << data.toString(); debugMessage("STOPPED FOR UNKNOWN REASON: " + data.toString());
// Ignore it. Will be handled with full response later in the // Ignore it. Will be handled with full response later in the
// JumpToLine or RunToFunction handlers // JumpToLine or RunToFunction handlers
#if 1 #if 1
@@ -1310,7 +1340,7 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
QString msg = response.data.findChild("consolestreamoutput").data(); QString msg = response.data.findChild("consolestreamoutput").data();
QRegExp supported("GNU gdb(.*) (\\d+)\\.(\\d+)(\\.(\\d+))?"); QRegExp supported("GNU gdb(.*) (\\d+)\\.(\\d+)(\\.(\\d+))?");
if (supported.indexIn(msg) == -1) { if (supported.indexIn(msg) == -1) {
qDebug() << "UNSUPPORTED GDB VERSION " << msg; debugMessage("UNSUPPORTED GDB VERSION " + msg);
QStringList list = msg.split("\n"); QStringList list = msg.split("\n");
while (list.size() > 2) while (list.size() > 2)
list.removeLast(); list.removeLast();
@@ -1331,7 +1361,7 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
m_gdbVersion = 10000 * supported.cap(2).toInt() m_gdbVersion = 10000 * supported.cap(2).toInt()
+ 100 * supported.cap(3).toInt() + 100 * supported.cap(3).toInt()
+ 1 * supported.cap(5).toInt(); + 1 * supported.cap(5).toInt();
//qDebug() << "GDB VERSION " << m_gdbVersion; //debugMessage(QString("GDB VERSION: %1").arg(m_gdbVersion));
} }
} }
} }
@@ -1387,7 +1417,7 @@ QString GdbEngine::fullName(const QString &fileName)
if (fileName.isEmpty()) if (fileName.isEmpty())
return QString(); return QString();
QString full = m_shortToFullName.value(fileName, QString()); QString full = m_shortToFullName.value(fileName, QString());
//qDebug() << "RESOLVING: " << fileName << full; //debugMessage("RESOLVING: " + fileName + " " + full);
if (!full.isEmpty()) if (!full.isEmpty())
return full; return full;
QFileInfo fi(fileName); QFileInfo fi(fileName);
@@ -1397,7 +1427,7 @@ QString GdbEngine::fullName(const QString &fileName)
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
full = QDir::cleanPath(full); full = QDir::cleanPath(full);
#endif #endif
//qDebug() << "STORING: " << fileName << full; //debugMessage("STORING: " + fileName + " " + full);
m_shortToFullName[fileName] = full; m_shortToFullName[fileName] = full;
m_fullToShortName[full] = fileName; m_fullToShortName[full] = fileName;
return full; return full;
@@ -1425,22 +1455,29 @@ void GdbEngine::shutdown()
void GdbEngine::exitDebugger() void GdbEngine::exitDebugger()
{ {
//qDebug() << "EXITING: " << m_gdbProc.state(); debugMessage(QString("GDBENGINE EXITDEBUFFER: %1").arg(m_gdbProc.state()));
if (m_gdbProc.state() == QProcess::Starting) if (m_gdbProc.state() == QProcess::Starting) {
debugMessage(QString("WAITING FOR GDB STARTUP TO SHUTDOWN: %1")
.arg(m_gdbProc.state()));
m_gdbProc.waitForStarted(); m_gdbProc.waitForStarted();
}
if (m_gdbProc.state() == QProcess::Running) { if (m_gdbProc.state() == QProcess::Running) {
debugMessage(QString("WAITING FOR RUNNING GDB TO SHUTDOWN: %1")
.arg(m_gdbProc.state()));
interruptInferior(); interruptInferior();
sendCommand("kill"); sendCommand("kill");
sendCommand("-gdb-exit"); sendCommand("-gdb-exit");
// 20s can easily happen when loading webkit debug information // 20s can easily happen when loading webkit debug information
m_gdbProc.waitForFinished(20000); m_gdbProc.waitForFinished(20000);
if (m_gdbProc.state() != QProcess::Running) { if (m_gdbProc.state() != QProcess::Running) {
debugMessage(QString("FORCING TERMINATION: %1")
.arg(m_gdbProc.state()));
m_gdbProc.terminate(); m_gdbProc.terminate();
m_gdbProc.waitForFinished(20000); m_gdbProc.waitForFinished(20000);
} }
} }
if (m_gdbProc.state() != QProcess::NotRunning) if (m_gdbProc.state() != QProcess::NotRunning)
qDebug() << "PROBLEM STOPPING DEBUGGER"; debugMessage("PROBLEM STOPPING DEBUGGER");
m_outputCollector.shutdown(); m_outputCollector.shutdown();
initializeVariables(); initializeVariables();
@@ -1462,7 +1499,7 @@ bool GdbEngine::startDebugger()
QString fileName = '"' + fi.absoluteFilePath() + '"'; QString fileName = '"' + fi.absoluteFilePath() + '"';
if (m_gdbProc.state() != QProcess::NotRunning) { if (m_gdbProc.state() != QProcess::NotRunning) {
qDebug() << "GDB IS ALREADY RUNNING!"; debugMessage("GDB IS ALREADY RUNNING!");
return false; return false;
} }
@@ -1525,6 +1562,7 @@ bool GdbEngine::startDebugger()
//sendCommand("set pagination off"); //sendCommand("set pagination off");
sendCommand("set breakpoint pending on", BreakEnablePending); sendCommand("set breakpoint pending on", BreakEnablePending);
sendCommand("set print elements 10000"); sendCommand("set print elements 10000");
sendCommand("-data-list-register-names", RegisterListNames);
// one of the following is needed to prevent crashes in gdb on code like: // one of the following is needed to prevent crashes in gdb on code like:
// template <class T> T foo() { return T(0); } // template <class T> T foo() { return T(0); }
@@ -1550,6 +1588,8 @@ bool GdbEngine::startDebugger()
sendCommand("set unwindonsignal on"); sendCommand("set unwindonsignal on");
sendCommand("pwd", GdbQueryPwd); sendCommand("pwd", GdbQueryPwd);
sendCommand("set width 0");
sendCommand("set height 0");
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
sendCommand("-gdb-set inferior-auto-start-cfm off"); sendCommand("-gdb-set inferior-auto-start-cfm off");
@@ -1579,7 +1619,10 @@ bool GdbEngine::startDebugger()
} }
} }
if (q->startMode() == q->startInternal) { if (q->startMode() == DebuggerManager::AttachExternal) {
sendCommand("attach " + QString::number(q->m_attachedPID));
} else {
// StartInternal or StartExternal
emit gdbInputAvailable(QString(), QString()); emit gdbInputAvailable(QString(), QString());
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols); sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
//sendCommand("file " + fileName, GdbFileExecAndSymbols); //sendCommand("file " + fileName, GdbFileExecAndSymbols);
@@ -1593,24 +1636,8 @@ bool GdbEngine::startDebugger()
sendCommand("x/2i " + startSymbolName(), GdbStart); sendCommand("x/2i " + startSymbolName(), GdbStart);
} }
if (q->startMode() == q->attachExternal) {
sendCommand("attach " + QString::number(q->m_attachedPID));
}
if (q->startMode() == q->startExternal) {
//sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
sendCommand("file " + fileName, GdbFileExecAndSymbols);
#ifdef Q_OS_MAC
sendCommand("sharedlibrary apply-load-rules all");
#endif
//sendCommand("-file-list-exec-source-files", GdbQuerySources);
//sendCommand("-gdb-set stop-on-solib-events 1");
}
sendCommand("-data-list-register-names", RegisterListNames);
// set all to "pending" // set all to "pending"
if (q->startMode() == q->attachExternal) if (q->startMode() == DebuggerManager::AttachExternal)
qq->breakHandler()->removeAllBreakpoints(); qq->breakHandler()->removeAllBreakpoints();
else else
qq->breakHandler()->setAllPending(); qq->breakHandler()->setAllPending();
@@ -1622,8 +1649,8 @@ void GdbEngine::continueInferior()
{ {
q->resetLocation(); q->resetLocation();
setTokenBarrier(); setTokenBarrier();
qq->notifyInferiorRunningRequested();
emit gdbInputAvailable(QString(), QString()); emit gdbInputAvailable(QString(), QString());
qq->notifyInferiorRunningRequested();
sendCommand("-exec-continue", GdbExecContinue); sendCommand("-exec-continue", GdbExecContinue);
} }
@@ -1636,24 +1663,24 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
QString msg = response.data.findChild("consolestreamoutput").data(); QString msg = response.data.findChild("consolestreamoutput").data();
QRegExp needle("0x([0-9a-f]+) <" + startSymbolName() + "\\+.*>:"); QRegExp needle("0x([0-9a-f]+) <" + startSymbolName() + "\\+.*>:");
if (needle.indexIn(msg) != -1) { if (needle.indexIn(msg) != -1) {
//qDebug() << "STREAM: " << msg << needle.cap(1); //debugMessage("STREAM: " + msg + " " + needle.cap(1));
sendCommand("tbreak *0x" + needle.cap(1)); sendCommand("tbreak *0x" + needle.cap(1));
m_waitingForFirstBreakpointToBeHit = true; m_waitingForFirstBreakpointToBeHit = true;
sendCommand("-exec-run");
qq->notifyInferiorRunningRequested(); qq->notifyInferiorRunningRequested();
sendCommand("-exec-run");
} else { } else {
qDebug() << "PARSING START ADDRESS FAILED" << msg; debugMessage("PARSING START ADDRESS FAILED: " + msg);
} }
} else if (response.resultClass == GdbResultError) { } else if (response.resultClass == GdbResultError) {
qDebug() << "PARSING START ADDRESS FAILED" << response.toString(); debugMessage("PARSING START ADDRESS FAILED: " + response.toString());
} }
} }
void GdbEngine::stepExec() void GdbEngine::stepExec()
{ {
setTokenBarrier(); setTokenBarrier();
qq->notifyInferiorRunningRequested();
emit gdbInputAvailable(QString(), QString()); emit gdbInputAvailable(QString(), QString());
qq->notifyInferiorRunningRequested();
sendCommand("-exec-step", GdbExecStep); sendCommand("-exec-step", GdbExecStep);
} }
@@ -1674,8 +1701,8 @@ void GdbEngine::stepOutExec()
void GdbEngine::nextExec() void GdbEngine::nextExec()
{ {
setTokenBarrier(); setTokenBarrier();
qq->notifyInferiorRunningRequested();
emit gdbInputAvailable(QString(), QString()); emit gdbInputAvailable(QString(), QString());
qq->notifyInferiorRunningRequested();
sendCommand("-exec-next", GdbExecNext); sendCommand("-exec-next", GdbExecNext);
} }
@@ -1740,12 +1767,12 @@ void GdbEngine::setTokenBarrier()
void GdbEngine::setDebugDumpers(bool on) void GdbEngine::setDebugDumpers(bool on)
{ {
if (on) { if (on) {
qDebug() << "SWITCHING ON DUMPER DEBUGGING"; debugMessage("SWITCHING ON DUMPER DEBUGGING");
sendCommand("set unwindonsignal off"); sendCommand("set unwindonsignal off");
q->breakByFunction("qDumpObjectData440"); q->breakByFunction("qDumpObjectData440");
//updateLocals(); //updateLocals();
} else { } else {
qDebug() << "SWITCHING OFF DUMPER DEBUGGING"; debugMessage("SWITCHING OFF DUMPER DEBUGGING");
sendCommand("set unwindonsignal on"); sendCommand("set unwindonsignal on");
} }
} }
@@ -1868,8 +1895,8 @@ void GdbEngine::sendInsertBreakpoint(int index)
// cmd += "-c " + data->condition + " "; // cmd += "-c " + data->condition + " ";
cmd += where; cmd += where;
#endif #endif
sendCommand(cmd, BreakInsert, index, true); debugMessage(QString("Current state: %1").arg(q->status()));
//processQueueAndContinue(); sendCommand(cmd, BreakInsert, index, NeedsStop);
} }
void GdbEngine::handleBreakList(const GdbResultRecord &record) void GdbEngine::handleBreakList(const GdbResultRecord &record)
@@ -2106,10 +2133,11 @@ void GdbEngine::attemptBreakpointSynchronization()
foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) { foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) {
QString bpNumber = data->bpNumber; QString bpNumber = data->bpNumber;
debugMessage(QString("DELETING BP %1 IN %2").arg(bpNumber)
.arg(data->markerFileName));
if (!bpNumber.trimmed().isEmpty()) if (!bpNumber.trimmed().isEmpty())
sendCommand("-break-delete " + bpNumber, BreakDelete, 0, true); sendCommand("-break-delete " + bpNumber, BreakDelete, QVariant(),
//else NeedsStop);
// qDebug() << "BP HAS NO NUMBER: " << data->markerFileName;
delete data; delete data;
} }

View File

@@ -158,12 +158,15 @@ private:
// queue". resultNeeded == true increments m_pendingResults on // queue". resultNeeded == true increments m_pendingResults on
// send and decrements on receipt, effectively preventing // send and decrements on receipt, effectively preventing
// watch model updates before everything is finished. // watch model updates before everything is finished.
enum StopNeeded { DoesNotNeedStop, NeedsStop };
enum Synchronization { NotSynchronized, Synchronized };
void sendCommand(const QString &command, void sendCommand(const QString &command,
int type = 0, const QVariant &cookie = QVariant(), int type = 0, const QVariant &cookie = QVariant(),
bool needStop = false, bool synchronized = false); StopNeeded needStop = DoesNotNeedStop,
Synchronization synchronized = NotSynchronized);
void sendSynchronizedCommand(const QString & command, void sendSynchronizedCommand(const QString & command,
int type = 0, const QVariant &cookie = QVariant(), int type = 0, const QVariant &cookie = QVariant(),
bool needStop = false); StopNeeded needStop = DoesNotNeedStop);
void setTokenBarrier(); void setTokenBarrier();
@@ -193,6 +196,7 @@ private:
void handleShowVersion(const GdbResultRecord &response); void handleShowVersion(const GdbResultRecord &response);
void handleQueryPwd(const GdbResultRecord &response); void handleQueryPwd(const GdbResultRecord &response);
void handleQuerySources(const GdbResultRecord &response); void handleQuerySources(const GdbResultRecord &response);
void debugMessage(const QString &msg);
OutputCollector m_outputCollector; OutputCollector m_outputCollector;
QTextCodec *m_outputCodec; QTextCodec *m_outputCodec;
@@ -334,6 +338,8 @@ private:
bool m_waitingForFirstBreakpointToBeHit; bool m_waitingForFirstBreakpointToBeHit;
bool m_modulesListOutdated; bool m_modulesListOutdated;
QList<GdbCookie> m_commandsToRunOnTemporaryBreak;
DebuggerManager *q; DebuggerManager *q;
IDebuggerManagerAccessForEngines *qq; IDebuggerManagerAccessForEngines *qq;
}; };

View File

@@ -33,11 +33,11 @@
#include "buildparserfactory.h" #include "buildparserfactory.h"
#include "qt4projectmanagerconstants.h" #include "projectexplorerconstants.h"
#include "gccparser.h" #include "gccparser.h"
#include "msvcparser.h" #include "msvcparser.h"
using namespace Qt4ProjectManager::Internal; using namespace ProjectExplorer::Internal;
GccParserFactory::~GccParserFactory() GccParserFactory::~GccParserFactory()
{ {

View File

@@ -36,14 +36,14 @@
#include <projectexplorer/buildparserinterface.h> #include <projectexplorer/buildparserinterface.h>
namespace Qt4ProjectManager { namespace ProjectExplorer {
namespace Internal { namespace Internal {
class GccParserFactory : public ProjectExplorer::IBuildParserFactory class GccParserFactory : public ProjectExplorer::IBuildParserFactory
{ {
Q_OBJECT Q_OBJECT
public: public:
GccParserFactory() {}; GccParserFactory() {}
virtual ~GccParserFactory(); virtual ~GccParserFactory();
virtual bool canCreate(const QString & name) const; virtual bool canCreate(const QString & name) const;
virtual ProjectExplorer::BuildParserInterface * create(const QString & name) const; virtual ProjectExplorer::BuildParserInterface * create(const QString & name) const;
@@ -53,13 +53,13 @@ class MsvcParserFactory : public ProjectExplorer::IBuildParserFactory
{ {
Q_OBJECT Q_OBJECT
public: public:
MsvcParserFactory() {}; MsvcParserFactory() {}
virtual ~MsvcParserFactory(); virtual ~MsvcParserFactory();
virtual bool canCreate(const QString & name) const; virtual bool canCreate(const QString & name) const;
virtual ProjectExplorer::BuildParserInterface * create(const QString & name) const; virtual ProjectExplorer::BuildParserInterface * create(const QString & name) const;
}; };
} // namespace Internal } // namespace Internal
} // namespace Qt4ProjectManager } // namespace ProjectExplorer
#endif // BUILDPARSERFACTORY_H #endif // BUILDPARSERFACTORY_H

View File

@@ -32,11 +32,11 @@
***************************************************************************/ ***************************************************************************/
#include "gccparser.h" #include "gccparser.h"
#include "qt4projectmanagerconstants.h" #include "projectexplorerconstants.h"
#include <QDebug> #include <QDebug>
using namespace Qt4ProjectManager; using namespace ProjectExplorer;
GccParser::GccParser() GccParser::GccParser()
{ {
@@ -56,7 +56,7 @@ GccParser::GccParser()
QString GccParser::name() const QString GccParser::name() const
{ {
return QLatin1String(Qt4ProjectManager::Constants::BUILD_PARSER_GCC); return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC);
} }
void GccParser::stdOutput(const QString & line) void GccParser::stdOutput(const QString & line)

View File

@@ -34,11 +34,11 @@
#ifndef GCCPARSER_H #ifndef GCCPARSER_H
#define GCCPARSER_H #define GCCPARSER_H
#include <projectexplorer/buildparserinterface.h> #include "buildparserinterface.h"
#include <QtCore/QRegExp> #include <QtCore/QRegExp>
namespace Qt4ProjectManager { namespace ProjectExplorer {
class GccParser : public ProjectExplorer::BuildParserInterface class GccParser : public ProjectExplorer::BuildParserInterface
{ {

View File

@@ -32,11 +32,11 @@
***************************************************************************/ ***************************************************************************/
#include "msvcparser.h" #include "msvcparser.h"
#include "qt4projectmanagerconstants.h" #include "projectexplorerconstants.h"
#include <QtCore/QStringList> #include <QtCore/QStringList>
using namespace Qt4ProjectManager; using namespace ProjectExplorer;
MsvcParser::MsvcParser() MsvcParser::MsvcParser()
{ {
@@ -48,7 +48,7 @@ MsvcParser::MsvcParser()
QString MsvcParser::name() const QString MsvcParser::name() const
{ {
return QLatin1String(Qt4ProjectManager::Constants::BUILD_PARSER_MSVC); return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_MSVC);
} }
void MsvcParser::stdError(const QString & line) void MsvcParser::stdError(const QString & line)

View File

@@ -34,11 +34,11 @@
#ifndef MSVCPARSER_H #ifndef MSVCPARSER_H
#define MSVCPARSER_H #define MSVCPARSER_H
#include <projectexplorer/buildparserinterface.h> #include "buildparserinterface.h"
#include <QtCore/QRegExp> #include <QtCore/QRegExp>
namespace Qt4ProjectManager { namespace ProjectExplorer {
class MsvcParser : public ProjectExplorer::BuildParserInterface class MsvcParser : public ProjectExplorer::BuildParserInterface
{ {

View File

@@ -59,6 +59,7 @@
#include "scriptwrappers.h" #include "scriptwrappers.h"
#include "session.h" #include "session.h"
#include "sessiondialog.h" #include "sessiondialog.h"
#include "buildparserfactory.h"
#include <coreplugin/basemode.h> #include <coreplugin/basemode.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
@@ -233,6 +234,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
addAutoReleasedObject(new ProjectFileWizardExtension); addAutoReleasedObject(new ProjectFileWizardExtension);
// Build parsers
addAutoReleasedObject(new GccParserFactory);
addAutoReleasedObject(new MsvcParserFactory);
// context menus // context menus
Core::ActionContainer *msessionContextMenu = Core::ActionContainer *msessionContextMenu =
am->createMenu(Constants::M_SESSIONCONTEXT); am->createMenu(Constants::M_SESSIONCONTEXT);

View File

@@ -54,7 +54,10 @@ HEADERS += projectexplorer.h \
projectmodels.h \ projectmodels.h \
currentprojectfind.h \ currentprojectfind.h \
toolchain.h \ toolchain.h \
cesdkhandler.h cesdkhandler.h\
buildparserfactory.h\
gccparser.h\
msvcparser.h
SOURCES += projectexplorer.cpp \ SOURCES += projectexplorer.cpp \
projectwindow.cpp \ projectwindow.cpp \
buildmanager.cpp \ buildmanager.cpp \
@@ -97,7 +100,10 @@ SOURCES += projectexplorer.cpp \
projectmodels.cpp \ projectmodels.cpp \
currentprojectfind.cpp \ currentprojectfind.cpp \
toolchain.cpp \ toolchain.cpp \
cesdkhandler.cpp cesdkhandler.cpp\
buildparserfactory.cpp \
gccparser.cpp\
msvcparser.cpp
FORMS += dependenciespanel.ui \ FORMS += dependenciespanel.ui \
buildsettingspropertiespage.ui \ buildsettingspropertiespage.ui \
processstep.ui \ processstep.ui \

View File

@@ -176,6 +176,11 @@ const char * const CPP_HEADER_MIMETYPE = "text/x-c++hdr";
const char * const FORM_MIMETYPE = "application/x-designer"; const char * const FORM_MIMETYPE = "application/x-designer";
const char * const RESOURCE_MIMETYPE = "application/vnd.nokia.xml.qt.resource"; const char * const RESOURCE_MIMETYPE = "application/vnd.nokia.xml.qt.resource";
// build parsers
const char * const BUILD_PARSER_MSVC = "BuildParser.MSVC";
const char * const BUILD_PARSER_GCC = "BuildParser.Gcc";
} // namespace Constants } // namespace Constants
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -36,6 +36,8 @@
#include "qt4project.h" #include "qt4project.h"
#include "qt4projectmanagerconstants.h" #include "qt4projectmanagerconstants.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -71,9 +73,9 @@ ProjectExplorer::BuildParserInterface *MakeStep::buildParser(const QtVersion * c
QString buildParser; QString buildParser;
ProjectExplorer::ToolChain::ToolChainType type = version->toolchainType(); ProjectExplorer::ToolChain::ToolChainType type = version->toolchainType();
if ( type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE) if ( type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE)
buildParser = Constants::BUILD_PARSER_MSVC; buildParser = ProjectExplorer::Constants::BUILD_PARSER_MSVC;
else else
buildParser = Constants::BUILD_PARSER_GCC; buildParser = ProjectExplorer::Constants::BUILD_PARSER_GCC;
QList<IBuildParserFactory *> buildParserFactories = QList<IBuildParserFactory *> buildParserFactories =
ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>(); ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();

View File

@@ -28,9 +28,6 @@ HEADERS = qt4projectmanagerplugin.h \
makestep.h \ makestep.h \
qmakestep.h \ qmakestep.h \
qmakebuildstepfactory.h \ qmakebuildstepfactory.h \
gccparser.h \
msvcparser.h \
buildparserfactory.h \
deployhelper.h \ deployhelper.h \
embeddedpropertiespage.h \ embeddedpropertiespage.h \
qt4runconfiguration.h \ qt4runconfiguration.h \
@@ -63,9 +60,6 @@ SOURCES = qt4projectmanagerplugin.cpp \
makestep.cpp \ makestep.cpp \
qmakestep.cpp \ qmakestep.cpp \
qmakebuildstepfactory.cpp \ qmakebuildstepfactory.cpp \
gccparser.cpp \
msvcparser.cpp \
buildparserfactory.cpp \
deployhelper.cpp \ deployhelper.cpp \
embeddedpropertiespage.cpp \ embeddedpropertiespage.cpp \
qt4runconfiguration.cpp \ qt4runconfiguration.cpp \

View File

@@ -79,10 +79,6 @@ const char * const GDBMACROSBUILDSTEP = "trolltech.qt4projectmanager.gdbmaros";
const char * const QT4RUNSTEP = "trolltech.qt4projectmanager.qt4runstep"; const char * const QT4RUNSTEP = "trolltech.qt4projectmanager.qt4runstep";
const char * const DEPLOYHELPERRUNSTEP = "trolltech.qt4projectmanager.deployhelperrunstep"; const char * const DEPLOYHELPERRUNSTEP = "trolltech.qt4projectmanager.deployhelperrunstep";
// build parsers
const char * const BUILD_PARSER_MSVC = "BuildParser.MSVC";
const char * const BUILD_PARSER_GCC = "BuildParser.Gcc";
// views // views
const char * const VIEW_DETAILED = "Qt4.View.Detailed"; const char * const VIEW_DETAILED = "Qt4.View.Detailed";
const char * const VIEW_PROFILESONLY = "Qt4.View.ProjectHierarchy"; const char * const VIEW_PROFILESONLY = "Qt4.View.ProjectHierarchy";

View File

@@ -41,7 +41,6 @@
#include "qt4projectmanagerconstants.h" #include "qt4projectmanagerconstants.h"
#include "qt4project.h" #include "qt4project.h"
#include "qmakebuildstepfactory.h" #include "qmakebuildstepfactory.h"
#include "buildparserfactory.h"
#include "qtversionmanager.h" #include "qtversionmanager.h"
#include "embeddedpropertiespage.h" #include "embeddedpropertiespage.h"
#include "qt4runconfiguration.h" #include "qt4runconfiguration.h"
@@ -133,9 +132,6 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString *
addAutoReleasedObject(new MakeBuildStepFactory); addAutoReleasedObject(new MakeBuildStepFactory);
addAutoReleasedObject(new GdbMacrosBuildStepFactory); addAutoReleasedObject(new GdbMacrosBuildStepFactory);
addAutoReleasedObject(new GccParserFactory);
addAutoReleasedObject(new MsvcParserFactory);
m_qtVersionManager = new QtVersionManager; m_qtVersionManager = new QtVersionManager;
addObject(m_qtVersionManager); addObject(m_qtVersionManager);

View File

@@ -1178,7 +1178,7 @@ unsigned DeclaratorListAST::lastToken() const
{ {
for (const DeclaratorListAST *it = this; it; it = it->next) { for (const DeclaratorListAST *it = this; it; it = it->next) {
if (! it->next) if (! it->next)
return it->lastToken(); return it->declarator->lastToken();
} }
return 0; return 0;
} }

View File

@@ -132,6 +132,7 @@ class BaseClass;
class Block; class Block;
class Class; class Class;
class Enum; class Enum;
class ForwardClassDeclaration;
class Use; class Use;

View File

@@ -136,6 +136,23 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
} }
} }
if (! ast->declarators && ast->decl_specifier_seq && ! ast->decl_specifier_seq->next) {
if (ElaboratedTypeSpecifierAST *elab_type_spec = ast->decl_specifier_seq->asElaboratedTypeSpecifier()) {
Name *name = semantic()->check(elab_type_spec->name, _scope);
ForwardClassDeclaration *symbol =
control()->newForwardClassDeclaration(elab_type_spec->firstToken(),
name);
if (_templateParameters) {
symbol->setTemplateParameters(_templateParameters);
_templateParameters = 0;
}
_scope->enterSymbol(symbol);
return false;
}
}
List<Declaration *> **decl_it = &ast->symbols; List<Declaration *> **decl_it = &ast->symbols;
for (DeclaratorListAST *it = ast->declarators; it; it = it->next) { for (DeclaratorListAST *it = ast->declarators; it; it = it->next) {
Name *name = 0; Name *name = 0;

View File

@@ -124,6 +124,7 @@ public:
delete_array_entries(usingNamespaceDirectives); delete_array_entries(usingNamespaceDirectives);
delete_array_entries(enums); delete_array_entries(enums);
delete_array_entries(usingDeclarations); delete_array_entries(usingDeclarations);
delete_array_entries(classForwardDeclarations);
} }
NameId *findOrInsertNameId(Identifier *id) NameId *findOrInsertNameId(Identifier *id)
@@ -322,6 +323,14 @@ public:
return u; return u;
} }
ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, Name *name)
{
ForwardClassDeclaration *c = new ForwardClassDeclaration(translationUnit,
sourceLocation, name);
classForwardDeclarations.push_back(c);
return c;
}
Enum *newEnum(unsigned sourceLocation, Name *name) Enum *newEnum(unsigned sourceLocation, Name *name)
{ {
Enum *e = new Enum(translationUnit, Enum *e = new Enum(translationUnit,
@@ -477,6 +486,7 @@ public:
std::vector<UsingNamespaceDirective *> usingNamespaceDirectives; std::vector<UsingNamespaceDirective *> usingNamespaceDirectives;
std::vector<Enum *> enums; std::vector<Enum *> enums;
std::vector<UsingDeclaration *> usingDeclarations; std::vector<UsingDeclaration *> usingDeclarations;
std::vector<ForwardClassDeclaration *> classForwardDeclarations;
}; };
Control::Control() Control::Control()
@@ -632,4 +642,9 @@ UsingNamespaceDirective *Control::newUsingNamespaceDirective(unsigned sourceLoca
UsingDeclaration *Control::newUsingDeclaration(unsigned sourceLocation, Name *name) UsingDeclaration *Control::newUsingDeclaration(unsigned sourceLocation, Name *name)
{ return d->newUsingDeclaration(sourceLocation, name); } { return d->newUsingDeclaration(sourceLocation, name); }
ForwardClassDeclaration *Control::newForwardClassDeclaration(unsigned sourceLocation,
Name *name)
{ return d->newForwardClassDeclaration(sourceLocation, name); }
CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_NAMESPACE

View File

@@ -148,6 +148,9 @@ public:
/// Creates a new UsingDeclaration symbol. /// Creates a new UsingDeclaration symbol.
UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, Name *name = 0); UsingDeclaration *newUsingDeclaration(unsigned sourceLocation, Name *name = 0);
/// Creates a new ForwardClassDeclaration symbol.
ForwardClassDeclaration *newForwardClassDeclaration(unsigned sourceLocation, Name *name = 0);
Identifier *findOrInsertIdentifier(const char *chars, unsigned size); Identifier *findOrInsertIdentifier(const char *chars, unsigned size);
Identifier *findOrInsertIdentifier(const char *chars); Identifier *findOrInsertIdentifier(const char *chars);

View File

@@ -334,6 +334,9 @@ bool Symbol::isNamespace() const
bool Symbol::isClass() const bool Symbol::isClass() const
{ return asClass() != 0; } { return asClass() != 0; }
bool Symbol::isForwardClassDeclaration() const
{ return asForwardClassDeclaration() != 0; }
bool Symbol::isBlock() const bool Symbol::isBlock() const
{ return asBlock() != 0; } { return asBlock() != 0; }

View File

@@ -197,6 +197,9 @@ public:
/// Returns true if this Symbol is a BaseClass. /// Returns true if this Symbol is a BaseClass.
bool isBaseClass() const; bool isBaseClass() const;
/// Returns true if this Symbol is a ForwardClassDeclaration.
bool isForwardClassDeclaration() const;
virtual const ScopedSymbol *asScopedSymbol() const { return 0; } virtual const ScopedSymbol *asScopedSymbol() const { return 0; }
virtual const Enum *asEnum() const { return 0; } virtual const Enum *asEnum() const { return 0; }
virtual const Function *asFunction() const { return 0; } virtual const Function *asFunction() const { return 0; }
@@ -208,6 +211,7 @@ public:
virtual const Declaration *asDeclaration() const { return 0; } virtual const Declaration *asDeclaration() const { return 0; }
virtual const Argument *asArgument() const { return 0; } virtual const Argument *asArgument() const { return 0; }
virtual const BaseClass *asBaseClass() const { return 0; } virtual const BaseClass *asBaseClass() const { return 0; }
virtual const ForwardClassDeclaration *asForwardClassDeclaration() const { return 0; }
virtual ScopedSymbol *asScopedSymbol() { return 0; } virtual ScopedSymbol *asScopedSymbol() { return 0; }
virtual Enum *asEnum() { return 0; } virtual Enum *asEnum() { return 0; }
@@ -220,6 +224,7 @@ public:
virtual Declaration *asDeclaration() { return 0; } virtual Declaration *asDeclaration() { return 0; }
virtual Argument *asArgument() { return 0; } virtual Argument *asArgument() { return 0; }
virtual BaseClass *asBaseClass() { return 0; } virtual BaseClass *asBaseClass() { return 0; }
virtual ForwardClassDeclaration *asForwardClassDeclaration() { return 0; }
/// Returns this Symbol's type. /// Returns this Symbol's type.
virtual FullySpecifiedType type() const = 0; virtual FullySpecifiedType type() const = 0;

View File

@@ -82,6 +82,7 @@ public:
virtual bool visit(Namespace *) { return true; } virtual bool visit(Namespace *) { return true; }
virtual bool visit(Class *) { return true; } virtual bool visit(Class *) { return true; }
virtual bool visit(Block *) { return true; } virtual bool visit(Block *) { return true; }
virtual bool visit(ForwardClassDeclaration *) { return true; }
}; };
CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_NAMESPACE

View File

@@ -401,6 +401,53 @@ void BaseClass::setVirtual(bool isVirtual)
void BaseClass::visitSymbol0(SymbolVisitor *visitor) void BaseClass::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); } { visitor->visit(this); }
ForwardClassDeclaration::ForwardClassDeclaration(TranslationUnit *translationUnit,
unsigned sourceLocation, Name *name)
: Symbol(translationUnit, sourceLocation, name),
_templateParameters(0)
{ }
ForwardClassDeclaration::~ForwardClassDeclaration()
{ delete _templateParameters; }
unsigned ForwardClassDeclaration::templateParameterCount() const
{
if (! _templateParameters)
return 0;
return _templateParameters->symbolCount();
}
Symbol *ForwardClassDeclaration::templateParameterAt(unsigned index) const
{ return _templateParameters->symbolAt(index); }
Scope *ForwardClassDeclaration::templateParameters() const
{ return _templateParameters; }
void ForwardClassDeclaration::setTemplateParameters(Scope *templateParameters)
{ _templateParameters = templateParameters; }
FullySpecifiedType ForwardClassDeclaration::type() const
{ return FullySpecifiedType(const_cast<ForwardClassDeclaration *>(this)); }
bool ForwardClassDeclaration::isEqualTo(const Type *other) const
{
if (const ForwardClassDeclaration *otherClassFwdTy = other->asForwardClassDeclarationType()) {
if (name() == otherClassFwdTy->name())
return true;
else if (name() && otherClassFwdTy->name())
return name()->isEqualTo(otherClassFwdTy->name());
return false;
}
return false;
}
void ForwardClassDeclaration::visitSymbol0(SymbolVisitor *visitor)
{ visitor->visit(this); }
void ForwardClassDeclaration::accept0(TypeVisitor *visitor)
{ visitor->visit(this); }
Class::Class(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name) Class::Class(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name)
: ScopedSymbol(translationUnit, sourceLocation, name), : ScopedSymbol(translationUnit, sourceLocation, name),
_key(ClassKey), _key(ClassKey),

View File

@@ -199,6 +199,42 @@ protected:
virtual void visitSymbol0(SymbolVisitor *visitor); virtual void visitSymbol0(SymbolVisitor *visitor);
}; };
class CPLUSPLUS_EXPORT ForwardClassDeclaration: public Symbol, public Type
{
public:
ForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, Name *name);
virtual ~ForwardClassDeclaration();
unsigned templateParameterCount() const;
Symbol *templateParameterAt(unsigned index) const;
Scope *templateParameters() const;
void setTemplateParameters(Scope *templateParameters);
virtual FullySpecifiedType type() const;
virtual bool isEqualTo(const Type *other) const;
virtual const ForwardClassDeclaration *asForwardClassDeclaration() const
{ return this; }
virtual ForwardClassDeclaration *asForwardClassDeclaration()
{ return this; }
virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const
{ return this; }
virtual ForwardClassDeclaration *asForwardClassDeclarationType()
{ return this; }
protected:
virtual void visitSymbol0(SymbolVisitor *visitor);
virtual void accept0(TypeVisitor *visitor);
private:
Scope *_templateParameters;
};
class CPLUSPLUS_EXPORT Enum: public ScopedSymbol, public Type class CPLUSPLUS_EXPORT Enum: public ScopedSymbol, public Type
{ {
public: public:
@@ -295,7 +331,6 @@ protected:
virtual void accept0(TypeVisitor *visitor); virtual void accept0(TypeVisitor *visitor);
private: private:
Name *_name;
Scope *_templateParameters; Scope *_templateParameters;
FullySpecifiedType _returnType; FullySpecifiedType _returnType;
union { union {

View File

@@ -102,6 +102,9 @@ bool Type::isClassType() const
bool Type::isEnumType() const bool Type::isEnumType() const
{ return asEnumType() != 0; } { return asEnumType() != 0; }
bool Type::isForwardClassDeclarationType() const
{ return asForwardClassDeclarationType() != 0; }
void Type::accept(TypeVisitor *visitor) void Type::accept(TypeVisitor *visitor)
{ {
if (visitor->preVisit(this)) if (visitor->preVisit(this))

View File

@@ -80,6 +80,7 @@ public:
bool isNamespaceType() const; bool isNamespaceType() const;
bool isClassType() const; bool isClassType() const;
bool isEnumType() const; bool isEnumType() const;
bool isForwardClassDeclarationType() const;
virtual const VoidType *asVoidType() const { return 0; } virtual const VoidType *asVoidType() const { return 0; }
virtual const IntegerType *asIntegerType() const { return 0; } virtual const IntegerType *asIntegerType() const { return 0; }
@@ -93,6 +94,7 @@ public:
virtual const Namespace *asNamespaceType() const { return 0; } virtual const Namespace *asNamespaceType() const { return 0; }
virtual const Class *asClassType() const { return 0; } virtual const Class *asClassType() const { return 0; }
virtual const Enum *asEnumType() const { return 0; } virtual const Enum *asEnumType() const { return 0; }
virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; }
virtual VoidType *asVoidType() { return 0; } virtual VoidType *asVoidType() { return 0; }
virtual IntegerType *asIntegerType() { return 0; } virtual IntegerType *asIntegerType() { return 0; }
@@ -106,6 +108,7 @@ public:
virtual Namespace *asNamespaceType() { return 0; } virtual Namespace *asNamespaceType() { return 0; }
virtual Class *asClassType() { return 0; } virtual Class *asClassType() { return 0; }
virtual Enum *asEnumType() { return 0; } virtual Enum *asEnumType() { return 0; }
virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; }
void accept(TypeVisitor *visitor); void accept(TypeVisitor *visitor);
static void accept(Type *type, TypeVisitor *visitor); static void accept(Type *type, TypeVisitor *visitor);

View File

@@ -84,6 +84,7 @@ public:
virtual void visit(Namespace *) {} virtual void visit(Namespace *) {}
virtual void visit(Class *) {} virtual void visit(Class *) {}
virtual void visit(Enum *) {} virtual void visit(Enum *) {}
virtual void visit(ForwardClassDeclaration *) {}
}; };
CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_NAMESPACE