forked from qt-creator/qt-creator
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
This commit is contained in:
@@ -100,7 +100,7 @@ QIcon Icons::iconForSymbol(const Symbol *symbol) const
|
||||
}
|
||||
} else if (symbol->isEnum()) {
|
||||
return _enumIcon;
|
||||
} else if (symbol->isClass()) {
|
||||
} else if (symbol->isClass() || symbol->isForwardClassDeclaration()) {
|
||||
return _classIcon;
|
||||
} else if (symbol->isNamespace()) {
|
||||
return _namespaceIcon;
|
||||
|
@@ -42,7 +42,8 @@ Overview::Overview()
|
||||
: _markArgument(0),
|
||||
_showArgumentNames(false),
|
||||
_showReturnTypes(false),
|
||||
_showFunctionSignatures(true)
|
||||
_showFunctionSignatures(true),
|
||||
_showFullyQualifiedNames(false)
|
||||
{ }
|
||||
|
||||
Overview::~Overview()
|
||||
@@ -88,6 +89,16 @@ void Overview::setShowFunctionSignatures(bool showFunctionSignatures)
|
||||
_showFunctionSignatures = showFunctionSignatures;
|
||||
}
|
||||
|
||||
bool Overview::showFullyQualifiedNames() const
|
||||
{
|
||||
return _showFullyQualifiedNames;
|
||||
}
|
||||
|
||||
void Overview::setShowFullyQualifiedNamed(bool showFullyQualifiedNames)
|
||||
{
|
||||
_showFullyQualifiedNames = showFullyQualifiedNames;
|
||||
}
|
||||
|
||||
QString Overview::prettyName(Name *name) const
|
||||
{
|
||||
NamePrettyPrinter pp(this);
|
||||
|
@@ -57,6 +57,9 @@ public:
|
||||
bool showFunctionSignatures() const;
|
||||
void setShowFunctionSignatures(bool showFunctionSignatures);
|
||||
|
||||
bool showFullyQualifiedNames() const;
|
||||
void setShowFullyQualifiedNamed(bool showFullyQualifiedNames);
|
||||
|
||||
// 1-based
|
||||
// ### rename
|
||||
unsigned markArgument() const;
|
||||
@@ -77,6 +80,7 @@ private:
|
||||
bool _showArgumentNames: 1;
|
||||
bool _showReturnTypes: 1;
|
||||
bool _showFunctionSignatures: 1;
|
||||
bool _showFullyQualifiedNames: 1;
|
||||
};
|
||||
|
||||
} // end of namespace CPlusPlus
|
||||
|
@@ -37,9 +37,41 @@
|
||||
#include <CoreTypes.h>
|
||||
#include <Symbols.h>
|
||||
#include <Scope.h>
|
||||
#include <QStringList>
|
||||
#include <QtDebug>
|
||||
|
||||
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)
|
||||
: _overview(overview),
|
||||
_name(0)
|
||||
@@ -150,16 +182,26 @@ void TypePrettyPrinter::visit(Namespace *type)
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
void TypePrettyPrinter::visit(Enum *type)
|
||||
{
|
||||
if (overview()->showFullyQualifiedNames())
|
||||
_text += fullyQualifiedName(type, overview());
|
||||
|
||||
else
|
||||
_text += overview()->prettyName(type->name());
|
||||
|
||||
applyPtrOperators();
|
||||
}
|
||||
|
||||
@@ -259,11 +301,14 @@ void TypePrettyPrinter::visit(Function *type)
|
||||
if (! _ptrOperators.isEmpty()) {
|
||||
out(QLatin1Char('('));
|
||||
applyPtrOperators(false);
|
||||
|
||||
if (! _name.isEmpty()) {
|
||||
_text += _name;
|
||||
_name.clear();
|
||||
}
|
||||
|
||||
out(QLatin1Char(')'));
|
||||
|
||||
} else if (! _name.isEmpty() && _overview->showFunctionSignatures()) {
|
||||
space();
|
||||
out(_name);
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include "cmakestep.h"
|
||||
#include "makestep.h"
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <cpptools/cppmodelmanagerinterface.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -103,7 +104,7 @@ void CMakeProject::parseCMakeLists()
|
||||
} else {
|
||||
// TODO hmm?
|
||||
}
|
||||
if (newToolChain == m_toolChain) {
|
||||
if (ProjectExplorer::ToolChain::equals(newToolChain, m_toolChain)) {
|
||||
delete newToolChain;
|
||||
newToolChain = 0;
|
||||
} 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 results;
|
||||
|
@@ -105,6 +105,7 @@ public:
|
||||
MakeStep *makeStep() const;
|
||||
CMakeStep *cmakeStep() const;
|
||||
QStringList targets() const;
|
||||
QString buildParser(const QString &buildConfiguration) const;
|
||||
|
||||
private:
|
||||
void parseCMakeLists();
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "makestep.h"
|
||||
#include "cmakeprojectconstants.h"
|
||||
#include "cmakeproject.h"
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <QtGui/QFormLayout>
|
||||
@@ -42,6 +43,11 @@
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QListWidget>
|
||||
|
||||
namespace {
|
||||
bool debug = false;
|
||||
}
|
||||
|
||||
|
||||
using namespace CMakeProjectManager;
|
||||
using namespace CMakeProjectManager::Internal;
|
||||
|
||||
@@ -52,10 +58,42 @@ MakeStep::MakeStep(CMakeProject *pro)
|
||||
|
||||
MakeStep::~MakeStep()
|
||||
{
|
||||
delete m_buildParser;
|
||||
m_buildParser = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
|
||||
setCommand(buildConfiguration, "make"); // TODO give full path here?
|
||||
@@ -89,6 +127,79 @@ bool MakeStep::immutable() const
|
||||
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
|
||||
{
|
||||
return m_pro;
|
||||
@@ -154,7 +265,6 @@ void MakeBuildStepConfigWidget::init(const QString &buildConfiguration)
|
||||
}
|
||||
// and connect again
|
||||
connect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
@@ -64,8 +64,17 @@ public:
|
||||
CMakeProject *project() const;
|
||||
bool buildsTarget(const QString &buildConfiguration, const QString &target) const;
|
||||
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:
|
||||
CMakeProject *m_pro;
|
||||
ProjectExplorer::BuildParserInterface *m_buildParser;
|
||||
QSet<QString> m_openDirectories;
|
||||
};
|
||||
|
||||
class MakeBuildStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include <CoreTypes.h>
|
||||
#include <FullySpecifiedType.h>
|
||||
#include <Literals.h>
|
||||
#include <Control.h>
|
||||
#include <Names.h>
|
||||
#include <Scope.h>
|
||||
#include <Symbol.h>
|
||||
@@ -141,30 +142,13 @@ void CppHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint
|
||||
}
|
||||
}
|
||||
|
||||
static QString buildHelpId(const FullySpecifiedType &type,
|
||||
const Symbol *symbol)
|
||||
static QString buildHelpId(Symbol *symbol, Name *name)
|
||||
{
|
||||
Name *name = 0;
|
||||
Scope *scope = 0;
|
||||
|
||||
if (const Function *f = type->asFunctionType()) {
|
||||
name = f->name();
|
||||
scope = f->scope();
|
||||
} 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 (symbol) {
|
||||
scope = symbol->scope();
|
||||
name = symbol->name();
|
||||
}
|
||||
|
||||
if (! name)
|
||||
@@ -178,14 +162,18 @@ static QString buildHelpId(const FullySpecifiedType &type,
|
||||
qualifiedNames.prepend(overview.prettyName(name));
|
||||
|
||||
for (; scope; scope = scope->enclosingScope()) {
|
||||
if (scope->owner() && scope->owner()->name() && !scope->isEnumScope()) {
|
||||
Name *name = scope->owner()->name();
|
||||
Symbol *owner = scope->owner();
|
||||
|
||||
if (owner && owner->name() && ! scope->isEnumScope()) {
|
||||
Name *name = owner->name();
|
||||
Identifier *id = 0;
|
||||
if (NameId *nameId = name->asNameId()) {
|
||||
|
||||
if (NameId *nameId = name->asNameId())
|
||||
id = nameId->identifier();
|
||||
} else if (TemplateNameId *nameId = name->asTemplateNameId()) {
|
||||
|
||||
else if (TemplateNameId *nameId = name->asTemplateNameId())
|
||||
id = nameId->identifier();
|
||||
}
|
||||
|
||||
if (id)
|
||||
qualifiedNames.prepend(QString::fromLatin1(id->chars(), id->size()));
|
||||
}
|
||||
@@ -194,6 +182,70 @@ static QString buildHelpId(const FullySpecifiedType &type,
|
||||
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)
|
||||
{
|
||||
m_helpId.clear();
|
||||
@@ -262,26 +314,38 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
|
||||
typeOfExpression(expression, doc, lastSymbol);
|
||||
|
||||
if (!types.isEmpty()) {
|
||||
FullySpecifiedType firstType = types.first().first;
|
||||
Symbol *symbol = types.first().second;
|
||||
FullySpecifiedType docType = firstType;
|
||||
const TypeOfExpression::Result result = types.first();
|
||||
|
||||
if (const PointerType *pt = firstType->asPointerType()) {
|
||||
docType = pt->elementType();
|
||||
} else if (const ReferenceType *rt = firstType->asReferenceType()) {
|
||||
docType = rt->elementType();
|
||||
}
|
||||
FullySpecifiedType firstType = result.first; // result of `type of expression'.
|
||||
Symbol *lookupSymbol = result.second; // lookup symbol
|
||||
|
||||
m_helpId = buildHelpId(docType, symbol);
|
||||
QString displayName = buildHelpId(firstType, symbol);
|
||||
Symbol *resolvedSymbol = 0;
|
||||
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.setShowArgumentNames(true);
|
||||
overview.setShowReturnTypes(true);
|
||||
m_toolTip = overview.prettyType(firstType, displayName);
|
||||
} else {
|
||||
overview.setShowFullyQualifiedNamed(true);
|
||||
|
||||
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;
|
||||
|
||||
} else {
|
||||
m_toolTip = overview.prettyType(firstType, m_helpId);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -150,10 +150,9 @@ void DebuggerManager::init()
|
||||
{
|
||||
m_status = -1;
|
||||
m_busy = false;
|
||||
m_shutdown = false;
|
||||
|
||||
m_attachedPID = 0;
|
||||
m_startMode = startInternal;
|
||||
m_startMode = StartInternal;
|
||||
|
||||
m_disassemblerHandler = 0;
|
||||
m_modulesHandler = 0;
|
||||
@@ -544,6 +543,12 @@ void DebuggerManager::notifyStartupFinished()
|
||||
showStatusMessage(tr("Startup finished. Debugger ready."), -1);
|
||||
}
|
||||
|
||||
void DebuggerManager::notifyInferiorStopRequested()
|
||||
{
|
||||
setStatus(DebuggerInferiorStopRequested);
|
||||
showStatusMessage(tr("Stop requested..."), 5000);
|
||||
}
|
||||
|
||||
void DebuggerManager::notifyInferiorStopped()
|
||||
{
|
||||
resetLocation();
|
||||
@@ -578,7 +583,7 @@ void DebuggerManager::notifyInferiorExited()
|
||||
void DebuggerManager::notifyInferiorPidChanged(int pid)
|
||||
{
|
||||
//QMessageBox::warning(0, "PID", "PID: " + QString::number(pid));
|
||||
qDebug() << "PID: " << pid;
|
||||
//qDebug() << "PID: " << pid;
|
||||
emit inferiorPidChanged(pid);
|
||||
}
|
||||
|
||||
@@ -590,9 +595,10 @@ void DebuggerManager::showApplicationOutput(const QString &str)
|
||||
void DebuggerManager::shutdown()
|
||||
{
|
||||
//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 = 0;
|
||||
|
||||
delete scriptEngine;
|
||||
@@ -657,6 +663,12 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber)
|
||||
{
|
||||
QTC_ASSERT(m_engine, 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);
|
||||
if (index == -1)
|
||||
m_breakHandler->setBreakpoint(fileName, lineNumber);
|
||||
@@ -737,13 +749,13 @@ void DebuggerManager::setConfigValue(const QString &name, const QVariant &value)
|
||||
|
||||
void DebuggerManager::startExternalApplication()
|
||||
{
|
||||
if (!startNewDebugger(startExternal))
|
||||
if (!startNewDebugger(StartExternal))
|
||||
emit debuggingFinished();
|
||||
}
|
||||
|
||||
void DebuggerManager::attachExternalApplication()
|
||||
{
|
||||
if (!startNewDebugger(attachExternal))
|
||||
if (!startNewDebugger(AttachExternal))
|
||||
emit debuggingFinished();
|
||||
}
|
||||
|
||||
@@ -752,7 +764,7 @@ bool DebuggerManager::startNewDebugger(StartMode mode)
|
||||
m_startMode = mode;
|
||||
// FIXME: Clean up
|
||||
|
||||
if (startMode() == startExternal) {
|
||||
if (startMode() == StartExternal) {
|
||||
StartExternalDialog dlg(mainWindow());
|
||||
dlg.setExecutableFile(
|
||||
configValue(QLatin1String("LastExternalExecutableFile")).toString());
|
||||
@@ -768,7 +780,7 @@ bool DebuggerManager::startNewDebugger(StartMode mode)
|
||||
m_processArgs = dlg.executableArguments().split(' ');
|
||||
m_workingDir = QString();
|
||||
m_attachedPID = -1;
|
||||
} else if (startMode() == attachExternal) {
|
||||
} else if (startMode() == AttachExternal) {
|
||||
AttachExternalDialog dlg(mainWindow());
|
||||
if (dlg.exec() != QDialog::Accepted)
|
||||
return false;
|
||||
@@ -781,7 +793,7 @@ bool DebuggerManager::startNewDebugger(StartMode mode)
|
||||
tr("Cannot attach to PID 0"));
|
||||
return false;
|
||||
}
|
||||
} else if (startMode() == startInternal) {
|
||||
} else if (startMode() == StartInternal) {
|
||||
if (m_executable.isEmpty()) {
|
||||
QString startDirectory = m_executable;
|
||||
if (m_executable.isEmpty()) {
|
||||
@@ -835,9 +847,8 @@ void DebuggerManager::cleanupViews()
|
||||
|
||||
void DebuggerManager::exitDebugger()
|
||||
{
|
||||
if (m_shutdown)
|
||||
return;
|
||||
QTC_ASSERT(m_engine, return);
|
||||
//qDebug() << "DebuggerManager::exitDebugger";
|
||||
if (m_engine)
|
||||
m_engine->exitDebugger();
|
||||
cleanupViews();
|
||||
setStatus(DebuggerProcessNotReady);
|
||||
@@ -960,33 +971,6 @@ void DebuggerManager::dumpLog()
|
||||
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()
|
||||
{
|
||||
// requires a selection, but that's the only case we want...
|
||||
|
@@ -151,6 +151,7 @@ private:
|
||||
|
||||
// called from the engines after successful startup
|
||||
virtual void notifyStartupFinished() = 0;
|
||||
virtual void notifyInferiorStopRequested() = 0;
|
||||
virtual void notifyInferiorStopped() = 0;
|
||||
virtual void notifyInferiorUpdateFinished() = 0;
|
||||
virtual void notifyInferiorRunningRequested() = 0;
|
||||
@@ -229,7 +230,7 @@ public:
|
||||
QLabel *statusLabel() const { return m_statusLabel; }
|
||||
DebuggerSettings *settings() { return &m_settings; }
|
||||
|
||||
enum StartMode { startInternal, startExternal, attachExternal };
|
||||
enum StartMode { StartInternal, StartExternal, AttachExternal };
|
||||
enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger };
|
||||
|
||||
public slots:
|
||||
@@ -339,6 +340,7 @@ private:
|
||||
void notifyInferiorStopped();
|
||||
void notifyInferiorUpdateFinished();
|
||||
void notifyInferiorRunningRequested();
|
||||
void notifyInferiorStopRequested();
|
||||
void notifyInferiorRunning();
|
||||
void notifyInferiorExited();
|
||||
void notifyInferiorPidChanged(int);
|
||||
@@ -466,8 +468,6 @@ private:
|
||||
IDebuggerEngine *engine();
|
||||
IDebuggerEngine *m_engine;
|
||||
DebuggerSettings m_settings;
|
||||
// set during application shutdown
|
||||
bool m_shutdown;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -115,6 +115,8 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
|
||||
connect(m_manager, SIGNAL(inferiorPidChanged(qint64)),
|
||||
this, SLOT(bringApplicationToForeground(qint64)),
|
||||
Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(stopRequested()),
|
||||
m_manager, SLOT(exitDebugger()));
|
||||
}
|
||||
|
||||
void DebuggerRunControl::start()
|
||||
@@ -135,7 +137,7 @@ void DebuggerRunControl::start()
|
||||
//<daniel> andre: + "\qtc-gdbmacros\"
|
||||
|
||||
//emit addToOutputWindow(this, tr("Debugging %1").arg(m_executable));
|
||||
if (m_manager->startNewDebugger(DebuggerManager::startInternal))
|
||||
if (m_manager->startNewDebugger(DebuggerManager::StartInternal))
|
||||
emit started();
|
||||
else
|
||||
debuggingFinished();
|
||||
@@ -148,17 +150,21 @@ void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data)
|
||||
|
||||
void DebuggerRunControl::stop()
|
||||
{
|
||||
m_manager->exitDebugger();
|
||||
//qDebug() << "DebuggerRunControl::stop";
|
||||
m_running = false;
|
||||
emit stopRequested();
|
||||
}
|
||||
|
||||
void DebuggerRunControl::debuggingFinished()
|
||||
{
|
||||
m_running = false;
|
||||
//qDebug() << "DebuggerRunControl::finished";
|
||||
//emit addToOutputWindow(this, tr("Debugging %1 finished").arg(m_executable));
|
||||
emit finished();
|
||||
}
|
||||
|
||||
bool DebuggerRunControl::isRunning() const
|
||||
{
|
||||
//qDebug() << "DebuggerRunControl::isRunning" << m_running;
|
||||
return m_running;
|
||||
}
|
||||
|
@@ -82,6 +82,9 @@ public:
|
||||
virtual void stop();
|
||||
virtual bool isRunning() const;
|
||||
|
||||
signals:
|
||||
void stopRequested();
|
||||
|
||||
private slots:
|
||||
void debuggingFinished();
|
||||
void slotAddToOutputWindowInline(const QString &output);
|
||||
|
@@ -115,6 +115,7 @@ enum GdbCommandType
|
||||
GdbInfoThreads,
|
||||
GdbQueryDataDumper1,
|
||||
GdbQueryDataDumper2,
|
||||
GdbTemporaryContinue,
|
||||
|
||||
BreakCondition = 200,
|
||||
BreakEnablePending,
|
||||
@@ -257,6 +258,8 @@ GdbEngine::GdbEngine(DebuggerManager *parent)
|
||||
|
||||
GdbEngine::~GdbEngine()
|
||||
{
|
||||
// prevent sending error messages afterwards
|
||||
m_gdbProc.disconnect(this);
|
||||
}
|
||||
|
||||
void GdbEngine::initializeConnections()
|
||||
@@ -303,6 +306,7 @@ void GdbEngine::initializeVariables()
|
||||
m_pendingRequests = 0;
|
||||
m_waitingForBreakpointSynchronizationToContinue = false;
|
||||
m_waitingForFirstBreakpointToBeHit = false;
|
||||
m_commandsToRunOnTemporaryBreak.clear();
|
||||
}
|
||||
|
||||
void GdbEngine::gdbProcError(QProcess::ProcessError error)
|
||||
@@ -386,6 +390,11 @@ void GdbEngine::readDebugeeOutput(const QByteArray &data)
|
||||
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
|
||||
// gdbResponseAvailable()
|
||||
void GdbEngine::handleResponse()
|
||||
@@ -643,22 +652,29 @@ void GdbEngine::readGdbStandardOutput()
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (q->m_attachedPID > 0) {
|
||||
if (interruptProcess(q->m_attachedPID))
|
||||
qq->notifyInferiorStopped();
|
||||
if (!interruptProcess(q->m_attachedPID))
|
||||
// qq->notifyInferiorStopped();
|
||||
//else
|
||||
debugMessage(QString("CANNOT INTERRUPT %1").arg(q->m_attachedPID));
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
sendCommand("-exec-interrupt", GdbExecInterrupt);
|
||||
qq->notifyInferiorStopped();
|
||||
//qq->notifyInferiorStopped();
|
||||
#else
|
||||
qDebug() << "CANNOT STOP INFERIOR" << m_gdbProc.pid();
|
||||
if (interruptChildProcess(m_gdbProc.pid()))
|
||||
qq->notifyInferiorStopped();
|
||||
if (!interruptChildProcess(m_gdbProc.pid()))
|
||||
// qq->notifyInferiorStopped();
|
||||
//else
|
||||
debugMessage(QString("CANNOT STOP INFERIOR"));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -666,38 +682,30 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
|
||||
{
|
||||
int pid = pid0.toInt();
|
||||
if (pid == 0) {
|
||||
qDebug() << "Cannot parse PID from " << pid0;
|
||||
debugMessage(QString("Cannot parse PID from %1").arg(pid0));
|
||||
return;
|
||||
}
|
||||
if (pid == q->m_attachedPID)
|
||||
return;
|
||||
qDebug() << "FOUND PID " << pid;
|
||||
debugMessage(QString("FOUND PID %1").arg(pid));
|
||||
q->m_attachedPID = pid;
|
||||
qq->notifyInferiorPidChanged(pid);
|
||||
}
|
||||
|
||||
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,
|
||||
const QVariant &cookie, bool needStop, bool synchronized)
|
||||
const QVariant &cookie, StopNeeded needStop, Synchronization synchronized)
|
||||
{
|
||||
if (m_gdbProc.state() == QProcess::NotRunning) {
|
||||
//qDebug() << "NO GDB PROCESS RUNNING, CMD IGNORED:" << command;
|
||||
debugMessage("NO GDB PROCESS RUNNING, CMD IGNORED: " + command);
|
||||
return;
|
||||
}
|
||||
|
||||
bool temporarilyStopped = false;
|
||||
if (needStop && q->status() == DebuggerInferiorRunning) {
|
||||
q->showStatusMessage(tr("Temporarily stopped"));
|
||||
interruptInferior();
|
||||
temporarilyStopped = true;
|
||||
}
|
||||
|
||||
++currentToken();
|
||||
if (synchronized) {
|
||||
++m_pendingRequests;
|
||||
PENDING_DEBUG(" TYPE " << type << " INCREMENTS PENDING TO: "
|
||||
@@ -710,28 +718,30 @@ void GdbEngine::sendCommand(const QString &command, int type,
|
||||
GdbCookie cmd;
|
||||
cmd.synchronized = synchronized;
|
||||
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.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;
|
||||
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");
|
||||
//emit gdbInputAvailable(QString(), " " + currentTime());
|
||||
//emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
|
||||
emit gdbInputAvailable(QString(), cmd.command);
|
||||
}
|
||||
|
||||
if (temporarilyStopped)
|
||||
sendCommand("-exec-continue");
|
||||
|
||||
// slows down
|
||||
//qApp->processEvents();
|
||||
}
|
||||
|
||||
void GdbEngine::handleResultRecord(const GdbResultRecord &record)
|
||||
@@ -817,6 +827,7 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
||||
//handleExecRunToFunction(record);
|
||||
break;
|
||||
case GdbExecInterrupt:
|
||||
qq->notifyInferiorStopped();
|
||||
break;
|
||||
case GdbExecJumpToLine:
|
||||
handleExecJumpToLine(record);
|
||||
@@ -839,6 +850,10 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
||||
case GdbQueryDataDumper2:
|
||||
handleQueryDataDumper2(record);
|
||||
break;
|
||||
case GdbTemporaryContinue:
|
||||
continueInferior();
|
||||
q->showStatusMessage(tr("Continuing after temporary stop."));
|
||||
break;
|
||||
|
||||
case BreakList:
|
||||
handleBreakList(record);
|
||||
@@ -920,8 +935,8 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug() << "FIXME: GdbEngine::handleResult: "
|
||||
"should not happen" << type;
|
||||
debugMessage(QString("FIXME: GdbEngine::handleResult: "
|
||||
"should not happen %1").arg(type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -930,7 +945,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
|
||||
{
|
||||
//createGdbProcessIfNeeded();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -938,11 +953,6 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
|
||||
cmd.command = command;
|
||||
cmd.type = -1;
|
||||
|
||||
//m_cookieForToken[currentToken()] = cmd;
|
||||
//++currentToken();
|
||||
|
||||
//qDebug() << "";
|
||||
//qDebug() << currentTime() << "Running command: " << cmd.command;
|
||||
emit gdbInputAvailable(QString(), cmd.command);
|
||||
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 = m_pwd.trimmed();
|
||||
#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: startSymbolName == data.findChild("frame").findChild("func")
|
||||
if (m_waitingForFirstBreakpointToBeHit) {
|
||||
qq->notifyInferiorStopped();
|
||||
m_waitingForFirstBreakpointToBeHit = false;
|
||||
//
|
||||
// that's the "early stop"
|
||||
@@ -1143,11 +1154,28 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
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();
|
||||
if (msg.contains("Stopped due to shared library event") || reason.isEmpty()) {
|
||||
if (qq->wantsSelectedPluginBreakpoints()) {
|
||||
qDebug() << "SHARED LIBRARY EVENT " << data.toString();
|
||||
qDebug() << "PATTERN" << qq->selectedPluginBreakpointsPattern();
|
||||
debugMessage("SHARED LIBRARY EVENT: " + data.toString());
|
||||
debugMessage("PATTERN: " + qq->selectedPluginBreakpointsPattern());
|
||||
sendCommand("sharedlibrary " + qq->selectedPluginBreakpointsPattern());
|
||||
continueInferior();
|
||||
q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString())));
|
||||
@@ -1182,6 +1210,8 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
+ data.findChild("signal-name").toString();
|
||||
}
|
||||
q->showStatusMessage(msg);
|
||||
// FIXME: shouldn't this use a statis change?
|
||||
debugMessage("CALLING PARENT EXITDEBUGGER");
|
||||
q->exitDebugger();
|
||||
return;
|
||||
}
|
||||
@@ -1193,21 +1223,21 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
if (qq->skipKnownFrames()) {
|
||||
if (reason == "end-stepping-range" || reason == "function-finished") {
|
||||
GdbMi frame = data.findChild("frame");
|
||||
//qDebug() << frame.toString();
|
||||
//debugMessage(frame.toString());
|
||||
m_currentFrame = frame.findChild("addr").data() + '%' +
|
||||
frame.findChild("func").data() + '%';
|
||||
|
||||
QString funcName = frame.findChild("func").data();
|
||||
QString fileName = frame.findChild("file").data();
|
||||
if (isLeavableFunction(funcName, fileName)) {
|
||||
//qDebug() << "LEAVING" << funcName;
|
||||
//debugMessage("LEAVING" + funcName);
|
||||
++stepCounter;
|
||||
q->stepOutExec();
|
||||
//stepExec();
|
||||
return;
|
||||
}
|
||||
if (isSkippableFunction(funcName, fileName)) {
|
||||
//qDebug() << "SKIPPING" << funcName;
|
||||
//debugMessage("SKIPPING" + funcName);
|
||||
++stepCounter;
|
||||
q->stepExec();
|
||||
return;
|
||||
@@ -1227,7 +1257,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
if (reason == "breakpoint-hit") {
|
||||
q->showStatusMessage(tr("Stopped at breakpoint"));
|
||||
GdbMi frame = data.findChild("frame");
|
||||
//qDebug() << "HIT BREAKPOINT: " << frame.toString();
|
||||
//debugMessage("HIT BREAKPOINT: " + frame.toString());
|
||||
m_currentFrame = frame.findChild("addr").data() + '%' +
|
||||
frame.findChild("func").data() + '%';
|
||||
|
||||
@@ -1243,7 +1273,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
|
||||
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
|
||||
// JumpToLine or RunToFunction handlers
|
||||
#if 1
|
||||
@@ -1310,7 +1340,7 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
|
||||
QString msg = response.data.findChild("consolestreamoutput").data();
|
||||
QRegExp supported("GNU gdb(.*) (\\d+)\\.(\\d+)(\\.(\\d+))?");
|
||||
if (supported.indexIn(msg) == -1) {
|
||||
qDebug() << "UNSUPPORTED GDB VERSION " << msg;
|
||||
debugMessage("UNSUPPORTED GDB VERSION " + msg);
|
||||
QStringList list = msg.split("\n");
|
||||
while (list.size() > 2)
|
||||
list.removeLast();
|
||||
@@ -1331,7 +1361,7 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
|
||||
m_gdbVersion = 10000 * supported.cap(2).toInt()
|
||||
+ 100 * supported.cap(3).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())
|
||||
return QString();
|
||||
QString full = m_shortToFullName.value(fileName, QString());
|
||||
//qDebug() << "RESOLVING: " << fileName << full;
|
||||
//debugMessage("RESOLVING: " + fileName + " " + full);
|
||||
if (!full.isEmpty())
|
||||
return full;
|
||||
QFileInfo fi(fileName);
|
||||
@@ -1397,7 +1427,7 @@ QString GdbEngine::fullName(const QString &fileName)
|
||||
#ifdef Q_OS_WIN
|
||||
full = QDir::cleanPath(full);
|
||||
#endif
|
||||
//qDebug() << "STORING: " << fileName << full;
|
||||
//debugMessage("STORING: " + fileName + " " + full);
|
||||
m_shortToFullName[fileName] = full;
|
||||
m_fullToShortName[full] = fileName;
|
||||
return full;
|
||||
@@ -1425,22 +1455,29 @@ void GdbEngine::shutdown()
|
||||
|
||||
void GdbEngine::exitDebugger()
|
||||
{
|
||||
//qDebug() << "EXITING: " << m_gdbProc.state();
|
||||
if (m_gdbProc.state() == QProcess::Starting)
|
||||
debugMessage(QString("GDBENGINE EXITDEBUFFER: %1").arg(m_gdbProc.state()));
|
||||
if (m_gdbProc.state() == QProcess::Starting) {
|
||||
debugMessage(QString("WAITING FOR GDB STARTUP TO SHUTDOWN: %1")
|
||||
.arg(m_gdbProc.state()));
|
||||
m_gdbProc.waitForStarted();
|
||||
}
|
||||
if (m_gdbProc.state() == QProcess::Running) {
|
||||
debugMessage(QString("WAITING FOR RUNNING GDB TO SHUTDOWN: %1")
|
||||
.arg(m_gdbProc.state()));
|
||||
interruptInferior();
|
||||
sendCommand("kill");
|
||||
sendCommand("-gdb-exit");
|
||||
// 20s can easily happen when loading webkit debug information
|
||||
m_gdbProc.waitForFinished(20000);
|
||||
if (m_gdbProc.state() != QProcess::Running) {
|
||||
debugMessage(QString("FORCING TERMINATION: %1")
|
||||
.arg(m_gdbProc.state()));
|
||||
m_gdbProc.terminate();
|
||||
m_gdbProc.waitForFinished(20000);
|
||||
}
|
||||
}
|
||||
if (m_gdbProc.state() != QProcess::NotRunning)
|
||||
qDebug() << "PROBLEM STOPPING DEBUGGER";
|
||||
debugMessage("PROBLEM STOPPING DEBUGGER");
|
||||
|
||||
m_outputCollector.shutdown();
|
||||
initializeVariables();
|
||||
@@ -1462,7 +1499,7 @@ bool GdbEngine::startDebugger()
|
||||
QString fileName = '"' + fi.absoluteFilePath() + '"';
|
||||
|
||||
if (m_gdbProc.state() != QProcess::NotRunning) {
|
||||
qDebug() << "GDB IS ALREADY RUNNING!";
|
||||
debugMessage("GDB IS ALREADY RUNNING!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1525,6 +1562,7 @@ bool GdbEngine::startDebugger()
|
||||
//sendCommand("set pagination off");
|
||||
sendCommand("set breakpoint pending on", BreakEnablePending);
|
||||
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:
|
||||
// template <class T> T foo() { return T(0); }
|
||||
@@ -1550,6 +1588,8 @@ bool GdbEngine::startDebugger()
|
||||
|
||||
sendCommand("set unwindonsignal on");
|
||||
sendCommand("pwd", GdbQueryPwd);
|
||||
sendCommand("set width 0");
|
||||
sendCommand("set height 0");
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
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());
|
||||
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
|
||||
//sendCommand("file " + fileName, GdbFileExecAndSymbols);
|
||||
@@ -1593,24 +1636,8 @@ bool GdbEngine::startDebugger()
|
||||
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"
|
||||
if (q->startMode() == q->attachExternal)
|
||||
if (q->startMode() == DebuggerManager::AttachExternal)
|
||||
qq->breakHandler()->removeAllBreakpoints();
|
||||
else
|
||||
qq->breakHandler()->setAllPending();
|
||||
@@ -1622,8 +1649,8 @@ void GdbEngine::continueInferior()
|
||||
{
|
||||
q->resetLocation();
|
||||
setTokenBarrier();
|
||||
qq->notifyInferiorRunningRequested();
|
||||
emit gdbInputAvailable(QString(), QString());
|
||||
qq->notifyInferiorRunningRequested();
|
||||
sendCommand("-exec-continue", GdbExecContinue);
|
||||
}
|
||||
|
||||
@@ -1636,24 +1663,24 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
|
||||
QString msg = response.data.findChild("consolestreamoutput").data();
|
||||
QRegExp needle("0x([0-9a-f]+) <" + startSymbolName() + "\\+.*>:");
|
||||
if (needle.indexIn(msg) != -1) {
|
||||
//qDebug() << "STREAM: " << msg << needle.cap(1);
|
||||
//debugMessage("STREAM: " + msg + " " + needle.cap(1));
|
||||
sendCommand("tbreak *0x" + needle.cap(1));
|
||||
m_waitingForFirstBreakpointToBeHit = true;
|
||||
sendCommand("-exec-run");
|
||||
qq->notifyInferiorRunningRequested();
|
||||
sendCommand("-exec-run");
|
||||
} else {
|
||||
qDebug() << "PARSING START ADDRESS FAILED" << msg;
|
||||
debugMessage("PARSING START ADDRESS FAILED: " + msg);
|
||||
}
|
||||
} else if (response.resultClass == GdbResultError) {
|
||||
qDebug() << "PARSING START ADDRESS FAILED" << response.toString();
|
||||
debugMessage("PARSING START ADDRESS FAILED: " + response.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void GdbEngine::stepExec()
|
||||
{
|
||||
setTokenBarrier();
|
||||
qq->notifyInferiorRunningRequested();
|
||||
emit gdbInputAvailable(QString(), QString());
|
||||
qq->notifyInferiorRunningRequested();
|
||||
sendCommand("-exec-step", GdbExecStep);
|
||||
}
|
||||
|
||||
@@ -1674,8 +1701,8 @@ void GdbEngine::stepOutExec()
|
||||
void GdbEngine::nextExec()
|
||||
{
|
||||
setTokenBarrier();
|
||||
qq->notifyInferiorRunningRequested();
|
||||
emit gdbInputAvailable(QString(), QString());
|
||||
qq->notifyInferiorRunningRequested();
|
||||
sendCommand("-exec-next", GdbExecNext);
|
||||
}
|
||||
|
||||
@@ -1740,12 +1767,12 @@ void GdbEngine::setTokenBarrier()
|
||||
void GdbEngine::setDebugDumpers(bool on)
|
||||
{
|
||||
if (on) {
|
||||
qDebug() << "SWITCHING ON DUMPER DEBUGGING";
|
||||
debugMessage("SWITCHING ON DUMPER DEBUGGING");
|
||||
sendCommand("set unwindonsignal off");
|
||||
q->breakByFunction("qDumpObjectData440");
|
||||
//updateLocals();
|
||||
} else {
|
||||
qDebug() << "SWITCHING OFF DUMPER DEBUGGING";
|
||||
debugMessage("SWITCHING OFF DUMPER DEBUGGING");
|
||||
sendCommand("set unwindonsignal on");
|
||||
}
|
||||
}
|
||||
@@ -1868,8 +1895,8 @@ void GdbEngine::sendInsertBreakpoint(int index)
|
||||
// cmd += "-c " + data->condition + " ";
|
||||
cmd += where;
|
||||
#endif
|
||||
sendCommand(cmd, BreakInsert, index, true);
|
||||
//processQueueAndContinue();
|
||||
debugMessage(QString("Current state: %1").arg(q->status()));
|
||||
sendCommand(cmd, BreakInsert, index, NeedsStop);
|
||||
}
|
||||
|
||||
void GdbEngine::handleBreakList(const GdbResultRecord &record)
|
||||
@@ -2106,10 +2133,11 @@ void GdbEngine::attemptBreakpointSynchronization()
|
||||
|
||||
foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) {
|
||||
QString bpNumber = data->bpNumber;
|
||||
debugMessage(QString("DELETING BP %1 IN %2").arg(bpNumber)
|
||||
.arg(data->markerFileName));
|
||||
if (!bpNumber.trimmed().isEmpty())
|
||||
sendCommand("-break-delete " + bpNumber, BreakDelete, 0, true);
|
||||
//else
|
||||
// qDebug() << "BP HAS NO NUMBER: " << data->markerFileName;
|
||||
sendCommand("-break-delete " + bpNumber, BreakDelete, QVariant(),
|
||||
NeedsStop);
|
||||
delete data;
|
||||
}
|
||||
|
||||
|
@@ -158,12 +158,15 @@ private:
|
||||
// queue". resultNeeded == true increments m_pendingResults on
|
||||
// send and decrements on receipt, effectively preventing
|
||||
// watch model updates before everything is finished.
|
||||
void sendCommand(const QString & command,
|
||||
enum StopNeeded { DoesNotNeedStop, NeedsStop };
|
||||
enum Synchronization { NotSynchronized, Synchronized };
|
||||
void sendCommand(const QString &command,
|
||||
int type = 0, const QVariant &cookie = QVariant(),
|
||||
bool needStop = false, bool synchronized = false);
|
||||
StopNeeded needStop = DoesNotNeedStop,
|
||||
Synchronization synchronized = NotSynchronized);
|
||||
void sendSynchronizedCommand(const QString & command,
|
||||
int type = 0, const QVariant &cookie = QVariant(),
|
||||
bool needStop = false);
|
||||
StopNeeded needStop = DoesNotNeedStop);
|
||||
|
||||
void setTokenBarrier();
|
||||
|
||||
@@ -193,6 +196,7 @@ private:
|
||||
void handleShowVersion(const GdbResultRecord &response);
|
||||
void handleQueryPwd(const GdbResultRecord &response);
|
||||
void handleQuerySources(const GdbResultRecord &response);
|
||||
void debugMessage(const QString &msg);
|
||||
|
||||
OutputCollector m_outputCollector;
|
||||
QTextCodec *m_outputCodec;
|
||||
@@ -334,6 +338,8 @@ private:
|
||||
bool m_waitingForFirstBreakpointToBeHit;
|
||||
bool m_modulesListOutdated;
|
||||
|
||||
QList<GdbCookie> m_commandsToRunOnTemporaryBreak;
|
||||
|
||||
DebuggerManager *q;
|
||||
IDebuggerManagerAccessForEngines *qq;
|
||||
};
|
||||
|
@@ -33,11 +33,11 @@
|
||||
|
||||
#include "buildparserfactory.h"
|
||||
|
||||
#include "qt4projectmanagerconstants.h"
|
||||
#include "projectexplorerconstants.h"
|
||||
#include "gccparser.h"
|
||||
#include "msvcparser.h"
|
||||
|
||||
using namespace Qt4ProjectManager::Internal;
|
||||
using namespace ProjectExplorer::Internal;
|
||||
|
||||
GccParserFactory::~GccParserFactory()
|
||||
{
|
@@ -36,14 +36,14 @@
|
||||
|
||||
#include <projectexplorer/buildparserinterface.h>
|
||||
|
||||
namespace Qt4ProjectManager {
|
||||
namespace ProjectExplorer {
|
||||
namespace Internal {
|
||||
|
||||
class GccParserFactory : public ProjectExplorer::IBuildParserFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GccParserFactory() {};
|
||||
GccParserFactory() {}
|
||||
virtual ~GccParserFactory();
|
||||
virtual bool canCreate(const QString & name) const;
|
||||
virtual ProjectExplorer::BuildParserInterface * create(const QString & name) const;
|
||||
@@ -53,13 +53,13 @@ class MsvcParserFactory : public ProjectExplorer::IBuildParserFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MsvcParserFactory() {};
|
||||
MsvcParserFactory() {}
|
||||
virtual ~MsvcParserFactory();
|
||||
virtual bool canCreate(const QString & name) const;
|
||||
virtual ProjectExplorer::BuildParserInterface * create(const QString & name) const;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Qt4ProjectManager
|
||||
} // namespace ProjectExplorer
|
||||
|
||||
#endif // BUILDPARSERFACTORY_H
|
@@ -32,11 +32,11 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "gccparser.h"
|
||||
#include "qt4projectmanagerconstants.h"
|
||||
#include "projectexplorerconstants.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace Qt4ProjectManager;
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
GccParser::GccParser()
|
||||
{
|
||||
@@ -56,7 +56,7 @@ GccParser::GccParser()
|
||||
|
||||
QString GccParser::name() const
|
||||
{
|
||||
return QLatin1String(Qt4ProjectManager::Constants::BUILD_PARSER_GCC);
|
||||
return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC);
|
||||
}
|
||||
|
||||
void GccParser::stdOutput(const QString & line)
|
@@ -34,11 +34,11 @@
|
||||
#ifndef GCCPARSER_H
|
||||
#define GCCPARSER_H
|
||||
|
||||
#include <projectexplorer/buildparserinterface.h>
|
||||
#include "buildparserinterface.h"
|
||||
|
||||
#include <QtCore/QRegExp>
|
||||
|
||||
namespace Qt4ProjectManager {
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class GccParser : public ProjectExplorer::BuildParserInterface
|
||||
{
|
@@ -32,11 +32,11 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "msvcparser.h"
|
||||
#include "qt4projectmanagerconstants.h"
|
||||
#include "projectexplorerconstants.h"
|
||||
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
using namespace Qt4ProjectManager;
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
MsvcParser::MsvcParser()
|
||||
{
|
||||
@@ -48,7 +48,7 @@ MsvcParser::MsvcParser()
|
||||
|
||||
QString MsvcParser::name() const
|
||||
{
|
||||
return QLatin1String(Qt4ProjectManager::Constants::BUILD_PARSER_MSVC);
|
||||
return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_MSVC);
|
||||
}
|
||||
|
||||
void MsvcParser::stdError(const QString & line)
|
@@ -34,11 +34,11 @@
|
||||
#ifndef MSVCPARSER_H
|
||||
#define MSVCPARSER_H
|
||||
|
||||
#include <projectexplorer/buildparserinterface.h>
|
||||
#include "buildparserinterface.h"
|
||||
|
||||
#include <QtCore/QRegExp>
|
||||
|
||||
namespace Qt4ProjectManager {
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class MsvcParser : public ProjectExplorer::BuildParserInterface
|
||||
{
|
@@ -59,6 +59,7 @@
|
||||
#include "scriptwrappers.h"
|
||||
#include "session.h"
|
||||
#include "sessiondialog.h"
|
||||
#include "buildparserfactory.h"
|
||||
|
||||
#include <coreplugin/basemode.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
@@ -233,6 +234,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
|
||||
|
||||
addAutoReleasedObject(new ProjectFileWizardExtension);
|
||||
|
||||
// Build parsers
|
||||
addAutoReleasedObject(new GccParserFactory);
|
||||
addAutoReleasedObject(new MsvcParserFactory);
|
||||
|
||||
// context menus
|
||||
Core::ActionContainer *msessionContextMenu =
|
||||
am->createMenu(Constants::M_SESSIONCONTEXT);
|
||||
|
@@ -54,7 +54,10 @@ HEADERS += projectexplorer.h \
|
||||
projectmodels.h \
|
||||
currentprojectfind.h \
|
||||
toolchain.h \
|
||||
cesdkhandler.h
|
||||
cesdkhandler.h\
|
||||
buildparserfactory.h\
|
||||
gccparser.h\
|
||||
msvcparser.h
|
||||
SOURCES += projectexplorer.cpp \
|
||||
projectwindow.cpp \
|
||||
buildmanager.cpp \
|
||||
@@ -97,7 +100,10 @@ SOURCES += projectexplorer.cpp \
|
||||
projectmodels.cpp \
|
||||
currentprojectfind.cpp \
|
||||
toolchain.cpp \
|
||||
cesdkhandler.cpp
|
||||
cesdkhandler.cpp\
|
||||
buildparserfactory.cpp \
|
||||
gccparser.cpp\
|
||||
msvcparser.cpp
|
||||
FORMS += dependenciespanel.ui \
|
||||
buildsettingspropertiespage.ui \
|
||||
processstep.ui \
|
||||
|
@@ -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 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 ProjectExplorer
|
||||
|
||||
|
@@ -36,6 +36,8 @@
|
||||
#include "qt4project.h"
|
||||
#include "qt4projectmanagerconstants.h"
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -71,9 +73,9 @@ ProjectExplorer::BuildParserInterface *MakeStep::buildParser(const QtVersion * c
|
||||
QString buildParser;
|
||||
ProjectExplorer::ToolChain::ToolChainType type = version->toolchainType();
|
||||
if ( type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE)
|
||||
buildParser = Constants::BUILD_PARSER_MSVC;
|
||||
buildParser = ProjectExplorer::Constants::BUILD_PARSER_MSVC;
|
||||
else
|
||||
buildParser = Constants::BUILD_PARSER_GCC;
|
||||
buildParser = ProjectExplorer::Constants::BUILD_PARSER_GCC;
|
||||
|
||||
QList<IBuildParserFactory *> buildParserFactories =
|
||||
ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();
|
||||
|
@@ -28,9 +28,6 @@ HEADERS = qt4projectmanagerplugin.h \
|
||||
makestep.h \
|
||||
qmakestep.h \
|
||||
qmakebuildstepfactory.h \
|
||||
gccparser.h \
|
||||
msvcparser.h \
|
||||
buildparserfactory.h \
|
||||
deployhelper.h \
|
||||
embeddedpropertiespage.h \
|
||||
qt4runconfiguration.h \
|
||||
@@ -63,9 +60,6 @@ SOURCES = qt4projectmanagerplugin.cpp \
|
||||
makestep.cpp \
|
||||
qmakestep.cpp \
|
||||
qmakebuildstepfactory.cpp \
|
||||
gccparser.cpp \
|
||||
msvcparser.cpp \
|
||||
buildparserfactory.cpp \
|
||||
deployhelper.cpp \
|
||||
embeddedpropertiespage.cpp \
|
||||
qt4runconfiguration.cpp \
|
||||
|
@@ -79,10 +79,6 @@ const char * const GDBMACROSBUILDSTEP = "trolltech.qt4projectmanager.gdbmaros";
|
||||
const char * const QT4RUNSTEP = "trolltech.qt4projectmanager.qt4runstep";
|
||||
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
|
||||
const char * const VIEW_DETAILED = "Qt4.View.Detailed";
|
||||
const char * const VIEW_PROFILESONLY = "Qt4.View.ProjectHierarchy";
|
||||
|
@@ -41,7 +41,6 @@
|
||||
#include "qt4projectmanagerconstants.h"
|
||||
#include "qt4project.h"
|
||||
#include "qmakebuildstepfactory.h"
|
||||
#include "buildparserfactory.h"
|
||||
#include "qtversionmanager.h"
|
||||
#include "embeddedpropertiespage.h"
|
||||
#include "qt4runconfiguration.h"
|
||||
@@ -133,9 +132,6 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString *
|
||||
addAutoReleasedObject(new MakeBuildStepFactory);
|
||||
addAutoReleasedObject(new GdbMacrosBuildStepFactory);
|
||||
|
||||
addAutoReleasedObject(new GccParserFactory);
|
||||
addAutoReleasedObject(new MsvcParserFactory);
|
||||
|
||||
m_qtVersionManager = new QtVersionManager;
|
||||
addObject(m_qtVersionManager);
|
||||
|
||||
|
@@ -1178,7 +1178,7 @@ unsigned DeclaratorListAST::lastToken() const
|
||||
{
|
||||
for (const DeclaratorListAST *it = this; it; it = it->next) {
|
||||
if (! it->next)
|
||||
return it->lastToken();
|
||||
return it->declarator->lastToken();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -132,6 +132,7 @@ class BaseClass;
|
||||
class Block;
|
||||
class Class;
|
||||
class Enum;
|
||||
class ForwardClassDeclaration;
|
||||
|
||||
class Use;
|
||||
|
||||
|
@@ -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;
|
||||
for (DeclaratorListAST *it = ast->declarators; it; it = it->next) {
|
||||
Name *name = 0;
|
||||
|
@@ -124,6 +124,7 @@ public:
|
||||
delete_array_entries(usingNamespaceDirectives);
|
||||
delete_array_entries(enums);
|
||||
delete_array_entries(usingDeclarations);
|
||||
delete_array_entries(classForwardDeclarations);
|
||||
}
|
||||
|
||||
NameId *findOrInsertNameId(Identifier *id)
|
||||
@@ -322,6 +323,14 @@ public:
|
||||
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 *e = new Enum(translationUnit,
|
||||
@@ -477,6 +486,7 @@ public:
|
||||
std::vector<UsingNamespaceDirective *> usingNamespaceDirectives;
|
||||
std::vector<Enum *> enums;
|
||||
std::vector<UsingDeclaration *> usingDeclarations;
|
||||
std::vector<ForwardClassDeclaration *> classForwardDeclarations;
|
||||
};
|
||||
|
||||
Control::Control()
|
||||
@@ -632,4 +642,9 @@ UsingNamespaceDirective *Control::newUsingNamespaceDirective(unsigned sourceLoca
|
||||
UsingDeclaration *Control::newUsingDeclaration(unsigned sourceLocation, Name *name)
|
||||
{ return d->newUsingDeclaration(sourceLocation, name); }
|
||||
|
||||
ForwardClassDeclaration *Control::newForwardClassDeclaration(unsigned sourceLocation,
|
||||
Name *name)
|
||||
{ return d->newForwardClassDeclaration(sourceLocation, name); }
|
||||
|
||||
|
||||
CPLUSPLUS_END_NAMESPACE
|
||||
|
@@ -148,6 +148,9 @@ public:
|
||||
/// Creates a new UsingDeclaration symbol.
|
||||
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);
|
||||
|
||||
|
@@ -334,6 +334,9 @@ bool Symbol::isNamespace() const
|
||||
bool Symbol::isClass() const
|
||||
{ return asClass() != 0; }
|
||||
|
||||
bool Symbol::isForwardClassDeclaration() const
|
||||
{ return asForwardClassDeclaration() != 0; }
|
||||
|
||||
bool Symbol::isBlock() const
|
||||
{ return asBlock() != 0; }
|
||||
|
||||
|
@@ -197,6 +197,9 @@ public:
|
||||
/// Returns true if this Symbol is a BaseClass.
|
||||
bool isBaseClass() const;
|
||||
|
||||
/// Returns true if this Symbol is a ForwardClassDeclaration.
|
||||
bool isForwardClassDeclaration() const;
|
||||
|
||||
virtual const ScopedSymbol *asScopedSymbol() const { return 0; }
|
||||
virtual const Enum *asEnum() const { return 0; }
|
||||
virtual const Function *asFunction() const { return 0; }
|
||||
@@ -208,6 +211,7 @@ public:
|
||||
virtual const Declaration *asDeclaration() const { return 0; }
|
||||
virtual const Argument *asArgument() const { return 0; }
|
||||
virtual const BaseClass *asBaseClass() const { return 0; }
|
||||
virtual const ForwardClassDeclaration *asForwardClassDeclaration() const { return 0; }
|
||||
|
||||
virtual ScopedSymbol *asScopedSymbol() { return 0; }
|
||||
virtual Enum *asEnum() { return 0; }
|
||||
@@ -220,6 +224,7 @@ public:
|
||||
virtual Declaration *asDeclaration() { return 0; }
|
||||
virtual Argument *asArgument() { return 0; }
|
||||
virtual BaseClass *asBaseClass() { return 0; }
|
||||
virtual ForwardClassDeclaration *asForwardClassDeclaration() { return 0; }
|
||||
|
||||
/// Returns this Symbol's type.
|
||||
virtual FullySpecifiedType type() const = 0;
|
||||
|
@@ -82,6 +82,7 @@ public:
|
||||
virtual bool visit(Namespace *) { return true; }
|
||||
virtual bool visit(Class *) { return true; }
|
||||
virtual bool visit(Block *) { return true; }
|
||||
virtual bool visit(ForwardClassDeclaration *) { return true; }
|
||||
};
|
||||
|
||||
CPLUSPLUS_END_NAMESPACE
|
||||
|
@@ -401,6 +401,53 @@ void BaseClass::setVirtual(bool isVirtual)
|
||||
void BaseClass::visitSymbol0(SymbolVisitor *visitor)
|
||||
{ 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)
|
||||
: ScopedSymbol(translationUnit, sourceLocation, name),
|
||||
_key(ClassKey),
|
||||
|
@@ -199,6 +199,42 @@ protected:
|
||||
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
|
||||
{
|
||||
public:
|
||||
@@ -295,7 +331,6 @@ protected:
|
||||
virtual void accept0(TypeVisitor *visitor);
|
||||
|
||||
private:
|
||||
Name *_name;
|
||||
Scope *_templateParameters;
|
||||
FullySpecifiedType _returnType;
|
||||
union {
|
||||
|
@@ -102,6 +102,9 @@ bool Type::isClassType() const
|
||||
bool Type::isEnumType() const
|
||||
{ return asEnumType() != 0; }
|
||||
|
||||
bool Type::isForwardClassDeclarationType() const
|
||||
{ return asForwardClassDeclarationType() != 0; }
|
||||
|
||||
void Type::accept(TypeVisitor *visitor)
|
||||
{
|
||||
if (visitor->preVisit(this))
|
||||
|
@@ -80,6 +80,7 @@ public:
|
||||
bool isNamespaceType() const;
|
||||
bool isClassType() const;
|
||||
bool isEnumType() const;
|
||||
bool isForwardClassDeclarationType() const;
|
||||
|
||||
virtual const VoidType *asVoidType() const { return 0; }
|
||||
virtual const IntegerType *asIntegerType() const { return 0; }
|
||||
@@ -93,6 +94,7 @@ public:
|
||||
virtual const Namespace *asNamespaceType() const { return 0; }
|
||||
virtual const Class *asClassType() const { return 0; }
|
||||
virtual const Enum *asEnumType() const { return 0; }
|
||||
virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; }
|
||||
|
||||
virtual VoidType *asVoidType() { return 0; }
|
||||
virtual IntegerType *asIntegerType() { return 0; }
|
||||
@@ -106,6 +108,7 @@ public:
|
||||
virtual Namespace *asNamespaceType() { return 0; }
|
||||
virtual Class *asClassType() { return 0; }
|
||||
virtual Enum *asEnumType() { return 0; }
|
||||
virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; }
|
||||
|
||||
void accept(TypeVisitor *visitor);
|
||||
static void accept(Type *type, TypeVisitor *visitor);
|
||||
|
@@ -84,6 +84,7 @@ public:
|
||||
virtual void visit(Namespace *) {}
|
||||
virtual void visit(Class *) {}
|
||||
virtual void visit(Enum *) {}
|
||||
virtual void visit(ForwardClassDeclaration *) {}
|
||||
};
|
||||
|
||||
CPLUSPLUS_END_NAMESPACE
|
||||
|
Reference in New Issue
Block a user