From f13d4a104ad34c6fdfffddd19b9bb243c3e56f35 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 26 Oct 2009 17:26:53 +0100 Subject: [PATCH 01/37] Autotests: Compile on Windows Reviewed-by: Roberto Raggi --- src/libs/cplusplus/cplusplus-lib.pri | 7 ++++++- src/libs/cplusplus/cplusplus.pro | 2 +- src/libs/utils/utils.pro | 2 +- src/libs/utils/utils_global.h | 4 +++- src/shared/cplusplus/CPlusPlusForwardDeclarations.h | 2 ++ tests/auto/cplusplus/shared/shared.pri | 2 +- tests/auto/debugger/debugger.pro | 2 +- tests/auto/fakevim/fakevim.pro | 3 +++ 8 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri index 812dbe0c9a4..2e50a401333 100644 --- a/src/libs/cplusplus/cplusplus-lib.pri +++ b/src/libs/cplusplus/cplusplus-lib.pri @@ -1,4 +1,9 @@ -DEFINES += CPLUSPLUS_BUILD_LIB +contains(CONFIG, dll) { + DEFINES += CPLUSPLUS_BUILD_LIB +} else { + DEFINES += CPLUSPLUS_BUILD_STATIC_LIB +} + INCLUDEPATH += $$PWD include(../../shared/cplusplus/cplusplus.pri) diff --git a/src/libs/cplusplus/cplusplus.pro b/src/libs/cplusplus/cplusplus.pro index a6e804439ba..88c6b18e3d3 100644 --- a/src/libs/cplusplus/cplusplus.pro +++ b/src/libs/cplusplus/cplusplus.pro @@ -1,5 +1,5 @@ TEMPLATE = lib - +CONFIG+=dll TARGET = CPlusPlus DEFINES += NDEBUG diff --git a/src/libs/utils/utils.pro b/src/libs/utils/utils.pro index 74939e2f063..88687c63b43 100644 --- a/src/libs/utils/utils.pro +++ b/src/libs/utils/utils.pro @@ -2,7 +2,7 @@ TEMPLATE = lib TARGET = Utils QT += gui \ network -DEFINES += QTCREATOR_UTILS_LIBRARY +DEFINES += QTCREATOR_UTILS_LIB include(../../qtcreatorlibrary.pri) SOURCES += reloadpromptutils.cpp \ settingsutils.cpp \ diff --git a/src/libs/utils/utils_global.h b/src/libs/utils/utils_global.h index a36b6e728b5..f158766087e 100644 --- a/src/libs/utils/utils_global.h +++ b/src/libs/utils/utils_global.h @@ -32,8 +32,10 @@ #include -#if defined(QTCREATOR_UTILS_LIBRARY) +#if defined(QTCREATOR_UTILS_LIB) # define QTCREATOR_UTILS_EXPORT Q_DECL_EXPORT +#elif defined(QTCREATOR_UTILS_STATIC_LIB) // Abuse single files for manual tests +# define QTCREATOR_UTILS_EXPORT #else # define QTCREATOR_UTILS_EXPORT Q_DECL_IMPORT #endif diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h index 9e570d2c1af..9616f51780d 100644 --- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h @@ -54,6 +54,8 @@ # if defined(CPLUSPLUS_BUILD_LIB) # define CPLUSPLUS_EXPORT Q_DECL_EXPORT +# elif defined(CPLUSPLUS_BUILD_STATIC_LIB) +# define CPLUSPLUS_EXPORT # else # define CPLUSPLUS_EXPORT Q_DECL_IMPORT # endif diff --git a/tests/auto/cplusplus/shared/shared.pri b/tests/auto/cplusplus/shared/shared.pri index 80dab035ba8..9b173daa613 100644 --- a/tests/auto/cplusplus/shared/shared.pri +++ b/tests/auto/cplusplus/shared/shared.pri @@ -1,4 +1,4 @@ - +DEFINES+=CPLUSPLUS_BUILD_STATIC_LIB INCLUDEPATH += $$PWD/../../../../src/shared/cplusplus INCLUDEPATH += $$PWD/../../../../src/libs/cplusplus DEPENDPATH += $$INCLUDEPATH . diff --git a/tests/auto/debugger/debugger.pro b/tests/auto/debugger/debugger.pro index ef1547f9ce6..c4cadd3715f 100644 --- a/tests/auto/debugger/debugger.pro +++ b/tests/auto/debugger/debugger.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs -SUBDIRS = dumpers.pro plugin.pro gdb.pro +SUBDIRS = dumpers.pro plugin.pro diff --git a/tests/auto/fakevim/fakevim.pro b/tests/auto/fakevim/fakevim.pro index a4aaea078ed..84c1029e3a6 100644 --- a/tests/auto/fakevim/fakevim.pro +++ b/tests/auto/fakevim/fakevim.pro @@ -1,6 +1,9 @@ QT += testlib +# Defines import symbol as empty +DEFINES+=QTCREATOR_UTILS_STATIC_LIB + FAKEVIMDIR = ../../../src/plugins/fakevim UTILSDIR = ../../../src/libs From ad65077adc42b2087512526e122c97bdc4b26b20 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Mon, 26 Oct 2009 17:26:04 +0100 Subject: [PATCH 02/37] Some refactoring on the Welcome Widget. Generalize tooltips. --- src/libs/utils/welcomemodetreewidget.cpp | 8 +++++-- src/libs/utils/welcomemodetreewidget.h | 2 +- .../projectwelcomepagewidget.cpp | 3 +-- .../welcome/communitywelcomepagewidget.cpp | 22 ++++++++++++++----- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/libs/utils/welcomemodetreewidget.cpp b/src/libs/utils/welcomemodetreewidget.cpp index 1fd3b52a432..b5cd3489515 100644 --- a/src/libs/utils/welcomemodetreewidget.cpp +++ b/src/libs/utils/welcomemodetreewidget.cpp @@ -30,6 +30,7 @@ #include "welcomemodetreewidget.h" #include +#include #include #include @@ -78,7 +79,7 @@ QSize WelcomeModeTreeWidget::sizeHint() const return QSize(QTreeWidget::sizeHint().width(), 30 * topLevelItemCount()); } -QTreeWidgetItem *WelcomeModeTreeWidget::addItem(const QString &label, const QString &data) +QTreeWidgetItem *WelcomeModeTreeWidget::addItem(const QString &label, const QString &data, const QString &toolTip) { QTreeWidgetItem *item = new QTreeWidgetItem(this); item->setIcon(0, m_d->bullet); @@ -94,7 +95,10 @@ QTreeWidgetItem *WelcomeModeTreeWidget::addItem(const QString &label, const QStr wdg->setLayout(lay); setItemWidget(item, 1, wdg); item->setData(0, Qt::UserRole, data); + if (!toolTip.isEmpty()) + wdg->setToolTip(toolTip); return item; + } void WelcomeModeTreeWidget::slotAddNewsItem(const QString &title, const QString &description, const QString &link) @@ -105,7 +109,7 @@ void WelcomeModeTreeWidget::slotAddNewsItem(const QString &title, const QString f.setBold(true); QString elidedTitle = QFontMetrics(f).elidedText(title, Qt::ElideRight, itemWidth); QString data = QString::fromLatin1("%1
%2").arg(elidedTitle).arg(elidedText); - addTopLevelItem(addItem(data,link)); + addTopLevelItem(addItem(data, link, link)); } void WelcomeModeTreeWidget::slotItemClicked(QTreeWidgetItem *item) diff --git a/src/libs/utils/welcomemodetreewidget.h b/src/libs/utils/welcomemodetreewidget.h index 61ae5b6de8c..2dc4cc2f928 100644 --- a/src/libs/utils/welcomemodetreewidget.h +++ b/src/libs/utils/welcomemodetreewidget.h @@ -56,7 +56,7 @@ class QTCREATOR_UTILS_EXPORT WelcomeModeTreeWidget : public QTreeWidget public: WelcomeModeTreeWidget(QWidget *parent = 0); ~WelcomeModeTreeWidget(); - QTreeWidgetItem *addItem(const QString &label, const QString &data); + QTreeWidgetItem *addItem(const QString &label, const QString &data,const QString &toolTip = QString::null); public slots: void slotAddNewsItem(const QString &title, const QString &description, const QString &link); diff --git a/src/plugins/projectexplorer/projectwelcomepagewidget.cpp b/src/plugins/projectexplorer/projectwelcomepagewidget.cpp index df576678443..4df5f9c9a57 100644 --- a/src/plugins/projectexplorer/projectwelcomepagewidget.cpp +++ b/src/plugins/projectexplorer/projectwelcomepagewidget.cpp @@ -119,9 +119,8 @@ void ProjectWelcomePageWidget::updateWelcomePage(const WelcomePageData &welcomeP typedef QPair QStringPair; if (welcomePageData.projectList.count() > 0) { foreach (const QStringPair &it, welcomePageData.projectList) { - QTreeWidgetItem *item = ui->projTreeWidget->addItem(it.second, it.first); const QFileInfo fi(it.first); - item->setToolTip(1, QDir::toNativeSeparators(fi.absolutePath())); + QTreeWidgetItem *item = ui->projTreeWidget->addItem(it.second, it.first, fi.absolutePath()); } } else { ui->projTreeWidget->hide(); diff --git a/src/plugins/welcome/communitywelcomepagewidget.cpp b/src/plugins/welcome/communitywelcomepagewidget.cpp index 5b54f23cb7d..f3048f3b608 100644 --- a/src/plugins/welcome/communitywelcomepagewidget.cpp +++ b/src/plugins/welcome/communitywelcomepagewidget.cpp @@ -32,11 +32,12 @@ #include "rssfetcher.h" +#include #include +#include namespace Welcome { namespace Internal { - CommunityWelcomePageWidget::CommunityWelcomePageWidget(QWidget *parent) : QWidget(parent), m_rssFetcher(new RSSFetcher(7)), @@ -54,13 +55,22 @@ CommunityWelcomePageWidget::CommunityWelcomePageWidget(QWidget *parent) : //: Add localized feed here only if one exists m_rssFetcher->fetch(QUrl(tr("http://labs.trolltech.com/blogs/feed"))); - ui->sitesTreeWidget->addItem(tr("Qt Home"), QLatin1String("http://qt.nokia.com")); - ui->sitesTreeWidget->addItem(tr("Qt Labs"), QLatin1String("http://labs.trolltech.com")); - ui->sitesTreeWidget->addItem(tr("Qt Git Hosting"), QLatin1String("http://qt.gitorious.org")); - ui->sitesTreeWidget->addItem(tr("Qt Centre"), QLatin1String("http://www.qtcentre.org")); - ui->sitesTreeWidget->addItem(tr("Qt for Symbian at Forum Nokia"), QLatin1String("http://discussion.forum.nokia.com/forum/forumdisplay.php?f=196")); + QMap sites; + sites[tr("Qt Home")] = QLatin1String("http://qt.nokia.com"); + sites[tr("Qt Labs")] = QLatin1String("http://labs.qt.nokia.com"); + sites[tr("Qt Git Hosting")] = QLatin1String("http://qt.gitorious.org"); + sites[tr("Qt Centre")] = QLatin1String("http://www.qtcentre.org"); + sites[tr("Qt for Symbian at Forum Nokia")] = QLatin1String("http://discussion.forum.nokia.com/forum/forumdisplay.php?f=196"); + + QMapIterator it(sites); + while (it.hasNext()) { + it.next(); + ui->sitesTreeWidget->addItem(it.key(), it.value(), it.value()); + } + } + CommunityWelcomePageWidget::~CommunityWelcomePageWidget() { delete m_rssFetcher; From b4744214c62645970f93127d8311a4e5fb7b03c5 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Mon, 26 Oct 2009 17:26:44 +0100 Subject: [PATCH 03/37] Add qt-apps.org to the welcome page. --- src/plugins/welcome/communitywelcomepagewidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/welcome/communitywelcomepagewidget.cpp b/src/plugins/welcome/communitywelcomepagewidget.cpp index f3048f3b608..a6ffff280c9 100644 --- a/src/plugins/welcome/communitywelcomepagewidget.cpp +++ b/src/plugins/welcome/communitywelcomepagewidget.cpp @@ -60,6 +60,7 @@ CommunityWelcomePageWidget::CommunityWelcomePageWidget(QWidget *parent) : sites[tr("Qt Labs")] = QLatin1String("http://labs.qt.nokia.com"); sites[tr("Qt Git Hosting")] = QLatin1String("http://qt.gitorious.org"); sites[tr("Qt Centre")] = QLatin1String("http://www.qtcentre.org"); + sites[tr("Qt Apps")] = QLatin1String("http://www.qt-apps.org"); sites[tr("Qt for Symbian at Forum Nokia")] = QLatin1String("http://discussion.forum.nokia.com/forum/forumdisplay.php?f=196"); QMapIterator it(sites); From 82ecb2c7b3ebdd814dc615b51471ad9b8e05faf1 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 17:54:32 +0100 Subject: [PATCH 04/37] Initial work on the `new' GenTemplateInstance. --- src/libs/cplusplus/GenTemplateInstance.cpp | 457 +++++++++++++----- src/libs/cplusplus/GenTemplateInstance.h | 42 +- src/libs/cplusplus/LookupContext.cpp | 4 +- src/libs/cplusplus/LookupContext.h | 1 + src/libs/cplusplus/ResolveExpression.cpp | 16 +- .../auto/cplusplus/semantic/tst_semantic.cpp | 4 +- 6 files changed, 359 insertions(+), 165 deletions(-) diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp index 07555932505..d3c1c895511 100644 --- a/src/libs/cplusplus/GenTemplateInstance.cpp +++ b/src/libs/cplusplus/GenTemplateInstance.cpp @@ -1,145 +1,354 @@ #include "GenTemplateInstance.h" +#include "Overview.h" + #include #include #include #include #include +#include + #include +#include using namespace CPlusPlus; -GenTemplateInstance::GenTemplateInstance(Control *control, const Substitution &substitution) - : _control(control), +namespace { + +class ApplySubstitution +{ +public: + ApplySubstitution(const LookupContext &context, const GenTemplateInstance::Substitution &substitution); + ~ApplySubstitution(); + + Control *control() const { return context.control(); } + + FullySpecifiedType operator()(Name *name); + FullySpecifiedType operator()(const FullySpecifiedType &type); + + int findSubstitution(Identifier *id) const; + FullySpecifiedType applySubstitution(int index) const; + +private: + class ApplyToType: protected TypeVisitor + { + public: + ApplyToType(ApplySubstitution *q) + : q(q) {} + + FullySpecifiedType operator()(const FullySpecifiedType &ty) + { + FullySpecifiedType previousType = switchType(ty); + accept(ty.type()); + return switchType(previousType); + } + + protected: + using TypeVisitor::visit; + + Control *control() const + { return q->control(); } + + FullySpecifiedType switchType(const FullySpecifiedType &type) + { + FullySpecifiedType previousType = _type; + _type = type; + return previousType; + } + + virtual void visit(VoidType *) + { + // nothing to do + } + + virtual void visit(IntegerType *) + { + // nothing to do + } + + virtual void visit(FloatType *) + { + // nothing to do + } + + virtual void visit(PointerToMemberType *) + { + qDebug() << Q_FUNC_INFO; // ### TODO + } + + virtual void visit(PointerType *ptrTy) + { + _type.setType(control()->pointerType(operator()(ptrTy->elementType()))); + } + + virtual void visit(ReferenceType *refTy) + { + _type.setType(control()->referenceType(operator()(refTy->elementType()))); + } + + virtual void visit(ArrayType *arrayTy) + { + _type.setType(control()->arrayType(operator()(arrayTy->elementType()), arrayTy->size())); + } + + virtual void visit(NamedType *ty) + { + FullySpecifiedType n = q->operator ()(ty->name()); + _type.setType(n.type()); + } + + virtual void visit(Function *funTy) + { + Function *fun = control()->newFunction(/*sourceLocation=*/ 0, funTy->name()); + fun->setScope(funTy->scope()); + fun->setConst(funTy->isConst()); + fun->setVolatile(funTy->isVolatile()); + fun->setVirtual(funTy->isVirtual()); + fun->setAmbiguous(funTy->isAmbiguous()); + fun->setVariadic(funTy->isVariadic()); + + fun->setReturnType(q->operator ()(funTy->returnType())); + + for (unsigned i = 0; i < funTy->argumentCount(); ++i) { + Argument *originalArgument = funTy->argumentAt(i)->asArgument(); + Argument *arg = control()->newArgument(/*sourceLocation*/ 0, + originalArgument->name()); + + arg->setType(q->operator ()(originalArgument->type())); + arg->setInitializer(originalArgument->hasInitializer()); + fun->arguments()->enterSymbol(arg); + } + + _type.setType(fun); + } + + virtual void visit(Namespace *) + { + qDebug() << Q_FUNC_INFO; + } + + virtual void visit(Class *) + { + qDebug() << Q_FUNC_INFO; + } + + virtual void visit(Enum *) + { + qDebug() << Q_FUNC_INFO; + } + + virtual void visit(ForwardClassDeclaration *) + { + qDebug() << Q_FUNC_INFO; + } + + virtual void visit(ObjCClass *) + { + qDebug() << Q_FUNC_INFO; + } + + virtual void visit(ObjCProtocol *) + { + qDebug() << Q_FUNC_INFO; + } + + virtual void visit(ObjCMethod *) + { + qDebug() << Q_FUNC_INFO; + } + + virtual void visit(ObjCForwardClassDeclaration *) + { + qDebug() << Q_FUNC_INFO; + } + + virtual void visit(ObjCForwardProtocolDeclaration *) + { + qDebug() << Q_FUNC_INFO; + } + + private: + ApplySubstitution *q; + FullySpecifiedType _type; + }; + + class ApplyToName: protected NameVisitor + { + public: + ApplyToName(ApplySubstitution *q): q(q) {} + + FullySpecifiedType operator()(Name *name) + { + FullySpecifiedType previousType = switchType(FullySpecifiedType()); + accept(name); + return switchType(previousType); + } + + protected: + Control *control() const + { return q->control(); } + + int findSubstitution(Identifier *id) const + { return q->findSubstitution(id); } + + FullySpecifiedType applySubstitution(int index) const + { return q->applySubstitution(index); } + + FullySpecifiedType switchType(const FullySpecifiedType &type) + { + FullySpecifiedType previousType = _type; + _type = type; + return previousType; + } + + virtual void visit(NameId *name) + { + int index = findSubstitution(name->identifier()); + + if (index != -1) + _type = applySubstitution(index); + + else + _type = control()->namedType(name); + } + + virtual void visit(TemplateNameId *name) + { + QVarLengthArray arguments(name->templateArgumentCount()); + for (unsigned i = 0; i < name->templateArgumentCount(); ++i) { + FullySpecifiedType argTy = name->templateArgumentAt(i); + arguments[i] = q->operator ()(argTy); + } + + TemplateNameId *templId = control()->templateNameId(name->identifier(), arguments.data(), arguments.size()); + _type = control()->namedType(templId); + } + + virtual void visit(QualifiedNameId *name) + { + QVarLengthArray names(name->nameCount()); + for (unsigned i = 0; i < name->nameCount(); ++i) { + Name *n = name->nameAt(i); + + if (TemplateNameId *templId = n->asTemplateNameId()) { + QVarLengthArray arguments(templId->templateArgumentCount()); + for (unsigned templateArgIndex = 0; templateArgIndex < templId->templateArgumentCount(); ++templateArgIndex) { + FullySpecifiedType argTy = templId->templateArgumentAt(templateArgIndex); + arguments[templateArgIndex] = q->operator ()(argTy); + } + + n = control()->templateNameId(templId->identifier(), arguments.data(), arguments.size()); + } + + names[i] = n; + } + + QualifiedNameId *q = control()->qualifiedNameId(names.data(), names.size(), name->isGlobal()); + _type = control()->namedType(q); + } + + virtual void visit(DestructorNameId *name) + { + Overview oo; + qWarning() << "ignored name:" << oo(name); + } + + virtual void visit(OperatorNameId *name) + { + Overview oo; + qWarning() << "ignored name:" << oo(name); + } + + virtual void visit(ConversionNameId *name) + { + Overview oo; + qWarning() << "ignored name:" << oo(name); + } + + virtual void visit(SelectorNameId *name) + { + Overview oo; + qWarning() << "ignored name:" << oo(name); + } + + private: + ApplySubstitution *q; + FullySpecifiedType _type; + }; + +public: // attributes + LookupContext context; + GenTemplateInstance::Substitution substitution; + +private: + ApplyToType applyToType; + ApplyToName applyToName; +}; + +ApplySubstitution::ApplySubstitution(const LookupContext &context, const GenTemplateInstance::Substitution &substitution) + : context(context), substitution(substitution), applyToType(this), applyToName(this) +{ } + +ApplySubstitution::~ApplySubstitution() +{ +} + +FullySpecifiedType ApplySubstitution::operator()(Name *name) +{ return applyToName(name); } + +FullySpecifiedType ApplySubstitution::operator()(const FullySpecifiedType &type) +{ return applyToType(type); } + +int ApplySubstitution::findSubstitution(Identifier *id) const +{ + Q_ASSERT(id != 0); + + for (int index = 0; index < substitution.size(); ++index) { + QPair s = substitution.at(index); + + if (id->isEqualTo(s.first)) + return index; + } + + return -1; +} + +FullySpecifiedType ApplySubstitution::applySubstitution(int index) const +{ + Q_ASSERT(index != -1); + Q_ASSERT(index < substitution.size()); + + return substitution.at(index).second; +} + +} // end of anonymous namespace + +GenTemplateInstance::GenTemplateInstance(const LookupContext &context, const Substitution &substitution) + : _symbol(0), + _context(context), _substitution(substitution) { } -FullySpecifiedType GenTemplateInstance::operator()(const FullySpecifiedType &ty) -{ return subst(ty); } - -FullySpecifiedType GenTemplateInstance::subst(Name *name) +FullySpecifiedType GenTemplateInstance::operator()(Symbol *symbol) { - if (TemplateNameId *t = name->asTemplateNameId()) { - QVarLengthArray args(t->templateArgumentCount()); + ApplySubstitution o(_context, _substitution); + return o(symbol->type()); +} - for (unsigned i = 0; i < t->templateArgumentCount(); ++i) - args[i] = subst(t->templateArgumentAt(i)); +Control *GenTemplateInstance::control() const +{ return _context.control(); } - TemplateNameId *n = _control->templateNameId(t->identifier(), - args.data(), args.size()); +int GenTemplateInstance::findSubstitution(Identifier *id) const +{ + int index = 0; - return FullySpecifiedType(_control->namedType(n)); - } else if (name->isQualifiedNameId()) { - // ### implement me + for (; index < _substitution.size(); ++index) { + const QPair s = _substitution.at(index); + + if (id->isEqualTo(s.first)) + break; } - for (int i = 0; i < _substitution.size(); ++i) { - const QPair s = _substitution.at(i); - if (name->isEqualTo(s.first)) - return s.second; - } - - return FullySpecifiedType(_control->namedType(name)); + return index; } - -FullySpecifiedType GenTemplateInstance::subst(const FullySpecifiedType &ty) -{ - FullySpecifiedType previousType = switchType(ty); - TypeVisitor::accept(ty.type()); - return switchType(previousType); -} - -FullySpecifiedType GenTemplateInstance::switchType(const FullySpecifiedType &type) -{ - FullySpecifiedType previousType = _type; - _type = type; - return previousType; -} - -// types -void GenTemplateInstance::visit(PointerToMemberType * /*ty*/) -{ - Q_ASSERT(false); -} - -void GenTemplateInstance::visit(PointerType *ty) -{ - FullySpecifiedType elementType = subst(ty->elementType()); - _type.setType(_control->pointerType(elementType)); -} - -void GenTemplateInstance::visit(ReferenceType *ty) -{ - FullySpecifiedType elementType = subst(ty->elementType()); - _type.setType(_control->referenceType(elementType)); -} - -void GenTemplateInstance::visit(ArrayType *ty) -{ - FullySpecifiedType elementType = subst(ty->elementType()); - _type.setType(_control->arrayType(elementType, ty->size())); -} - -void GenTemplateInstance::visit(NamedType *ty) -{ - Name *name = ty->name(); - _type.setType(subst(name).type()); -} - -void GenTemplateInstance::visit(Function *ty) -{ - Name *name = ty->name(); - FullySpecifiedType returnType = subst(ty->returnType()); - - Function *fun = _control->newFunction(0, name); - fun->setScope(ty->scope()); - fun->setConst(ty->isConst()); - fun->setVolatile(ty->isVolatile()); - fun->setReturnType(returnType); - for (unsigned i = 0; i < ty->argumentCount(); ++i) { - Symbol *arg = ty->argumentAt(i); - FullySpecifiedType argTy = subst(arg->type()); - Argument *newArg = _control->newArgument(0, arg->name()); - newArg->setType(argTy); - fun->arguments()->enterSymbol(newArg); - } - _type.setType(fun); -} - -void GenTemplateInstance::visit(VoidType *) -{ /* nothing to do*/ } - -void GenTemplateInstance::visit(IntegerType *) -{ /* nothing to do*/ } - -void GenTemplateInstance::visit(FloatType *) -{ /* nothing to do*/ } - -void GenTemplateInstance::visit(Namespace *) -{ Q_ASSERT(false); } - -void GenTemplateInstance::visit(Class *) -{ Q_ASSERT(false); } - -void GenTemplateInstance::visit(Enum *) -{ Q_ASSERT(false); } - -// names -void GenTemplateInstance::visit(NameId *) -{ Q_ASSERT(false); } - -void GenTemplateInstance::visit(TemplateNameId *) -{ Q_ASSERT(false); } - -void GenTemplateInstance::visit(DestructorNameId *) -{ Q_ASSERT(false); } - -void GenTemplateInstance::visit(OperatorNameId *) -{ Q_ASSERT(false); } - -void GenTemplateInstance::visit(ConversionNameId *) -{ Q_ASSERT(false); } - -void GenTemplateInstance::visit(QualifiedNameId *) -{ Q_ASSERT(false); } - diff --git a/src/libs/cplusplus/GenTemplateInstance.h b/src/libs/cplusplus/GenTemplateInstance.h index a4845f8bc3d..0d1a8879032 100644 --- a/src/libs/cplusplus/GenTemplateInstance.h +++ b/src/libs/cplusplus/GenTemplateInstance.h @@ -5,51 +5,29 @@ #include #include +#include "LookupContext.h" + #include #include namespace CPlusPlus { -class CPLUSPLUS_EXPORT GenTemplateInstance: protected TypeVisitor, protected NameVisitor +class CPLUSPLUS_EXPORT GenTemplateInstance { public: - typedef QList< QPair > Substitution; + typedef QList< QPair > Substitution; public: - GenTemplateInstance(Control *control, const Substitution &substitution); + GenTemplateInstance(const LookupContext &context, const Substitution &substitution); - FullySpecifiedType operator()(const FullySpecifiedType &ty); + FullySpecifiedType operator()(Symbol *symbol); -protected: - FullySpecifiedType subst(Name *name); - FullySpecifiedType subst(const FullySpecifiedType &ty); - - FullySpecifiedType switchType(const FullySpecifiedType &type); - - virtual void visit(PointerToMemberType * /*ty*/); - virtual void visit(PointerType *ty); - virtual void visit(ReferenceType *ty); - virtual void visit(ArrayType *ty); - virtual void visit(NamedType *ty); - virtual void visit(Function *ty); - virtual void visit(VoidType *); - virtual void visit(IntegerType *); - virtual void visit(FloatType *); - virtual void visit(Namespace *); - virtual void visit(Class *); - virtual void visit(Enum *); - - // names - virtual void visit(NameId *); - virtual void visit(TemplateNameId *); - virtual void visit(DestructorNameId *); - virtual void visit(OperatorNameId *); - virtual void visit(ConversionNameId *); - virtual void visit(QualifiedNameId *); + Control *control() const; + int findSubstitution(Identifier *id) const; private: - Control *_control; - FullySpecifiedType _type; + Symbol *_symbol; + LookupContext _context; const Substitution _substitution; }; diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index ef8b11ccb1a..4d3ed932759 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -347,8 +347,10 @@ QList LookupContext::buildVisibleScopes() } QList LookupContext::visibleScopes(const QPair &result) const +{ return visibleScopes(result.second); } + +QList LookupContext::visibleScopes(Symbol *symbol) const { - Symbol *symbol = result.second; QList scopes; for (Scope *scope = symbol->scope(); scope; scope = scope->enclosingScope()) scopes.append(scope); diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index 5424da869ca..e9d84c83aec 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -98,6 +98,7 @@ public: QList visibleScopes() const { return _visibleScopes; } + QList visibleScopes(Symbol *symbol) const; QList visibleScopes(const QPair &result) const; QList expand(const QList &scopes) const; diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index f89c2c9afd5..43694659a5d 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -695,7 +695,7 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass, QList scopes; _context.expand(klass->members(), _context.visibleScopes(), &scopes); - QList candidates = _context.resolve(memberName, scopes); + const QList candidates = _context.resolve(memberName, scopes); foreach (Symbol *candidate, candidates) { FullySpecifiedType ty = candidate->type(); @@ -710,13 +710,17 @@ ResolveExpression::resolveMember(Name *memberName, Class *klass, for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) { FullySpecifiedType templArgTy = templId->templateArgumentAt(i); - if (i < klass->templateParameterCount()) - subst.append(qMakePair(klass->templateParameterAt(i)->name(), - templArgTy)); + if (i < klass->templateParameterCount()) { + Name *templArgName = klass->templateParameterAt(i)->name(); + if (templArgName && templArgName->identifier()) { + Identifier *templArgId = templArgName->identifier(); + subst.append(qMakePair(templArgId, templArgTy)); + } + } } - GenTemplateInstance inst(control(), subst); - ty = inst(ty); + GenTemplateInstance inst(_context, subst); + ty = inst(candidate); } results.append(Result(ty, candidate)); diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index 827a227f053..6da954ae92f 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -408,12 +408,12 @@ void tst_Semantic::template_instance_1() QVERIFY(decl); GenTemplateInstance::Substitution subst; - Name *nameTp = control.nameId(control.findOrInsertIdentifier("_Tp")); + Identifier *nameTp = control.findOrInsertIdentifier("_Tp"); FullySpecifiedType intTy(control.integerType(IntegerType::Int)); subst.append(qMakePair(nameTp, intTy)); GenTemplateInstance inst(&control, subst); - FullySpecifiedType genTy = inst(decl->type()); + FullySpecifiedType genTy = inst(decl); Overview oo; oo.setShowReturnTypes(true); From a3580ab57640ad76f707f8701e4171db267a9a01 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 18:00:49 +0100 Subject: [PATCH 05/37] Added the copyright header --- src/libs/cplusplus/GenTemplateInstance.cpp | 28 +++++++++++++++++++++ src/libs/cplusplus/GenTemplateInstance.h | 29 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp index d3c1c895511..a7c9d4f6a56 100644 --- a/src/libs/cplusplus/GenTemplateInstance.cpp +++ b/src/libs/cplusplus/GenTemplateInstance.cpp @@ -1,3 +1,31 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ #include "GenTemplateInstance.h" #include "Overview.h" diff --git a/src/libs/cplusplus/GenTemplateInstance.h b/src/libs/cplusplus/GenTemplateInstance.h index 0d1a8879032..69d7d1c885a 100644 --- a/src/libs/cplusplus/GenTemplateInstance.h +++ b/src/libs/cplusplus/GenTemplateInstance.h @@ -1,3 +1,32 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + #ifndef GENTEMPLATEINSTANCE_H #define GENTEMPLATEINSTANCE_H From 9dc11c5d73952df80eedd36135abde9b9cc88d26 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 26 Oct 2009 18:05:11 +0100 Subject: [PATCH 06/37] Debugger: Handle core shutdown, prompt user to terminate debugging. Add a corelistener and trigger on shutdown. Notify about critical states. Reviewed-by: Oswald Buddenhagen --- src/plugins/debugger/debuggermanager.cpp | 4 +- src/plugins/debugger/debuggermanager.h | 2 + src/plugins/debugger/debuggerplugin.cpp | 57 +++++++++++++++++++++++- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 51f7d210c11..a90cb2bbfbc 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -180,7 +180,7 @@ using namespace Debugger::Internal; static const QString tooltipIName = "tooltip"; -static const char *stateName(int s) +const char *DebuggerManager::stateName(int s) { #define SN(x) case x: return #x; switch (s) { @@ -1766,7 +1766,7 @@ void DebuggerManager::ensureLogVisible() QDebug operator<<(QDebug d, DebuggerState state) { - return d << stateName(state) << '(' << int(state) << ')'; + return d << DebuggerManager::stateName(state) << '(' << int(state) << ')'; } ////////////////////////////////////////////////////////////////////// diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index b2c5bb94f5b..5e78170a1ec 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -241,6 +241,8 @@ public slots: void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever void clearCppCodeModelSnapshot(); + static const char *stateName(int s); + public slots: // FIXME void showDebuggerOutput(const QString &msg) { showDebuggerOutput(LogDebug, msg); } diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index c0d60ba6a75..9dca44cb337 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -204,6 +205,60 @@ DebugMode::~DebugMode() EditorManager::instance()->setParent(0); } +/////////////////////////////////////////////////////////////////////// +// +// DebuggerListener: Close the debugging session if running. +// +/////////////////////////////////////////////////////////////////////// + +class DebuggerListener : public Core::ICoreListener { + Q_OBJECT +public: + explicit DebuggerListener(QObject *parent = 0); + virtual bool coreAboutToClose(); +}; + +DebuggerListener::DebuggerListener(QObject *parent) : + Core::ICoreListener(parent) +{ +} + +bool DebuggerListener::coreAboutToClose() +{ + DebuggerManager *mgr = DebuggerManager::instance(); + if (!mgr) + return true; + // Ask to terminate the session. + const QString title = tr("Close Debugging Session"); + bool cleanTermination = false; + switch (mgr->state()) { + case DebuggerNotReady: + return true; + case AdapterStarted: // Most importantly, terminating a running + case AdapterStartFailed: // debuggee can cause problems. + case InferiorUnrunnable: + case InferiorStartFailed: + case InferiorStopped: + case InferiorShutDown: + cleanTermination = true; + break; + default: + break; + } + const QString question = cleanTermination ? + tr("A debugging session is still in progress. Would you like to terminate it?") : + tr("A debugging session is still in progress. Terminating the session in the current" + " state (%1) can leave the target in an inconsistent state." + " Would you like to terminate it?") + .arg(QLatin1String(DebuggerManager::stateName(mgr->state()))); + QMessageBox::StandardButton answer = QMessageBox::question(0, title, question, + QMessageBox::Yes|QMessageBox::No, QMessageBox::No); + if (answer == QMessageBox::No) + return false; + mgr->exitDebugger(); + return true; +} + } // namespace Internal } // namespace Debugger @@ -753,7 +808,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess addAutoReleasedObject(new DebuggingHelperOptionPage); foreach (Core::IOptionsPage* op, engineOptionPages) addAutoReleasedObject(op); - + addAutoReleasedObject(new DebuggerListener); m_locationMark = 0; From 07a5604ab70e5a0af985d8ca5fd82cd5eb119268 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 26 Oct 2009 18:05:37 +0100 Subject: [PATCH 07/37] Removed unused code. --- src/libs/cplusplus/GenTemplateInstance.cpp | 14 -------------- src/libs/cplusplus/GenTemplateInstance.h | 1 - 2 files changed, 15 deletions(-) diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp index a7c9d4f6a56..7282d787adb 100644 --- a/src/libs/cplusplus/GenTemplateInstance.cpp +++ b/src/libs/cplusplus/GenTemplateInstance.cpp @@ -366,17 +366,3 @@ FullySpecifiedType GenTemplateInstance::operator()(Symbol *symbol) Control *GenTemplateInstance::control() const { return _context.control(); } - -int GenTemplateInstance::findSubstitution(Identifier *id) const -{ - int index = 0; - - for (; index < _substitution.size(); ++index) { - const QPair s = _substitution.at(index); - - if (id->isEqualTo(s.first)) - break; - } - - return index; -} diff --git a/src/libs/cplusplus/GenTemplateInstance.h b/src/libs/cplusplus/GenTemplateInstance.h index 69d7d1c885a..a59d1a74717 100644 --- a/src/libs/cplusplus/GenTemplateInstance.h +++ b/src/libs/cplusplus/GenTemplateInstance.h @@ -52,7 +52,6 @@ public: FullySpecifiedType operator()(Symbol *symbol); Control *control() const; - int findSubstitution(Identifier *id) const; private: Symbol *_symbol; From 9abcd93c5ceb8c58295be07a65e8ddaa2a57d0c3 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Mon, 26 Oct 2009 18:34:57 +0100 Subject: [PATCH 08/37] QtS60 Run Configuration: Proper slashes for path Reviewed-By: con --- .../qt-s60/s60devicerunconfigurationwidget.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp index 46ebf4f0443..a80c4200c98 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfigurationwidget.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -67,12 +68,13 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget( m_detailsWidget(new Utils::DetailsWidget), m_serialPortsCombo(new QComboBox), m_nameLineEdit(new QLineEdit(m_runConfiguration->name())), - m_sisxFileLabel(new QLabel(m_runConfiguration->basePackageFilePath() + QLatin1String(".sisx"))), + m_sisxFileLabel(new QLabel), m_deviceInfoButton(new QToolButton), m_deviceInfoDescriptionLabel(new QLabel(tr("Device:"))), m_deviceInfoLabel(new QLabel), m_infoTimeOutTimer(0) { + updateTargetInformation(); QVBoxLayout *mainBoxLayout = new QVBoxLayout(); mainBoxLayout->setMargin(0); setLayout(mainBoxLayout); @@ -100,7 +102,7 @@ S60DeviceRunConfigurationWidget::S60DeviceRunConfigurationWidget( connect(m_serialPortsCombo, SIGNAL(activated(int)), this, SLOT(setSerialPort(int))); QHBoxLayout *serialPortHBoxLayout = new QHBoxLayout; serialPortHBoxLayout->addWidget(m_serialPortsCombo); - serialPortHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored)); + serialPortHBoxLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored)); formLayout->addRow(tr("Device on Serial Port:"), serialPortHBoxLayout); @@ -218,7 +220,8 @@ void S60DeviceRunConfigurationWidget::nameEdited(const QString &text) void S60DeviceRunConfigurationWidget::updateTargetInformation() { - m_sisxFileLabel->setText(m_runConfiguration->basePackageFilePath() + QLatin1String(".sisx")); + m_sisxFileLabel->setText(QDir::toNativeSeparators(m_runConfiguration->basePackageFilePath() + + QLatin1String(".sisx"))); } void S60DeviceRunConfigurationWidget::setSerialPort(int index) From 293b49aecba4807dfdce317938f06c2a9f4b86d0 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 26 Oct 2009 19:59:16 +0100 Subject: [PATCH 09/37] improve messages --- src/plugins/debugger/debuggermanager.cpp | 11 +++++------ src/plugins/debugger/gdb/gdbengine.cpp | 2 +- src/plugins/debugger/watchutils.cpp | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index a90cb2bbfbc..1091b031adf 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -1483,20 +1483,19 @@ void DebuggerManager::showQtDumperLibraryWarning(const QString &details) QMessageBox dialog(mainWindow()); QPushButton *qtPref = dialog.addButton(tr("Open Qt preferences"), QMessageBox::ActionRole); - QPushButton *helperOff = dialog.addButton(tr("Turn helper usage off"), + QPushButton *helperOff = dialog.addButton(tr("Turn off helper usage"), QMessageBox::ActionRole); QPushButton *justContinue = dialog.addButton(tr("Continue anyway"), QMessageBox::AcceptRole); dialog.setDefaultButton(justContinue); dialog.setWindowTitle(tr("Debugging helper missing")); - dialog.setText(tr("The debugger did not find the debugging helper library.")); + dialog.setText(tr("The debugger could not load the debugging helper library.")); dialog.setInformativeText(tr( "The debugging helper is used to nicely format the values of some Qt " "and Standard Library data types. " - "It must be compiled for each Qt version which " - "you can do in the Qt preferences page by selecting " - "a Qt installation and clicking on 'Rebuild' for the debugging " - "helper.")); + "It must be compiled for each used Qt version separately. " + "This can be done in the Qt preferences page by selecting a Qt installation " + "and clicking on 'Rebuild' in the 'Debugging Helper' row.")); if (!details.isEmpty()) dialog.setDetailedText(details); dialog.exec(); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 8980ccec838..88defc4e9d1 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3785,7 +3785,7 @@ void GdbEngine::tryLoadDebuggingHelpers() const QFileInfo fi(lib); if (!fi.exists()) { const QString loc = locations.join(QLatin1String(", ")); - const QString msg = tr("The dumper library was not found at %1.").arg(loc); + const QString msg = tr("The debugging helper library was not found at %1.").arg(loc); debugMessage(msg); manager()->showQtDumperLibraryWarning(msg); return; diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 3e18cd43f7d..1e1137694fd 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -755,7 +755,7 @@ void QtDumperHelper::clear() QString QtDumperHelper::msgDumperOutdated(double requiredVersion, double currentVersion) { return QCoreApplication::translate("QtDumperHelper", - "Found a too-old version of the debugging helper library (%1); version %2 is required."). + "Found an outdated version of the debugging helper library (%1); version %2 is required."). arg(currentVersion).arg(requiredVersion); } From f244008a0fc9e6f59b57c9408939baf388a2a15f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 26 Oct 2009 21:07:42 +0100 Subject: [PATCH 10/37] don't translate debug messages this isn't bullet-proof - integrated error messages are already translated. but at least we know *where* the message comes from. also, saves the translators from some pretty useless work. --- src/plugins/debugger/gdb/gdbengine.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 88defc4e9d1..59ed22c04d5 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3798,16 +3798,15 @@ void GdbEngine::tryLoadDebuggingHelpers() SharedLibraryInjector injector(inferiorPid()); QString errorMessage; if (injector.remoteInject(lib, false, &errorMessage)) { - debugMessage(tr("Dumper injection loading triggered (%1)...").arg(lib)); + debugMessage(_("Dumper injection loading triggered (%1)...").arg(lib)); } else { - debugMessage(tr("Dumper loading (%1) failed: %2").arg(lib, errorMessage)); - debugMessage(errorMessage); + debugMessage(_("Dumper loading (%1) failed: %2").arg(lib, errorMessage)); manager()->showQtDumperLibraryWarning(errorMessage); m_debuggingHelperState = DebuggingHelperUnavailable; return; } } else { - debugMessage(tr("Loading dumpers via debugger call (%1)...").arg(lib)); + debugMessage(_("Loading dumpers via debugger call (%1)...").arg(lib)); postCommand(_("sharedlibrary .*")); // for LoadLibraryA //postCommand(_("handle SIGSEGV pass stop print")); //postCommand(_("set unwindonsignal off")); From 3fd1e5b23fd3917681f98e6b30e5b9c51f37a7e7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Oct 2009 09:51:14 +0100 Subject: [PATCH 11/37] Debugger: Fix exit crash, dump QVariantList with gdb Handle QVariantList within dumpers, as gdb does not resolve typedefs. Disconnect the gdb process on exit, one more round of event loop when quitting. --- share/qtcreator/gdbmacros/gdbmacros.cpp | 11 +++++++++-- share/qtcreator/gdbmacros/test/main.cpp | 22 ++++++++++++++++++++++ src/plugins/debugger/debuggerplugin.cpp | 1 + src/plugins/debugger/gdb/gdbengine.cpp | 2 +- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index ae677bcdb69..648c79e95d3 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -3590,10 +3590,16 @@ static void handleProtocolVersion2and3(QDumper &d) break; case 'V': #ifndef QT_BOOTSTRAPPED - if (isEqual(type, "QVariant")) + if (isEqual(type, "QVariantList")) { // resolve typedef + d.outerType = "QList"; + d.innerType = "QVariant"; + d.extraInt[0] = sizeof(QVariant); + qDumpQList(d); + } else if (isEqual(type, "QVariant")) { qDumpQVariant(d); - else if (isEqual(type, "QVector")) + } else if (isEqual(type, "QVector")) { qDumpQVector(d); + } #endif break; case 'W': @@ -3801,6 +3807,7 @@ void *qDumpObjectData440( "\""NS"QStringList\"," "\""NS"QTextCodec\"," "\""NS"QVariant\"," + "\""NS"QVariantList\"," "\""NS"QVector\"," #if QT_VERSION >= 0x040500 "\""NS"QMultiMap\"," diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp index 60e0989294b..de8fc9f91f2 100644 --- a/share/qtcreator/gdbmacros/test/main.cpp +++ b/share/qtcreator/gdbmacros/test/main.cpp @@ -280,6 +280,27 @@ static int dumpQVariant() return 0; } +static int dumpQVariantList() +{ + QVariantList test; + if (!optEmptyContainers) { + test.push_back(QVariant(QLatin1String("hallo"))); + test.push_back(QVariant(42)); + test.push_back(QVariant(3.141)); + } + // As a list + prepareInBuffer("QList", "local.qvariantlist", "local.qvariantlist", "QVariant"); + qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QVariant), 0,0 ,0); + fputs(qDumpOutBuffer, stdout); + // As typedef + fputs("\n\n", stdout); + prepareInBuffer("QVariantList", "local.qvariantlist", "local.qvariantlist", ""); + qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + // --------------- std types static int dumpStdString() @@ -548,6 +569,7 @@ static TypeDumpFunctionMap registerTypes() rc.insert("QObject", dumpQObject); rc.insert("QObjectList", dumpQObjectList); rc.insert("QVariant", dumpQVariant); + rc.insert("QVariantList", dumpQVariantList); return rc; } diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 9dca44cb337..a305eb278c6 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -256,6 +256,7 @@ bool DebuggerListener::coreAboutToClose() if (answer == QMessageBox::No) return false; mgr->exitDebugger(); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); return true; } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 59ed22c04d5..8b1e3b2c380 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -225,7 +225,7 @@ QMainWindow *GdbEngine::mainWindow() const GdbEngine::~GdbEngine() { // prevent sending error messages afterwards - disconnect(&m_gdbProc); + disconnect(&m_gdbProc, 0, this, 0); delete m_gdbAdapter; m_gdbAdapter = 0; } From 8ef85c6489778041d1530da5c360327972b3444d Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 11:05:35 +0100 Subject: [PATCH 12/37] Removed obsoleted test. --- .../preprocessor/tst_preprocessor.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp index 5a0bff45eb8..8abd64b1e63 100644 --- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp +++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp @@ -8,24 +8,9 @@ class tst_Preprocessor: public QObject Q_OBJECT private Q_SLOTS: - void pp_with_no_client(); - void unfinished_function_like_macro_call(); }; -void tst_Preprocessor::pp_with_no_client() -{ - Client *client = 0; // no client. - Environment env; - - Preprocessor preprocess(client, &env); - QByteArray preprocessed = preprocess(QLatin1String(""), - QByteArray("\n#define foo(a,b) a + b" - "\nfoo(1, 2)\n")); - QByteArray expected = "1 + 2"; - QCOMPARE(preprocessed.trimmed(), expected); -} - void tst_Preprocessor::unfinished_function_like_macro_call() { Client *client = 0; // no client. @@ -35,8 +20,8 @@ void tst_Preprocessor::unfinished_function_like_macro_call() QByteArray preprocessed = preprocess(QLatin1String(""), QByteArray("\n#define foo(a,b) a + b" "\nfoo(1, 2\n")); - QByteArray expected = "foo"; - QCOMPARE(preprocessed.trimmed(), expected); + + QCOMPARE(preprocessed.trimmed(), QByteArray("foo")); } QTEST_APPLESS_MAIN(tst_Preprocessor) From 83a7e0f5186acd1d88d33e397dbe26ef203eb9b9 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 11:31:26 +0100 Subject: [PATCH 13/37] Print the result of the preprocessor. --- tests/manual/preprocessor/main.cpp | 32 ++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/manual/preprocessor/main.cpp b/tests/manual/preprocessor/main.cpp index 64de2e56f54..2aaecb0027d 100644 --- a/tests/manual/preprocessor/main.cpp +++ b/tests/manual/preprocessor/main.cpp @@ -69,9 +69,15 @@ public: #endif } + virtual void passedMacroDefinitionCheck(unsigned, const Macro &) + { } + + virtual void failedMacroDefinitionCheck(unsigned, const QByteArray &) + { } + virtual void startExpandingMacro(unsigned, const Macro &, const QByteArray &, - const QVector &) + bool, const QVector &) { } virtual void stopExpandingMacro(unsigned, const Macro &) @@ -84,11 +90,33 @@ public: { } }; +int make_depend(QCoreApplication *app); + + int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); - QStringList todo = app.arguments(); + QStringList args = app.arguments(); + args.removeFirst(); + + foreach (const QString &fileName, args) { + QFile file(fileName); + if (file.open(QFile::ReadOnly)) { + QTextStream in(&file); + const QString source = in.readAll(); + + Environment env; + Preprocessor pp(/*client=*/ 0, &env); + const QByteArray preprocessedCode = pp(fileName, source); + std::cout << preprocessedCode.constData(); + } + } +} + +int make_depend(QCoreApplication *app) +{ + QStringList todo = app->arguments(); todo.removeFirst(); if (todo.isEmpty()) From fefd72b293d080cfa05eeea27e359e9996dcd6b7 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 12:01:45 +0100 Subject: [PATCH 14/37] Introduced CPlusPlus::FindUsages. --- src/libs/cplusplus/FindUsages.cpp | 444 ++++++++++++++++++++ src/libs/cplusplus/FindUsages.h | 121 ++++++ src/libs/cplusplus/cplusplus-lib.pri | 2 + src/plugins/cpptools/cppfindreferences.cpp | 457 +-------------------- src/plugins/cpptools/cppfindreferences.h | 6 +- 5 files changed, 583 insertions(+), 447 deletions(-) create mode 100644 src/libs/cplusplus/FindUsages.cpp create mode 100644 src/libs/cplusplus/FindUsages.h diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp new file mode 100644 index 00000000000..714f524fdf7 --- /dev/null +++ b/src/libs/cplusplus/FindUsages.cpp @@ -0,0 +1,444 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "FindUsages.h" +#include "TypeOfExpression.h" + +#include +#include +#include +#include +#include + +#include + +using namespace CPlusPlus; + +FindUsages::FindUsages(Document::Ptr doc, const Snapshot &snapshot, QFutureInterface *future) + : ASTVisitor(doc->control()), + _future(future), + _doc(doc), + _snapshot(snapshot), + _source(_doc->source()), + _sem(doc->control()), + _inSimpleDeclaration(0) +{ + _snapshot.insert(_doc); +} + +void FindUsages::setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding) +{ + _globalNamespaceBinding = globalNamespaceBinding; +} + +QList FindUsages::operator()(Symbol *symbol, Identifier *id, AST *ast) +{ + _references.clear(); + _declSymbol = symbol; + _id = id; + _exprDoc = Document::create(""); + accept(ast); + return _references; +} + +QString FindUsages::matchingLine(const Token &tk) const +{ + const char *beg = _source.constData(); + const char *cp = beg + tk.offset; + for (; cp != beg - 1; --cp) { + if (*cp == '\n') + break; + } + + ++cp; + + const char *lineEnd = cp + 1; + for (; *lineEnd; ++lineEnd) { + if (*lineEnd == '\n') + break; + } + + const QString matchingLine = QString::fromUtf8(cp, lineEnd - cp); + return matchingLine; +} + +void FindUsages::reportResult(unsigned tokenIndex, const QList &candidates) +{ + const bool isStrongResult = checkCandidates(candidates); + + if (isStrongResult) + reportResult(tokenIndex); +} + +void FindUsages::reportResult(unsigned tokenIndex) +{ + const Token &tk = tokenAt(tokenIndex); + const QString lineText = matchingLine(tk); + + unsigned line, col; + getTokenStartPosition(tokenIndex, &line, &col); + + if (col) + --col; // adjust the column position. + + const int len = tk.f.length; + + if (_future) { + const QString path = QDir::toNativeSeparators(_doc->fileName()); + _future->reportResult(Usage(path, line, lineText, col, len)); + } + + _references.append(tokenIndex); +} + +bool FindUsages::checkCandidates(const QList &candidates) const +{ + if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates, _globalNamespaceBinding.data())) { + +#if 0 + qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName() + << canonicalSymbol->line() << canonicalSymbol->column() + << "candidates:" << candidates.size(); +#endif + + return checkSymbol(canonicalSymbol); + } + + return false; +} + +bool FindUsages::checkScope(Symbol *symbol, Symbol *otherSymbol) const +{ + if (! (symbol && otherSymbol)) + return false; + + else if (symbol->scope() == otherSymbol->scope()) + return true; + + else if (symbol->name() && otherSymbol->name()) { + + if (! symbol->name()->isEqualTo(otherSymbol->name())) + return false; + + } else if (symbol->name() != otherSymbol->name()) { + return false; + } + + return checkScope(symbol->enclosingSymbol(), otherSymbol->enclosingSymbol()); +} + +bool FindUsages::checkSymbol(Symbol *symbol) const +{ + if (! symbol) { + return false; + + } else if (symbol == _declSymbol) { + return true; + + } else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) { + if (! qstrcmp(symbol->fileName(), _declSymbol->fileName())) + return true; + + } else if (symbol->isForwardClassDeclaration() && (_declSymbol->isClass() || + _declSymbol->isForwardClassDeclaration())) { + return checkScope(symbol, _declSymbol); + + } else if (_declSymbol->isForwardClassDeclaration() && (symbol->isClass() || + symbol->isForwardClassDeclaration())) { + return checkScope(symbol, _declSymbol); + } + + return false; +} + +LookupContext FindUsages::currentContext(AST *ast) +{ + unsigned line, column; + getTokenStartPosition(ast->firstToken(), &line, &column); + Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); + + if (lastVisibleSymbol && lastVisibleSymbol == _previousContext.symbol()) + return _previousContext; + + LookupContext ctx(lastVisibleSymbol, _exprDoc, _doc, _snapshot); + _previousContext = ctx; + return ctx; +} + +void FindUsages::ensureNameIsValid(NameAST *ast) +{ + if (ast && ! ast->name) + ast->name = _sem.check(ast, /*scope = */ 0); +} + +bool FindUsages::visit(MemInitializerAST *ast) +{ + if (ast->name && ast->name->asSimpleName() != 0) { + ensureNameIsValid(ast->name); + + SimpleNameAST *simple = ast->name->asSimpleName(); + if (identifier(simple->identifier_token) == _id) { + LookupContext context = currentContext(ast); + const QList candidates = context.resolve(simple->name); + reportResult(simple->identifier_token, candidates); + } + } + accept(ast->expression); + return false; +} + +bool FindUsages::visit(PostfixExpressionAST *ast) +{ + _postfixExpressionStack.append(ast); + return true; +} + +void FindUsages::endVisit(PostfixExpressionAST *) +{ + _postfixExpressionStack.removeLast(); +} + +bool FindUsages::visit(MemberAccessAST *ast) +{ + if (ast->member_name) { + if (SimpleNameAST *simple = ast->member_name->asSimpleName()) { + if (identifier(simple->identifier_token) == _id) { + Q_ASSERT(! _postfixExpressionStack.isEmpty()); + + checkExpression(_postfixExpressionStack.last()->firstToken(), + simple->identifier_token); + + return false; + } + } + } + + return true; +} + +void FindUsages::checkExpression(unsigned startToken, unsigned endToken) +{ + const unsigned begin = tokenAt(startToken).begin(); + const unsigned end = tokenAt(endToken).end(); + + const QString expression = _source.mid(begin, end - begin); + // qDebug() << "*** check expression:" << expression; + + TypeOfExpression typeofExpression; + typeofExpression.setSnapshot(_snapshot); + + unsigned line, column; + getTokenStartPosition(startToken, &line, &column); + Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); + + const QList results = + typeofExpression(expression, _doc, lastVisibleSymbol, + TypeOfExpression::Preprocess); + + QList candidates; + + foreach (TypeOfExpression::Result r, results) { + FullySpecifiedType ty = r.first; + Symbol *lastVisibleSymbol = r.second; + + candidates.append(lastVisibleSymbol); + } + + reportResult(endToken, candidates); +} + +bool FindUsages::visit(QualifiedNameAST *ast) +{ + for (NestedNameSpecifierAST *nested_name_specifier = ast->nested_name_specifier; + nested_name_specifier; nested_name_specifier = nested_name_specifier->next) { + + if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) { + SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName(); + + TemplateIdAST *template_id = 0; + if (! simple_name) { + template_id = class_or_namespace_name->asTemplateId(); + + if (template_id) { + for (TemplateArgumentListAST *template_arguments = template_id->template_arguments; + template_arguments; template_arguments = template_arguments->next) { + accept(template_arguments->template_argument); + } + } + } + + if (simple_name || template_id) { + const unsigned identifier_token = simple_name + ? simple_name->identifier_token + : template_id->identifier_token; + + if (identifier(identifier_token) == _id) + checkExpression(ast->firstToken(), identifier_token); + } + } + } + + if (NameAST *unqualified_name = ast->unqualified_name) { + unsigned identifier_token = 0; + + if (SimpleNameAST *simple_name = unqualified_name->asSimpleName()) + identifier_token = simple_name->identifier_token; + + else if (DestructorNameAST *dtor_name = unqualified_name->asDestructorName()) + identifier_token = dtor_name->identifier_token; + + TemplateIdAST *template_id = 0; + if (! identifier_token) { + template_id = unqualified_name->asTemplateId(); + + if (template_id) { + identifier_token = template_id->identifier_token; + + for (TemplateArgumentListAST *template_arguments = template_id->template_arguments; + template_arguments; template_arguments = template_arguments->next) { + accept(template_arguments->template_argument); + } + } + } + + if (identifier_token && identifier(identifier_token) == _id) + checkExpression(ast->firstToken(), identifier_token); + } + + return false; +} + +bool FindUsages::visit(EnumeratorAST *ast) +{ + Identifier *id = identifier(ast->identifier_token); + if (id == _id) { + LookupContext context = currentContext(ast); + const QList candidates = context.resolve(control()->nameId(id)); + reportResult(ast->identifier_token, candidates); + } + + accept(ast->expression); + + return false; +} + +bool FindUsages::visit(SimpleNameAST *ast) +{ + Identifier *id = identifier(ast->identifier_token); + if (id == _id) { + LookupContext context = currentContext(ast); + const QList candidates = context.resolve(ast->name); + reportResult(ast->identifier_token, candidates); + } + + return false; +} + +bool FindUsages::visit(DestructorNameAST *ast) +{ + Identifier *id = identifier(ast->identifier_token); + if (id == _id) { + LookupContext context = currentContext(ast); + const QList candidates = context.resolve(ast->name); + reportResult(ast->identifier_token, candidates); + } + + return false; +} + +bool FindUsages::visit(TemplateIdAST *ast) +{ + if (_id == identifier(ast->identifier_token)) { + LookupContext context = currentContext(ast); + const QList candidates = context.resolve(ast->name); + reportResult(ast->identifier_token, candidates); + } + + for (TemplateArgumentListAST *template_arguments = ast->template_arguments; + template_arguments; template_arguments = template_arguments->next) { + accept(template_arguments->template_argument); + } + + return false; +} + +bool FindUsages::visit(ParameterDeclarationAST *ast) +{ + for (SpecifierAST *spec = ast->type_specifier; spec; spec = spec->next) + accept(spec); + + if (DeclaratorAST *declarator = ast->declarator) { + for (SpecifierAST *attr = declarator->attributes; attr; attr = attr->next) + accept(attr); + + for (PtrOperatorAST *ptr_op = declarator->ptr_operators; ptr_op; ptr_op = ptr_op->next) + accept(ptr_op); + + if (! _inSimpleDeclaration) // visit the core declarator only if we are not in simple-declaration. + accept(declarator->core_declarator); + + for (PostfixDeclaratorAST *fx_op = declarator->postfix_declarators; fx_op; fx_op = fx_op->next) + accept(fx_op); + + for (SpecifierAST *spec = declarator->post_attributes; spec; spec = spec->next) + accept(spec); + + accept(declarator->initializer); + } + + accept(ast->expression); + return false; +} + +bool FindUsages::visit(ExpressionOrDeclarationStatementAST *ast) +{ + accept(ast->declaration); + return false; +} + +bool FindUsages::visit(FunctionDeclaratorAST *ast) +{ + accept(ast->parameters); + + for (SpecifierAST *spec = ast->cv_qualifier_seq; spec; spec = spec->next) + accept(spec); + + accept(ast->exception_specification); + + return false; +} + +bool FindUsages::visit(SimpleDeclarationAST *) +{ + ++_inSimpleDeclaration; + return true; +} + +void FindUsages::endVisit(SimpleDeclarationAST *) +{ --_inSimpleDeclaration; } diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h new file mode 100644 index 00000000000..9f829493806 --- /dev/null +++ b/src/libs/cplusplus/FindUsages.h @@ -0,0 +1,121 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef FINDUSAGES_H +#define FINDUSAGES_H + +#include "LookupContext.h" +#include "CppDocument.h" +#include "CppBindings.h" +#include "Semantic.h" + +#include +#include + +namespace CPlusPlus { + +class CPLUSPLUS_EXPORT Usage +{ +public: + Usage() + : line(0), col(0), len(0) {} + + Usage(const QString &path, int line, const QString &lineText, int col, int len) + : path(path), line(line), lineText(lineText), col(col), len(len) {} + +public: + QString path; + int line; + QString lineText; + int col; + int len; +}; + +class CPLUSPLUS_EXPORT FindUsages: protected ASTVisitor +{ +public: + FindUsages(Document::Ptr doc, const Snapshot &snapshot, QFutureInterface *future); + + void setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding); + + QList operator()(Symbol *symbol, Identifier *id, AST *ast); + +protected: + using ASTVisitor::visit; + using ASTVisitor::endVisit; + + QString matchingLine(const Token &tk) const; + + void reportResult(unsigned tokenIndex, const QList &candidates); + void reportResult(unsigned tokenIndex); + + bool checkSymbol(Symbol *symbol) const; + bool checkCandidates(const QList &candidates) const; + bool checkScope(Symbol *symbol, Symbol *otherSymbol) const; + void checkExpression(unsigned startToken, unsigned endToken); + + LookupContext currentContext(AST *ast); + + void ensureNameIsValid(NameAST *ast); + + virtual bool visit(MemInitializerAST *ast); + virtual bool visit(PostfixExpressionAST *ast); + virtual void endVisit(PostfixExpressionAST *); + virtual bool visit(MemberAccessAST *ast); + virtual bool visit(QualifiedNameAST *ast); + virtual bool visit(EnumeratorAST *ast); + virtual bool visit(SimpleNameAST *ast); + virtual bool visit(DestructorNameAST *ast); + virtual bool visit(TemplateIdAST *ast); + virtual bool visit(ParameterDeclarationAST *ast); + virtual bool visit(ExpressionOrDeclarationStatementAST *ast); + virtual bool visit(FunctionDeclaratorAST *ast); + virtual bool visit(SimpleDeclarationAST *); + virtual void endVisit(SimpleDeclarationAST *); + +private: + QFutureInterface *_future; + Identifier *_id; + Symbol *_declSymbol; + Document::Ptr _doc; + Snapshot _snapshot; + QByteArray _source; + Document::Ptr _exprDoc; + Semantic _sem; + NamespaceBindingPtr _globalNamespaceBinding; + QList _postfixExpressionStack; + QList _qualifiedNameStack; + QList _references; + LookupContext _previousContext; + int _inSimpleDeclaration; +}; + +} // end of namespace CPlusPlus + +#endif // FINDUSAGES_H diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri index 2e50a401333..611fadf0ac4 100644 --- a/src/libs/cplusplus/cplusplus-lib.pri +++ b/src/libs/cplusplus/cplusplus-lib.pri @@ -38,6 +38,7 @@ HEADERS += \ $$PWD/CppBindings.h \ $$PWD/ASTParent.h \ $$PWD/GenTemplateInstance.h \ + $$PWD/FindUsages.h \ $$PWD/CheckUndefinedSymbols.h \ $$PWD/PreprocessorClient.h \ $$PWD/PreprocessorEnvironment.h \ @@ -61,6 +62,7 @@ SOURCES += \ $$PWD/CppBindings.cpp \ $$PWD/ASTParent.cpp \ $$PWD/GenTemplateInstance.cpp \ + $$PWD/FindUsages.cpp \ $$PWD/CheckUndefinedSymbols.cpp \ $$PWD/PreprocessorClient.cpp \ $$PWD/PreprocessorEnvironment.cpp \ diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 06ae9790602..f8eb27419df 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -50,11 +50,8 @@ #include #include -#include -#include #include -#include -#include +#include #include #include @@ -65,438 +62,6 @@ using namespace CppTools::Internal; using namespace CPlusPlus; -namespace { - -struct Process: protected ASTVisitor -{ -public: - Process(Document::Ptr doc, const Snapshot &snapshot, - QFutureInterface *future) - : ASTVisitor(doc->control()), - _future(future), - _doc(doc), - _snapshot(snapshot), - _source(_doc->source()), - _sem(doc->control()), - _inSimpleDeclaration(0) - { - _snapshot.insert(_doc); - } - - void setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding) - { - _globalNamespaceBinding = globalNamespaceBinding; - } - - QList operator()(Symbol *symbol, Identifier *id, AST *ast) - { - _references.clear(); - _declSymbol = symbol; - _id = id; - _exprDoc = Document::create(""); - accept(ast); - return _references; - } - -protected: - using ASTVisitor::visit; - - QString matchingLine(const Token &tk) const - { - const char *beg = _source.constData(); - const char *cp = beg + tk.offset; - for (; cp != beg - 1; --cp) { - if (*cp == '\n') - break; - } - - ++cp; - - const char *lineEnd = cp + 1; - for (; *lineEnd; ++lineEnd) { - if (*lineEnd == '\n') - break; - } - - const QString matchingLine = QString::fromUtf8(cp, lineEnd - cp); - return matchingLine; - - } - - void reportResult(unsigned tokenIndex, const QList &candidates) - { - const bool isStrongResult = checkCandidates(candidates); - - if (isStrongResult) - reportResult(tokenIndex); - } - - void reportResult(unsigned tokenIndex) - { - const Token &tk = tokenAt(tokenIndex); - const QString lineText = matchingLine(tk); - - unsigned line, col; - getTokenStartPosition(tokenIndex, &line, &col); - - if (col) - --col; // adjust the column position. - - const int len = tk.f.length; - - if (_future) - _future->reportResult(Utils::FileSearchResult(QDir::toNativeSeparators(_doc->fileName()), - line, lineText, col, len)); - - _references.append(tokenIndex); - } - - bool checkCandidates(const QList &candidates) const - { - if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates, _globalNamespaceBinding.data())) { - -#if 0 - qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName() - << canonicalSymbol->line() << canonicalSymbol->column() - << "candidates:" << candidates.size(); -#endif - - return isDeclSymbol(canonicalSymbol); - } - - return false; - } - - bool checkScope(Symbol *symbol, Symbol *otherSymbol) const - { - if (! (symbol && otherSymbol)) - return false; - - else if (symbol->scope() == otherSymbol->scope()) - return true; - - else if (symbol->name() && otherSymbol->name()) { - - if (! symbol->name()->isEqualTo(otherSymbol->name())) - return false; - - } else if (symbol->name() != otherSymbol->name()) { - return false; - } - - return checkScope(symbol->enclosingSymbol(), otherSymbol->enclosingSymbol()); - } - - bool isDeclSymbol(Symbol *symbol) const - { - if (! symbol) { - return false; - - } else if (symbol == _declSymbol) { - return true; - - } else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) { - if (! qstrcmp(symbol->fileName(), _declSymbol->fileName())) - return true; - - } else if (symbol->isForwardClassDeclaration() && (_declSymbol->isClass() || - _declSymbol->isForwardClassDeclaration())) { - return checkScope(symbol, _declSymbol); - - } else if (_declSymbol->isForwardClassDeclaration() && (symbol->isClass() || - symbol->isForwardClassDeclaration())) { - return checkScope(symbol, _declSymbol); - } - - return false; - } - - LookupContext _previousContext; - - LookupContext currentContext(AST *ast) - { - unsigned line, column; - getTokenStartPosition(ast->firstToken(), &line, &column); - Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); - - if (lastVisibleSymbol && lastVisibleSymbol == _previousContext.symbol()) - return _previousContext; - - LookupContext ctx(lastVisibleSymbol, _exprDoc, _doc, _snapshot); - _previousContext = ctx; - return ctx; - } - - void ensureNameIsValid(NameAST *ast) - { - if (ast && ! ast->name) - ast->name = _sem.check(ast, /*scope = */ 0); - } - - virtual bool visit(MemInitializerAST *ast) - { - if (ast->name && ast->name->asSimpleName() != 0) { - ensureNameIsValid(ast->name); - - SimpleNameAST *simple = ast->name->asSimpleName(); - if (identifier(simple->identifier_token) == _id) { - LookupContext context = currentContext(ast); - const QList candidates = context.resolve(simple->name); - reportResult(simple->identifier_token, candidates); - } - } - accept(ast->expression); - return false; - } - - virtual bool visit(PostfixExpressionAST *ast) - { - _postfixExpressionStack.append(ast); - return true; - } - - virtual void endVisit(PostfixExpressionAST *) - { - _postfixExpressionStack.removeLast(); - } - - virtual bool visit(MemberAccessAST *ast) - { - if (ast->member_name) { - if (SimpleNameAST *simple = ast->member_name->asSimpleName()) { - if (identifier(simple->identifier_token) == _id) { - Q_ASSERT(! _postfixExpressionStack.isEmpty()); - - checkExpression(_postfixExpressionStack.last()->firstToken(), - simple->identifier_token); - - return false; - } - } - } - - return true; - } - - void checkExpression(unsigned startToken, unsigned endToken) - { - const unsigned begin = tokenAt(startToken).begin(); - const unsigned end = tokenAt(endToken).end(); - - const QString expression = _source.mid(begin, end - begin); - // qDebug() << "*** check expression:" << expression; - - TypeOfExpression typeofExpression; - typeofExpression.setSnapshot(_snapshot); - - unsigned line, column; - getTokenStartPosition(startToken, &line, &column); - Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); - - const QList results = - typeofExpression(expression, _doc, lastVisibleSymbol, - TypeOfExpression::Preprocess); - - QList candidates; - - foreach (TypeOfExpression::Result r, results) { - FullySpecifiedType ty = r.first; - Symbol *lastVisibleSymbol = r.second; - - candidates.append(lastVisibleSymbol); - } - - reportResult(endToken, candidates); - } - - virtual bool visit(QualifiedNameAST *ast) - { - for (NestedNameSpecifierAST *nested_name_specifier = ast->nested_name_specifier; - nested_name_specifier; nested_name_specifier = nested_name_specifier->next) { - - if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) { - SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName(); - - TemplateIdAST *template_id = 0; - if (! simple_name) { - template_id = class_or_namespace_name->asTemplateId(); - - if (template_id) { - for (TemplateArgumentListAST *template_arguments = template_id->template_arguments; - template_arguments; template_arguments = template_arguments->next) { - accept(template_arguments->template_argument); - } - } - } - - if (simple_name || template_id) { - const unsigned identifier_token = simple_name - ? simple_name->identifier_token - : template_id->identifier_token; - - if (identifier(identifier_token) == _id) - checkExpression(ast->firstToken(), identifier_token); - } - } - } - - if (NameAST *unqualified_name = ast->unqualified_name) { - unsigned identifier_token = 0; - - if (SimpleNameAST *simple_name = unqualified_name->asSimpleName()) - identifier_token = simple_name->identifier_token; - - else if (DestructorNameAST *dtor_name = unqualified_name->asDestructorName()) - identifier_token = dtor_name->identifier_token; - - TemplateIdAST *template_id = 0; - if (! identifier_token) { - template_id = unqualified_name->asTemplateId(); - - if (template_id) { - identifier_token = template_id->identifier_token; - - for (TemplateArgumentListAST *template_arguments = template_id->template_arguments; - template_arguments; template_arguments = template_arguments->next) { - accept(template_arguments->template_argument); - } - } - } - - if (identifier_token && identifier(identifier_token) == _id) - checkExpression(ast->firstToken(), identifier_token); - } - - return false; - } - - virtual bool visit(EnumeratorAST *ast) - { - Identifier *id = identifier(ast->identifier_token); - if (id == _id) { - LookupContext context = currentContext(ast); - const QList candidates = context.resolve(control()->nameId(id)); - reportResult(ast->identifier_token, candidates); - } - - accept(ast->expression); - - return false; - } - - virtual bool visit(SimpleNameAST *ast) - { - Identifier *id = identifier(ast->identifier_token); - if (id == _id) { - LookupContext context = currentContext(ast); - const QList candidates = context.resolve(ast->name); - reportResult(ast->identifier_token, candidates); - } - - return false; - } - - virtual bool visit(DestructorNameAST *ast) - { - Identifier *id = identifier(ast->identifier_token); - if (id == _id) { - LookupContext context = currentContext(ast); - const QList candidates = context.resolve(ast->name); - reportResult(ast->identifier_token, candidates); - } - - return false; - } - - virtual bool visit(TemplateIdAST *ast) - { - if (_id == identifier(ast->identifier_token)) { - LookupContext context = currentContext(ast); - const QList candidates = context.resolve(ast->name); - reportResult(ast->identifier_token, candidates); - } - - for (TemplateArgumentListAST *template_arguments = ast->template_arguments; - template_arguments; template_arguments = template_arguments->next) { - accept(template_arguments->template_argument); - } - - return false; - } - - virtual bool visit(ParameterDeclarationAST *ast) - { - for (SpecifierAST *spec = ast->type_specifier; spec; spec = spec->next) - accept(spec); - - if (DeclaratorAST *declarator = ast->declarator) { - for (SpecifierAST *attr = declarator->attributes; attr; attr = attr->next) - accept(attr); - - for (PtrOperatorAST *ptr_op = declarator->ptr_operators; ptr_op; ptr_op = ptr_op->next) - accept(ptr_op); - - if (! _inSimpleDeclaration) // visit the core declarator only if we are not in simple-declaration. - accept(declarator->core_declarator); - - for (PostfixDeclaratorAST *fx_op = declarator->postfix_declarators; fx_op; fx_op = fx_op->next) - accept(fx_op); - - for (SpecifierAST *spec = declarator->post_attributes; spec; spec = spec->next) - accept(spec); - - accept(declarator->initializer); - } - - accept(ast->expression); - return false; - } - - virtual bool visit(ExpressionOrDeclarationStatementAST *ast) - { - accept(ast->declaration); - return false; - } - - virtual bool visit(FunctionDeclaratorAST *ast) - { - accept(ast->parameters); - - for (SpecifierAST *spec = ast->cv_qualifier_seq; spec; spec = spec->next) - accept(spec); - - accept(ast->exception_specification); - - return false; - } - - virtual bool visit(SimpleDeclarationAST *) - { - ++_inSimpleDeclaration; - return true; - } - - virtual void endVisit(SimpleDeclarationAST *) - { --_inSimpleDeclaration; } - -private: - QFutureInterface *_future; - Identifier *_id; // ### remove me - Symbol *_declSymbol; - Document::Ptr _doc; - Snapshot _snapshot; - QByteArray _source; - Document::Ptr _exprDoc; - Semantic _sem; - NamespaceBindingPtr _globalNamespaceBinding; - QList _postfixExpressionStack; - QList _qualifiedNameStack; - QList _references; - int _inSimpleDeclaration; -}; - -} // end of anonymous namespace - CppFindReferences::CppFindReferences(CppTools::CppModelManagerInterface *modelManager) : _modelManager(modelManager), _resultWindow(ExtensionSystem::PluginManager::instance()->getObject()) @@ -526,14 +91,14 @@ QList CppFindReferences::references(Symbol *symbol, TranslationUnit *translationUnit = doc->translationUnit(); Q_ASSERT(translationUnit != 0); - Process process(doc, snapshot, /*future = */ 0); + FindUsages process(doc, snapshot, /*future = */ 0); process.setGlobalNamespaceBinding(bind(doc, snapshot)); references = process(symbol, id, translationUnit->ast()); return references; } -static void find_helper(QFutureInterface &future, +static void find_helper(QFutureInterface &future, const QMap wl, Snapshot snapshot, Symbol *symbol) @@ -613,7 +178,7 @@ static void find_helper(QFutureInterface &future, tm.start(); - Process process(doc, snapshot, &future); + FindUsages process(doc, snapshot, &future); process.setGlobalNamespaceBinding(bind(doc, snapshot)); TranslationUnit *unit = doc->translationUnit(); @@ -666,7 +231,7 @@ void CppFindReferences::findAll_helper(Symbol *symbol) Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager(); - QFuture result = QtConcurrent::run(&find_helper, wl, snapshot, symbol); + QFuture result = QtConcurrent::run(&find_helper, wl, snapshot, symbol); m_watcher.setFuture(result); Core::FutureProgress *progress = progressManager->addTask(result, tr("Searching..."), @@ -759,12 +324,12 @@ void CppFindReferences::onReplaceButtonClicked(const QString &text, void CppFindReferences::displayResult(int index) { - Utils::FileSearchResult result = m_watcher.future().resultAt(index); - _resultWindow->addResult(result.fileName, - result.lineNumber, - result.matchingLine, - result.matchStart, - result.matchLength); + Usage result = m_watcher.future().resultAt(index); + _resultWindow->addResult(result.path, + result.line, + result.lineText, + result.col, + result.len); } void CppFindReferences::searchFinished() diff --git a/src/plugins/cpptools/cppfindreferences.h b/src/plugins/cpptools/cppfindreferences.h index cbddf8fb5c3..5cdfbdcecb3 100644 --- a/src/plugins/cpptools/cppfindreferences.h +++ b/src/plugins/cpptools/cppfindreferences.h @@ -42,6 +42,10 @@ namespace Find { struct SearchResultItem; } // end of namespace Find +namespace CPlusPlus { + class Usage; +} // end of namespace CPlusPlus + namespace CppTools { class CppModelManagerInterface; @@ -78,7 +82,7 @@ private: private: QPointer _modelManager; Find::SearchResultWindow *_resultWindow; - QFutureWatcher m_watcher; + QFutureWatcher m_watcher; }; } // end of namespace Internal From 65e13b70345b546c55b561ef490cce652f5534a3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Oct 2009 12:25:11 +0100 Subject: [PATCH 15/37] Debugger: Fix autotests on Windows Format pointers consistently using 0x%[l]x in printf/scanf. Remove %p formatting as the existence of the prefix 0x is platform-dependent (missing with MSVC), which caused a scanf error and thus dumper crash for QAbstractItem. Reviewed-by: ck --- share/qtcreator/gdbmacros/gdbmacros.cpp | 27 +++++++++++++------------ tests/auto/debugger/tst_dumpers.cpp | 12 ++++++++--- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index 648c79e95d3..b49a7fcceac 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -57,6 +57,12 @@ #include #include +#if (QT_POINTER_SIZE==4) // How to printf/scanf a pointer (uintptr_t) +# define POINTER_PRINTFORMAT "0x%x" +#else +# define POINTER_PRINTFORMAT "0x%lx" +#endif + #ifndef QT_BOOTSTRAPPED #include @@ -630,18 +636,10 @@ QDumper &QDumper::put(int i) QDumper &QDumper::put(const void *p) { - static char buf[100]; if (p) { - sprintf(buf, "%p", p); - // we get a '0x' prefix only on some implementations. - // if it isn't there, write it out manually. - if (buf[1] != 'x') { - put('0'); - put('x'); - } - put(buf); + pos += sprintf(outBuffer + pos, POINTER_PRINTFORMAT, reinterpret_cast(p)); } else { - put(""); + pos += sprintf(outBuffer + pos, ""); } return *this; } @@ -1070,7 +1068,10 @@ static void qDumpQAbstractItem(QDumper &d) QModelIndex mi; { ModelIndex *mm = reinterpret_cast(&mi); - sscanf(d.templateParameters[0], "%d,%d,%p,%p", &mm->r, &mm->c, &mm->p, &mm->m); + mm->r = mm->c = 0; + mm->p = mm->m = 0; + sscanf(d.templateParameters[0], "%d,%d,"POINTER_PRINTFORMAT","POINTER_PRINTFORMAT, &mm->r, &mm->c, + reinterpret_cast(&mm->p), reinterpret_cast(&mm->m)); } const QAbstractItemModel *m = mi.model(); const int rowCount = m->rowCount(mi); @@ -2149,8 +2150,8 @@ static void qDumpQVariantHelper(const QVariant *v, QString *value, default: { char buf[1000]; const char *format = (v->typeName()[0] == 'Q') - ? "'"NS"%s "NS"qVariantValue<"NS"%s >'(*('"NS"QVariant'*)%p)" - : "'%s "NS"qVariantValue<%s >'(*('"NS"QVariant'*)%p)"; + ? "'"NS"%s "NS"qVariantValue<"NS"%s >'(*('"NS"QVariant'*)"POINTER_PRINTFORMAT")" + : "'%s "NS"qVariantValue<%s >'(*('"NS"QVariant'*)"POINTER_PRINTFORMAT")"; qsnprintf(buf, sizeof(buf) - 1, format, v->typeName(), v->typeName(), v); *exp = QLatin1String(buf); *numchild = 1; diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 7dc603f664a..eff6f97dbd2 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -10,6 +10,12 @@ #include //#include +#if (QT_POINTER_SIZE==4) +# define POINTER_PRINTFORMAT "0x%x" +#else +# define POINTER_PRINTFORMAT "0x%lx" +#endif + #undef NS #ifdef QT_NAMESPACE # define STRINGIFY0(s) #s @@ -387,7 +393,7 @@ static void testDumper(QByteArray expected0, const void *data, QByteArray outert extraInt0, extraInt1, extraInt2, extraInt3); QString expected(expected0); char buf[100]; - sprintf(buf, "%p", data); + sprintf(buf, POINTER_PRINTFORMAT, (uintptr_t)data); if ((!expected.startsWith('t') && !expected.startsWith('f')) || expected.startsWith("type")) expected = "tiname='$I',addr='$A'," + expected; @@ -417,7 +423,7 @@ static void testDumper(QByteArray expected0, const void *data, QByteArray outert QByteArray str(const void *p) { char buf[100]; - sprintf(buf, "%p", p); + sprintf(buf, POINTER_PRINTFORMAT, (uintptr_t)p); return buf; } @@ -880,7 +886,7 @@ void tst_Debugger::dumpQByteArray() &ba, NS"QByteArray", true); // Case 5: Regular and special characters and the replacement character. - ba = QByteArray("abc\a\n\r\e\'\"?"); + ba = QByteArray("abc\a\n\r\033\'\"?"); testDumper("value='YWJjBwoNGyciPw==',valueencoded='1',type='"NS"QByteArray'," "numchild='10',childtype='char',childnumchild='0',children=[" "{value='61 (97 'a')'},{value='62 (98 'b')'}," From b7f3d924c356fb808e6ab61a42ca492d0c1d6e3b Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 12:31:49 +0100 Subject: [PATCH 16/37] Remove duplicates from the working list. --- src/libs/cplusplus/FindUsages.cpp | 4 +++- src/plugins/cpptools/cppfindreferences.cpp | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp index 714f524fdf7..46f98920f73 100644 --- a/src/libs/cplusplus/FindUsages.cpp +++ b/src/libs/cplusplus/FindUsages.cpp @@ -122,9 +122,11 @@ bool FindUsages::checkCandidates(const QList &candidates) const if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates, _globalNamespaceBinding.data())) { #if 0 + Symbol *c = candidates.first(); qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName() << canonicalSymbol->line() << canonicalSymbol->column() - << "candidates:" << candidates.size(); + << "candidates:" << candidates.size() + << c->fileName() << c->line() << c->column(); #endif return checkSymbol(canonicalSymbol); diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index f8eb27419df..3a7a0b0970f 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -127,6 +127,8 @@ static void find_helper(QFutureInterface &future, files += snapshot.dependsOn(sourceFile); } + files.removeDuplicates(); + //qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size(); future.setProgressRange(0, files.size()); From 43ff8a0fb0ab535c3bc0ff95e9d37676e3b4384e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Oct 2009 12:36:07 +0100 Subject: [PATCH 17/37] Compile Windows --- src/plugins/cpptools/cppfindreferences.cpp | 1 - src/plugins/cpptools/cppfindreferences.h | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 3a7a0b0970f..01f7668d7d5 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -51,7 +51,6 @@ #include #include #include -#include #include #include diff --git a/src/plugins/cpptools/cppfindreferences.h b/src/plugins/cpptools/cppfindreferences.h index 5cdfbdcecb3..61ba876546f 100644 --- a/src/plugins/cpptools/cppfindreferences.h +++ b/src/plugins/cpptools/cppfindreferences.h @@ -36,16 +36,13 @@ #include #include #include +#include namespace Find { class SearchResultWindow; struct SearchResultItem; } // end of namespace Find -namespace CPlusPlus { - class Usage; -} // end of namespace CPlusPlus - namespace CppTools { class CppModelManagerInterface; From 60902c69bc358c1a1b122d9080461c1c69067784 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 14:03:19 +0100 Subject: [PATCH 18/37] Set the `virtual' attribute. --- src/shared/cplusplus/CheckDeclaration.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index 6a81784360a..616ea0fe137 100644 --- a/src/shared/cplusplus/CheckDeclaration.cpp +++ b/src/shared/cplusplus/CheckDeclaration.cpp @@ -190,6 +190,7 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast) fun->setScope(_scope); fun->setName(name); fun->setMethodKey(semantic()->currentMethodKey()); + fun->setVirtual(qualTy.isVirtual()); if (isQ_SIGNAL) fun->setMethodKey(Function::SignalMethod); else if (isQ_SLOT) From 4f9efcba7b282011ac632b97d25c723fd2ab765e Mon Sep 17 00:00:00 2001 From: con Date: Tue, 27 Oct 2009 14:43:42 +0100 Subject: [PATCH 19/37] "MWC Directory" is not a good term. Use "Carbide Directory" instead, because that's what it is. --- src/plugins/qt4projectmanager/qtoptionspage.cpp | 2 +- src/plugins/qt4projectmanager/qtversionmanager.ui | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qt4projectmanager/qtoptionspage.cpp b/src/plugins/qt4projectmanager/qtoptionspage.cpp index 70d83b6590d..48e39d27e42 100644 --- a/src/plugins/qt4projectmanager/qtoptionspage.cpp +++ b/src/plugins/qt4projectmanager/qtoptionspage.cpp @@ -121,7 +121,7 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList ver m_ui->mingwPath->setExpectedKind(Utils::PathChooser::Directory); m_ui->mingwPath->setPromptDialogTitle(tr("Select the MinGW Directory")); m_ui->mwcPath->setExpectedKind(Utils::PathChooser::Directory); - m_ui->mwcPath->setPromptDialogTitle(tr("Select \"x86build\" Directory from Carbide Install")); + m_ui->mwcPath->setPromptDialogTitle(tr("Select Carbide Install Directory")); m_ui->addButton->setIcon(QIcon(Core::Constants::ICON_PLUS)); m_ui->delButton->setIcon(QIcon(Core::Constants::ICON_MINUS)); diff --git a/src/plugins/qt4projectmanager/qtversionmanager.ui b/src/plugins/qt4projectmanager/qtversionmanager.ui index 81d7156c4bc..2f3d39e7f02 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.ui +++ b/src/plugins/qt4projectmanager/qtversionmanager.ui @@ -210,7 +210,7 @@ p, li { white-space: pre-wrap; } - MWC Directory: + Carbide Directory: From 9ff5676e72365faa6394a3874a5ec31124829a11 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 14:59:10 +0100 Subject: [PATCH 20/37] Introduced FullySpecifiedType::copySpecifiers() --- src/shared/cplusplus/FullySpecifiedType.cpp | 19 +++++++++++++++++++ src/shared/cplusplus/FullySpecifiedType.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/shared/cplusplus/FullySpecifiedType.cpp b/src/shared/cplusplus/FullySpecifiedType.cpp index 578c6c9b7d6..a9063fda67f 100644 --- a/src/shared/cplusplus/FullySpecifiedType.cpp +++ b/src/shared/cplusplus/FullySpecifiedType.cpp @@ -80,6 +80,10 @@ FullySpecifiedType FullySpecifiedType::qualifiedType() const ty.setExtern(false); ty.setMutable(false); ty.setTypedef(false); + + ty.setInline(false); + ty.setVirtual(false); + ty.setExplicit(false); return ty; } @@ -209,4 +213,19 @@ FullySpecifiedType FullySpecifiedType::simplified() const return *this; } +void FullySpecifiedType::copySpecifiers(const FullySpecifiedType &type) +{ + // class storage specifiers + f._isFriend = type.f._isFriend; + f._isRegister = type.f._isRegister; + f._isStatic = type.f._isStatic; + f._isExtern = type.f._isExtern; + f._isMutable = type.f._isMutable; + f._isTypedef = type.f._isTypedef; + + // function specifiers + f._isInline = type.f._isInline; + f._isVirtual = type.f._isVirtual; + f._isExplicit = type.f._isExplicit; +} diff --git a/src/shared/cplusplus/FullySpecifiedType.h b/src/shared/cplusplus/FullySpecifiedType.h index 6c9f83d9145..5aea04dca18 100644 --- a/src/shared/cplusplus/FullySpecifiedType.h +++ b/src/shared/cplusplus/FullySpecifiedType.h @@ -121,6 +121,8 @@ public: FullySpecifiedType simplified() const; + void copySpecifiers(const FullySpecifiedType &type); + private: Type *_type; struct Flags { From 38d3ded8329f8dcb9ae33c329269a4677cc7d438 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 14:59:27 +0100 Subject: [PATCH 21/37] Set the `virtual' attribute of a function definition. --- src/shared/cplusplus/CheckDeclaration.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index 616ea0fe137..7e7d01d9071 100644 --- a/src/shared/cplusplus/CheckDeclaration.cpp +++ b/src/shared/cplusplus/CheckDeclaration.cpp @@ -190,7 +190,7 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast) fun->setScope(_scope); fun->setName(name); fun->setMethodKey(semantic()->currentMethodKey()); - fun->setVirtual(qualTy.isVirtual()); + fun->setVirtual(ty.isVirtual()); if (isQ_SIGNAL) fun->setMethodKey(Function::SignalMethod); else if (isQ_SLOT) @@ -282,6 +282,7 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast) } Function *fun = funTy->asFunctionType(); + fun->setVirtual(ty.isVirtual()); fun->setStartOffset(tokenAt(ast->firstToken()).offset); fun->setEndOffset(tokenAt(ast->lastToken()).offset); if (ast->declarator) From 6526143626b7ee9f8a2d64ac11179da5b27450a2 Mon Sep 17 00:00:00 2001 From: mae Date: Tue, 27 Oct 2009 15:22:01 +0100 Subject: [PATCH 22/37] apply insert-whole-lines magic only if the cursor is at the beginning of the line. --- src/plugins/texteditor/basetexteditor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 440acd8456d..e9beb84e156 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -4651,7 +4651,8 @@ void BaseTextEditor::insertFromMimeData(const QMimeData *source) || text.endsWith(QChar::ParagraphSeparator) || text.endsWith(QLatin1Char('\r'))); - if (hasFinalNewline) // since we'll add a final newline, preserve current line's indentation + if (insertAtBeginningOfLine + && hasFinalNewline) // since we'll add a final newline, preserve current line's indentation cursor.setPosition(cursor.block().position()); int cursorPosition = cursor.position(); From 0b294b41c7f7239da03332e891301441290c6bf3 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Tue, 27 Oct 2009 15:26:37 +0100 Subject: [PATCH 23/37] S60: Falling back to epocRoot if toolsRoot is empty. Reviewed-by: con --- src/plugins/qt4projectmanager/qt-s60/s60devices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp index a9aa6dceb58..1667ed4294b 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp @@ -140,6 +140,8 @@ bool S60Devices::readWin() device.toolsRoot = xml.readElementText(); } } + if (device.toolsRoot.isEmpty()) + device.toolsRoot = device.epocRoot; m_devices.append(device); } } From 213316f2a7feb2bb62fb281a975d2b0d1d03b08b Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 16:08:23 +0100 Subject: [PATCH 24/37] Handle ambiguous function declarations vs c++-like initialized declarations. --- src/libs/cplusplus/ResolveExpression.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index 43694659a5d..2ae4f84da1c 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -566,6 +566,11 @@ ResolveExpression::resolveBaseExpression(const QList &baseResults, int a FullySpecifiedType ty = result.first.simplified(); Symbol *lastVisibleSymbol = result.second; + if (Function *funTy = ty->asFunctionType()) { + if (funTy->isAmbiguous()) + ty = funTy->returnType().simplified(); + } + if (accessOp == T_ARROW) { if (lastVisibleSymbol && ty->isClassType() && ! lastVisibleSymbol->isClass()) { // ### remove ! lastVisibleSymbol->isClass() from the condition. From 960716df45dbb6603d5fe1195a7abb9b4a0210a5 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 27 Oct 2009 16:12:39 +0100 Subject: [PATCH 25/37] Cleanup --- src/libs/cplusplus/GenTemplateInstance.cpp | 51 +++++++++++++--------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/src/libs/cplusplus/GenTemplateInstance.cpp b/src/libs/cplusplus/GenTemplateInstance.cpp index 7282d787adb..0267efeefa8 100644 --- a/src/libs/cplusplus/GenTemplateInstance.cpp +++ b/src/libs/cplusplus/GenTemplateInstance.cpp @@ -47,13 +47,13 @@ namespace { class ApplySubstitution { public: - ApplySubstitution(const LookupContext &context, const GenTemplateInstance::Substitution &substitution); + ApplySubstitution(const LookupContext &context, Symbol *symbol, const GenTemplateInstance::Substitution &substitution); ~ApplySubstitution(); Control *control() const { return context.control(); } - FullySpecifiedType operator()(Name *name); - FullySpecifiedType operator()(const FullySpecifiedType &type); + FullySpecifiedType apply(Name *name); + FullySpecifiedType apply(const FullySpecifiedType &type); int findSubstitution(Identifier *id) const; FullySpecifiedType applySubstitution(int index) const; @@ -107,22 +107,22 @@ private: virtual void visit(PointerType *ptrTy) { - _type.setType(control()->pointerType(operator()(ptrTy->elementType()))); + _type.setType(control()->pointerType(q->apply(ptrTy->elementType()))); } virtual void visit(ReferenceType *refTy) { - _type.setType(control()->referenceType(operator()(refTy->elementType()))); + _type.setType(control()->referenceType(q->apply(refTy->elementType()))); } virtual void visit(ArrayType *arrayTy) { - _type.setType(control()->arrayType(operator()(arrayTy->elementType()), arrayTy->size())); + _type.setType(control()->arrayType(q->apply(arrayTy->elementType()), arrayTy->size())); } virtual void visit(NamedType *ty) { - FullySpecifiedType n = q->operator ()(ty->name()); + FullySpecifiedType n = q->apply(ty->name()); _type.setType(n.type()); } @@ -136,14 +136,14 @@ private: fun->setAmbiguous(funTy->isAmbiguous()); fun->setVariadic(funTy->isVariadic()); - fun->setReturnType(q->operator ()(funTy->returnType())); + fun->setReturnType(q->apply(funTy->returnType())); for (unsigned i = 0; i < funTy->argumentCount(); ++i) { Argument *originalArgument = funTy->argumentAt(i)->asArgument(); Argument *arg = control()->newArgument(/*sourceLocation*/ 0, originalArgument->name()); - arg->setType(q->operator ()(originalArgument->type())); + arg->setType(q->apply(originalArgument->type())); arg->setInitializer(originalArgument->hasInitializer()); fun->arguments()->enterSymbol(arg); } @@ -199,6 +199,7 @@ private: private: ApplySubstitution *q; FullySpecifiedType _type; + QHash _processed; }; class ApplyToName: protected NameVisitor @@ -246,7 +247,7 @@ private: QVarLengthArray arguments(name->templateArgumentCount()); for (unsigned i = 0; i < name->templateArgumentCount(); ++i) { FullySpecifiedType argTy = name->templateArgumentAt(i); - arguments[i] = q->operator ()(argTy); + arguments[i] = q->apply(argTy); } TemplateNameId *templId = control()->templateNameId(name->identifier(), arguments.data(), arguments.size()); @@ -263,7 +264,7 @@ private: QVarLengthArray arguments(templId->templateArgumentCount()); for (unsigned templateArgIndex = 0; templateArgIndex < templId->templateArgumentCount(); ++templateArgIndex) { FullySpecifiedType argTy = templId->templateArgumentAt(templateArgIndex); - arguments[templateArgIndex] = q->operator ()(argTy); + arguments[templateArgIndex] = q->apply(argTy); } n = control()->templateNameId(templId->identifier(), arguments.data(), arguments.size()); @@ -307,26 +308,34 @@ private: public: // attributes LookupContext context; + Symbol *symbol; GenTemplateInstance::Substitution substitution; - -private: ApplyToType applyToType; ApplyToName applyToName; }; -ApplySubstitution::ApplySubstitution(const LookupContext &context, const GenTemplateInstance::Substitution &substitution) - : context(context), substitution(substitution), applyToType(this), applyToName(this) +ApplySubstitution::ApplySubstitution(const LookupContext &context, Symbol *symbol, + const GenTemplateInstance::Substitution &substitution) + : context(context), symbol(symbol), + substitution(substitution), + applyToType(this), applyToName(this) { } ApplySubstitution::~ApplySubstitution() { } -FullySpecifiedType ApplySubstitution::operator()(Name *name) -{ return applyToName(name); } +FullySpecifiedType ApplySubstitution::apply(Name *name) +{ + FullySpecifiedType ty = applyToName(name); + return ty; +} -FullySpecifiedType ApplySubstitution::operator()(const FullySpecifiedType &type) -{ return applyToType(type); } +FullySpecifiedType ApplySubstitution::apply(const FullySpecifiedType &type) +{ + FullySpecifiedType ty = applyToType(type); + return ty; +} int ApplySubstitution::findSubstitution(Identifier *id) const { @@ -360,8 +369,8 @@ GenTemplateInstance::GenTemplateInstance(const LookupContext &context, const Sub FullySpecifiedType GenTemplateInstance::operator()(Symbol *symbol) { - ApplySubstitution o(_context, _substitution); - return o(symbol->type()); + ApplySubstitution o(_context, symbol, _substitution); + return o.apply(symbol->type()); } Control *GenTemplateInstance::control() const From 833b86d5e2edf67005ccbe0cf4b0fb0eeb7d4fcb Mon Sep 17 00:00:00 2001 From: dt Date: Tue, 27 Oct 2009 16:13:09 +0100 Subject: [PATCH 26/37] Fix that the cmake plugin did not allow removing build targets --- src/plugins/cmakeprojectmanager/makestep.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp index 1d88b4cddac..3a9b975882e 100644 --- a/src/plugins/cmakeprojectmanager/makestep.cpp +++ b/src/plugins/cmakeprojectmanager/makestep.cpp @@ -132,9 +132,11 @@ void MakeStep::setBuildTarget(const QString &buildConfiguration, const QString & { QStringList old = value(buildConfiguration, "buildTargets").toStringList(); if (on && !old.contains(target)) - setValue(buildConfiguration, "buildTargets", old << target); + old.append(target); else if(!on && old.contains(target)) - setValue(buildConfiguration, "buildTargets", old.removeOne(target)); + old.removeOne(target); + + setValue(buildConfiguration, "buildTargets", old); } QStringList MakeStep::additionalArguments(const QString &buildConfiguration) const From 6010b02e1887264a1f714c0a72c9d71d61c8884b Mon Sep 17 00:00:00 2001 From: dt Date: Tue, 27 Oct 2009 16:14:18 +0100 Subject: [PATCH 27/37] Fix setBuildTargets() in the generic project manager --- src/plugins/genericprojectmanager/genericmakestep.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/genericprojectmanager/genericmakestep.cpp b/src/plugins/genericprojectmanager/genericmakestep.cpp index 0ce416f2f5a..57e648d455e 100644 --- a/src/plugins/genericprojectmanager/genericmakestep.cpp +++ b/src/plugins/genericprojectmanager/genericmakestep.cpp @@ -142,9 +142,10 @@ void GenericMakeStep::setBuildTarget(const QString &buildConfiguration, const QS { QStringList old = value(buildConfiguration, "buildTargets").toStringList(); if (on && !old.contains(target)) - setValue(buildConfiguration, "buildTargets", old << target); + old << target; else if(!on && old.contains(target)) - setValue(buildConfiguration, "buildTargets", old.removeOne(target)); + old.removeOne(target); + setValue(buildConfiguration, "buildTargets", old); } // From 7bbd2532e84968ba2bb56328e8b794360acf467d Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 26 Oct 2009 13:37:27 +0100 Subject: [PATCH 28/37] compile fix with namespaces --- src/plugins/qmleditor/parser/qmljsastvisitor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmleditor/parser/qmljsastvisitor.cpp b/src/plugins/qmleditor/parser/qmljsastvisitor.cpp index 642bcee26b9..d3a1d530682 100644 --- a/src/plugins/qmleditor/parser/qmljsastvisitor.cpp +++ b/src/plugins/qmleditor/parser/qmljsastvisitor.cpp @@ -41,7 +41,7 @@ #include "qmljsastvisitor_p.h" -QT_BEGIN_NAMESPACE +QT_QML_BEGIN_NAMESPACE namespace QmlJS { namespace AST { @@ -55,4 +55,4 @@ Visitor::~Visitor() } } // namespace QmlJS::AST -QT_END_NAMESPACE +QT_QML_END_NAMESPACE From 695201b02da0a3ec8f972dfa5752a88413a65ae6 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 27 Oct 2009 16:34:32 +0100 Subject: [PATCH 29/37] debugger: allow NULL pointers in QVector and QStack dumpers --- share/qtcreator/gdbmacros/gdbmacros.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index b49a7fcceac..7746670f381 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -2926,7 +2926,7 @@ static void qDumpQVector(QDumper &d) if (innerIsPointerType && nn > 0) for (int i = 0; i != n; ++i) if (const void *p = addOffset(v, i * innersize + typeddatasize)) - qCheckAccess(deref(p)); + qCheckPointer(deref(p)); d.putItemCount("value", n); d.putItem("valueeditable", "false"); From 80f0239b1d7a080781338888b0d11578a5d6fb5e Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 27 Oct 2009 16:35:49 +0100 Subject: [PATCH 30/37] debugger: work on dumper autotests --- tests/auto/debugger/tst_gdb.cpp | 81 ++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/tests/auto/debugger/tst_gdb.cpp b/tests/auto/debugger/tst_gdb.cpp index f40b0756c7d..034e53221c1 100644 --- a/tests/auto/debugger/tst_gdb.cpp +++ b/tests/auto/debugger/tst_gdb.cpp @@ -194,6 +194,8 @@ private slots: void dumpQWeakPointer(); void dumpQVector(); + void dumpQHash(); + public slots: void dumperCompatibility(); #if 0 @@ -203,7 +205,6 @@ public slots: void dumpQDir(); void dumpQFile(); void dumpQFileInfo(); - void dumpQHash(); void dumpQHashNode(); void dumpQImage(); void dumpQImageData(); @@ -2557,6 +2558,84 @@ void tst_Gdb::dumpQWeakPointerHelper(QWeakPointer &ptr) #endif } +///////////////////////////// QHash ////////////////////////////// + +void dumpQHash_QString_QString() +{ + /* A */ QHash h; + /* B */ h["hello"] = "world"; + /* C */ h["foo"] = "bar"; + /* D */ (void) 0; +} + +void dumpQHash_int_int() +{ + /* A */ QHash h; + /* B */ h[43] = 44; + /* C */ h[45] = 46; + /* D */ (void) 0; +} + +void tst_Gdb::dumpQHash() +{ + // Need to check the following combinations: + // int-key optimization, small value + //struct NodeOS { void *next; uint k; uint v; } nodeOS + // int-key optimiatzion, large value + //struct NodeOL { void *next; uint k; void *v; } nodeOL + // no optimization, small value + //struct NodeNS + { void *next; uint h; uint k; uint v; } nodeNS + // no optimization, large value + //struct NodeNL { void *next; uint h; uint k; void *v; } nodeNL + // complex key + //struct NodeL { void *next; uint h; void *k; void *v; } nodeL + + prepare("dumpQHash_int_int"); + if (checkUninitialized) + run("A","{iname='local.h',addr='-',name='h'," + "type='"NS"QHash',value=''," + "numchild='0'}"); + next(); + next(); + next(); + run("D","{iname='local.h',addr='-',name='h'," + "type='"NS"QHash',value='<2 items>',numchild='2'," + "childtype='int',childnumchild='0',children=[" + "{name='43',value='44'}," + "{name='45',value='46'}]}", + "local.h"); + + prepare("dumpQHash_QString_QString"); + if (checkUninitialized) + run("A","{iname='local.h',addr='-',name='h'," + "type='"NS"QHash<"NS"QString, "NS"QString>',value=''," + "numchild='0'}"); + next(); + //run("B","{iname='local.h',addr='-',name='h'," + // "type='"NS"QHash<"NS"QString, "NS"QString>',value='<0 items>'," + // "numchild='0'}"); + next(); + next(); + //run("D","{iname='local.h',addr='-',name='h'," + // "type='"NS"QHash<"NS"QString, "NS"QString>',value='<2 items>'," + // "numchild='2'}"); + run("D","{iname='local.h',addr='-',name='h'," + "type='"NS"QHash<"NS"QString, "NS"QString>',value='<2 items>'," + "numchild='2',childtype='"NS"QHashNode<"NS"QString, "NS"QString>'," + "children=[" + "{value=' ',numchild='2',children=[{name='key',valueencoded='7'," + "value='66006f006f00',numchild='0'}," + "{name='value',valueencoded='7'," + "value='620061007200',numchild='0'}]}," + "{value=' ',numchild='2',children=[{name='key',valueencoded='7'," + "value='680065006c006c006f00',numchild='0'}," + "{name='value',valueencoded='7'," + "value='77006f0072006c006400',numchild='0'}]}" + "]}", + "local.h,local.h.0,local.h.1"); +} + + ///////////////////////////// QList ///////////////////////////////// void dumpQList_int() From 05e56fc1a3a6d9a2e0750d44505c4facf1e0e189 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 27 Oct 2009 16:36:23 +0100 Subject: [PATCH 31/37] debugger: prevent endless recursion due to broken dumpers --- src/plugins/debugger/gdb/gdbengine.cpp | 82 +++++++++++++++----------- src/plugins/debugger/gdb/gdbengine.h | 4 +- 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 8b1e3b2c380..7572c30fba3 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -692,10 +692,10 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd) if (cmd.flags & RebuildModel) { ++m_pendingRequests; - PENDING_DEBUG(" CALLBACK" << cmd.callbackName + PENDING_DEBUG(" COMMAND" << cmd.callbackName << "INCREMENTS PENDING TO:" << m_pendingRequests << cmd.command); } else { - PENDING_DEBUG(" UNKNOWN CALLBACK" << cmd.callbackName + PENDING_DEBUG(" UNKNOWN COMMAND" << cmd.callbackName << "LEAVES PENDING AT:" << m_pendingRequests << cmd.command); } @@ -816,14 +816,14 @@ void GdbEngine::handleResultRecord(GdbResponse *response) if (cmd.flags & RebuildModel) { --m_pendingRequests; - PENDING_DEBUG(" TYPE " << cmd.callbackName << " DECREMENTS PENDING TO: " + PENDING_DEBUG(" RESULT " << cmd.callbackName << " DECREMENTS PENDING TO: " << m_pendingRequests << cmd.command); if (m_pendingRequests <= 0) { PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n"); rebuildModel(); } } else { - PENDING_DEBUG(" UNKNOWN TYPE " << cmd.callbackName << " LEAVES PENDING AT: " + PENDING_DEBUG(" UNKNOWN RESULT " << cmd.callbackName << " LEAVES PENDING AT: " << m_pendingRequests << cmd.command); } @@ -1120,6 +1120,8 @@ void GdbEngine::handleStopResponse(const GdbMi &data) if (initHelpers && reason == "signal-received" && data.findChild("signal-name").data() != "SIGTRAP") initHelpers = false; + if (isSynchroneous()) + initHelpers = false; if (initHelpers) { tryLoadDebuggingHelpers(); QVariant var = QVariant::fromValue(data); @@ -2952,6 +2954,22 @@ void GdbEngine::updateWatchData(const WatchData &data) #else if (data.iname.endsWith(_("."))) return; + + // Avoid endless loops created by faulty dumpers. + QString processedName = QString(_("%1-%2").arg(1).arg(data.iname)); + //qDebug() << "PROCESSED NAMES: " << processedName << m_processedNames; + if (m_processedNames.contains(processedName)) { + WatchData data1 = data; + gdbInputAvailable(LogStatus, + _("").arg(data1.iname)); + data1.setAllUnneeded(); + data1.setValue(_("")); + data1.setHasChildren(false); + insertData(data1); + return; + } + m_processedNames.insert(processedName); + updateLocals(); #endif } else { @@ -2990,7 +3008,8 @@ void GdbEngine::rebuildModel() { static int count = 0; ++count; - m_processedNames.clear(); + if (!isSynchroneous()) + m_processedNames.clear(); PENDING_DEBUG("REBUILDING MODEL" << count); gdbInputAvailable(LogStatus, _("").arg(count)); showStatusMessage(tr("Finished retrieving data."), 400); @@ -3359,27 +3378,26 @@ void GdbEngine::handleDebuggingHelperValue3(const GdbResponse &response) void GdbEngine::updateLocals(const QVariant &cookie) { m_pendingRequests = 0; - m_processedNames.clear(); - - PENDING_DEBUG("\nRESET PENDING"); - //m_toolTipCache.clear(); - m_toolTipExpression.clear(); - manager()->watchHandler()->beginCycle(); - - // Asynchronous load of injected library, initialize in first stop - if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried - && m_dumperHelper.typeCount() == 0 - && inferiorPid() > 0) - tryQueryDebuggingHelpers(); - if (isSynchroneous()) { QStringList expanded = m_manager->watchHandler()->expandedINames().toList(); postCommand(_("bb %1 %2") .arg(int(theDebuggerBoolSetting(UseDebuggingHelpers))) .arg(expanded.join(_(","))), - CB(handleStackFrame1)); - postCommand(_("p 1"), CB(handleStackFrame2)); + CB(handleStackFrame)); } else { + m_processedNames.clear(); + + PENDING_DEBUG("\nRESET PENDING"); + //m_toolTipCache.clear(); + m_toolTipExpression.clear(); + manager()->watchHandler()->beginCycle(); + + // Asynchronous load of injected library, initialize in first stop + if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried + && m_dumperHelper.typeCount() == 0 + && inferiorPid() > 0) + tryQueryDebuggingHelpers(); + QString level = QString::number(currentFrame()); // '2' is 'list with type and value' QString cmd = _("-stack-list-arguments 2 ") + level + _c(' ') + level; @@ -3390,27 +3408,13 @@ void GdbEngine::updateLocals(const QVariant &cookie) } } -void GdbEngine::handleStackFrame1(const GdbResponse &response) -{ - if (response.resultClass == GdbResultDone) { - QByteArray out = response.data.findChild("consolestreamoutput").data(); - while (out.endsWith(' ') || out.endsWith('\n')) - out.chop(1); - //qDebug() << "FIRST CHUNK: " << out; - m_firstChunk = out; - } else { - QTC_ASSERT(false, qDebug() << response.toString()); - } -} - -void GdbEngine::handleStackFrame2(const GdbResponse &response) +void GdbEngine::handleStackFrame(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { QByteArray out = response.data.findChild("consolestreamoutput").data(); while (out.endsWith(' ') || out.endsWith('\n')) out.chop(1); //qDebug() << "SECOND CHUNK: " << out; - out = m_firstChunk + out; int pos = out.indexOf("locals="); if (pos != 0) { qDebug() << "DISCARDING JUNK AT BEGIN OF RESPONSE: " @@ -3436,7 +3440,13 @@ void GdbEngine::handleStackFrame2(const GdbResponse &response) // FIXME: //manager()->watchHandler()->updateWatchers(); - rebuildModel(); + PENDING_DEBUG("AFTER handleStackFrame()"); + // FIXME: This should only be used when updateLocals() was + // triggered by expanding an item in the view. + if (m_pendingRequests <= 0) { + PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n"); + rebuildModel(); + } } else { QTC_ASSERT(false, /**/); } diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 786ac7696a6..9e23fee2b2e 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -370,14 +370,12 @@ private: ////////// View & Data Stuff ////////// void handleStackListFrames(const GdbResponse &response); void handleStackSelectThread(const GdbResponse &response); void handleStackListThreads(const GdbResponse &response); - void handleStackFrame1(const GdbResponse &response); - void handleStackFrame2(const GdbResponse &response); + void handleStackFrame(const GdbResponse &response); Q_SLOT void reloadStack(bool forceGotoLocation); Q_SLOT void reloadFullStack(); int currentFrame() const; QList m_currentFunctionArgs; - QByteArray m_firstChunk; QString m_currentFrame; // From cb5a93ff492fca86b79cadbb3b4f6538d2750708 Mon Sep 17 00:00:00 2001 From: dt Date: Tue, 27 Oct 2009 17:27:37 +0100 Subject: [PATCH 32/37] Fix "Add New" using the wrong directory for cmake projects --- src/plugins/cmakeprojectmanager/cmakeproject.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index acf75f5c61d..770ee8411fa 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -497,11 +497,13 @@ ProjectExplorer::FolderNode *CMakeProject::findOrCreateFolder(CMakeProjectNode * QString relativePath = QDir(QFileInfo(rootNode->path()).path()).relativeFilePath(directory); QStringList parts = relativePath.split("/", QString::SkipEmptyParts); ProjectExplorer::FolderNode *parent = rootNode; + QString path = QFileInfo(rootNode->path()).path(); foreach (const QString &part, parts) { + path += "/" + part; // Find folder in subFolders bool found = false; foreach (ProjectExplorer::FolderNode *folder, parent->subFolderNodes()) { - if (QFileInfo(folder->path()).fileName() == part) { + if (folder->path() == path) { // yeah found something :) parent = folder; found = true; @@ -510,7 +512,8 @@ ProjectExplorer::FolderNode *CMakeProject::findOrCreateFolder(CMakeProjectNode * } if (!found) { // No FolderNode yet, so create it - ProjectExplorer::FolderNode *tmp = new ProjectExplorer::FolderNode(part); + ProjectExplorer::FolderNode *tmp = new ProjectExplorer::FolderNode(path); + tmp->setFolderName(part); rootNode->addFolderNodes(QList() << tmp, parent); parent = tmp; } From 097d1e4e6cbb8d44df57e1cd7052e751c056b47b Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 27 Oct 2009 17:16:46 +0100 Subject: [PATCH 33/37] debugger: call beginCycle also for new dumpers --- src/plugins/debugger/gdb/gdbengine.cpp | 3 +++ src/plugins/debugger/watchhandler.cpp | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 7572c30fba3..bc5be521b81 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -101,6 +101,7 @@ namespace Internal { #else # define PENDING_DEBUG(s) #endif +#define PENDING_DEBUGX(s) qDebug() << s #define CB(callback) &GdbEngine::callback, STRINGIFY(callback) @@ -3379,6 +3380,8 @@ void GdbEngine::updateLocals(const QVariant &cookie) { m_pendingRequests = 0; if (isSynchroneous()) { + manager()->watchHandler()->beginCycle(); + m_toolTipExpression.clear(); QStringList expanded = m_manager->watchHandler()->expandedINames().toList(); postCommand(_("bb %1 %2") .arg(int(theDebuggerBoolSetting(UseDebuggingHelpers))) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 6b774591764..23a7109a1db 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -1095,7 +1095,6 @@ void WatchHandler::beginCycle() void WatchHandler::endCycle() { - //qDebug() << "END CYCLE"; m_locals->endCycle(); m_watchers->endCycle(); m_tooltips->endCycle(); From 87b27a2fb25ae102cf2ebb5def6766f61fe31a3f Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 27 Oct 2009 17:19:47 +0100 Subject: [PATCH 34/37] debugger: disable warning that triggers too often --- src/plugins/debugger/watchhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 23a7109a1db..ba7c24ff04f 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -792,7 +792,7 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro if (role == ExpandedRole) { if (value.toBool()) { // Should already have been triggered by fetchMore() - QTC_ASSERT(m_handler->m_expandedINames.contains(data.iname), /**/); + //QTC_ASSERT(m_handler->m_expandedINames.contains(data.iname), /**/); m_handler->m_expandedINames.insert(data.iname); } else { m_handler->m_expandedINames.remove(data.iname); From 1ef61e07203dc11cfbbe0a92af2864ce98432b1f Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 27 Oct 2009 17:37:13 +0100 Subject: [PATCH 35/37] debugger: add missing .pro file --- tests/auto/debugger/debugger.pro | 2 +- tests/auto/debugger/gdb.pro | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/auto/debugger/gdb.pro diff --git a/tests/auto/debugger/debugger.pro b/tests/auto/debugger/debugger.pro index c4cadd3715f..ef1547f9ce6 100644 --- a/tests/auto/debugger/debugger.pro +++ b/tests/auto/debugger/debugger.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs -SUBDIRS = dumpers.pro plugin.pro +SUBDIRS = dumpers.pro plugin.pro gdb.pro diff --git a/tests/auto/debugger/gdb.pro b/tests/auto/debugger/gdb.pro new file mode 100644 index 00000000000..7f1d52a5372 --- /dev/null +++ b/tests/auto/debugger/gdb.pro @@ -0,0 +1,15 @@ +QT -= gui +QT += testlib + +UTILSDIR = ../../../src/libs + +DEBUGGERDIR = ../../../src/plugins/debugger + +INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR + +SOURCES += \ + tst_gdb.cpp \ + $$DEBUGGERDIR/gdb/gdbmi.cpp \ + +TARGET = tst_$$TARGET + From 7c12dad4a0aae40959e05323c931a61b9f61d78a Mon Sep 17 00:00:00 2001 From: con Date: Tue, 27 Oct 2009 17:59:53 +0100 Subject: [PATCH 36/37] Make it possible to use non-autodetected Qt for Symbian. Users can specify a S60 SDK root for Qt for Symbian versions now. --- .../qt4projectmanager/qt-s60/s60devices.cpp | 10 +++++ .../qt4projectmanager/qt-s60/s60devices.h | 1 + .../qt4projectmanager/qt-s60/s60manager.cpp | 28 ++++++++----- .../qt4projectmanager/qtoptionspage.cpp | 39 +++++++++++++---- src/plugins/qt4projectmanager/qtoptionspage.h | 3 +- .../qt4projectmanager/qtversionmanager.cpp | 11 +++++ .../qt4projectmanager/qtversionmanager.h | 3 ++ .../qt4projectmanager/qtversionmanager.ui | 42 ++++++++++++------- 8 files changed, 100 insertions(+), 37 deletions(-) diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp index 1667ed4294b..a9bcc354e0f 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp @@ -214,6 +214,16 @@ S60Devices::Device S60Devices::deviceForId(const QString &id) const return Device(); } +S60Devices::Device S60Devices::deviceForEpocRoot(const QString &root) const +{ + foreach (const S60Devices::Device &i, m_devices) { + if (i.epocRoot == root) { + return i; + } + } + return Device(); +} + QString S60Devices::cleanedRootPath(const QString &deviceRoot) { QString path = deviceRoot; diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devices.h b/src/plugins/qt4projectmanager/qt-s60/s60devices.h index 839fd32967a..01173d979af 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60devices.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.h @@ -63,6 +63,7 @@ public: QList devices() const; bool detectQtForDevices(); Device deviceForId(const QString &id) const; + Device deviceForEpocRoot(const QString &root) const; static QString cleanedRootPath(const QString &deviceRoot); signals: diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp index 4b16410e61b..0c9084c88dd 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp @@ -177,6 +177,7 @@ void S60Manager::updateQtVersions() deviceVersion->setName(deviceVersion->name().arg(deviceVersion->qtVersionString())); versionsToAdd.append(deviceVersion); } + deviceVersion->setS60SDKDirectory(device.epocRoot); } // remove old autodetected versions foreach (QtVersion *version, versions) { @@ -202,8 +203,9 @@ ProjectExplorer::ToolChain *S60Manager::createGCCEToolChain(const Qt4ProjectMana return new GCCEToolChain(deviceForQtVersion(version)); } -ProjectExplorer::ToolChain *S60Manager::createRVCTToolChain(const Qt4ProjectManager::QtVersion *version, - ProjectExplorer::ToolChain::ToolChainType type) const +ProjectExplorer::ToolChain *S60Manager::createRVCTToolChain( + const Qt4ProjectManager::QtVersion *version, + ProjectExplorer::ToolChain::ToolChainType type) const { return new RVCTToolChain(deviceForQtVersion(version), type); } @@ -215,15 +217,19 @@ S60Devices::Device S60Manager::deviceForQtVersion(const Qt4ProjectManager::QtVer if (version->isAutodetected()) deviceId = deviceIdFromDetectionSource(version->autodetectionSource()); if (deviceId.isEmpty()) { // it's not an s60 autodetected version - // have a look if we find the device root anyhow - QString qtPath = version->versionInfo().value("QT_INSTALL_DATA"); - if (QFile::exists(QString::fromLatin1("%1/epoc32").arg(qtPath))) { - device.epocRoot = qtPath; - device.toolsRoot = device.epocRoot; - device.qt = device.epocRoot; - device.isDefault = false; - device.name = QString::fromLatin1("SDK"); - device.id = QString::fromLatin1("SDK"); + // try to find a device entry belonging to the root given in Qt prefs + QString sdkRoot = version->s60SDKDirectory(); + device = m_devices->deviceForEpocRoot(sdkRoot); + if (device.epocRoot.isEmpty()) { // no device found + // check if we can construct a dummy one + if (QFile::exists(QString::fromLatin1("%1/epoc32").arg(sdkRoot))) { + device.epocRoot = sdkRoot; + device.toolsRoot = device.epocRoot; + device.qt = QFileInfo(QFileInfo(version->qmakeCommand()).path()).path(); + device.isDefault = false; + device.name = QString::fromLatin1("Manual"); + device.id = QString::fromLatin1("Manual"); + } } } else { device = m_devices->deviceForId(deviceId); diff --git a/src/plugins/qt4projectmanager/qtoptionspage.cpp b/src/plugins/qt4projectmanager/qtoptionspage.cpp index 48e39d27e42..da0f1346f2a 100644 --- a/src/plugins/qt4projectmanager/qtoptionspage.cpp +++ b/src/plugins/qt4projectmanager/qtoptionspage.cpp @@ -122,6 +122,8 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList ver m_ui->mingwPath->setPromptDialogTitle(tr("Select the MinGW Directory")); m_ui->mwcPath->setExpectedKind(Utils::PathChooser::Directory); m_ui->mwcPath->setPromptDialogTitle(tr("Select Carbide Install Directory")); + m_ui->s60SDKPath->setExpectedKind(Utils::PathChooser::Directory); + m_ui->s60SDKPath->setPromptDialogTitle(tr("Select S60 SDK Root")); m_ui->addButton->setIcon(QIcon(Core::Constants::ICON_PLUS)); m_ui->delButton->setIcon(QIcon(Core::Constants::ICON_MINUS)); @@ -167,6 +169,8 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList ver #ifdef QTCREATOR_WITH_S60 connect(m_ui->mwcPath, SIGNAL(changed(QString)), this, SLOT(updateCurrentMwcDirectory())); + connect(m_ui->s60SDKPath, SIGNAL(changed(QString)), + this, SLOT(updateCurrentS60SDKDirectory())); #endif connect(m_ui->addButton, SIGNAL(clicked()), @@ -367,6 +371,8 @@ void QtOptionsPageWidget::updateState() m_ui->nameEdit->setEnabled(enabled && !isAutodetected); m_ui->qmakePath->setEnabled(enabled && !isAutodetected); m_ui->mingwPath->setEnabled(enabled); + m_ui->mwcPath->setEnabled(enabled); + m_ui->s60SDKPath->setEnabled(enabled && !isAutodetected); const bool hasLog = enabled && !m_ui->qtdirList->currentItem()->data(2, Qt::UserRole).toString().isEmpty(); m_ui->showLogButton->setEnabled(hasLog); @@ -388,10 +394,12 @@ void QtOptionsPageWidget::makeMSVCVisible(bool visible) m_ui->msvcNotFoundLabel->setVisible(false); } -void QtOptionsPageWidget::makeMWCVisible(bool visible) +void QtOptionsPageWidget::makeS60Visible(bool visible) { m_ui->mwcLabel->setVisible(visible); m_ui->mwcPath->setVisible(visible); + m_ui->s60SDKLabel->setVisible(visible); + m_ui->s60SDKPath->setVisible(visible); } void QtOptionsPageWidget::showEnvironmentPage(QTreeWidgetItem *item) @@ -401,7 +409,7 @@ void QtOptionsPageWidget::showEnvironmentPage(QTreeWidgetItem *item) if (index < 0) { makeMSVCVisible(false); makeMingwVisible(false); - makeMWCVisible(false); + makeS60Visible(false); return; } m_ui->errorLabel->setText(""); @@ -409,12 +417,12 @@ void QtOptionsPageWidget::showEnvironmentPage(QTreeWidgetItem *item) if (types.contains(ProjectExplorer::ToolChain::MinGW)) { makeMSVCVisible(false); makeMingwVisible(true); - makeMWCVisible(false); + makeS60Visible(false); m_ui->mingwPath->setPath(m_versions.at(index)->mingwDirectory()); } else if (types.contains(ProjectExplorer::ToolChain::MSVC) || types.contains(ProjectExplorer::ToolChain::WINCE)){ makeMSVCVisible(false); makeMingwVisible(false); - makeMWCVisible(false); + makeS60Visible(false); QStringList msvcEnvironments = ProjectExplorer::ToolChain::availableMSVCVersions(); if (msvcEnvironments.count() == 0) { m_ui->msvcLabel->setVisible(true); @@ -432,16 +440,20 @@ void QtOptionsPageWidget::showEnvironmentPage(QTreeWidgetItem *item) m_ui->msvcComboBox->blockSignals(block); } #ifdef QTCREATOR_WITH_S60 - } else if (types.contains(ProjectExplorer::ToolChain::WINSCW)) { + } else if (types.contains(ProjectExplorer::ToolChain::WINSCW) + || types.contains(ProjectExplorer::ToolChain::RVCT_ARMV5) + || types.contains(ProjectExplorer::ToolChain::RVCT_ARMV6) + || types.contains(ProjectExplorer::ToolChain::GCCE)) { makeMSVCVisible(false); makeMingwVisible(false); - makeMWCVisible(true); + makeS60Visible(true); m_ui->mwcPath->setPath(m_versions.at(index)->mwcDirectory()); + m_ui->s60SDKPath->setPath(m_versions.at(index)->s60SDKDirectory()); #endif } else if (types.contains(ProjectExplorer::ToolChain::INVALID)) { makeMSVCVisible(false); makeMingwVisible(false); - makeMWCVisible(false); + makeS60Visible(false); if (!m_versions.at(index)->isInstalled()) m_ui->errorLabel->setText(tr("The Qt Version identified by %1 is not installed. Run make install") .arg(QDir::toNativeSeparators(m_versions.at(index)->qmakeCommand()))); @@ -450,7 +462,7 @@ void QtOptionsPageWidget::showEnvironmentPage(QTreeWidgetItem *item) } else { //ProjectExplorer::ToolChain::GCC makeMSVCVisible(false); makeMingwVisible(false); - makeMWCVisible(false); + makeS60Visible(false); m_ui->errorLabel->setText(tr("Found Qt version %1, using mkspec %2") .arg(m_versions.at(index)->qtVersionString(), m_versions.at(index)->mkspec())); @@ -458,7 +470,7 @@ void QtOptionsPageWidget::showEnvironmentPage(QTreeWidgetItem *item) } else { makeMSVCVisible(false); makeMingwVisible(false); - makeMWCVisible(false); + makeS60Visible(false); } } @@ -654,6 +666,15 @@ void QtOptionsPageWidget::updateCurrentMwcDirectory() return; m_versions[currentItemIndex]->setMwcDirectory(m_ui->mwcPath->path()); } +void QtOptionsPageWidget::updateCurrentS60SDKDirectory() +{ + QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem(); + Q_ASSERT(currentItem); + int currentItemIndex = indexForTreeItem(currentItem); + if (currentItemIndex < 0) + return; + m_versions[currentItemIndex]->setS60SDKDirectory(m_ui->s60SDKPath->path()); +} #endif QList QtOptionsPageWidget::versions() const diff --git a/src/plugins/qt4projectmanager/qtoptionspage.h b/src/plugins/qt4projectmanager/qtoptionspage.h index 9581f37d425..c4778d36cda 100644 --- a/src/plugins/qt4projectmanager/qtoptionspage.h +++ b/src/plugins/qt4projectmanager/qtoptionspage.h @@ -109,7 +109,7 @@ private slots: void updateState(); void makeMingwVisible(bool visible); void makeMSVCVisible(bool visible); - void makeMWCVisible(bool visible); + void makeS60Visible(bool visible); void onQtBrowsed(); void onMingwBrowsed(); void defaultChanged(int index); @@ -118,6 +118,7 @@ private slots: void updateCurrentMingwDirectory(); #ifdef QTCREATOR_WITH_S60 void updateCurrentMwcDirectory(); + void updateCurrentS60SDKDirectory(); #endif void msvcVersionChanged(); void buildDebuggingHelper(); diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 22f5663cc57..b9de0fbaa08 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -126,6 +126,7 @@ QtVersionManager::QtVersionManager() version->setMsvcVersion(s->value("msvcVersion").toString()); #ifdef QTCREATOR_WITH_S60 version->setMwcDirectory(s->value("MwcDirectory").toString()); + version->setS60SDKDirectory(s->value("S60SDKDirectory").toString()); #endif m_versions.append(version); } @@ -245,6 +246,7 @@ void QtVersionManager::writeVersionsIntoSettings() s->setValue("autodetectionSource", version->autodetectionSource()); #ifdef QTCREATOR_WITH_S60 s->setValue("MwcDirectory", version->mwcDirectory()); + s->setValue("S60SDKDirectory", version->s60SDKDirectory()); #endif } s->endArray(); @@ -1170,6 +1172,15 @@ void QtVersion::setMwcDirectory(const QString &directory) { m_mwcDirectory = directory; } +QString QtVersion::s60SDKDirectory() const +{ + return m_s60SDKDirectory; +} + +void QtVersion::setS60SDKDirectory(const QString &directory) +{ + m_s60SDKDirectory = directory; +} #endif QString QtVersion::mingwDirectory() const diff --git a/src/plugins/qt4projectmanager/qtversionmanager.h b/src/plugins/qt4projectmanager/qtversionmanager.h index 3e96ab5344b..545fcc8c2cf 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.h +++ b/src/plugins/qt4projectmanager/qtversionmanager.h @@ -86,6 +86,8 @@ public: #ifdef QTCREATOR_WITH_S60 QString mwcDirectory() const; void setMwcDirectory(const QString &directory); + QString s60SDKDirectory() const; + void setS60SDKDirectory(const QString &directory); #endif QString mingwDirectory() const; void setMingwDirectory(const QString &directory); @@ -141,6 +143,7 @@ private: bool m_hasDebuggingHelper; #ifdef QTCREATOR_WITH_S60 QString m_mwcDirectory; + QString m_s60SDKDirectory; #endif mutable bool m_mkspecUpToDate; diff --git a/src/plugins/qt4projectmanager/qtversionmanager.ui b/src/plugins/qt4projectmanager/qtversionmanager.ui index 2f3d39e7f02..2f0a1dc840f 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.ui +++ b/src/plugins/qt4projectmanager/qtversionmanager.ui @@ -100,7 +100,7 @@ p, li { white-space: pre-wrap; } - + @@ -193,30 +193,40 @@ p, li { white-space: pre-wrap; } - - - - Debugging Helper: - - - - - - - - - - + + + S60 SDK: + + + + + + + Carbide Directory: - + + + + + Debugging Helper: + + + + + + + + + + From 33fedfea6471703a7ca6967f322e89b476bde731 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Oct 2009 18:05:04 +0100 Subject: [PATCH 37/37] Qt4ProjectManager: Give a verbose tooltip on the Qt versions. Reviewed-by: dt --- .../qt4projectmanager/qtoptionspage.cpp | 23 ++++++++++ src/plugins/qt4projectmanager/qtoptionspage.h | 2 + .../qt4projectmanager/qtversionmanager.cpp | 43 ++++++++++++++++++- .../qt4projectmanager/qtversionmanager.h | 3 ++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/plugins/qt4projectmanager/qtoptionspage.cpp b/src/plugins/qt4projectmanager/qtoptionspage.cpp index da0f1346f2a..0796dc44b92 100644 --- a/src/plugins/qt4projectmanager/qtoptionspage.cpp +++ b/src/plugins/qt4projectmanager/qtoptionspage.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; @@ -133,6 +135,7 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList ver // setup parent items for auto-detected and manual versions m_ui->qtdirList->header()->setResizeMode(QHeaderView::ResizeToContents); QTreeWidgetItem *autoItem = new QTreeWidgetItem(m_ui->qtdirList); + m_ui->qtdirList->installEventFilter(this); autoItem->setText(0, tr("Auto-detected")); autoItem->setFirstColumnSpanned(true); QTreeWidgetItem *manualItem = new QTreeWidgetItem(m_ui->qtdirList); @@ -200,6 +203,26 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList ver updateState(); } +bool QtOptionsPageWidget::eventFilter(QObject *o, QEvent *e) +{ + // Set the items tooltip, which may cause costly initialization + // of QtVersion and must be up-to-date + if (o != m_ui->qtdirList || e->type() != QEvent::ToolTip) + return false; + QHelpEvent *helpEvent = static_cast(e); + const QPoint treePos = helpEvent->pos() - QPoint(0, m_ui->qtdirList->header()->height()); + QTreeWidgetItem *item = m_ui->qtdirList->itemAt(treePos); + if (!item) + return false; + const int index = indexForTreeItem(item); + if (index == -1) + return false; + const QString tooltip = m_versions.at(index)->toHtml(); + QToolTip::showText(helpEvent->globalPos(), tooltip, m_ui->qtdirList); + helpEvent->accept(); + return true; +} + int QtOptionsPageWidget::currentIndex() const { if (QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem()) diff --git a/src/plugins/qt4projectmanager/qtoptionspage.h b/src/plugins/qt4projectmanager/qtoptionspage.h index c4778d36cda..4e1f2b49fe8 100644 --- a/src/plugins/qt4projectmanager/qtoptionspage.h +++ b/src/plugins/qt4projectmanager/qtoptionspage.h @@ -82,6 +82,8 @@ public: int defaultVersion() const; void finish(); + virtual bool eventFilter(QObject *o, QEvent *e); + private: void showEnvironmentPage(QTreeWidgetItem * item); void fixQtVersionName(int index); diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index b9de0fbaa08..b202dd3b058 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -482,6 +483,46 @@ QtVersion::~QtVersion() } +QString QtVersion::toHtml() const +{ + QString rc; + QTextStream str(&rc); + str << ""; + str << ""; + str << ""; + str << ""; + str << ""; + updateVersionInfo(); + if (m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease) { + str << ""; + } // default config. + if (!qmakeCXX().isEmpty()) + str << ""; + str << ""; + if (hasDebuggingHelper()) + str << ""; + const QHash vInfo = versionInfo(); + if (!vInfo.isEmpty()) { + const QHash::const_iterator vcend = vInfo.constEnd(); + for (QHash::const_iterator it = vInfo.constBegin(); it != vcend; ++it) + str << ""; + } + str << "
" << QtVersionManager::tr("Name:") + << "" << name() << "
" << QtVersionManager::tr("Source:") + << "" << sourcePath() << "
" << QtVersionManager::tr("mkspec:") + << "" << mkspec() << "
" << QtVersionManager::tr("qmake:") + << "" << m_qmakeCommand << "
" << QtVersionManager::tr("Default:") << ""; + if (m_defaultConfigIsDebug) + str << "debug"; + if (m_defaultConfigIsDebugAndRelease) + str << "default_and_release"; + str << "
" << QtVersionManager::tr("Compiler:") + << "" << qmakeCXX() << "
" << QtVersionManager::tr("Version:") + << "" << qtVersionString() << "
" << QtVersionManager::tr("Debugging helper:") + << "" << debuggingHelperLibrary() << "
" << it.key() <<  "
" << it.value() << "
"; + return rc; +} + QString QtVersion::name() const { return m_name; @@ -1307,7 +1348,7 @@ bool QtVersion::isQt64Bit() const #ifdef Q_OS_WIN32 # ifdef __GNUC__ // MinGW lacking some definitions/winbase.h # define SCS_64BIT_BINARY 6 -# endif +# endif DWORD binaryType = 0; bool success = GetBinaryTypeW(reinterpret_cast(make.utf16()), &binaryType) != 0; if (success && binaryType == SCS_64BIT_BINARY) diff --git a/src/plugins/qt4projectmanager/qtversionmanager.h b/src/plugins/qt4projectmanager/qtversionmanager.h index 545fcc8c2cf..0a5d0f97edf 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.h +++ b/src/plugins/qt4projectmanager/qtversionmanager.h @@ -124,6 +124,9 @@ public: }; QmakeBuildConfig defaultBuildConfig() const; + + QString toHtml() const; + private: static int getUniqueId(); // Also used by QtOptionsPageWidget