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

This commit is contained in:
mae
2009-02-16 12:51:11 +01:00
33 changed files with 838 additions and 592 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
version=4.4.3
version="4.5-rc1"
workdir=/home/berlin/dev/qt-${version}-temp
destdir=/home/berlin/dev/qt-${version}-shipping/qt # "/qt" suffix for Bitrock
dir=qt-x11-opensource-src-${version}

View File

@@ -68,6 +68,11 @@ bool Overview::showReturnTypes() const
return _showReturnTypes;
}
unsigned Overview::markArgument() const
{
return _markArgument;
}
void Overview::setMarkArgument(unsigned position)
{
_markArgument = position;
@@ -98,9 +103,5 @@ QString Overview::prettyType(const FullySpecifiedType &ty,
const QString &name) const
{
TypePrettyPrinter pp(this);
pp.setMarkArgument(_markArgument);
pp.setShowArgumentNames(_showArgumentNames);
pp.setShowReturnTypes(_showReturnTypes);
pp.setShowFunctionSignatures(_showFunctionSignatures);
return pp(ty, name);
}

View File

@@ -57,7 +57,10 @@ public:
bool showFunctionSignatures() const;
void setShowFunctionSignatures(bool showFunctionSignatures);
void setMarkArgument(unsigned position); // 1-based
// 1-based
// ### rename
unsigned markArgument() const;
void setMarkArgument(unsigned position);
QString operator()(Name *name) const
{ return prettyName(name); }

View File

@@ -42,37 +42,12 @@ using namespace CPlusPlus;
TypePrettyPrinter::TypePrettyPrinter(const Overview *overview)
: _overview(overview),
_name(0),
_markArgument(0),
_showArgumentNames(false),
_showReturnTypes(false),
_showFunctionSignatures(true)
_name(0)
{ }
TypePrettyPrinter::~TypePrettyPrinter()
{ }
bool TypePrettyPrinter::showArgumentNames() const
{ return _showArgumentNames; }
void TypePrettyPrinter::setShowArgumentNames(bool showArgumentNames)
{ _showArgumentNames = showArgumentNames; }
bool TypePrettyPrinter::showReturnTypes() const
{ return _showReturnTypes; }
void TypePrettyPrinter::setShowReturnTypes(bool showReturnTypes)
{ _showReturnTypes = showReturnTypes; }
bool TypePrettyPrinter::showFunctionSignatures() const
{ return _showFunctionSignatures; }
void TypePrettyPrinter::setShowFunctionSignatures(bool showFunctionSignatures)
{ _showFunctionSignatures = showFunctionSignatures; }
void TypePrettyPrinter::setMarkArgument(unsigned position)
{ _markArgument = position; }
const Overview *TypePrettyPrinter::overview() const
{ return _overview; }
@@ -102,15 +77,16 @@ QString TypePrettyPrinter::operator()(const FullySpecifiedType &type, const QStr
void TypePrettyPrinter::acceptType(const FullySpecifiedType &ty)
{
if (ty.isConst())
_text += QLatin1String("const ");
if (ty.isVolatile())
_text += QLatin1String("volatile ");
if (ty.isSigned())
_text += QLatin1String("signed ");
if (ty.isUnsigned())
_text += QLatin1String("unsigned ");
out(QLatin1String("signed "));
else if (ty.isUnsigned())
out(QLatin1String("unsigned "));
const FullySpecifiedType previousFullySpecifiedType = _fullySpecifiedType;
_fullySpecifiedType = ty;
accept(ty.type());
_fullySpecifiedType = previousFullySpecifiedType;
}
QString TypePrettyPrinter::switchName(const QString &name)
@@ -127,9 +103,9 @@ QString TypePrettyPrinter::switchText(const QString &name)
return previousName;
}
QList<Type *> TypePrettyPrinter::switchPtrOperators(const QList<Type *> &ptrOperators)
QList<FullySpecifiedType> TypePrettyPrinter::switchPtrOperators(const QList<FullySpecifiedType> &ptrOperators)
{
QList<Type *> previousPtrOperators = _ptrOperators;
QList<FullySpecifiedType> previousPtrOperators = _ptrOperators;
_ptrOperators = ptrOperators;
return previousPtrOperators;
}
@@ -137,31 +113,53 @@ QList<Type *> TypePrettyPrinter::switchPtrOperators(const QList<Type *> &ptrOper
void TypePrettyPrinter::applyPtrOperators(bool wantSpace)
{
for (int i = _ptrOperators.size() - 1; i != -1; --i) {
Type *op = _ptrOperators.at(i);
const FullySpecifiedType op = _ptrOperators.at(i);
if (i == 0 && wantSpace)
_text += QLatin1Char(' ');
space();
if (PointerType *ptrTy = op->asPointerType()) {
_text += QLatin1Char('*');
if (ptrTy->elementType().isConst())
_text += " const";
if (ptrTy->elementType().isVolatile())
_text += " volatile";
if (op->isPointerType()) {
out(QLatin1Char('*'));
outCV(op);
} else if (op->isReferenceType()) {
_text += QLatin1Char('&');
} else if (PointerToMemberType *memPtrTy = op->asPointerToMemberType()) {
_text += QLatin1Char(' ');
_text += _overview->prettyName(memPtrTy->memberName());
_text += QLatin1Char('*');
out(QLatin1Char('&'));
} else if (const PointerToMemberType *memPtrTy = op->asPointerToMemberType()) {
space();
out(_overview->prettyName(memPtrTy->memberName()));
out(QLatin1Char('*'));
outCV(op);
}
}
}
void TypePrettyPrinter::visit(VoidType *)
{
_text += QLatin1String("void");
out(QLatin1String("void"));
applyPtrOperators();
}
void TypePrettyPrinter::visit(NamedType *type)
{
out(overview()->prettyName(type->name()));
applyPtrOperators();
}
void TypePrettyPrinter::visit(Namespace *type)
{
_text += overview()->prettyName(type->name());
applyPtrOperators();
}
void TypePrettyPrinter::visit(Class *type)
{
_text += overview()->prettyName(type->name());
applyPtrOperators();
}
void TypePrettyPrinter::visit(Enum *type)
{
_text += overview()->prettyName(type->name());
applyPtrOperators();
}
@@ -169,25 +167,25 @@ void TypePrettyPrinter::visit(IntegerType *type)
{
switch (type->kind()) {
case IntegerType::Char:
_text += QLatin1String("char");
out(QLatin1String("char"));
break;
case IntegerType::WideChar:
_text += QLatin1String("wchar_t");
out(QLatin1String("wchar_t"));
break;
case IntegerType::Bool:
_text += QLatin1String("bool");
out(QLatin1String("bool"));
break;
case IntegerType::Short:
_text += QLatin1String("short");
out(QLatin1String("short"));
break;
case IntegerType::Int:
_text += QLatin1String("int");
out(QLatin1String("int"));
break;
case IntegerType::Long:
_text += QLatin1String("long");
out(QLatin1String("long"));
break;
case IntegerType::LongLong:
_text += QLatin1String("long long");
out(QLatin1String("long long"));
break;
}
@@ -198,13 +196,13 @@ void TypePrettyPrinter::visit(FloatType *type)
{
switch (type->kind()) {
case FloatType::Float:
_text += QLatin1String("float");
out(QLatin1String("float"));
break;
case FloatType::Double:
_text += QLatin1String("double");
out(QLatin1String("double"));
break;
case FloatType::LongDouble:
_text += QLatin1String("long double");
out(QLatin1String("long double"));
break;
}
@@ -213,99 +211,135 @@ void TypePrettyPrinter::visit(FloatType *type)
void TypePrettyPrinter::visit(PointerToMemberType *type)
{
_ptrOperators.append(type);
outCV(type->elementType());
space();
_ptrOperators.append(_fullySpecifiedType);
acceptType(type->elementType());
}
void TypePrettyPrinter::visit(PointerType *type)
{
_ptrOperators.append(type);
outCV(type->elementType());
space();
_ptrOperators.append(_fullySpecifiedType);
acceptType(type->elementType());
}
void TypePrettyPrinter::visit(ReferenceType *type)
{
_ptrOperators.append(type);
outCV(type->elementType());
space();
_ptrOperators.append(_fullySpecifiedType);
acceptType(type->elementType());
}
void TypePrettyPrinter::visit(ArrayType *type)
{
_text += overview()->prettyType(type->elementType());
out(overview()->prettyType(type->elementType()));
if (! _ptrOperators.isEmpty()) {
_text += QLatin1Char('(');
out(QLatin1Char('('));
applyPtrOperators(false);
if (! _name.isEmpty()) {
_text += _name;
out(_name);
_name.clear();
}
_text += QLatin1Char(')');
out(QLatin1Char(')'));
}
_text += QLatin1String("[]");
}
void TypePrettyPrinter::visit(NamedType *type)
{
_text += overview()->prettyName(type->name());
applyPtrOperators();
out(QLatin1String("[]"));
}
void TypePrettyPrinter::visit(Function *type)
{
if (_showReturnTypes)
_text += _overview->prettyType(type->returnType());
if (_overview->showReturnTypes())
out(_overview->prettyType(type->returnType()));
if (! _ptrOperators.isEmpty()) {
_text += QLatin1Char('(');
out(QLatin1Char('('));
applyPtrOperators(false);
if (! _name.isEmpty()) {
_text += _name;
_name.clear();
}
_text += QLatin1Char(')');
} else if (! _name.isEmpty() && _showFunctionSignatures) {
_text += QLatin1Char(' '); // ### fixme
_text += _name;
out(QLatin1Char(')'));
} else if (! _name.isEmpty() && _overview->showFunctionSignatures()) {
space();
out(_name);
_name.clear();
}
if (_showFunctionSignatures) {
if (_overview->showFunctionSignatures()) {
Overview argumentText;
_text += QLatin1Char('(');
argumentText.setShowReturnTypes(true);
argumentText.setShowArgumentNames(false);
argumentText.setShowFunctionSignatures(true);
out(QLatin1Char('('));
for (unsigned index = 0; index < type->argumentCount(); ++index) {
if (index != 0)
_text += QLatin1String(", ");
out(QLatin1String(", "));
if (Argument *arg = type->argumentAt(index)->asArgument()) {
if (index + 1 == _markArgument)
_text += QLatin1String("<b>");
if (index + 1 == _overview->markArgument())
out(QLatin1String("<b>"));
Name *name = 0;
if (_showArgumentNames)
if (_overview->showArgumentNames())
name = arg->name();
_text += argumentText(arg->type(), name);
if (index + 1 == _markArgument)
_text += QLatin1String("</b>");
out(argumentText(arg->type(), name));
if (index + 1 == _overview->markArgument())
out(QLatin1String("</b>"));
}
}
if (type->isVariadic())
_text += QLatin1String("...");
out(QLatin1String("..."));
_text += QLatin1Char(')');
if (type->isConst())
_text += QLatin1String(" const");
if (type->isVolatile())
_text += QLatin1String(" volatile");
out(QLatin1Char(')'));
if (type->isConst() && type->isVolatile()) {
space();
out("const volatile");
} else if (type->isConst()) {
space();
out("const");
} else if (type->isVolatile()) {
space();
out("volatile");
}
}
}
void TypePrettyPrinter::visit(Namespace *type)
{ _text += overview()->prettyName(type->name()); }
void TypePrettyPrinter::space()
{
if (_text.isEmpty())
return;
void TypePrettyPrinter::visit(Class *type)
{ _text += overview()->prettyName(type->name()); }
const QChar ch = _text.at(_text.length() - 1);
void TypePrettyPrinter::visit(Enum *type)
{ _text += overview()->prettyName(type->name()); }
if (ch.isLetterOrNumber() || ch == QLatin1Char('_') || ch == QLatin1Char(')'))
_text += QLatin1Char(' ');
}
void TypePrettyPrinter::out(const QString &text)
{ _text += text; }
void TypePrettyPrinter::out(const QChar &ch)
{ _text += ch; }
void TypePrettyPrinter::outCV(const FullySpecifiedType &ty)
{
if (ty.isConst() && ty.isVolatile())
out(QLatin1String("const volatile"));
else if (ty.isConst())
out(QLatin1String("const"));
else if (ty.isVolatile())
out(QLatin1String("volatile"));
}

View File

@@ -33,7 +33,8 @@
#ifndef TYPEPRETTYPRINTER_H
#define TYPEPRETTYPRINTER_H
#include "TypeVisitor.h"
#include <TypeVisitor.h>
#include <FullySpecifiedType.h>
#include <QString>
#include <QList>
@@ -50,23 +51,12 @@ public:
const Overview *overview() const;
bool showArgumentNames() const;
void setShowArgumentNames(bool showArgumentNames);
bool showReturnTypes() const;
void setShowReturnTypes(bool showReturnTypes);
bool showFunctionSignatures() const;
void setShowFunctionSignatures(bool showFunctionSignatures);
void setMarkArgument(unsigned position); // 1-based
QString operator()(const FullySpecifiedType &type);
QString operator()(const FullySpecifiedType &type, const QString &name);
protected:
QString switchText(const QString &text = QString());
QList<Type *> switchPtrOperators(const QList<Type *> &ptrOperators);
QList<FullySpecifiedType> switchPtrOperators(const QList<FullySpecifiedType> &ptrOperators);
QString switchName(const QString &name);
void applyPtrOperators(bool wantSpace = true);
@@ -85,15 +75,17 @@ protected:
virtual void visit(Class *type);
virtual void visit(Enum *type);
void space();
void out(const QString &text);
void out(const QChar &ch);
void outCV(const FullySpecifiedType &ty);
private:
const Overview *_overview;
QString _name;
QString _text;
QList<Type *> _ptrOperators;
unsigned _markArgument;
bool _showArgumentNames: 1;
bool _showReturnTypes: 1;
bool _showFunctionSignatures: 1;
FullySpecifiedType _fullySpecifiedType;
QList<FullySpecifiedType> _ptrOperators;
};
} // end of namespace CPlusPlus

View File

@@ -185,7 +185,9 @@ void CodepasterPlugin::post()
// Submit to codepaster
m_poster = new CustomPoster(serverUrl());
m_poster = new CustomPoster(serverUrl(),
m_settingsPage->copyToClipBoard(),
m_settingsPage->displayOutput());
// Copied from cpaster. Otherwise lineendings will screw up
if (!data.contains("\r\n")) {

View File

@@ -65,8 +65,8 @@ public:
QString username() const;
QUrl serverUrl() const;
bool copyToClipBoard() const;
bool displayOutput() const;
inline bool copyToClipBoard() const { return m_copy; }
inline bool displayOutput() const { return m_output; }
private:
Ui_SettingsPage m_ui;

View File

@@ -158,8 +158,10 @@ static QString buildHelpId(const FullySpecifiedType &type,
scope = e->scope();
} else if (const NamedType *t = type->asNamedType()) {
name = t->name();
} else if (const Declaration *d = symbol->asDeclaration()) {
if (d->scope() && d->scope()->owner()->isEnum()) {
} else if (symbol && symbol->isDeclaration()) {
const Declaration *d = symbol->asDeclaration();
if (d->scope() && d->scope()->isEnumScope()) {
name = d->name();
scope = d->scope();
}

View File

@@ -187,7 +187,7 @@ using namespace CppTools::Internal;
FunctionArgumentWidget::FunctionArgumentWidget()
: m_item(0)
{
QObject *editorObject = Core::ICore::instance()->editorManager()->currentEditor();
QObject *editorObject = Core::EditorManager::instance()->currentEditor();
m_editor = qobject_cast<TextEditor::ITextEditor *>(editorObject);
m_popupFrame = new QFrame(0, Qt::ToolTip | Qt::WindowStaysOnTopHint);
@@ -518,7 +518,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
if (exprTy->isReferenceType())
exprTy = exprTy->asReferenceType()->elementType();
if (m_completionOperator == T_LPAREN && completeFunction(exprTy, resolvedTypes, context)) {
if (m_completionOperator == T_LPAREN && completeConstructorOrFunction(exprTy, resolvedTypes)) {
return m_startPosition;
} else if ((m_completionOperator == T_DOT || m_completionOperator == T_ARROW) &&
completeMember(resolvedTypes, context)) {
@@ -551,7 +551,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
foreach (const TypeOfExpression::Result &result, results) {
if (result.first->isClassType()) {
FullySpecifiedType exprTy = result.first;
if (completeConstructors(exprTy->asClassType()))
if (completeConstructorOrFunction(exprTy, QList<TypeOfExpression::Result>()))
return m_startPosition;
break;
}
@@ -563,18 +563,29 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
return -1;
}
bool CppCodeCompletion::completeFunction(FullySpecifiedType exprTy,
const QList<TypeOfExpression::Result> &resolvedTypes,
const LookupContext &)
bool CppCodeCompletion::completeConstructorOrFunction(FullySpecifiedType exprTy,
const QList<TypeOfExpression::Result> &resolvedTypes)
{
if (Class *klass = exprTy->asClassType()) {
completeConstructors(klass);
} else {
ConvertToCompletionItem toCompletionItem(this);
Overview o;
o.setShowReturnTypes(true);
o.setShowArgumentNames(true);
if (Class *klass = exprTy->asClassType()) {
for (unsigned i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
if (! member->type()->isFunctionType())
continue;
else if (! member->identity())
continue;
else if (! member->identity()->isEqualTo(klass->identity()))
continue;
if (TextEditor::CompletionItem item = toCompletionItem(member)) {
item.m_text = o(member->type(), member->name());
m_completions.append(item);
}
}
} else {
QSet<QString> signatures;
foreach (TypeOfExpression::Result p, resolvedTypes) {
FullySpecifiedType ty = p.first;
@@ -594,6 +605,10 @@ bool CppCodeCompletion::completeFunction(FullySpecifiedType exprTy,
}
}
// If there is only one item, show the function argument widget immediately
if (m_completions.size() == 1)
complete(m_completions.takeFirst());
return ! m_completions.isEmpty();
}
@@ -887,30 +902,6 @@ void CppCodeCompletion::completeClass(const QList<Symbol *> &candidates,
}
}
bool CppCodeCompletion::completeConstructors(Class *klass)
{
ConvertToCompletionItem toCompletionItem(this);
Overview o;
o.setShowReturnTypes(true);
o.setShowArgumentNames(true);
for (unsigned i = 0; i < klass->memberCount(); ++i) {
Symbol *member = klass->memberAt(i);
if (! member->type()->isFunctionType())
continue;
else if (! member->identity())
continue;
else if (! member->identity()->isEqualTo(klass->identity()))
continue;
if (TextEditor::CompletionItem item = toCompletionItem(member)) {
item.m_text = o(member->type(), member->name());
m_completions.append(item);
}
}
return ! m_completions.isEmpty();
}
bool CppCodeCompletion::completeQtMethod(CPlusPlus::FullySpecifiedType,
const QList<TypeOfExpression::Result> &results,
const LookupContext &context,
@@ -1078,7 +1069,10 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item)
Function *function = symbol->type()->asFunctionType();
QTC_ASSERT(function, return);
m_functionArgumentWidget = new FunctionArgumentWidget();
// Recreate if necessary
if (!m_functionArgumentWidget)
m_functionArgumentWidget = new FunctionArgumentWidget;
m_functionArgumentWidget->showFunctionHint(function, typeOfExpression.snapshot());
}
} else if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) {

View File

@@ -86,9 +86,8 @@ private:
void addMacros(const CPlusPlus::LookupContext &context);
void addCompletionItem(CPlusPlus::Symbol *symbol);
bool completeFunction(CPlusPlus::FullySpecifiedType exprTy,
const QList<CPlusPlus::TypeOfExpression::Result> &,
const CPlusPlus::LookupContext &context);
bool completeConstructorOrFunction(CPlusPlus::FullySpecifiedType exprTy,
const QList<CPlusPlus::TypeOfExpression::Result> &);
bool completeMember(const QList<CPlusPlus::TypeOfExpression::Result> &,
const CPlusPlus::LookupContext &context);

View File

@@ -84,7 +84,7 @@ HEADERS += $$PWD/modeltest.h
DEFINES += USE_MODEL_TEST=1
}
win32 {
false {
HEADERS += \
cdbdebugengine.h \

View File

@@ -33,7 +33,6 @@
#include "debuggermanager.h"
#include "assert.h"
#include "debuggerconstants.h"
#include "idebuggerengine.h"
@@ -58,6 +57,8 @@
#include "startexternaldialog.h"
#include "attachexternaldialog.h"
#include <utils/qtcassert.h>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
@@ -149,6 +150,7 @@ void DebuggerManager::init()
{
m_status = -1;
m_busy = false;
m_shutdown = false;
m_attachedPID = 0;
m_startMode = startInternal;
@@ -451,10 +453,7 @@ QDockWidget *DebuggerManager::createDockForWidget(QWidget *widget)
{
QDockWidget *dockWidget = new QDockWidget(widget->windowTitle(), m_mainWindow);
dockWidget->setObjectName(widget->windowTitle());
//dockWidget->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea);
dockWidget->setAllowedAreas(Qt::AllDockWidgetAreas); // that space is needed.
//dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
dockWidget->setTitleBarWidget(new QWidget(dockWidget));
dockWidget->setWidget(widget);
connect(dockWidget->toggleViewAction(), SIGNAL(toggled(bool)),
@@ -543,12 +542,6 @@ void DebuggerManager::notifyStartupFinished()
{
setStatus(DebuggerProcessReady);
showStatusMessage(tr("Startup finished. Debugger ready."), -1);
if (m_startMode == attachExternal) {
// we continue the execution
engine()->continueInferior();
} else {
engine()->runInferior();
}
}
void DebuggerManager::notifyInferiorStopped()
@@ -567,7 +560,7 @@ void DebuggerManager::notifyInferiorUpdateFinished()
void DebuggerManager::notifyInferiorRunningRequested()
{
setStatus(DebuggerInferiorRunningRequested);
showStatusMessage(tr("Running..."), 5000);
showStatusMessage(tr("Running requested..."), 5000);
}
void DebuggerManager::notifyInferiorRunning()
@@ -585,7 +578,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);
}
@@ -597,7 +590,18 @@ void DebuggerManager::showApplicationOutput(const QString &str)
void DebuggerManager::shutdown()
{
//qDebug() << "DEBUGGER_MANAGER SHUTDOWN START";
engine()->shutdown();
m_shutdown = true;
if (m_engine)
m_engine->shutdown();
m_engine = 0;
delete scriptEngine;
scriptEngine = 0;
delete gdbEngine;
gdbEngine = 0;
delete winEngine;
winEngine = 0;
// Delete these manually before deleting the manager
// (who will delete the models for most views)
delete m_breakWindow;
@@ -651,41 +655,49 @@ void DebuggerManager::toggleBreakpoint()
void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber)
{
QTC_ASSERT(m_engine, return);
QTC_ASSERT(m_breakHandler, return);
int index = m_breakHandler->indexOf(fileName, lineNumber);
if (index == -1)
breakHandler()->setBreakpoint(fileName, lineNumber);
m_breakHandler->setBreakpoint(fileName, lineNumber);
else
breakHandler()->removeBreakpoint(index);
engine()->attemptBreakpointSynchronization();
m_breakHandler->removeBreakpoint(index);
m_engine->attemptBreakpointSynchronization();
}
void DebuggerManager::setToolTipExpression(const QPoint &pos, const QString &exp)
{
engine()->setToolTipExpression(pos, exp);
QTC_ASSERT(m_engine, return);
m_engine->setToolTipExpression(pos, exp);
}
void DebuggerManager::updateWatchModel()
{
engine()->updateWatchModel();
QTC_ASSERT(m_engine, return);
m_engine->updateWatchModel();
}
void DebuggerManager::expandChildren(const QModelIndex &idx)
{
watchHandler()->expandChildren(idx);
QTC_ASSERT(m_watchHandler, return);
m_watchHandler->expandChildren(idx);
}
void DebuggerManager::collapseChildren(const QModelIndex &idx)
{
watchHandler()->collapseChildren(idx);
QTC_ASSERT(m_watchHandler, return);
m_watchHandler->collapseChildren(idx);
}
void DebuggerManager::removeWatchExpression(const QString &exp)
{
watchHandler()->removeWatchExpression(exp);
QTC_ASSERT(m_watchHandler, return);
m_watchHandler->removeWatchExpression(exp);
}
QVariant DebuggerManager::sessionValue(const QString &name)
{
// this is answered by the plugin
QVariant value;
emit sessionValueRequested(name, &value);
return value;
@@ -693,16 +705,19 @@ QVariant DebuggerManager::sessionValue(const QString &name)
void DebuggerManager::querySessionValue(const QString &name, QVariant *value)
{
// this is answered by the plugin
emit sessionValueRequested(name, value);
}
void DebuggerManager::setSessionValue(const QString &name, const QVariant &value)
{
// this is answered by the plugin
emit setSessionValueRequested(name, value);
}
QVariant DebuggerManager::configValue(const QString &name)
{
// this is answered by the plugin
QVariant value;
emit configValueRequested(name, &value);
return value;
@@ -710,11 +725,13 @@ QVariant DebuggerManager::configValue(const QString &name)
void DebuggerManager::queryConfigValue(const QString &name, QVariant *value)
{
// this is answered by the plugin
emit configValueRequested(name, value);
}
void DebuggerManager::setConfigValue(const QString &name, const QVariant &value)
{
// this is answered by the plugin
emit setConfigValueRequested(name, value);
}
@@ -797,7 +814,7 @@ bool DebuggerManager::startNewDebugger(StartMode mode)
else
setDebuggerType(GdbDebugger);
if (!engine()->startDebugger())
if (!m_engine->startDebugger())
return false;
m_busy = false;
@@ -818,7 +835,10 @@ void DebuggerManager::cleanupViews()
void DebuggerManager::exitDebugger()
{
engine()->exitDebugger();
if (m_shutdown)
return;
QTC_ASSERT(m_engine, return);
m_engine->exitDebugger();
cleanupViews();
setStatus(DebuggerProcessNotReady);
setBusyCursor(false);
@@ -827,62 +847,73 @@ void DebuggerManager::exitDebugger()
void DebuggerManager::assignValueInDebugger(const QString &expr, const QString &value)
{
engine()->assignValueInDebugger(expr, value);
QTC_ASSERT(m_engine, return);
m_engine->assignValueInDebugger(expr, value);
}
void DebuggerManager::activateFrame(int index)
{
engine()->activateFrame(index);
QTC_ASSERT(m_engine, return);
m_engine->activateFrame(index);
}
void DebuggerManager::selectThread(int index)
{
engine()->selectThread(index);
QTC_ASSERT(m_engine, return);
m_engine->selectThread(index);
}
void DebuggerManager::loadAllSymbols()
{
engine()->loadAllSymbols();
QTC_ASSERT(m_engine, return);
m_engine->loadAllSymbols();
}
void DebuggerManager::loadSymbols(const QString &module)
{
engine()->loadSymbols(module);
QTC_ASSERT(m_engine, return);
m_engine->loadSymbols(module);
}
void DebuggerManager::stepExec()
{
QTC_ASSERT(m_engine, return);
resetLocation();
engine()->stepExec();
m_engine->stepExec();
}
void DebuggerManager::stepOutExec()
{
QTC_ASSERT(m_engine, return);
resetLocation();
engine()->stepOutExec();
m_engine->stepOutExec();
}
void DebuggerManager::nextExec()
{
QTC_ASSERT(m_engine, return);
resetLocation();
engine()->nextExec();
m_engine->nextExec();
}
void DebuggerManager::stepIExec()
{
QTC_ASSERT(m_engine, return);
resetLocation();
engine()->stepIExec();
m_engine->stepIExec();
}
void DebuggerManager::nextIExec()
{
QTC_ASSERT(m_engine, return);
resetLocation();
engine()->nextIExec();
m_engine->nextIExec();
}
void DebuggerManager::executeDebuggerCommand(const QString &command)
{
engine()->executeDebuggerCommand(command);
QTC_ASSERT(m_engine, return);
m_engine->executeDebuggerCommand(command);
}
void DebuggerManager::sessionLoaded()
@@ -900,16 +931,18 @@ void DebuggerManager::aboutToSaveSession()
void DebuggerManager::loadSessionData()
{
QTC_ASSERT(m_engine, return);
m_breakHandler->loadSessionData();
m_watchHandler->loadSessionData();
engine()->loadSessionData();
m_engine->loadSessionData();
}
void DebuggerManager::saveSessionData()
{
QTC_ASSERT(m_engine, return);
m_breakHandler->saveSessionData();
m_watchHandler->saveSessionData();
engine()->saveSessionData();
m_engine->saveSessionData();
}
void DebuggerManager::dumpLog()
@@ -968,19 +1001,24 @@ void DebuggerManager::addToWatchWindow()
void DebuggerManager::watchExpression(const QString &expression)
{
watchHandler()->watchExpression(expression);
QTC_ASSERT(m_watchHandler, return);
m_watchHandler->watchExpression(expression);
}
void DebuggerManager::setBreakpoint(const QString &fileName, int lineNumber)
{
breakHandler()->setBreakpoint(fileName, lineNumber);
engine()->attemptBreakpointSynchronization();
QTC_ASSERT(m_breakHandler, return);
QTC_ASSERT(m_engine, return);
m_breakHandler->setBreakpoint(fileName, lineNumber);
m_engine->attemptBreakpointSynchronization();
}
void DebuggerManager::breakByFunction(const QString &functionName)
{
breakHandler()->breakByFunction(functionName);
engine()->attemptBreakpointSynchronization();
QTC_ASSERT(m_breakHandler, return);
QTC_ASSERT(m_engine, return);
m_breakHandler->breakByFunction(functionName);
m_engine->attemptBreakpointSynchronization();
}
void DebuggerManager::breakByFunction()
@@ -1088,26 +1126,18 @@ bool DebuggerManager::useCustomDumpers() const
return m_settings.m_useCustomDumpers;
}
bool DebuggerManager::useFastStart() const
{
return 0; // && m_settings.m_useFastStart;
}
void DebuggerManager::setUseCustomDumpers(bool on)
{
QTC_ASSERT(m_engine, return);
m_settings.m_useCustomDumpers = on;
engine()->setUseCustomDumpers(on);
}
void DebuggerManager::setUseFastStart(bool on)
{
m_settings.m_useFastStart = on;
m_engine->setUseCustomDumpers(on);
}
void DebuggerManager::setDebugDumpers(bool on)
{
QTC_ASSERT(m_engine, return);
m_settings.m_debugDumpers = on;
engine()->setDebugDumpers(on);
m_engine->setDebugDumpers(on);
}
void DebuggerManager::setSkipKnownFrames(bool on)
@@ -1123,29 +1153,31 @@ void DebuggerManager::queryCurrentTextEditor(QString *fileName, int *lineNumber,
void DebuggerManager::continueExec()
{
engine()->continueInferior();
m_engine->continueInferior();
}
void DebuggerManager::interruptDebuggingRequest()
{
QTC_ASSERT(m_engine, return);
//qDebug() << "INTERRUPTING AT" << status();
bool interruptIsExit = (status() != DebuggerInferiorRunning);
if (interruptIsExit)
exitDebugger();
else {
setStatus(DebuggerInferiorStopRequested);
engine()->interruptInferior();
m_engine->interruptInferior();
}
}
void DebuggerManager::runToLineExec()
{
QTC_ASSERT(m_engine, return);
QString fileName;
int lineNumber = -1;
emit currentTextEditorRequested(&fileName, &lineNumber, 0);
if (!fileName.isEmpty())
engine()->runToLineExec(fileName, lineNumber);
m_engine->runToLineExec(fileName, lineNumber);
}
void DebuggerManager::runToFunctionExec()
@@ -1177,7 +1209,7 @@ void DebuggerManager::runToFunctionExec()
}
//qDebug() << "RUN TO FUNCTION " << functionName;
if (!functionName.isEmpty())
engine()->runToFunctionExec(functionName);
m_engine->runToFunctionExec(functionName);
}
void DebuggerManager::jumpToLineExec()
@@ -1186,20 +1218,20 @@ void DebuggerManager::jumpToLineExec()
int lineNumber = -1;
emit currentTextEditorRequested(&fileName, &lineNumber, 0);
if (!fileName.isEmpty())
engine()->jumpToLineExec(fileName, lineNumber);
m_engine->jumpToLineExec(fileName, lineNumber);
}
void DebuggerManager::resetLocation()
{
//m_watchHandler->removeMouseMoveCatcher(editor->widget());
// connected to the plugin
emit resetLocationRequested();
}
void DebuggerManager::gotoLocation(const QString &fileName, int line,
bool setMarker)
{
// connected to the plugin
emit gotoLocationRequested(fileName, line, setMarker);
//m_watchHandler->installMouseMoveCatcher(editor->widget());
}
@@ -1211,9 +1243,10 @@ void DebuggerManager::gotoLocation(const QString &fileName, int line,
void DebuggerManager::reloadDisassembler()
{
QTC_ASSERT(m_engine, return);
if (!m_disassemblerDock || !m_disassemblerDock->isVisible())
return;
engine()->reloadDisassembler();
m_engine->reloadDisassembler();
}
void DebuggerManager::disassemblerDockToggled(bool on)
@@ -1233,7 +1266,7 @@ void DebuggerManager::reloadModules()
{
if (!m_modulesDock || !m_modulesDock->isVisible())
return;
engine()->reloadModules();
m_engine->reloadModules();
}
void DebuggerManager::modulesDockToggled(bool on)
@@ -1251,11 +1284,13 @@ void DebuggerManager::modulesDockToggled(bool on)
void DebuggerManager::showDebuggerOutput(const QString &prefix, const QString &msg)
{
QTC_ASSERT(m_outputWindow, return);
m_outputWindow->showOutput(prefix, msg);
}
void DebuggerManager::showDebuggerInput(const QString &prefix, const QString &msg)
{
QTC_ASSERT(m_outputWindow, return);
m_outputWindow->showInput(prefix, msg);
}
@@ -1276,7 +1311,7 @@ void DebuggerManager::reloadRegisters()
{
if (!m_registerDock || !m_registerDock->isVisible())
return;
engine()->reloadRegisters();
m_engine->reloadRegisters();
}

View File

@@ -170,7 +170,11 @@ private:
virtual bool skipKnownFrames() const = 0;
virtual bool debugDumpers() const = 0;
virtual bool useCustomDumpers() const = 0;
virtual bool useFastStart() const = 0;
virtual bool wantsAllPluginBreakpoints() const = 0;
virtual bool wantsSelectedPluginBreakpoints() const = 0;
virtual bool wantsNoPluginBreakpoints() const = 0;
virtual QString selectedPluginBreakpointsPattern() const = 0;
virtual void reloadDisassembler() = 0;
virtual void reloadModules() = 0;
@@ -200,6 +204,11 @@ public:
bool m_useToolTips;
QString m_scriptFile;
bool m_pluginAllBreakpoints;
bool m_pluginSelectedBreakpoints;
bool m_pluginNoBreakpoints;
QString m_pluginSelectedBreakpointsPattern;
};
//
@@ -283,7 +292,6 @@ public slots:
void setUseCustomDumpers(bool on);
void setDebugDumpers(bool on);
void setSkipKnownFrames(bool on);
void setUseFastStart(bool on);
private slots:
void showDebuggerOutput(const QString &prefix, const QString &msg);
@@ -318,7 +326,14 @@ private:
bool skipKnownFrames() const;
bool debugDumpers() const;
bool useCustomDumpers() const;
bool useFastStart() const;
bool wantsAllPluginBreakpoints() const
{ return m_settings.m_pluginAllBreakpoints; }
bool wantsSelectedPluginBreakpoints() const
{ return m_settings.m_pluginSelectedBreakpoints; }
bool wantsNoPluginBreakpoints() const
{ return m_settings.m_pluginNoBreakpoints; }
QString selectedPluginBreakpointsPattern() const
{ return m_settings.m_pluginSelectedBreakpointsPattern; }
void notifyStartupFinished();
void notifyInferiorStopped();
@@ -451,6 +466,8 @@ private:
IDebuggerEngine *engine();
IDebuggerEngine *m_engine;
DebuggerSettings m_settings;
// set during application shutdown
bool m_shutdown;
};
} // namespace Internal

View File

@@ -274,15 +274,26 @@ QWidget *GdbOptionPage::createPage(QWidget *parent)
m_ui.scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script File"));
m_ui.scriptFileChooser->setPath(m_settings.m_scriptFile);
m_ui.environmentEdit->setText(m_settings.m_gdbEnv);
m_ui.autoStartBox->setChecked(m_settings.m_autoRun);
m_ui.autoQuitBox->setChecked(m_settings.m_autoQuit);
m_ui.radioButtonAllPluginBreakpoints->
setChecked(m_settings.m_pluginAllBreakpoints);
m_ui.radioButtonSelectedPluginBreakpoints->
setChecked(m_settings.m_pluginSelectedBreakpoints);
m_ui.radioButtonNoPluginBreakpoints->
setChecked(m_settings.m_pluginNoBreakpoints);
m_ui.lineEditSelectedPluginBreakpointsPattern->
setText(m_settings.m_pluginSelectedBreakpointsPattern);
m_ui.lineEditSelectedPluginBreakpointsPattern->
setEnabled(m_settings.m_pluginSelectedBreakpoints);
m_ui.checkBoxSkipKnownFrames->setChecked(m_settings.m_skipKnownFrames);
m_ui.checkBoxDebugDumpers->setChecked(m_settings.m_debugDumpers);
m_ui.checkBoxUseCustomDumpers->setChecked(m_settings.m_useCustomDumpers);
m_ui.checkBoxFastStart->setChecked(m_settings.m_useFastStart);
m_ui.checkBoxUseToolTips->setChecked(m_settings.m_useToolTips);
connect(m_ui.radioButtonSelectedPluginBreakpoints, SIGNAL(toggled(bool)),
m_ui.lineEditSelectedPluginBreakpointsPattern, SLOT(setEnabled(bool)));
#ifndef QT_DEBUG
#if 0
cmd = am->registerAction(m_manager->m_dumpLogAction,
@@ -294,14 +305,9 @@ QWidget *GdbOptionPage::createPage(QWidget *parent)
#endif
// FIXME
m_ui.autoStartBox->hide();
m_ui.autoQuitBox->hide();
m_ui.environmentEdit->hide();
m_ui.labelEnvironment->hide();
m_ui.checkBoxFastStart->setChecked(false);
m_ui.checkBoxFastStart->hide();
//m_dumpLogAction = new QAction(this);
//m_dumpLogAction->setText(tr("Dump Log File for Debugging Purposes"));
//
@@ -315,16 +321,22 @@ void GdbOptionPage::apply()
{
m_settings.m_gdbCmd = m_ui.gdbLocationChooser->path();
m_settings.m_gdbEnv = m_ui.environmentEdit->text();
m_settings.m_autoRun = m_ui.autoStartBox->isChecked();
m_settings.m_autoQuit = m_ui.autoQuitBox->isChecked();
m_settings.m_scriptFile = m_ui.scriptFileChooser->path();
m_settings.m_skipKnownFrames = m_ui.checkBoxSkipKnownFrames->isChecked();
m_settings.m_debugDumpers = m_ui.checkBoxDebugDumpers->isChecked();
m_settings.m_useCustomDumpers = m_ui.checkBoxUseCustomDumpers->isChecked();
m_settings.m_useFastStart = m_ui.checkBoxFastStart->isChecked();
m_settings.m_useToolTips = m_ui.checkBoxUseToolTips->isChecked();
m_settings.m_pluginAllBreakpoints =
m_ui.radioButtonAllPluginBreakpoints->isChecked();
m_settings.m_pluginSelectedBreakpoints =
m_ui.radioButtonSelectedPluginBreakpoints->isChecked();
m_settings.m_pluginNoBreakpoints =
m_ui.radioButtonNoPluginBreakpoints->isChecked();
m_settings.m_pluginSelectedBreakpointsPattern =
m_ui.lineEditSelectedPluginBreakpointsPattern->text();
*m_plugin->m_manager->settings() = m_settings;
m_plugin->writeSettings();
}
@@ -889,11 +901,16 @@ void DebuggerPlugin::writeSettings() const
s->setValue("AutoRun", m->m_autoRun);
s->setValue("AutoQuit", m->m_autoQuit);
s->setValue("UseFastStart", m->m_useFastStart);
s->setValue("UseToolTips", m->m_useToolTips);
s->setValue("UseCustomDumpers", m->m_useCustomDumpers);
s->setValue("SkipKnowFrames", m->m_skipKnownFrames);
s->setValue("DebugDumpers", m->m_debugDumpers);
s->setValue("AllPluginBreakpoints", m->m_pluginAllBreakpoints);
s->setValue("SelectedPluginBreakpoints", m->m_pluginSelectedBreakpoints);
s->setValue("NoPluginBreakpoints", m->m_pluginNoBreakpoints);
s->setValue("SelectedPluginBreakpointsPattern", m->m_pluginSelectedBreakpointsPattern);
s->endGroup();
}
@@ -911,6 +928,7 @@ void DebuggerPlugin::readSettings()
QString defaultScript;
s->beginGroup(QLatin1String("DebugMode"));
QByteArray ba = s->value("State", QByteArray()).toByteArray();
m_toggleLockedAction->setChecked(s->value("Locked", true).toBool());
m->m_gdbCmd = s->value("Location", defaultCommand).toString();
@@ -922,8 +940,17 @@ void DebuggerPlugin::readSettings()
m->m_skipKnownFrames = s->value("SkipKnownFrames", false).toBool();
m->m_debugDumpers = s->value("DebugDumpers", false).toBool();
m->m_useCustomDumpers = s->value("UseCustomDumpers", true).toBool();
m->m_useFastStart = s->value("UseFastStart", false).toBool();
m->m_useToolTips = s->value("UseToolTips", false).toBool();
m->m_pluginAllBreakpoints =
s->value("AllPluginBreakpoints", false).toBool();
m->m_pluginSelectedBreakpoints =
s->value("SelectedPluginBreakpoints", false).toBool();
m->m_pluginNoBreakpoints =
s->value("NoPluginBreakpoints", true).toBool();
m->m_pluginSelectedBreakpointsPattern =
s->value("SelectedPluginBreakpointsPattern").toString();
s->endGroup();
m_manager->mainWindow()->restoreState(ba);

View File

@@ -107,11 +107,14 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
: RunControl(runConfiguration), m_manager(manager), m_running(false)
{
connect(m_manager, SIGNAL(debuggingFinished()),
this, SLOT(debuggingFinished()));
this, SLOT(debuggingFinished()),
Qt::QueuedConnection);
connect(m_manager, SIGNAL(applicationOutputAvailable(QString)),
this, SLOT(slotAddToOutputWindowInline(QString)));
this, SLOT(slotAddToOutputWindowInline(QString)),
Qt::QueuedConnection);
connect(m_manager, SIGNAL(inferiorPidChanged(qint64)),
this, SLOT(bringApplicationToForeground(qint64)));
this, SLOT(bringApplicationToForeground(qint64)),
Qt::QueuedConnection);
}
void DebuggerRunControl::start()

View File

@@ -99,6 +99,7 @@ enum GdbCommandType
GdbQueryPwd,
GdbQuerySources,
GdbAsyncOutput2,
GdbStart,
GdbExecRun,
GdbExecRunToFunction,
GdbExecStep,
@@ -111,6 +112,7 @@ enum GdbCommandType
GdbExecInterrupt,
GdbInfoShared,
GdbInfoProc,
GdbInfoThreads,
GdbQueryDataDumper1,
GdbQueryDataDumper2,
@@ -229,6 +231,15 @@ static bool isLeavableFunction(const QString &funcName, const QString &fileName)
return false;
}
static QString startSymbolName()
{
#ifdef Q_OS_WIN
return "WinMainCRTStartup";
#else
return "_start";
#endif
}
///////////////////////////////////////////////////////////////////////
//
@@ -240,23 +251,16 @@ GdbEngine::GdbEngine(DebuggerManager *parent)
{
q = parent;
qq = parent->engineInterface();
init();
initializeVariables();
initializeConnections();
}
GdbEngine::~GdbEngine()
{
}
void GdbEngine::init()
void GdbEngine::initializeConnections()
{
m_pendingRequests = 0;
m_gdbVersion = 100;
m_shared = 0;
m_outputCodec = QTextCodec::codecForLocale();
m_dataDumperState = DataDumperUninitialized;
m_oldestAcceptableToken = -1;
// Gdb Process interaction
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)), this,
SLOT(gdbProcError(QProcess::ProcessError)));
@@ -284,6 +288,23 @@ void GdbEngine::init()
Qt::QueuedConnection);
}
void GdbEngine::initializeVariables()
{
m_dataDumperState = DataDumperUninitialized;
m_gdbVersion = 100;
m_fullToShortName.clear();
m_shortToFullName.clear();
m_varToType.clear();
m_modulesListOutdated = true;
m_oldestAcceptableToken = -1;
m_outputCodec = QTextCodec::codecForLocale();
m_pendingRequests = 0;
m_waitingForBreakpointSynchronizationToContinue = false;
m_waitingForFirstBreakpointToBeHit = false;
}
void GdbEngine::gdbProcError(QProcess::ProcessError error)
{
QString msg;
@@ -458,13 +479,28 @@ void GdbEngine::handleResponse()
break;
}
case '~':
case '@':
case '~': {
QString data = GdbMi::parseCString(from, to);
m_pendingConsoleStreamOutput += data;
m_inbuffer = QByteArray(from, to - from);
break;
}
case '@': {
QString data = GdbMi::parseCString(from, to);
m_pendingTargetStreamOutput += data;
m_inbuffer = QByteArray(from, to - from);
break;
}
case '&': {
QString data = GdbMi::parseCString(from, to);
handleStreamOutput(data, c);
//dump(oldfrom, from, record.toString());
m_pendingLogStreamOutput += data;
m_inbuffer = QByteArray(from, to - from);
// On Windows, the contents seem to depend on the debugger
// version and/or OS version used.
if (data.startsWith("warning:"))
qq->showApplicationOutput(data);
break;
}
@@ -635,6 +671,7 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
}
if (pid == q->m_attachedPID)
return;
qDebug() << "FOUND PID " << pid;
q->m_attachedPID = pid;
qq->notifyInferiorPidChanged(pid);
}
@@ -686,8 +723,8 @@ void GdbEngine::sendCommand(const QString &command, int type,
//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);
//emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
emit gdbInputAvailable(QString(), cmd.command);
}
if (temporarilyStopped)
@@ -734,8 +771,10 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
--m_pendingRequests;
PENDING_DEBUG(" TYPE " << cmd.type << " DECREMENTS PENDING TO: "
<< m_pendingRequests << cmd.command);
if (m_pendingRequests <= 0)
if (m_pendingRequests <= 0) {
PENDING_DEBUG(" .... AND TRIGGERS MODEL UPDATE");
updateWatchModel2();
}
} else {
PENDING_DEBUG(" UNKNOWN TYPE " << cmd.type << " LEAVES PENDING AT: "
<< m_pendingRequests << cmd.command);
@@ -753,12 +792,18 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
case GdbExecContinue:
case GdbExecFinish:
// evil code sharing
case GdbExecRun:
handleExecRun(record);
break;
case GdbStart:
handleStart(record);
break;
case GdbInfoProc:
handleInfoProc(record);
break;
case GdbInfoThreads:
handleInfoThreads(record);
break;
case GdbShowVersion:
handleShowVersion(record);
@@ -952,6 +997,19 @@ void GdbEngine::handleQuerySources(const GdbResultRecord &record)
}
}
void GdbEngine::handleInfoThreads(const GdbResultRecord &record)
{
if (record.resultClass == GdbResultDone) {
// FIXME: use something more robust
// WIN: * 3 Thread 2312.0x4d0 0x7c91120f in ?? ()
// LINUX: * 1 Thread 0x7f466273c6f0 (LWP 21455) 0x0000000000404542 in ...
QRegExp re(QLatin1String("Thread (\\d+)\\.0x.* in"));
QString data = record.data.findChild("consolestreamoutput").data();
if (re.indexIn(data) != -1)
maybeHandleInferiorPidChanged(re.cap(1));
}
}
void GdbEngine::handleInfoProc(const GdbResultRecord &record)
{
if (record.resultClass == GdbResultDone) {
@@ -975,18 +1033,6 @@ void GdbEngine::handleInfoShared(const GdbResultRecord &record)
if (record.resultClass == GdbResultDone) {
// let the modules handler do the parsing
handleModulesList(record);
QList<Module> modules = qq->modulesHandler()->modules();
bool reloadNeeded = false;
foreach (const Module &module, modules) {
// FIXME: read this from some list
if (!module.symbolsRead && !module.moduleName.contains("Q")) {
reloadNeeded = true;
sendCommand("sharedlibrary " + dotEscape(module.moduleName));
}
}
if (reloadNeeded)
reloadModules();
continueInferior();
}
}
@@ -1028,84 +1074,6 @@ void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record)
q->gotoLocation(file, line, true);
}
void GdbEngine::handleStreamOutput(const QString &data, char code)
{
// Linux
if (data.contains("[New Thread")) {
QRegExp re("\\[New Thread 0x([0-9a-f]*) \\(LWP ([0-9]*)\\)\\]");
if (re.indexIn(data) != -1)
maybeHandleInferiorPidChanged(re.cap(2));
}
// Mac
if (data.contains("[Switching to process ")) {
QRegExp re("\\[Switching to process ([0-9]*) local thread 0x([0-9a-f]*)\\]");
if (re.indexIn(data) != -1)
maybeHandleInferiorPidChanged(re.cap(1));
}
// present it twice: now and together with the next 'real' result
switch (code) {
case '~':
m_pendingConsoleStreamOutput += data;
break;
case '@':
m_pendingTargetStreamOutput += data;
break;
case '&':
m_pendingLogStreamOutput += data;
// On Windows, the contents seem to depend on the debugger
// version and/or OS version used.
if (data.startsWith("warning:"))
qq->showApplicationOutput(data);
break;
}
#ifdef Q_OS_LINUX
if (data.startsWith("Pending break") && data.contains("\" resolved")) {
qDebug() << "SCHEDULING -break-list";
//m_breakListOnStopNeeded = true;
}
#endif
#if 0
if (m_slurpingPTypeOutput)
qDebug() << "SLURP: " << output.data;
// "No symbol \"__dlopen\" in current context."
// "No symbol \"dlopen\" in current context."
if (output.data.startsWith("No symbol ")
&& output.data.contains("dlopen")) {
m_dlopened = true;
return;
}
// output of 'ptype <foo>'
if (output.data.startsWith("type = ")) {
if (output.data.endsWith("{") || output.data.endsWith("{\\n")) {
// multi-line output started here...
m_slurpingPTypeOutput = true;
m_slurpedPTypeOutput = output.data;
} else {
// Happens for simple types. Process it immediately
m_watchHandler->handleTypeContents(output.data);
}
return;
}
if (m_slurpingPTypeOutput) {
m_slurpedPTypeOutput += '\n';
m_slurpedPTypeOutput += output.data;
if (output.data.startsWith("}")) {
// this is the last line...
m_slurpingPTypeOutput = false;
m_watchHandler->handleTypeContents(m_slurpedPTypeOutput);
m_slurpedPTypeOutput.clear();
}
return;
}
#endif
}
static bool isExitedReason(const QString &reason)
{
return reason == QLatin1String("exited-normally") // inferior exited normally
@@ -1133,33 +1101,70 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
{
const QString reason = data.findChild("reason").data();
QString console = data.findChild("consolestreamoutput").data();
if (console.contains("Stopped due to shared library event") || reason.isEmpty()) {
++m_shared;
//if (m_shared == 2)
// tryLoadCustomDumpers();
//qDebug() << "SHARED LIBRARY EVENT " << data.toString() << m_shared;
if (qq->useFastStart()) {
if (1 || m_shared <= 16) { // libpthread?
sendCommand("info shared", GdbInfoShared);
//sendCommand("sharedlibrary gdbdebugger ");
//continueInferior();
} else {
// auto-load from now on
sendCommand("info shared");
sendCommand("set auto-solib-add on");
//MAC: bool isFirstStop = data.findChild("bkptno").data() == "1";
//!MAC: startSymbolName == data.findChild("frame").findChild("func")
if (m_waitingForFirstBreakpointToBeHit) {
m_waitingForFirstBreakpointToBeHit = false;
//
// that's the "early stop"
//
#if defined(Q_OS_WIN)
sendCommand("info thread", GdbInfoThreads);
#endif
#if defined(Q_OS_LINUX)
sendCommand("info proc", GdbInfoProc);
#endif
#if defined(Q_OS_MAC)
sendCommand("info pid", GdbInfoProc, QVariant(), true);
#endif
sendCommand("-file-list-exec-source-files", GdbQuerySources);
sendCommand("-break-list", BreakList);
//sendCommand("bt");
//QVariant var = QVariant::fromValue<GdbMi>(data);
//sendCommand("p 1", GdbAsyncOutput2, var); // dummy
continueInferior();
tryLoadCustomDumpers();
// intentionally after tryLoadCustomDumpers(),
// otherwise we'd interupt solib loading.
if (qq->wantsAllPluginBreakpoints()) {
sendCommand("set auto-solib-add on");
sendCommand("set stop-on-solib-events 0");
sendCommand("sharedlibrary .*");
} else if (qq->wantsSelectedPluginBreakpoints()) {
sendCommand("set auto-solib-add on");
sendCommand("set stop-on-solib-events 1");
sendCommand("sharedlibrary "+qq->selectedPluginBreakpointsPattern());
} else if (qq->wantsNoPluginBreakpoints()) {
// should be like that already
sendCommand("set auto-solib-add off");
sendCommand("set stop-on-solib-events 0");
}
} else {
// slow start requested.
// nicer to see a bit of the world we live in
reloadModules();
// this will "continue" if done
m_waitingForBreakpointSynchronizationToContinue = true;
QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
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();
sendCommand("sharedlibrary " + qq->selectedPluginBreakpointsPattern());
continueInferior();
q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString())));
continueInferior();
return;
}
m_modulesListOutdated = true;
// fall through
}
// seen on XP after removing a breakpoint while running
// stdout:945*stopped,reason="signal-received",signal-name="SIGTRAP",
// signal-meaning="Trace/breakpoint trap",thread-id="2",
// frame={addr="0x7c91120f",func="ntdll!DbgUiConnectToDbg",
// args=[],from="C:\\WINDOWS\\system32\\ntdll.dll"}
if (reason == "signal-received"
&& data.findChild("signal-name").toString() == "SIGTRAP") {
continueInferior();
return;
}
@@ -1214,11 +1219,15 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
}
if (isStoppedReason(reason) || reason.isEmpty()) {
if (m_modulesListOutdated) {
reloadModules();
m_modulesListOutdated = false;
}
// Need another round trip
if (reason == "breakpoint-hit") {
q->showStatusMessage(tr("Stopped at breakpoint"));
GdbMi frame = data.findChild("frame");
//qDebug() << frame.toString();
//qDebug() << "HIT BREAKPOINT: " << frame.toString();
m_currentFrame = frame.findChild("addr").data() + '%' +
frame.findChild("func").data() + '%';
@@ -1265,30 +1274,6 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data)
{
qq->notifyInferiorStopped();
//
// Breakpoints
//
//qDebug() << "BREAK ASYNC: " << output.toString();
//sendListBreakpoints();
//attemptBreakpointSynchronization();
//if (m_breakListOnStopNeeded)
// sendListBreakpoints();
// something reasonably 'invariant'
// Linux:
//"79*stopped,reason="end-stepping-range",reason="breakpoint-hit",bkptno="1",
//thread-id="1",frame={addr="0x0000000000405d8f",func="run1",
//args=[{name="argc",value="1"},{name="argv",value="0x7fffb7c23058"}],
//file="test1.cpp",fullname="/home/apoenitz/dev/work/test1/test1.cpp"
//,line="261"}"
// Mac: (but only sometimes)
// "82*stopped,bkpt={number="0",type="step
// resume",disp="keep",enabled="y",addr="0x43127171",at="<Find::
// Internal::FindToolWindow::invokeFindIncremental()
// +225>",thread="1",shlib="/Users/epreuss/dev/ide/main/bin/
// workbench.app/Contents/PlugIns/Trolltech/libFind.1.0.0.dylib",
// frame="0xbfffd800",thread="1",times="1"},
//
// Stack
//
@@ -1370,7 +1355,6 @@ void GdbEngine::handleExecRun(const GdbResultRecord &response)
if (response.resultClass == GdbResultRunning) {
qq->notifyInferiorRunning();
q->showStatusMessage(tr("Running..."));
//reloadModules();
} else if (response.resultClass == GdbResultError) {
QString msg = response.data.findChild("msg").data();
if (msg == "Cannot find bounds of current function") {
@@ -1458,12 +1442,8 @@ void GdbEngine::exitDebugger()
if (m_gdbProc.state() != QProcess::NotRunning)
qDebug() << "PROBLEM STOPPING DEBUGGER";
m_shortToFullName.clear();
m_fullToShortName.clear();
m_varToType.clear();
m_dataDumperState = DataDumperUninitialized;
m_shared = 0;
m_outputCollector.shutdown();
initializeVariables();
//q->settings()->m_debugDumpers = false;
}
@@ -1530,12 +1510,7 @@ bool GdbEngine::startDebugger()
q->showStatusMessage(tr("Gdb Running"));
sendCommand("show version", GdbShowVersion);
if (qq->useFastStart()) {
sendCommand("set auto-solib-add off");
sendCommand("set stop-on-solib-events 1");
}
//sendCommand("-enable-timings");
//sendCommand("set stop-on-solib-events 1");
sendCommand("set print static-members off"); // Seemingly doesn't work.
//sendCommand("define hook-stop\n-thread-list-ids\n-stack-list-frames\nend");
//sendCommand("define hook-stop\nprint 4\nend");
@@ -1604,16 +1579,31 @@ bool GdbEngine::startDebugger()
}
}
if (q->startMode() == q->startInternal) {
emit gdbInputAvailable(QString(), QString());
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
//sendCommand("file " + fileName, GdbFileExecAndSymbols);
#ifdef Q_OS_MAC
sendCommand("sharedlibrary apply-load-rules all");
#endif
setTokenBarrier();
if (!q->m_processArgs.isEmpty())
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
sendCommand("set auto-solib-add off");
sendCommand("x/2i " + startSymbolName(), GdbStart);
}
if (q->startMode() == q->attachExternal) {
sendCommand("attach " + QString::number(q->m_attachedPID));
}
if (q->startMode() == q->startInternal || q->startMode() == q->startExternal) {
sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols);
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("-file-list-exec-source-files", GdbQuerySources);
//sendCommand("-gdb-set stop-on-solib-events 1");
}
@@ -1625,8 +1615,6 @@ bool GdbEngine::startDebugger()
else
qq->breakHandler()->setAllPending();
QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization()));
return true;
}
@@ -1639,25 +1627,26 @@ void GdbEngine::continueInferior()
sendCommand("-exec-continue", GdbExecContinue);
}
void GdbEngine::runInferior()
void GdbEngine::handleStart(const GdbResultRecord &response)
{
q->resetLocation();
// FIXME: this ignores important startup messages
setTokenBarrier();
if (!q->m_processArgs.isEmpty())
sendCommand("-exec-arguments " + q->m_processArgs.join(" "));
if (response.resultClass == GdbResultDone) {
// stdout:&"x/2i _start\n"
// stdout:~"0x404540 <_start>:\txor %ebp,%ebp\n"
// stdout:~"0x404542 <_start+2>:\tmov %rdx,%r9\n"
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);
sendCommand("tbreak *0x" + needle.cap(1));
m_waitingForFirstBreakpointToBeHit = true;
sendCommand("-exec-run");
qq->notifyInferiorRunningRequested();
emit gdbInputAvailable(QString(), QString());
sendCommand("-exec-run", GdbExecRun);
#if defined(Q_OS_WIN)
sendCommand("info proc", GdbInfoProc);
#endif
#if defined(Q_OS_LINUX)
sendCommand("info proc", GdbInfoProc);
#endif
#if defined(Q_OS_MAC)
sendCommand("info pid", GdbInfoProc, QVariant(), true);
#endif
} else {
qDebug() << "PARSING START ADDRESS FAILED" << msg;
}
} else if (response.resultClass == GdbResultError) {
qDebug() << "PARSING START ADDRESS FAILED" << response.toString();
}
}
void GdbEngine::stepExec()
@@ -2108,11 +2097,14 @@ void GdbEngine::handleBreakInsert1(const GdbResultRecord &record, int index)
void GdbEngine::attemptBreakpointSynchronization()
{
// Non-lethal check for nested calls
static bool inBreakpointSychronization = false;
QTC_ASSERT(!inBreakpointSychronization, /**/);
inBreakpointSychronization = true;
BreakHandler *handler = qq->breakHandler();
//qDebug() << "BREAKPOINT SYNCHRONIZATION ";
foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) {
//qDebug() << " SYNCHRONIZATION REMOVING" << data;
QString bpNumber = data->bpNumber;
if (!bpNumber.trimmed().isEmpty())
sendCommand("-break-delete " + bpNumber, BreakDelete, 0, true);
@@ -2178,13 +2170,13 @@ void GdbEngine::attemptBreakpointSynchronization()
}
}
if (updateNeeded) {
//interruptAndContinue();
//sendListBreakpoints();
if (!updateNeeded && m_waitingForBreakpointSynchronizationToContinue) {
m_waitingForBreakpointSynchronizationToContinue = false;
// we continue the execution
continueInferior();
}
if (!updateNeeded && q->status() == DebuggerProcessStartingUp)
qq->notifyStartupFinished();
inBreakpointSychronization = false;
}
@@ -3472,8 +3464,6 @@ void GdbEngine::handleDumpCustomValue1(const GdbResultRecord &record,
&& msg.startsWith("The program being debugged stopped while")
&& msg.contains("qDumpObjectData440")) {
// Fake full stop
sendCommand("-file-list-exec-source-files", GdbQuerySources);
sendCommand("-break-list", BreakList);
sendCommand("p 0", GdbAsyncOutput2); // dummy
return;
}
@@ -3603,7 +3593,7 @@ void GdbEngine::updateLocals()
// '2' is 'list with type and value'
sendSynchronizedCommand("-stack-list-locals 2", StackListLocals); // stage 2/2
tryLoadCustomDumpers();
//tryLoadCustomDumpers();
}
void GdbEngine::handleStackListArguments(const GdbResultRecord &record)
@@ -3949,74 +3939,66 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString &
sendCommand("-var-assign assign " + value, WatchVarAssign);
}
void GdbEngine::tryLoadCustomDumpers()
{
if (m_dataDumperState != DataDumperUninitialized)
return;
PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS");
m_dataDumperState = DataDumperLoadTried;
m_dataDumperState = DataDumperUnavailable;
#if defined(Q_OS_LINUX)
QString lib = q->m_buildDir + "/qtc-gdbmacros/libgdbmacros.so";
if (QFileInfo(lib).isExecutable()) {
if (QFileInfo(lib).exists()) {
m_dataDumperState = DataDumperLoadTried;
//sendCommand("p dlopen");
//if (qq->useFastStart())
// sendCommand("set stop-on-solib-events 0");
QString flag = QString::number(RTLD_NOW);
sendSynchronizedCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
sendCommand("sharedlibrary libc"); // for malloc
sendCommand("sharedlibrary libdl"); // for dlopen
sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
WatchDumpCustomSetup);
// some older systems like CentOS 4.6 prefer this:
sendSynchronizedCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")",
sendCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")",
WatchDumpCustomSetup);
sendSynchronizedCommand("sharedlibrary " + dotEscape(lib));
//if (qq->useFastStart())
// sendCommand("set stop-on-solib-events 1");
} else {
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
<< lib << QFileInfo(lib).isExecutable();
sendCommand("sharedlibrary " + dotEscape(lib));
}
#endif
#if defined(Q_OS_MAC)
QString lib = q->m_buildDir + "/qtc-gdbmacros/libgdbmacros.dylib";
if (QFileInfo(lib).isExecutable()) {
//sendCommand("p dlopen"); // FIXME: remove me
//if (qq->useFastStart())
// sendCommand("set stop-on-solib-events 0");
if (QFileInfo(lib).exists()) {
m_dataDumperState = DataDumperLoadTried;
sendCommand("sharedlibrary libc"); // for malloc
sendCommand("sharedlibrary libdl"); // for dlopen
QString flag = QString::number(RTLD_NOW);
sendSynchronizedCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")",
WatchDumpCustomSetup);
sendSynchronizedCommand("sharedlibrary " + dotEscape(lib));
//if (qq->useFastStart())
// sendCommand("set stop-on-solib-events 1");
} else {
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
<< lib << QFileInfo(lib).isExecutable();
sendCommand("sharedlibrary " + dotEscape(lib));
}
#endif
#if defined(Q_OS_WIN)
QString lib = q->m_buildDir + "/qtc-gdbmacros/debug/gdbmacros.dll";
if (QFileInfo(lib).exists()) {
//if (qq->useFastStart())
// sendCommand("set stop-on-solib-events 0");
m_dataDumperState = DataDumperLoadTried;
sendCommand("sharedlibrary .*"); // for LoadLibraryA
//sendCommand("handle SIGSEGV pass stop print");
//sendCommand("set unwindonsignal off");
sendSynchronizedCommand("call LoadLibraryA(\"" + lib + "\")",
sendCommand("call LoadLibraryA(\"" + lib + "\")",
WatchDumpCustomSetup);
sendSynchronizedCommand("sharedlibrary " + dotEscape(lib));
//if (qq->useFastStart())
// sendCommand("set stop-on-solib-events 1");
} else {
qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: "
<< lib << QFileInfo(lib).isExecutable();
sendCommand("sharedlibrary " + dotEscape(lib));
}
#endif
if (m_dataDumperState == DataDumperLoadTried) {
// retreive list of dumpable classes
sendSynchronizedCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)",
sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)",
GdbQueryDataDumper1);
sendSynchronizedCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper2);
sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper2);
} else {
gdbOutputAvailable("", QString("DEBUG HELPER LIBRARY IS NOT USABLE: "
" %1 EXISTS: %2, EXECUTABLE: %3").arg(lib)
.arg(QFileInfo(lib).exists())
.arg(QFileInfo(lib).isExecutable()));
}
}

View File

@@ -113,7 +113,6 @@ private:
void exitDebugger();
void continueInferior();
void runInferior();
void interruptInferior();
void runToLineExec(const QString &fileName, int lineNumber);
@@ -145,7 +144,8 @@ private:
bool supportsThreads() const;
void init(); // called by destructor
void initializeConnections();
void initializeVariables();
void queryFullName(const QString &fileName, QString *fullName);
QString fullName(const QString &fileName);
QString shortName(const QString &fullName);
@@ -179,7 +179,7 @@ private slots:
private:
int terminationIndex(const QByteArray &buffer, int &length);
void handleStreamOutput(const QString &output, char code);
void handleStart(const GdbResultRecord &response);
void handleAsyncOutput2(const GdbMi &data);
void handleAsyncOutput(const GdbMi &data);
void handleResultRecord(const GdbResultRecord &response);
@@ -189,6 +189,7 @@ private:
void handleExecRunToFunction(const GdbResultRecord &response);
void handleInfoShared(const GdbResultRecord &response);
void handleInfoProc(const GdbResultRecord &response);
void handleInfoThreads(const GdbResultRecord &response);
void handleShowVersion(const GdbResultRecord &response);
void handleQueryPwd(const GdbResultRecord &response);
void handleQuerySources(const GdbResultRecord &response);
@@ -215,7 +216,6 @@ private:
int m_oldestAcceptableToken;
int m_gdbVersion; // 6.8.0 is 680
int m_shared;
// awful hack to keep track of used files
QHash<QString, QString> m_shortToFullName;
@@ -330,6 +330,10 @@ private:
QString m_currentFrame;
QMap<QString, QString> m_varToType;
bool m_waitingForBreakpointSynchronizationToContinue;
bool m_waitingForFirstBreakpointToBeHit;
bool m_modulesListOutdated;
DebuggerManager *q;
IDebuggerManagerAccessForEngines *qq;
};

View File

@@ -6,26 +6,20 @@
<rect>
<x>0</x>
<y>0</y>
<width>465</width>
<height>372</height>
<width>398</width>
<height>385</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBoxLocations">
<property name="title">
<string>Locations</string>
</property>
<layout class="QGridLayout">
<layout class="QGridLayout" name="gridLayout_3">
<property name="margin">
<number>9</number>
</property>
@@ -74,7 +68,70 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBoxPluginDebugging">
<property name="title">
<string>Behaviour of breakpoint setting in plugins</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QRadioButton" name="radioButtonAllPluginBreakpoints">
<property name="toolTip">
<string>This is the slowest but safest option.</string>
</property>
<property name="text">
<string>Try to set breakpoints in plugins always automatically.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="radioButtonSelectedPluginBreakpoints">
<property name="text">
<string>Try to set breakpoints in selected plugins</string>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelSelectedPluginBreakpoints">
<property name="text">
<string>Matching regular expression: </string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditSelectedPluginBreakpointsPattern"/>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QRadioButton" name="radioButtonNoPluginBreakpoints">
<property name="text">
<string>Never set breakpoints in plugins automatically</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBoxUseCustomDumpers">
<property name="toolTip">
<string>Checking this will make the debugger try to use code to format certain data (QObject, QString, std::string etc.) nicely.</string>
@@ -84,17 +141,7 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxFastStart">
<property name="toolTip">
<string>Checking this will make the debugger start fast by loading only very few debug symbols on start up. This might lead to situations where breakpoints can not be set properly. So uncheck this option if you experience breakpoint related problems.</string>
</property>
<property name="text">
<string>Fast debugger start</string>
</property>
</widget>
</item>
<item>
<item row="3" column="0">
<widget class="QCheckBox" name="checkBoxSkipKnownFrames">
<property name="toolTip">
<string>When this option is checked, 'Step Into' compresses several steps into one in certain situations, leading to 'less noisy' debugging. So will, e.g., the atomic
@@ -105,7 +152,7 @@
</property>
</widget>
</item>
<item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkBoxUseToolTips">
<property name="toolTip">
<string>Checking this will make enable tooltips for variable values during debugging. Since this can slow down debugging and does not provide reliable information as it does not use scope information, it is switched off by default.</string>
@@ -115,7 +162,7 @@
</property>
</widget>
</item>
<item>
<item row="5" column="0">
<widget class="QCheckBox" name="checkBoxDebugDumpers">
<property name="toolTip">
<string notr="true">This is an internal tool to make debugging the Custom Data Dumper code easier. Using this action is in general not needed unless you want do debug Qt Creator itself.</string>
@@ -125,29 +172,15 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoStartBox">
<property name="text">
<string>Auto run executable on debugger startup</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoQuitBox">
<property name="text">
<string>Quit debugger when the executable exits</string>
</property>
</widget>
</item>
<item>
<spacer>
<item row="6" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>415</width>
<height>41</height>
<width>10</width>
<height>1</height>
</size>
</property>
</spacer>

View File

@@ -62,7 +62,6 @@ public:
virtual void nextIExec() = 0;
virtual void continueInferior() = 0;
virtual void runInferior() = 0;
virtual void interruptInferior() = 0;
virtual void runToLineExec(const QString &fileName, int lineNumber) = 0;

View File

@@ -45,6 +45,8 @@
#include <QtDesigner/QDesignerFormWindowInterface>
#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerFormWindowManagerInterface>
#include <QtDesigner/QDesignerPropertyEditorInterface>
#include <QtDesigner/QDesignerWidgetDataBaseInterface>
#include <qt_private/formwindowbase_p.h>
#include <qt_private/qtresourcemodel_p.h>
@@ -325,3 +327,25 @@ void FormWindowEditor::activate()
{
m_editorWidget->activate();
}
QString FormWindowEditor::contextHelpId() const
{
// TODO [13.2.09]: Replace this by QDesignerIntegrations context help Id
// in the upcoming version of Qt
QDesignerFormEditorInterface *core = FormEditorW::instance()->designerEditor();
QObject *o = core->propertyEditor()->object();
if (!o)
return QString();
const QDesignerWidgetDataBaseInterface *db = core->widgetDataBase();
const int dbIndex = db->indexOfObject(o, true);
if (dbIndex == -1)
return QString();
QString className = db->item(dbIndex)->name();
if (className == QLatin1String("Line"))
className = QLatin1String("QFrame");
else if (className == QLatin1String("Spacer"))
className = QLatin1String("QSpacerItem");
else if (className == QLatin1String("QLayoutWidget"))
className = QLatin1String("QLayout");
return className;
}

View File

@@ -63,7 +63,6 @@ class EditorWidget;
class FormWindowEditor : public Core::IEditor
{
Q_OBJECT
public:
FormWindowEditor(const QList<int> &context,
QDesignerFormWindowInterface *form,
@@ -84,8 +83,9 @@ public:
bool restoreState(const QByteArray &state);
// ContextInterface
QList<int> context() const;
QWidget *widget();
virtual QList<int> context() const;
virtual QWidget *widget();
virtual QString contextHelpId() const;
QDesignerFormWindowInterface *formWindow() const;
QWidget *integrationContainer();

View File

@@ -207,20 +207,20 @@ void GitClient::diff(const QString &workingDirectory,
QStringList arguments;
arguments << QLatin1String("diff") << diffArgs;
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
command->addJob(arguments);
command->addJob(arguments, m_settings.timeout);
} else {
// Files diff.
if (!unstagedFileNames.empty()) {
QStringList arguments;
arguments << QLatin1String("diff") << diffArgs << QLatin1String("--") << unstagedFileNames;
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
command->addJob(arguments);
command->addJob(arguments, m_settings.timeout);
}
if (!stagedFileNames.empty()) {
QStringList arguments;
arguments << QLatin1String("diff") << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames;
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
command->addJob(arguments);
command->addJob(arguments, m_settings.timeout);
}
}
command->execute();
@@ -503,7 +503,7 @@ void GitClient::executeGit(const QString &workingDirectory,
{
m_plugin->outputWindow()->append(formatCommand(QLatin1String(Constants::GIT_BINARY), arguments));
GitCommand *command = createCommand(workingDirectory, editor, outputToWindow);
command->addJob(arguments);
command->addJob(arguments, m_settings.timeout);
command->execute();
}

View File

@@ -55,8 +55,9 @@ static inline QStringList environmentToList(const ProjectExplorer::Environment &
return ProjectExplorer::Environment::systemEnvironment().toStringList();
}
GitCommand::Job::Job(const QStringList &a) :
arguments(a)
GitCommand::Job::Job(const QStringList &a, int t) :
arguments(a),
timeout(t)
{
}
@@ -67,9 +68,9 @@ GitCommand::GitCommand(const QString &workingDirectory,
{
}
void GitCommand::addJob(const QStringList &arguments)
void GitCommand::addJob(const QStringList &arguments, int timeout)
{
m_jobs.push_back(Job(arguments));
m_jobs.push_back(Job(arguments, timeout));
}
void GitCommand::execute()
@@ -109,7 +110,7 @@ void GitCommand::run()
qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments;
process.start(QLatin1String(Constants::GIT_BINARY), m_jobs.at(j).arguments);
if (!process.waitForFinished()) {
if (!process.waitForFinished(m_jobs.at(j).timeout * 1000)) {
ok = false;
error += QLatin1String("Error: Git timed out");
break;

View File

@@ -49,7 +49,7 @@ public:
ProjectExplorer::Environment &environment);
void addJob(const QStringList &arguments);
void addJob(const QStringList &arguments, int timeout);
void execute();
private:
@@ -61,9 +61,10 @@ Q_SIGNALS:
private:
struct Job {
explicit Job(const QStringList &a);
explicit Job(const QStringList &a, int t);
QStringList arguments;
int timeout;
};
QStringList environment() const;

View File

@@ -40,15 +40,17 @@ static const char *groupC = "Git";
static const char *sysEnvKeyC = "SysEnv";
static const char *pathKeyC = "Path";
static const char *logCountKeyC = "LogCount";
static const char *timeoutKeyC = "TimeOut";
enum { defaultLogCount = 10 };
enum { defaultLogCount = 10 , defaultTimeOut = 30};
namespace Git {
namespace Internal {
GitSettings::GitSettings() :
adoptPath(false),
logCount(defaultLogCount)
logCount(defaultLogCount),
timeout(defaultTimeOut)
{
}
@@ -58,6 +60,7 @@ void GitSettings::fromSettings(QSettings *settings)
adoptPath = settings->value(QLatin1String(sysEnvKeyC), false).toBool();
path = settings->value(QLatin1String(pathKeyC), QString()).toString();
logCount = settings->value(QLatin1String(logCountKeyC), defaultLogCount).toInt();
timeout = settings->value(QLatin1String(timeoutKeyC), defaultTimeOut).toInt();
settings->endGroup();
}
@@ -67,12 +70,13 @@ void GitSettings::toSettings(QSettings *settings) const
settings->setValue(QLatin1String(sysEnvKeyC), adoptPath);
settings->setValue(QLatin1String(pathKeyC), path);
settings->setValue(QLatin1String(logCountKeyC), logCount);
settings->setValue(QLatin1String(timeoutKeyC), timeout);
settings->endGroup();
}
bool GitSettings::equals(const GitSettings &s) const
{
return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount;
return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount && timeout == s.timeout;
}
}

View File

@@ -56,6 +56,7 @@ struct GitSettings
bool adoptPath;
QString path;
int logCount;
int timeout;
};
inline bool operator==(const GitSettings &p1, const GitSettings &p2)

View File

@@ -52,6 +52,7 @@ GitSettings SettingsPageWidget::settings() const
rc.path = m_ui.pathLineEdit->text();
rc.adoptPath = m_ui.environmentGroupBox->isChecked() && !rc.path.isEmpty();
rc.logCount = m_ui.logCountSpinBox->value();
rc.timeout = m_ui.timeoutSpinBox->value();
return rc;
}
@@ -60,6 +61,7 @@ void SettingsPageWidget::setSettings(const GitSettings &s)
m_ui.environmentGroupBox->setChecked(s.adoptPath);
m_ui.pathLineEdit->setText(s.path);
m_ui.logCountSpinBox->setValue(s.logCount);
m_ui.timeoutSpinBox->setValue(s.timeout);
}
void SettingsPageWidget::setSystemPath()

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>403</width>
<height>183</height>
<height>251</height>
</rect>
</property>
<property name="windowTitle">
@@ -69,10 +69,14 @@
</widget>
</item>
<item>
<layout class="QFormLayout" name="logFormLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="logCountLabel">
<property name="text">
<string>Log commit display count:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="logCountSpinBox">
<property name="toolTip">
@@ -83,10 +87,23 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="logCountLabel">
<item row="1" column="0">
<widget class="QLabel" name="timeoutLabel">
<property name="text">
<string>Log commit display count:</string>
<string>Timeout (seconds):</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="timeoutSpinBox">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>300</number>
</property>
<property name="value">
<number>30</number>
</property>
</widget>
</item>

View File

@@ -170,16 +170,24 @@ bool MinGWToolChain::equals(ToolChain *other) const
void MinGWToolChain::addToEnvironment(ProjectExplorer::Environment &env)
{
//qDebug()<<"MinGWToolChain::addToEnvironment";
QString binDir = m_mingwPath + "/bin";
if (QFileInfo(binDir).exists())
env.prependOrSetPath(binDir);
// if (QFileInfo(binDir).exists())
// qDebug()<<"Adding "<<binDir<<" to the PATH";
}
MSVCToolChain::MSVCToolChain(const QString &name)
: m_name(name), m_valuesSet(false)
{
if (m_name.isEmpty()) { // Could be because system qt doesn't set this
QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7",
QSettings::NativeFormat);
if (registry.allKeys().count())
m_name = registry.allKeys().first();
}
}
ToolChain::ToolChainType MSVCToolChain::type() const
@@ -211,10 +219,11 @@ QList<HeaderPath> MSVCToolChain::systemHeaderPaths()
//TODO fix this code
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
addToEnvironment(env);
#ifdef QTCREATOR_WITH_MSVC_INCLUDES
return env.value("INCLUDE").split(QLatin1Char(';'));
#endif
return QList<HeaderPath>();
QList<HeaderPath> headerPaths;
foreach(const QString &path, env.value("INCLUDE").split(QLatin1Char(';'))) {
headerPaths.append(HeaderPath(path, HeaderPath::GlobalHeaderPath));
}
return headerPaths;
}
void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env)
@@ -222,6 +231,8 @@ void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env)
if (!m_valuesSet) {
QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7",
QSettings::NativeFormat);
if (m_name.isEmpty())
return;
QString path = registry.value(m_name).toString();
ProjectExplorer::Environment oldEnv(env);
QString desc;
@@ -264,11 +275,12 @@ void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env)
m_valuesSet = true;
}
//qDebug()<<"MSVC Environment:";
QList< QPair<QString, QString> >::const_iterator it, end;
end = m_values.constEnd();
for (it = m_values.constBegin(); it != end; ++it) {
env.set((*it).first, (*it).second);
qDebug()<<"variable:"<<(*it).first<<"value:"<<(*it).second;
//qDebug()<<"variable:"<<(*it).first<<"value:"<<(*it).second;
}
}
@@ -325,4 +337,6 @@ void WinCEToolChain::addToEnvironment(ProjectExplorer::Environment &env)
CeSdkHandler cesdkhandler;
cesdkhandler.parse(path);
cesdkhandler.find(m_platform).addToEnvironment(env);
//qDebug()<<"WinCE Final Environment:";
//qDebug()<<env.toStringList();
}

View File

@@ -40,6 +40,7 @@ public:
enum ToolChainType
{
GCC,
LinuxICC,
MinGW,
MSVC,
WINCE,

View File

@@ -404,8 +404,10 @@ void Qt4Project::scheduleUpdateCodeModel()
ProjectExplorer::ToolChain *Qt4Project::toolChain(const QString &buildConfiguration) const
{
if (debug)
qDebug()<<"Qt4Project::toolChain() for buildconfiguration:"<<buildConfiguration;
Q_UNUSED(buildConfiguration);
ToolChain *m_test;
ToolChain *m_test= 0;
QtVersion *version = qtVersion(activeBuildConfiguration());
ToolChain::ToolChainType t = version->toolchainType();
if (t == ToolChain::MinGW) {
@@ -415,20 +417,27 @@ ProjectExplorer::ToolChain *Qt4Project::toolChain(const QString &buildConfigurat
qtVersion(activeBuildConfiguration())->addToEnvironment(env);
qmake_cxx = env.searchInPath(qmake_cxx);
m_test = ToolChain::createMinGWToolChain(qmake_cxx, version->mingwDirectory());
qDebug()<<"Mingw ToolChain";
} else if(t == ToolChain::MSVC) {
m_test = ToolChain::createMSVCToolChain(version->msvcVersion());
//qDebug()<<"MSVC ToolChain ("<<version->msvcVersion()<<")";
} else if(t == ToolChain::WINCE) {
m_test = ToolChain::createWinCEToolChain(version->msvcVersion(), version->wincePlatform());
} else if(t == ToolChain::GCC) {
//qDebug()<<"WinCE ToolChain ("<<version->msvcVersion()<<","<<version->wincePlatform()<<")";
} else if(t == ToolChain::GCC || t == ToolChain::LinuxICC) {
QStringList list = rootProjectNode()->variableValue(Internal::CxxCompilerVar);
QString qmake_cxx = list.isEmpty() ? QString::null : list.first();
Environment env = Environment::systemEnvironment();
qtVersion(activeBuildConfiguration())->addToEnvironment(env);
qmake_cxx = env.searchInPath(qmake_cxx);
m_test = ToolChain::createGccToolChain(qmake_cxx);
//qDebug()<<"GCC ToolChain ("<<qmake_cxx<<")";
} else {
qDebug()<<"Could not detect ToolChain for"<<version->mkspec();
qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines.";
}
if (m_test == m_toolChain) {
if (ToolChain::equals(m_test, m_toolChain)) {
delete m_test;
} else {
delete m_toolChain;
@@ -457,8 +466,18 @@ void Qt4Project::updateCodeModel()
const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS"));
ToolChain *tc = toolChain(activeBuildConfiguration());
QByteArray predefinedMacros = tc->predefinedMacros();
QList<HeaderPath> allHeaderPaths = tc->systemHeaderPaths();
QByteArray predefinedMacros;
QList<HeaderPath> allHeaderPaths;
if (tc) {
predefinedMacros = tc->predefinedMacros();
allHeaderPaths = tc->systemHeaderPaths();
//qDebug()<<"Predifined Macros";
//qDebug()<<tc->predefinedMacros();
//qDebug()<<"";
//qDebug()<<"System Header Paths";
//foreach(const HeaderPath &hp, tc->systemHeaderPaths())
// qDebug()<<hp.path();
}
foreach (HeaderPath headerPath, allHeaderPaths) {
if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
allFrameworkPaths.append(headerPath.path());
@@ -696,7 +715,9 @@ ProjectExplorer::Environment Qt4Project::baseEnvironment(const QString &buildCon
{
Environment env = useSystemEnvironment(buildConfiguration) ? Environment(QProcess::systemEnvironment()) : Environment();
qtVersion(buildConfiguration)->addToEnvironment(env);
toolChain(buildConfiguration)->addToEnvironment(env);
ToolChain *tc = toolChain(buildConfiguration);
if (tc)
tc->addToEnvironment(env);
return env;
}
@@ -863,14 +884,14 @@ void Qt4Project::checkForDeletedApplicationProjects()
foreach (Qt4ProFileNode * node, applicationProFiles())
paths.append(node->path());
qDebug()<<"Still existing paths :"<<paths;
// qDebug()<<"Still existing paths :"<<paths;
QList<QSharedPointer<Qt4RunConfiguration> > removeList;
foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) {
if (!paths.contains(qt4rc->proFilePath())) {
removeList.append(qt4rc);
qDebug()<<"Removing runConfiguration for "<<qt4rc->proFilePath();
// qDebug()<<"Removing runConfiguration for "<<qt4rc->proFilePath();
}
}
}

View File

@@ -241,12 +241,17 @@ void QtVersionManager::addNewVersionsFromInstaller()
// or NewQtVersions="qt 4.3.2=c:\\qt\\qt432=c:\\qtcreator\\mingw\\=prependToPath;
// Duplicate entries are not added, the first new version is set as default.
QSettings *settings = Core::ICore::instance()->settings();
if (!settings->contains(newQtVersionsKey))
if (!settings->contains(newQtVersionsKey) &&
!settings->contains(QLatin1String("Installer/")+newQtVersionsKey))
return;
// qDebug()<<"QtVersionManager::addNewVersionsFromInstaller()";
QString newVersionsValue = settings->value(newQtVersionsKey).toString();
if (newVersionsValue.isEmpty())
newVersionsValue = settings->value(QLatin1String("Installer/")+newQtVersionsKey).toString();
QStringList newVersionsList = newVersionsValue.split(';', QString::SkipEmptyParts);
bool defaultVersionWasReset = false;
foreach (QString newVersion, newVersionsList) {
@@ -281,6 +286,7 @@ void QtVersionManager::addNewVersionsFromInstaller()
}
}
settings->remove(newQtVersionsKey);
settings->remove(QLatin1String("Installer/")+newQtVersionsKey);
updateUniqueIdToIndexMap();
}
@@ -1183,14 +1189,17 @@ ProjectExplorer::ToolChain::ToolChainType QtVersion::toolchainType() const
if (!isValid())
return ProjectExplorer::ToolChain::INVALID;
const QString &spec = mkspec();
// qDebug()<<"spec="<<spec;
if (spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc")))
return ProjectExplorer::ToolChain::MSVC;
else if (spec == "win32-g++")
else if (spec.contains("win32-g++"))
return ProjectExplorer::ToolChain::MinGW;
else if (spec == QString::null)
return ProjectExplorer::ToolChain::INVALID;
else if (spec.startsWith("wince"))
else if (spec.contains("wince"))
return ProjectExplorer::ToolChain::WINCE;
else if (spec.contains("linux-icc"))
return ProjectExplorer::ToolChain::LinuxICC;
else
return ProjectExplorer::ToolChain::GCC;
}
@@ -1222,7 +1231,7 @@ QString QtVersion::msvcVersion() const
QString QtVersion::wincePlatform() const
{
qDebug()<<"QtVersion::wincePlatform returning"<<ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf");
// qDebug()<<"QtVersion::wincePlatform returning"<<ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf");
return ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf");
}

View File

@@ -99,6 +99,7 @@ private slots:
void typedef_2();
void typedef_3();
void const_1();
void const_2();
};
void tst_Semantic::function_declaration_1()
@@ -323,7 +324,7 @@ void tst_Semantic::typedef_3()
void tst_Semantic::const_1()
{
QSharedPointer<Document> doc = document("\n"
"int foo(const void *s);\n"
"int foo(const int *s);\n"
);
QCOMPARE(doc->errorCount, 0U);
@@ -340,7 +341,30 @@ void tst_Semantic::const_1()
QVERIFY(! arg->type().isConst());
QVERIFY(arg->type()->isPointerType());
QVERIFY(arg->type()->asPointerType()->elementType().isConst());
QVERIFY(arg->type()->asPointerType()->elementType()->isVoidType());
QVERIFY(arg->type()->asPointerType()->elementType()->isIntegerType());
}
void tst_Semantic::const_2()
{
QSharedPointer<Document> doc = document("\n"
"int foo(char * const s);\n"
);
QCOMPARE(doc->errorCount, 0U);
QCOMPARE(doc->globals->symbolCount(), 1U);
Declaration *decl = doc->globals->symbolAt(0)->asDeclaration();
QVERIFY(decl);
QVERIFY(decl->type()->isFunctionType());
Function *funTy = decl->type()->asFunctionType();
QVERIFY(funTy->returnType()->isIntegerType());
QCOMPARE(funTy->argumentCount(), 1U);
Argument *arg = funTy->argumentAt(0)->asArgument();
QVERIFY(arg);
QVERIFY(arg->type().isConst());
QVERIFY(arg->type()->isPointerType());
QVERIFY(! arg->type()->asPointerType()->elementType().isConst());
QVERIFY(arg->type()->asPointerType()->elementType()->isIntegerType());
}
QTEST_APPLESS_MAIN(tst_Semantic)