diff --git a/scripts/shipping/prepare-linux-qt-for-shipping.sh b/scripts/shipping/prepare-linux-qt-for-shipping.sh index 2f49413ebdd121875144ded7c319bcd5a4676f83..b8c058a84cb6dcf3b09ee3fc9ca242fdf69d25d9 100755 --- a/scripts/shipping/prepare-linux-qt-for-shipping.sh +++ b/scripts/shipping/prepare-linux-qt-for-shipping.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -version=4.4.3 +version="4.5-rc1" workdir=/home/berlin/dev/qt-${version}-temp destdir=/home/berlin/dev/qt-${version}-shipping/qt # "/qt" suffix for Bitrock dir=qt-x11-opensource-src-${version} diff --git a/src/libs/cplusplus/Overview.cpp b/src/libs/cplusplus/Overview.cpp index 2494d11ec5e7f4574297ce47e983e093ba1717dd..0f973753d0b29326d52c866eea639f1e28c3cea1 100644 --- a/src/libs/cplusplus/Overview.cpp +++ b/src/libs/cplusplus/Overview.cpp @@ -68,6 +68,11 @@ bool Overview::showReturnTypes() const return _showReturnTypes; } +unsigned Overview::markArgument() const +{ + return _markArgument; +} + void Overview::setMarkArgument(unsigned position) { _markArgument = position; @@ -98,9 +103,5 @@ QString Overview::prettyType(const FullySpecifiedType &ty, const QString &name) const { TypePrettyPrinter pp(this); - pp.setMarkArgument(_markArgument); - pp.setShowArgumentNames(_showArgumentNames); - pp.setShowReturnTypes(_showReturnTypes); - pp.setShowFunctionSignatures(_showFunctionSignatures); return pp(ty, name); } diff --git a/src/libs/cplusplus/Overview.h b/src/libs/cplusplus/Overview.h index fa1f3cf919fa4df75b450a15cad96423a6a11428..6918ee45ff86539b1462b14df89bc2ba2c249ad8 100644 --- a/src/libs/cplusplus/Overview.h +++ b/src/libs/cplusplus/Overview.h @@ -57,7 +57,10 @@ public: bool showFunctionSignatures() const; void setShowFunctionSignatures(bool showFunctionSignatures); - void setMarkArgument(unsigned position); // 1-based + // 1-based + // ### rename + unsigned markArgument() const; + void setMarkArgument(unsigned position); QString operator()(Name *name) const { return prettyName(name); } diff --git a/src/libs/cplusplus/TypePrettyPrinter.cpp b/src/libs/cplusplus/TypePrettyPrinter.cpp index 6fd6a2cf2451d33d9895951567f6dcacaa04ae5a..6e46361b7f42a15a1f77ba4fc7e6eea32fcf6f9a 100644 --- a/src/libs/cplusplus/TypePrettyPrinter.cpp +++ b/src/libs/cplusplus/TypePrettyPrinter.cpp @@ -42,37 +42,12 @@ using namespace CPlusPlus; TypePrettyPrinter::TypePrettyPrinter(const Overview *overview) : _overview(overview), - _name(0), - _markArgument(0), - _showArgumentNames(false), - _showReturnTypes(false), - _showFunctionSignatures(true) + _name(0) { } TypePrettyPrinter::~TypePrettyPrinter() { } -bool TypePrettyPrinter::showArgumentNames() const -{ return _showArgumentNames; } - -void TypePrettyPrinter::setShowArgumentNames(bool showArgumentNames) -{ _showArgumentNames = showArgumentNames; } - -bool TypePrettyPrinter::showReturnTypes() const -{ return _showReturnTypes; } - -void TypePrettyPrinter::setShowReturnTypes(bool showReturnTypes) -{ _showReturnTypes = showReturnTypes; } - -bool TypePrettyPrinter::showFunctionSignatures() const -{ return _showFunctionSignatures; } - -void TypePrettyPrinter::setShowFunctionSignatures(bool showFunctionSignatures) -{ _showFunctionSignatures = showFunctionSignatures; } - -void TypePrettyPrinter::setMarkArgument(unsigned position) -{ _markArgument = position; } - const Overview *TypePrettyPrinter::overview() const { return _overview; } @@ -102,15 +77,16 @@ QString TypePrettyPrinter::operator()(const FullySpecifiedType &type, const QStr void TypePrettyPrinter::acceptType(const FullySpecifiedType &ty) { - if (ty.isConst()) - _text += QLatin1String("const "); - if (ty.isVolatile()) - _text += QLatin1String("volatile "); if (ty.isSigned()) - _text += QLatin1String("signed "); - if (ty.isUnsigned()) - _text += QLatin1String("unsigned "); + out(QLatin1String("signed ")); + + else if (ty.isUnsigned()) + out(QLatin1String("unsigned ")); + + const FullySpecifiedType previousFullySpecifiedType = _fullySpecifiedType; + _fullySpecifiedType = ty; accept(ty.type()); + _fullySpecifiedType = previousFullySpecifiedType; } QString TypePrettyPrinter::switchName(const QString &name) @@ -127,9 +103,9 @@ QString TypePrettyPrinter::switchText(const QString &name) return previousName; } -QList<Type *> TypePrettyPrinter::switchPtrOperators(const QList<Type *> &ptrOperators) +QList<FullySpecifiedType> TypePrettyPrinter::switchPtrOperators(const QList<FullySpecifiedType> &ptrOperators) { - QList<Type *> previousPtrOperators = _ptrOperators; + QList<FullySpecifiedType> previousPtrOperators = _ptrOperators; _ptrOperators = ptrOperators; return previousPtrOperators; } @@ -137,31 +113,53 @@ QList<Type *> TypePrettyPrinter::switchPtrOperators(const QList<Type *> &ptrOper void TypePrettyPrinter::applyPtrOperators(bool wantSpace) { for (int i = _ptrOperators.size() - 1; i != -1; --i) { - Type *op = _ptrOperators.at(i); + const FullySpecifiedType op = _ptrOperators.at(i); if (i == 0 && wantSpace) - _text += QLatin1Char(' '); - - if (PointerType *ptrTy = op->asPointerType()) { - _text += QLatin1Char('*'); - if (ptrTy->elementType().isConst()) - _text += " const"; - if (ptrTy->elementType().isVolatile()) - _text += " volatile"; + space(); + + if (op->isPointerType()) { + out(QLatin1Char('*')); + outCV(op); } else if (op->isReferenceType()) { - _text += QLatin1Char('&'); - } else if (PointerToMemberType *memPtrTy = op->asPointerToMemberType()) { - _text += QLatin1Char(' '); - _text += _overview->prettyName(memPtrTy->memberName()); - _text += QLatin1Char('*'); + out(QLatin1Char('&')); + } else if (const PointerToMemberType *memPtrTy = op->asPointerToMemberType()) { + space(); + out(_overview->prettyName(memPtrTy->memberName())); + out(QLatin1Char('*')); + outCV(op); } } } void TypePrettyPrinter::visit(VoidType *) { - _text += QLatin1String("void"); + out(QLatin1String("void")); + applyPtrOperators(); +} +void TypePrettyPrinter::visit(NamedType *type) +{ + out(overview()->prettyName(type->name())); + applyPtrOperators(); +} + +void TypePrettyPrinter::visit(Namespace *type) +{ + _text += overview()->prettyName(type->name()); + applyPtrOperators(); +} + +void TypePrettyPrinter::visit(Class *type) +{ + _text += overview()->prettyName(type->name()); + applyPtrOperators(); +} + + +void TypePrettyPrinter::visit(Enum *type) +{ + _text += overview()->prettyName(type->name()); applyPtrOperators(); } @@ -169,25 +167,25 @@ void TypePrettyPrinter::visit(IntegerType *type) { switch (type->kind()) { case IntegerType::Char: - _text += QLatin1String("char"); + out(QLatin1String("char")); break; case IntegerType::WideChar: - _text += QLatin1String("wchar_t"); + out(QLatin1String("wchar_t")); break; case IntegerType::Bool: - _text += QLatin1String("bool"); + out(QLatin1String("bool")); break; case IntegerType::Short: - _text += QLatin1String("short"); + out(QLatin1String("short")); break; case IntegerType::Int: - _text += QLatin1String("int"); + out(QLatin1String("int")); break; case IntegerType::Long: - _text += QLatin1String("long"); + out(QLatin1String("long")); break; case IntegerType::LongLong: - _text += QLatin1String("long long"); + out(QLatin1String("long long")); break; } @@ -198,13 +196,13 @@ void TypePrettyPrinter::visit(FloatType *type) { switch (type->kind()) { case FloatType::Float: - _text += QLatin1String("float"); + out(QLatin1String("float")); break; case FloatType::Double: - _text += QLatin1String("double"); + out(QLatin1String("double")); break; case FloatType::LongDouble: - _text += QLatin1String("long double"); + out(QLatin1String("long double")); break; } @@ -213,99 +211,135 @@ void TypePrettyPrinter::visit(FloatType *type) void TypePrettyPrinter::visit(PointerToMemberType *type) { - _ptrOperators.append(type); + outCV(type->elementType()); + space(); + + _ptrOperators.append(_fullySpecifiedType); acceptType(type->elementType()); } void TypePrettyPrinter::visit(PointerType *type) { - _ptrOperators.append(type); + outCV(type->elementType()); + space(); + + _ptrOperators.append(_fullySpecifiedType); acceptType(type->elementType()); } void TypePrettyPrinter::visit(ReferenceType *type) { - _ptrOperators.append(type); + outCV(type->elementType()); + space(); + + _ptrOperators.append(_fullySpecifiedType); acceptType(type->elementType()); } void TypePrettyPrinter::visit(ArrayType *type) { - _text += overview()->prettyType(type->elementType()); + out(overview()->prettyType(type->elementType())); if (! _ptrOperators.isEmpty()) { - _text += QLatin1Char('('); + out(QLatin1Char('(')); applyPtrOperators(false); if (! _name.isEmpty()) { - _text += _name; + out(_name); _name.clear(); } - _text += QLatin1Char(')'); + out(QLatin1Char(')')); } - _text += QLatin1String("[]"); -} - -void TypePrettyPrinter::visit(NamedType *type) -{ - _text += overview()->prettyName(type->name()); - applyPtrOperators(); + out(QLatin1String("[]")); } void TypePrettyPrinter::visit(Function *type) { - if (_showReturnTypes) - _text += _overview->prettyType(type->returnType()); + if (_overview->showReturnTypes()) + out(_overview->prettyType(type->returnType())); if (! _ptrOperators.isEmpty()) { - _text += QLatin1Char('('); + out(QLatin1Char('(')); applyPtrOperators(false); if (! _name.isEmpty()) { _text += _name; _name.clear(); } - _text += QLatin1Char(')'); - } else if (! _name.isEmpty() && _showFunctionSignatures) { - _text += QLatin1Char(' '); // ### fixme - _text += _name; + out(QLatin1Char(')')); + } else if (! _name.isEmpty() && _overview->showFunctionSignatures()) { + space(); + out(_name); _name.clear(); } - if (_showFunctionSignatures) { + if (_overview->showFunctionSignatures()) { Overview argumentText; - _text += QLatin1Char('('); + argumentText.setShowReturnTypes(true); + argumentText.setShowArgumentNames(false); + argumentText.setShowFunctionSignatures(true); + + out(QLatin1Char('(')); + for (unsigned index = 0; index < type->argumentCount(); ++index) { if (index != 0) - _text += QLatin1String(", "); + out(QLatin1String(", ")); if (Argument *arg = type->argumentAt(index)->asArgument()) { - if (index + 1 == _markArgument) - _text += QLatin1String("<b>"); + if (index + 1 == _overview->markArgument()) + out(QLatin1String("<b>")); + Name *name = 0; - if (_showArgumentNames) + + if (_overview->showArgumentNames()) name = arg->name(); - _text += argumentText(arg->type(), name); - if (index + 1 == _markArgument) - _text += QLatin1String("</b>"); + + out(argumentText(arg->type(), name)); + + if (index + 1 == _overview->markArgument()) + out(QLatin1String("</b>")); } } if (type->isVariadic()) - _text += QLatin1String("..."); + out(QLatin1String("...")); + + out(QLatin1Char(')')); + if (type->isConst() && type->isVolatile()) { + space(); + out("const volatile"); + } else if (type->isConst()) { + space(); + out("const"); + } else if (type->isVolatile()) { + space(); + out("volatile"); + } + } +} - _text += QLatin1Char(')'); +void TypePrettyPrinter::space() +{ + if (_text.isEmpty()) + return; - if (type->isConst()) - _text += QLatin1String(" const"); + const QChar ch = _text.at(_text.length() - 1); - if (type->isVolatile()) - _text += QLatin1String(" volatile"); - } + if (ch.isLetterOrNumber() || ch == QLatin1Char('_') || ch == QLatin1Char(')')) + _text += QLatin1Char(' '); } -void TypePrettyPrinter::visit(Namespace *type) -{ _text += overview()->prettyName(type->name()); } +void TypePrettyPrinter::out(const QString &text) +{ _text += text; } -void TypePrettyPrinter::visit(Class *type) -{ _text += overview()->prettyName(type->name()); } +void TypePrettyPrinter::out(const QChar &ch) +{ _text += ch; } -void TypePrettyPrinter::visit(Enum *type) -{ _text += overview()->prettyName(type->name()); } +void TypePrettyPrinter::outCV(const FullySpecifiedType &ty) +{ + if (ty.isConst() && ty.isVolatile()) + out(QLatin1String("const volatile")); + + else if (ty.isConst()) + out(QLatin1String("const")); + + else if (ty.isVolatile()) + out(QLatin1String("volatile")); +} diff --git a/src/libs/cplusplus/TypePrettyPrinter.h b/src/libs/cplusplus/TypePrettyPrinter.h index 790999dc824c38e9c31b2e456250079b543cd84c..6191cf01af0b87c2a874f21c3fe2bd44b5c162ee 100644 --- a/src/libs/cplusplus/TypePrettyPrinter.h +++ b/src/libs/cplusplus/TypePrettyPrinter.h @@ -33,7 +33,8 @@ #ifndef TYPEPRETTYPRINTER_H #define TYPEPRETTYPRINTER_H -#include "TypeVisitor.h" +#include <TypeVisitor.h> +#include <FullySpecifiedType.h> #include <QString> #include <QList> @@ -50,23 +51,12 @@ public: const Overview *overview() const; - bool showArgumentNames() const; - void setShowArgumentNames(bool showArgumentNames); - - bool showReturnTypes() const; - void setShowReturnTypes(bool showReturnTypes); - - bool showFunctionSignatures() const; - void setShowFunctionSignatures(bool showFunctionSignatures); - - void setMarkArgument(unsigned position); // 1-based - QString operator()(const FullySpecifiedType &type); QString operator()(const FullySpecifiedType &type, const QString &name); protected: QString switchText(const QString &text = QString()); - QList<Type *> switchPtrOperators(const QList<Type *> &ptrOperators); + QList<FullySpecifiedType> switchPtrOperators(const QList<FullySpecifiedType> &ptrOperators); QString switchName(const QString &name); void applyPtrOperators(bool wantSpace = true); @@ -85,15 +75,17 @@ protected: virtual void visit(Class *type); virtual void visit(Enum *type); + void space(); + void out(const QString &text); + void out(const QChar &ch); + void outCV(const FullySpecifiedType &ty); + private: const Overview *_overview; QString _name; QString _text; - QList<Type *> _ptrOperators; - unsigned _markArgument; - bool _showArgumentNames: 1; - bool _showReturnTypes: 1; - bool _showFunctionSignatures: 1; + FullySpecifiedType _fullySpecifiedType; + QList<FullySpecifiedType> _ptrOperators; }; } // end of namespace CPlusPlus diff --git a/src/plugins/cpaster/cpasterplugin.cpp b/src/plugins/cpaster/cpasterplugin.cpp index f0cda5147c2eed82ed7969c63e8d206611a041e8..82a8be37d721e20bd05ff907afd70b2ecbbc8810 100644 --- a/src/plugins/cpaster/cpasterplugin.cpp +++ b/src/plugins/cpaster/cpasterplugin.cpp @@ -185,7 +185,9 @@ void CodepasterPlugin::post() // Submit to codepaster - m_poster = new CustomPoster(serverUrl()); + m_poster = new CustomPoster(serverUrl(), + m_settingsPage->copyToClipBoard(), + m_settingsPage->displayOutput()); // Copied from cpaster. Otherwise lineendings will screw up if (!data.contains("\r\n")) { diff --git a/src/plugins/cpaster/settingspage.h b/src/plugins/cpaster/settingspage.h index a492030752c7ec8b6b9f5c7b32cb2c395adab66e..98df299a5f667f5234ac378f21e94e5f82841610 100644 --- a/src/plugins/cpaster/settingspage.h +++ b/src/plugins/cpaster/settingspage.h @@ -65,8 +65,8 @@ public: QString username() const; QUrl serverUrl() const; - bool copyToClipBoard() const; - bool displayOutput() const; + inline bool copyToClipBoard() const { return m_copy; } + inline bool displayOutput() const { return m_output; } private: Ui_SettingsPage m_ui; diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp index 8f371bb28701d36ecfcf8fd873950d40e2b67ca2..e47fbe658127ab192ef824b1a122007014741627 100644 --- a/src/plugins/cppeditor/cpphoverhandler.cpp +++ b/src/plugins/cppeditor/cpphoverhandler.cpp @@ -158,8 +158,10 @@ static QString buildHelpId(const FullySpecifiedType &type, scope = e->scope(); } else if (const NamedType *t = type->asNamedType()) { name = t->name(); - } else if (const Declaration *d = symbol->asDeclaration()) { - if (d->scope() && d->scope()->owner()->isEnum()) { + } else if (symbol && symbol->isDeclaration()) { + const Declaration *d = symbol->asDeclaration(); + + if (d->scope() && d->scope()->isEnumScope()) { name = d->name(); scope = d->scope(); } diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp index f9ea3b0bbe96266a996471eb30c54fc086887634..7bb3a36c40ddb3876e9861c5399092d032d50c9b 100644 --- a/src/plugins/cpptools/cppcodecompletion.cpp +++ b/src/plugins/cpptools/cppcodecompletion.cpp @@ -187,10 +187,10 @@ using namespace CppTools::Internal; FunctionArgumentWidget::FunctionArgumentWidget() : m_item(0) { - QObject *editorObject = Core::ICore::instance()->editorManager()->currentEditor(); + QObject *editorObject = Core::EditorManager::instance()->currentEditor(); m_editor = qobject_cast<TextEditor::ITextEditor *>(editorObject); - m_popupFrame = new QFrame(0, Qt::ToolTip|Qt::WindowStaysOnTopHint); + m_popupFrame = new QFrame(0, Qt::ToolTip | Qt::WindowStaysOnTopHint); m_popupFrame->setFocusPolicy(Qt::NoFocus); m_popupFrame->setAttribute(Qt::WA_DeleteOnClose); @@ -518,7 +518,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) if (exprTy->isReferenceType()) exprTy = exprTy->asReferenceType()->elementType(); - if (m_completionOperator == T_LPAREN && completeFunction(exprTy, resolvedTypes, context)) { + if (m_completionOperator == T_LPAREN && completeConstructorOrFunction(exprTy, resolvedTypes)) { return m_startPosition; } else if ((m_completionOperator == T_DOT || m_completionOperator == T_ARROW) && completeMember(resolvedTypes, context)) { @@ -551,7 +551,7 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) foreach (const TypeOfExpression::Result &result, results) { if (result.first->isClassType()) { FullySpecifiedType exprTy = result.first; - if (completeConstructors(exprTy->asClassType())) + if (completeConstructorOrFunction(exprTy, QList<TypeOfExpression::Result>())) return m_startPosition; break; } @@ -563,18 +563,29 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) return -1; } -bool CppCodeCompletion::completeFunction(FullySpecifiedType exprTy, - const QList<TypeOfExpression::Result> &resolvedTypes, - const LookupContext &) +bool CppCodeCompletion::completeConstructorOrFunction(FullySpecifiedType exprTy, + const QList<TypeOfExpression::Result> &resolvedTypes) { + ConvertToCompletionItem toCompletionItem(this); + Overview o; + o.setShowReturnTypes(true); + o.setShowArgumentNames(true); + if (Class *klass = exprTy->asClassType()) { - completeConstructors(klass); + for (unsigned i = 0; i < klass->memberCount(); ++i) { + Symbol *member = klass->memberAt(i); + if (! member->type()->isFunctionType()) + continue; + else if (! member->identity()) + continue; + else if (! member->identity()->isEqualTo(klass->identity())) + continue; + if (TextEditor::CompletionItem item = toCompletionItem(member)) { + item.m_text = o(member->type(), member->name()); + m_completions.append(item); + } + } } else { - ConvertToCompletionItem toCompletionItem(this); - Overview o; - o.setShowReturnTypes(true); - o.setShowArgumentNames(true); - QSet<QString> signatures; foreach (TypeOfExpression::Result p, resolvedTypes) { FullySpecifiedType ty = p.first; @@ -594,6 +605,10 @@ bool CppCodeCompletion::completeFunction(FullySpecifiedType exprTy, } } + // If there is only one item, show the function argument widget immediately + if (m_completions.size() == 1) + complete(m_completions.takeFirst()); + return ! m_completions.isEmpty(); } @@ -887,30 +902,6 @@ void CppCodeCompletion::completeClass(const QList<Symbol *> &candidates, } } -bool CppCodeCompletion::completeConstructors(Class *klass) -{ - ConvertToCompletionItem toCompletionItem(this); - Overview o; - o.setShowReturnTypes(true); - o.setShowArgumentNames(true); - - for (unsigned i = 0; i < klass->memberCount(); ++i) { - Symbol *member = klass->memberAt(i); - if (! member->type()->isFunctionType()) - continue; - else if (! member->identity()) - continue; - else if (! member->identity()->isEqualTo(klass->identity())) - continue; - if (TextEditor::CompletionItem item = toCompletionItem(member)) { - item.m_text = o(member->type(), member->name()); - m_completions.append(item); - } - } - - return ! m_completions.isEmpty(); -} - bool CppCodeCompletion::completeQtMethod(CPlusPlus::FullySpecifiedType, const QList<TypeOfExpression::Result> &results, const LookupContext &context, @@ -1078,7 +1069,10 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item) Function *function = symbol->type()->asFunctionType(); QTC_ASSERT(function, return); - m_functionArgumentWidget = new FunctionArgumentWidget(); + // Recreate if necessary + if (!m_functionArgumentWidget) + m_functionArgumentWidget = new FunctionArgumentWidget; + m_functionArgumentWidget->showFunctionHint(function, typeOfExpression.snapshot()); } } else if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) { diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h index 02bcdc0f524f56cda0f9786254902c415b409148..79f580236f9f50cba34befdec1dc261e8b646d6f 100644 --- a/src/plugins/cpptools/cppcodecompletion.h +++ b/src/plugins/cpptools/cppcodecompletion.h @@ -86,9 +86,8 @@ private: void addMacros(const CPlusPlus::LookupContext &context); void addCompletionItem(CPlusPlus::Symbol *symbol); - bool completeFunction(CPlusPlus::FullySpecifiedType exprTy, - const QList<CPlusPlus::TypeOfExpression::Result> &, - const CPlusPlus::LookupContext &context); + bool completeConstructorOrFunction(CPlusPlus::FullySpecifiedType exprTy, + const QList<CPlusPlus::TypeOfExpression::Result> &); bool completeMember(const QList<CPlusPlus::TypeOfExpression::Result> &, const CPlusPlus::LookupContext &context); diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index b3fd6257e1fb8cfaec02073824b1244b573a9556..a87cf96ca3282f1eb4ab4cd93edc5bd2e14d182a 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -84,7 +84,7 @@ HEADERS += $$PWD/modeltest.h DEFINES += USE_MODEL_TEST=1 } -win32 { +false { HEADERS += \ cdbdebugengine.h \ diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 423321fc7ba41e3cd1151baeb95d3e5f9f666dc7..203bfc5b6b9e8b85671520fe615268fc89668633 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -33,7 +33,6 @@ #include "debuggermanager.h" -#include "assert.h" #include "debuggerconstants.h" #include "idebuggerengine.h" @@ -58,6 +57,8 @@ #include "startexternaldialog.h" #include "attachexternaldialog.h" +#include <utils/qtcassert.h> + #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QFileInfo> @@ -149,6 +150,7 @@ void DebuggerManager::init() { m_status = -1; m_busy = false; + m_shutdown = false; m_attachedPID = 0; m_startMode = startInternal; @@ -451,10 +453,7 @@ QDockWidget *DebuggerManager::createDockForWidget(QWidget *widget) { QDockWidget *dockWidget = new QDockWidget(widget->windowTitle(), m_mainWindow); dockWidget->setObjectName(widget->windowTitle()); - //dockWidget->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea); - dockWidget->setAllowedAreas(Qt::AllDockWidgetAreas); // that space is needed. - //dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures); - dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures); + dockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures); dockWidget->setTitleBarWidget(new QWidget(dockWidget)); dockWidget->setWidget(widget); connect(dockWidget->toggleViewAction(), SIGNAL(toggled(bool)), @@ -543,12 +542,6 @@ void DebuggerManager::notifyStartupFinished() { setStatus(DebuggerProcessReady); showStatusMessage(tr("Startup finished. Debugger ready."), -1); - if (m_startMode == attachExternal) { - // we continue the execution - engine()->continueInferior(); - } else { - engine()->runInferior(); - } } void DebuggerManager::notifyInferiorStopped() @@ -567,7 +560,7 @@ void DebuggerManager::notifyInferiorUpdateFinished() void DebuggerManager::notifyInferiorRunningRequested() { setStatus(DebuggerInferiorRunningRequested); - showStatusMessage(tr("Running..."), 5000); + showStatusMessage(tr("Running requested..."), 5000); } void DebuggerManager::notifyInferiorRunning() @@ -585,7 +578,7 @@ void DebuggerManager::notifyInferiorExited() void DebuggerManager::notifyInferiorPidChanged(int pid) { //QMessageBox::warning(0, "PID", "PID: " + QString::number(pid)); - //qDebug() << "PID: " << pid; + qDebug() << "PID: " << pid; emit inferiorPidChanged(pid); } @@ -597,7 +590,18 @@ void DebuggerManager::showApplicationOutput(const QString &str) void DebuggerManager::shutdown() { //qDebug() << "DEBUGGER_MANAGER SHUTDOWN START"; - engine()->shutdown(); + m_shutdown = true; + if (m_engine) + m_engine->shutdown(); + m_engine = 0; + + delete scriptEngine; + scriptEngine = 0; + delete gdbEngine; + gdbEngine = 0; + delete winEngine; + winEngine = 0; + // Delete these manually before deleting the manager // (who will delete the models for most views) delete m_breakWindow; @@ -651,41 +655,49 @@ void DebuggerManager::toggleBreakpoint() void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) { + QTC_ASSERT(m_engine, return); + QTC_ASSERT(m_breakHandler, return); int index = m_breakHandler->indexOf(fileName, lineNumber); if (index == -1) - breakHandler()->setBreakpoint(fileName, lineNumber); + m_breakHandler->setBreakpoint(fileName, lineNumber); else - breakHandler()->removeBreakpoint(index); - engine()->attemptBreakpointSynchronization(); + m_breakHandler->removeBreakpoint(index); + m_engine->attemptBreakpointSynchronization(); } void DebuggerManager::setToolTipExpression(const QPoint &pos, const QString &exp) { - engine()->setToolTipExpression(pos, exp); + QTC_ASSERT(m_engine, return); + m_engine->setToolTipExpression(pos, exp); } void DebuggerManager::updateWatchModel() { - engine()->updateWatchModel(); + QTC_ASSERT(m_engine, return); + m_engine->updateWatchModel(); } void DebuggerManager::expandChildren(const QModelIndex &idx) { - watchHandler()->expandChildren(idx); + QTC_ASSERT(m_watchHandler, return); + m_watchHandler->expandChildren(idx); } void DebuggerManager::collapseChildren(const QModelIndex &idx) { - watchHandler()->collapseChildren(idx); + QTC_ASSERT(m_watchHandler, return); + m_watchHandler->collapseChildren(idx); } void DebuggerManager::removeWatchExpression(const QString &exp) { - watchHandler()->removeWatchExpression(exp); + QTC_ASSERT(m_watchHandler, return); + m_watchHandler->removeWatchExpression(exp); } QVariant DebuggerManager::sessionValue(const QString &name) { + // this is answered by the plugin QVariant value; emit sessionValueRequested(name, &value); return value; @@ -693,16 +705,19 @@ QVariant DebuggerManager::sessionValue(const QString &name) void DebuggerManager::querySessionValue(const QString &name, QVariant *value) { + // this is answered by the plugin emit sessionValueRequested(name, value); } void DebuggerManager::setSessionValue(const QString &name, const QVariant &value) { + // this is answered by the plugin emit setSessionValueRequested(name, value); } QVariant DebuggerManager::configValue(const QString &name) { + // this is answered by the plugin QVariant value; emit configValueRequested(name, &value); return value; @@ -710,11 +725,13 @@ QVariant DebuggerManager::configValue(const QString &name) void DebuggerManager::queryConfigValue(const QString &name, QVariant *value) { + // this is answered by the plugin emit configValueRequested(name, value); } void DebuggerManager::setConfigValue(const QString &name, const QVariant &value) { + // this is answered by the plugin emit setConfigValueRequested(name, value); } @@ -797,7 +814,7 @@ bool DebuggerManager::startNewDebugger(StartMode mode) else setDebuggerType(GdbDebugger); - if (!engine()->startDebugger()) + if (!m_engine->startDebugger()) return false; m_busy = false; @@ -818,7 +835,10 @@ void DebuggerManager::cleanupViews() void DebuggerManager::exitDebugger() { - engine()->exitDebugger(); + if (m_shutdown) + return; + QTC_ASSERT(m_engine, return); + m_engine->exitDebugger(); cleanupViews(); setStatus(DebuggerProcessNotReady); setBusyCursor(false); @@ -827,62 +847,73 @@ void DebuggerManager::exitDebugger() void DebuggerManager::assignValueInDebugger(const QString &expr, const QString &value) { - engine()->assignValueInDebugger(expr, value); + QTC_ASSERT(m_engine, return); + m_engine->assignValueInDebugger(expr, value); } void DebuggerManager::activateFrame(int index) { - engine()->activateFrame(index); + QTC_ASSERT(m_engine, return); + m_engine->activateFrame(index); } void DebuggerManager::selectThread(int index) { - engine()->selectThread(index); + QTC_ASSERT(m_engine, return); + m_engine->selectThread(index); } void DebuggerManager::loadAllSymbols() { - engine()->loadAllSymbols(); + QTC_ASSERT(m_engine, return); + m_engine->loadAllSymbols(); } void DebuggerManager::loadSymbols(const QString &module) { - engine()->loadSymbols(module); + QTC_ASSERT(m_engine, return); + m_engine->loadSymbols(module); } void DebuggerManager::stepExec() { + QTC_ASSERT(m_engine, return); resetLocation(); - engine()->stepExec(); + m_engine->stepExec(); } void DebuggerManager::stepOutExec() { + QTC_ASSERT(m_engine, return); resetLocation(); - engine()->stepOutExec(); + m_engine->stepOutExec(); } void DebuggerManager::nextExec() { + QTC_ASSERT(m_engine, return); resetLocation(); - engine()->nextExec(); + m_engine->nextExec(); } void DebuggerManager::stepIExec() { + QTC_ASSERT(m_engine, return); resetLocation(); - engine()->stepIExec(); + m_engine->stepIExec(); } void DebuggerManager::nextIExec() { + QTC_ASSERT(m_engine, return); resetLocation(); - engine()->nextIExec(); + m_engine->nextIExec(); } void DebuggerManager::executeDebuggerCommand(const QString &command) { - engine()->executeDebuggerCommand(command); + QTC_ASSERT(m_engine, return); + m_engine->executeDebuggerCommand(command); } void DebuggerManager::sessionLoaded() @@ -900,16 +931,18 @@ void DebuggerManager::aboutToSaveSession() void DebuggerManager::loadSessionData() { + QTC_ASSERT(m_engine, return); m_breakHandler->loadSessionData(); m_watchHandler->loadSessionData(); - engine()->loadSessionData(); + m_engine->loadSessionData(); } void DebuggerManager::saveSessionData() { + QTC_ASSERT(m_engine, return); m_breakHandler->saveSessionData(); m_watchHandler->saveSessionData(); - engine()->saveSessionData(); + m_engine->saveSessionData(); } void DebuggerManager::dumpLog() @@ -968,19 +1001,24 @@ void DebuggerManager::addToWatchWindow() void DebuggerManager::watchExpression(const QString &expression) { - watchHandler()->watchExpression(expression); + QTC_ASSERT(m_watchHandler, return); + m_watchHandler->watchExpression(expression); } void DebuggerManager::setBreakpoint(const QString &fileName, int lineNumber) { - breakHandler()->setBreakpoint(fileName, lineNumber); - engine()->attemptBreakpointSynchronization(); + QTC_ASSERT(m_breakHandler, return); + QTC_ASSERT(m_engine, return); + m_breakHandler->setBreakpoint(fileName, lineNumber); + m_engine->attemptBreakpointSynchronization(); } void DebuggerManager::breakByFunction(const QString &functionName) { - breakHandler()->breakByFunction(functionName); - engine()->attemptBreakpointSynchronization(); + QTC_ASSERT(m_breakHandler, return); + QTC_ASSERT(m_engine, return); + m_breakHandler->breakByFunction(functionName); + m_engine->attemptBreakpointSynchronization(); } void DebuggerManager::breakByFunction() @@ -1088,26 +1126,18 @@ bool DebuggerManager::useCustomDumpers() const return m_settings.m_useCustomDumpers; } -bool DebuggerManager::useFastStart() const -{ - return 0; // && m_settings.m_useFastStart; -} - void DebuggerManager::setUseCustomDumpers(bool on) { + QTC_ASSERT(m_engine, return); m_settings.m_useCustomDumpers = on; - engine()->setUseCustomDumpers(on); -} - -void DebuggerManager::setUseFastStart(bool on) -{ - m_settings.m_useFastStart = on; + m_engine->setUseCustomDumpers(on); } void DebuggerManager::setDebugDumpers(bool on) { + QTC_ASSERT(m_engine, return); m_settings.m_debugDumpers = on; - engine()->setDebugDumpers(on); + m_engine->setDebugDumpers(on); } void DebuggerManager::setSkipKnownFrames(bool on) @@ -1123,29 +1153,31 @@ void DebuggerManager::queryCurrentTextEditor(QString *fileName, int *lineNumber, void DebuggerManager::continueExec() { - engine()->continueInferior(); + m_engine->continueInferior(); } void DebuggerManager::interruptDebuggingRequest() { + QTC_ASSERT(m_engine, return); //qDebug() << "INTERRUPTING AT" << status(); bool interruptIsExit = (status() != DebuggerInferiorRunning); if (interruptIsExit) exitDebugger(); else { setStatus(DebuggerInferiorStopRequested); - engine()->interruptInferior(); + m_engine->interruptInferior(); } } void DebuggerManager::runToLineExec() { + QTC_ASSERT(m_engine, return); QString fileName; int lineNumber = -1; emit currentTextEditorRequested(&fileName, &lineNumber, 0); if (!fileName.isEmpty()) - engine()->runToLineExec(fileName, lineNumber); + m_engine->runToLineExec(fileName, lineNumber); } void DebuggerManager::runToFunctionExec() @@ -1177,7 +1209,7 @@ void DebuggerManager::runToFunctionExec() } //qDebug() << "RUN TO FUNCTION " << functionName; if (!functionName.isEmpty()) - engine()->runToFunctionExec(functionName); + m_engine->runToFunctionExec(functionName); } void DebuggerManager::jumpToLineExec() @@ -1186,20 +1218,20 @@ void DebuggerManager::jumpToLineExec() int lineNumber = -1; emit currentTextEditorRequested(&fileName, &lineNumber, 0); if (!fileName.isEmpty()) - engine()->jumpToLineExec(fileName, lineNumber); + m_engine->jumpToLineExec(fileName, lineNumber); } void DebuggerManager::resetLocation() { - //m_watchHandler->removeMouseMoveCatcher(editor->widget()); + // connected to the plugin emit resetLocationRequested(); } void DebuggerManager::gotoLocation(const QString &fileName, int line, bool setMarker) { + // connected to the plugin emit gotoLocationRequested(fileName, line, setMarker); - //m_watchHandler->installMouseMoveCatcher(editor->widget()); } @@ -1211,9 +1243,10 @@ void DebuggerManager::gotoLocation(const QString &fileName, int line, void DebuggerManager::reloadDisassembler() { + QTC_ASSERT(m_engine, return); if (!m_disassemblerDock || !m_disassemblerDock->isVisible()) return; - engine()->reloadDisassembler(); + m_engine->reloadDisassembler(); } void DebuggerManager::disassemblerDockToggled(bool on) @@ -1233,7 +1266,7 @@ void DebuggerManager::reloadModules() { if (!m_modulesDock || !m_modulesDock->isVisible()) return; - engine()->reloadModules(); + m_engine->reloadModules(); } void DebuggerManager::modulesDockToggled(bool on) @@ -1251,11 +1284,13 @@ void DebuggerManager::modulesDockToggled(bool on) void DebuggerManager::showDebuggerOutput(const QString &prefix, const QString &msg) { + QTC_ASSERT(m_outputWindow, return); m_outputWindow->showOutput(prefix, msg); } void DebuggerManager::showDebuggerInput(const QString &prefix, const QString &msg) { + QTC_ASSERT(m_outputWindow, return); m_outputWindow->showInput(prefix, msg); } @@ -1276,7 +1311,7 @@ void DebuggerManager::reloadRegisters() { if (!m_registerDock || !m_registerDock->isVisible()) return; - engine()->reloadRegisters(); + m_engine->reloadRegisters(); } diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 1c12a73164392318dab4edff402e4187b767b103..bd10b7b025967d1793f5145304fd702dcaa0b46f 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -170,7 +170,11 @@ private: virtual bool skipKnownFrames() const = 0; virtual bool debugDumpers() const = 0; virtual bool useCustomDumpers() const = 0; - virtual bool useFastStart() const = 0; + + virtual bool wantsAllPluginBreakpoints() const = 0; + virtual bool wantsSelectedPluginBreakpoints() const = 0; + virtual bool wantsNoPluginBreakpoints() const = 0; + virtual QString selectedPluginBreakpointsPattern() const = 0; virtual void reloadDisassembler() = 0; virtual void reloadModules() = 0; @@ -200,6 +204,11 @@ public: bool m_useToolTips; QString m_scriptFile; + + bool m_pluginAllBreakpoints; + bool m_pluginSelectedBreakpoints; + bool m_pluginNoBreakpoints; + QString m_pluginSelectedBreakpointsPattern; }; // @@ -283,7 +292,6 @@ public slots: void setUseCustomDumpers(bool on); void setDebugDumpers(bool on); void setSkipKnownFrames(bool on); - void setUseFastStart(bool on); private slots: void showDebuggerOutput(const QString &prefix, const QString &msg); @@ -318,7 +326,14 @@ private: bool skipKnownFrames() const; bool debugDumpers() const; bool useCustomDumpers() const; - bool useFastStart() const; + bool wantsAllPluginBreakpoints() const + { return m_settings.m_pluginAllBreakpoints; } + bool wantsSelectedPluginBreakpoints() const + { return m_settings.m_pluginSelectedBreakpoints; } + bool wantsNoPluginBreakpoints() const + { return m_settings.m_pluginNoBreakpoints; } + QString selectedPluginBreakpointsPattern() const + { return m_settings.m_pluginSelectedBreakpointsPattern; } void notifyStartupFinished(); void notifyInferiorStopped(); @@ -451,6 +466,8 @@ private: IDebuggerEngine *engine(); IDebuggerEngine *m_engine; DebuggerSettings m_settings; + // set during application shutdown + bool m_shutdown; }; } // namespace Internal diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index b8bffaa14eba8f3de58ca7fb4bb7a6dd3f52287a..d3e61c79c29aea470ebf95656604d9912c815a9d 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -274,15 +274,26 @@ QWidget *GdbOptionPage::createPage(QWidget *parent) m_ui.scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script File")); m_ui.scriptFileChooser->setPath(m_settings.m_scriptFile); m_ui.environmentEdit->setText(m_settings.m_gdbEnv); - m_ui.autoStartBox->setChecked(m_settings.m_autoRun); - m_ui.autoQuitBox->setChecked(m_settings.m_autoQuit); + + m_ui.radioButtonAllPluginBreakpoints-> + setChecked(m_settings.m_pluginAllBreakpoints); + m_ui.radioButtonSelectedPluginBreakpoints-> + setChecked(m_settings.m_pluginSelectedBreakpoints); + m_ui.radioButtonNoPluginBreakpoints-> + setChecked(m_settings.m_pluginNoBreakpoints); + m_ui.lineEditSelectedPluginBreakpointsPattern-> + setText(m_settings.m_pluginSelectedBreakpointsPattern); + m_ui.lineEditSelectedPluginBreakpointsPattern-> + setEnabled(m_settings.m_pluginSelectedBreakpoints); m_ui.checkBoxSkipKnownFrames->setChecked(m_settings.m_skipKnownFrames); m_ui.checkBoxDebugDumpers->setChecked(m_settings.m_debugDumpers); m_ui.checkBoxUseCustomDumpers->setChecked(m_settings.m_useCustomDumpers); - m_ui.checkBoxFastStart->setChecked(m_settings.m_useFastStart); m_ui.checkBoxUseToolTips->setChecked(m_settings.m_useToolTips); + connect(m_ui.radioButtonSelectedPluginBreakpoints, SIGNAL(toggled(bool)), + m_ui.lineEditSelectedPluginBreakpointsPattern, SLOT(setEnabled(bool))); + #ifndef QT_DEBUG #if 0 cmd = am->registerAction(m_manager->m_dumpLogAction, @@ -294,14 +305,9 @@ QWidget *GdbOptionPage::createPage(QWidget *parent) #endif // FIXME - m_ui.autoStartBox->hide(); - m_ui.autoQuitBox->hide(); m_ui.environmentEdit->hide(); m_ui.labelEnvironment->hide(); - m_ui.checkBoxFastStart->setChecked(false); - m_ui.checkBoxFastStart->hide(); - //m_dumpLogAction = new QAction(this); //m_dumpLogAction->setText(tr("Dump Log File for Debugging Purposes")); // @@ -315,16 +321,22 @@ void GdbOptionPage::apply() { m_settings.m_gdbCmd = m_ui.gdbLocationChooser->path(); m_settings.m_gdbEnv = m_ui.environmentEdit->text(); - m_settings.m_autoRun = m_ui.autoStartBox->isChecked(); - m_settings.m_autoQuit = m_ui.autoQuitBox->isChecked(); m_settings.m_scriptFile = m_ui.scriptFileChooser->path(); m_settings.m_skipKnownFrames = m_ui.checkBoxSkipKnownFrames->isChecked(); m_settings.m_debugDumpers = m_ui.checkBoxDebugDumpers->isChecked(); m_settings.m_useCustomDumpers = m_ui.checkBoxUseCustomDumpers->isChecked(); - m_settings.m_useFastStart = m_ui.checkBoxFastStart->isChecked(); m_settings.m_useToolTips = m_ui.checkBoxUseToolTips->isChecked(); + m_settings.m_pluginAllBreakpoints = + m_ui.radioButtonAllPluginBreakpoints->isChecked(); + m_settings.m_pluginSelectedBreakpoints = + m_ui.radioButtonSelectedPluginBreakpoints->isChecked(); + m_settings.m_pluginNoBreakpoints = + m_ui.radioButtonNoPluginBreakpoints->isChecked(); + m_settings.m_pluginSelectedBreakpointsPattern = + m_ui.lineEditSelectedPluginBreakpointsPattern->text(); + *m_plugin->m_manager->settings() = m_settings; m_plugin->writeSettings(); } @@ -889,11 +901,16 @@ void DebuggerPlugin::writeSettings() const s->setValue("AutoRun", m->m_autoRun); s->setValue("AutoQuit", m->m_autoQuit); - s->setValue("UseFastStart", m->m_useFastStart); s->setValue("UseToolTips", m->m_useToolTips); s->setValue("UseCustomDumpers", m->m_useCustomDumpers); s->setValue("SkipKnowFrames", m->m_skipKnownFrames); s->setValue("DebugDumpers", m->m_debugDumpers); + + s->setValue("AllPluginBreakpoints", m->m_pluginAllBreakpoints); + s->setValue("SelectedPluginBreakpoints", m->m_pluginSelectedBreakpoints); + s->setValue("NoPluginBreakpoints", m->m_pluginNoBreakpoints); + s->setValue("SelectedPluginBreakpointsPattern", m->m_pluginSelectedBreakpointsPattern); + s->endGroup(); } @@ -911,6 +928,7 @@ void DebuggerPlugin::readSettings() QString defaultScript; s->beginGroup(QLatin1String("DebugMode")); + QByteArray ba = s->value("State", QByteArray()).toByteArray(); m_toggleLockedAction->setChecked(s->value("Locked", true).toBool()); m->m_gdbCmd = s->value("Location", defaultCommand).toString(); @@ -922,8 +940,17 @@ void DebuggerPlugin::readSettings() m->m_skipKnownFrames = s->value("SkipKnownFrames", false).toBool(); m->m_debugDumpers = s->value("DebugDumpers", false).toBool(); m->m_useCustomDumpers = s->value("UseCustomDumpers", true).toBool(); - m->m_useFastStart = s->value("UseFastStart", false).toBool(); m->m_useToolTips = s->value("UseToolTips", false).toBool(); + + m->m_pluginAllBreakpoints = + s->value("AllPluginBreakpoints", false).toBool(); + m->m_pluginSelectedBreakpoints = + s->value("SelectedPluginBreakpoints", false).toBool(); + m->m_pluginNoBreakpoints = + s->value("NoPluginBreakpoints", true).toBool(); + m->m_pluginSelectedBreakpointsPattern = + s->value("SelectedPluginBreakpointsPattern").toString(); + s->endGroup(); m_manager->mainWindow()->restoreState(ba); diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 7f3e42f47fa122af31fd00454dbd7ca595c141ee..21313428aefbdc14eca3592321211140176a10b4 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -107,11 +107,14 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager, : RunControl(runConfiguration), m_manager(manager), m_running(false) { connect(m_manager, SIGNAL(debuggingFinished()), - this, SLOT(debuggingFinished())); + this, SLOT(debuggingFinished()), + Qt::QueuedConnection); connect(m_manager, SIGNAL(applicationOutputAvailable(QString)), - this, SLOT(slotAddToOutputWindowInline(QString))); + this, SLOT(slotAddToOutputWindowInline(QString)), + Qt::QueuedConnection); connect(m_manager, SIGNAL(inferiorPidChanged(qint64)), - this, SLOT(bringApplicationToForeground(qint64))); + this, SLOT(bringApplicationToForeground(qint64)), + Qt::QueuedConnection); } void DebuggerRunControl::start() diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index f6413db72f9259d181413948d7159b8bd0c01e52..0641dac2114aeb7bcf20bb2a35ac90c189adf41f 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -99,6 +99,7 @@ enum GdbCommandType GdbQueryPwd, GdbQuerySources, GdbAsyncOutput2, + GdbStart, GdbExecRun, GdbExecRunToFunction, GdbExecStep, @@ -111,6 +112,7 @@ enum GdbCommandType GdbExecInterrupt, GdbInfoShared, GdbInfoProc, + GdbInfoThreads, GdbQueryDataDumper1, GdbQueryDataDumper2, @@ -229,6 +231,15 @@ static bool isLeavableFunction(const QString &funcName, const QString &fileName) return false; } +static QString startSymbolName() +{ +#ifdef Q_OS_WIN + return "WinMainCRTStartup"; +#else + return "_start"; +#endif +} + /////////////////////////////////////////////////////////////////////// // @@ -240,23 +251,16 @@ GdbEngine::GdbEngine(DebuggerManager *parent) { q = parent; qq = parent->engineInterface(); - init(); + initializeVariables(); + initializeConnections(); } GdbEngine::~GdbEngine() { } -void GdbEngine::init() +void GdbEngine::initializeConnections() { - m_pendingRequests = 0; - m_gdbVersion = 100; - m_shared = 0; - m_outputCodec = QTextCodec::codecForLocale(); - m_dataDumperState = DataDumperUninitialized; - - m_oldestAcceptableToken = -1; - // Gdb Process interaction connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)), this, SLOT(gdbProcError(QProcess::ProcessError))); @@ -284,6 +288,23 @@ void GdbEngine::init() Qt::QueuedConnection); } +void GdbEngine::initializeVariables() +{ + m_dataDumperState = DataDumperUninitialized; + m_gdbVersion = 100; + + m_fullToShortName.clear(); + m_shortToFullName.clear(); + m_varToType.clear(); + + m_modulesListOutdated = true; + m_oldestAcceptableToken = -1; + m_outputCodec = QTextCodec::codecForLocale(); + m_pendingRequests = 0; + m_waitingForBreakpointSynchronizationToContinue = false; + m_waitingForFirstBreakpointToBeHit = false; +} + void GdbEngine::gdbProcError(QProcess::ProcessError error) { QString msg; @@ -458,13 +479,28 @@ void GdbEngine::handleResponse() break; } - case '~': - case '@': + case '~': { + QString data = GdbMi::parseCString(from, to); + m_pendingConsoleStreamOutput += data; + m_inbuffer = QByteArray(from, to - from); + break; + } + + case '@': { + QString data = GdbMi::parseCString(from, to); + m_pendingTargetStreamOutput += data; + m_inbuffer = QByteArray(from, to - from); + break; + } + case '&': { QString data = GdbMi::parseCString(from, to); - handleStreamOutput(data, c); - //dump(oldfrom, from, record.toString()); + m_pendingLogStreamOutput += data; m_inbuffer = QByteArray(from, to - from); + // On Windows, the contents seem to depend on the debugger + // version and/or OS version used. + if (data.startsWith("warning:")) + qq->showApplicationOutput(data); break; } @@ -635,6 +671,7 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0) } if (pid == q->m_attachedPID) return; + qDebug() << "FOUND PID " << pid; q->m_attachedPID = pid; qq->notifyInferiorPidChanged(pid); } @@ -686,8 +723,8 @@ void GdbEngine::sendCommand(const QString &command, int type, //qDebug() << qPrintable(currentTime()) << "RUNNING" << cmd.command; m_gdbProc.write(cmd.command.toLatin1() + "\r\n"); //emit gdbInputAvailable(QString(), " " + currentTime()); - emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command); - //emit gdbInputAvailable(QString(), cmd.command); + //emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command); + emit gdbInputAvailable(QString(), cmd.command); } if (temporarilyStopped) @@ -734,8 +771,10 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) --m_pendingRequests; PENDING_DEBUG(" TYPE " << cmd.type << " DECREMENTS PENDING TO: " << m_pendingRequests << cmd.command); - if (m_pendingRequests <= 0) + if (m_pendingRequests <= 0) { + PENDING_DEBUG(" .... AND TRIGGERS MODEL UPDATE"); updateWatchModel2(); + } } else { PENDING_DEBUG(" UNKNOWN TYPE " << cmd.type << " LEAVES PENDING AT: " << m_pendingRequests << cmd.command); @@ -753,12 +792,18 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type, case GdbExecContinue: case GdbExecFinish: // evil code sharing - case GdbExecRun: handleExecRun(record); break; + + case GdbStart: + handleStart(record); + break; case GdbInfoProc: handleInfoProc(record); break; + case GdbInfoThreads: + handleInfoThreads(record); + break; case GdbShowVersion: handleShowVersion(record); @@ -952,6 +997,19 @@ void GdbEngine::handleQuerySources(const GdbResultRecord &record) } } +void GdbEngine::handleInfoThreads(const GdbResultRecord &record) +{ + if (record.resultClass == GdbResultDone) { + // FIXME: use something more robust + // WIN: * 3 Thread 2312.0x4d0 0x7c91120f in ?? () + // LINUX: * 1 Thread 0x7f466273c6f0 (LWP 21455) 0x0000000000404542 in ... + QRegExp re(QLatin1String("Thread (\\d+)\\.0x.* in")); + QString data = record.data.findChild("consolestreamoutput").data(); + if (re.indexIn(data) != -1) + maybeHandleInferiorPidChanged(re.cap(1)); + } +} + void GdbEngine::handleInfoProc(const GdbResultRecord &record) { if (record.resultClass == GdbResultDone) { @@ -975,18 +1033,6 @@ void GdbEngine::handleInfoShared(const GdbResultRecord &record) if (record.resultClass == GdbResultDone) { // let the modules handler do the parsing handleModulesList(record); - QList<Module> modules = qq->modulesHandler()->modules(); - bool reloadNeeded = false; - foreach (const Module &module, modules) { - // FIXME: read this from some list - if (!module.symbolsRead && !module.moduleName.contains("Q")) { - reloadNeeded = true; - sendCommand("sharedlibrary " + dotEscape(module.moduleName)); - } - } - if (reloadNeeded) - reloadModules(); - continueInferior(); } } @@ -1028,84 +1074,6 @@ void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record) q->gotoLocation(file, line, true); } -void GdbEngine::handleStreamOutput(const QString &data, char code) -{ - // Linux - if (data.contains("[New Thread")) { - QRegExp re("\\[New Thread 0x([0-9a-f]*) \\(LWP ([0-9]*)\\)\\]"); - if (re.indexIn(data) != -1) - maybeHandleInferiorPidChanged(re.cap(2)); - } - - // Mac - if (data.contains("[Switching to process ")) { - QRegExp re("\\[Switching to process ([0-9]*) local thread 0x([0-9a-f]*)\\]"); - if (re.indexIn(data) != -1) - maybeHandleInferiorPidChanged(re.cap(1)); - } - - // present it twice: now and together with the next 'real' result - switch (code) { - case '~': - m_pendingConsoleStreamOutput += data; - break; - case '@': - m_pendingTargetStreamOutput += data; - break; - case '&': - m_pendingLogStreamOutput += data; - // On Windows, the contents seem to depend on the debugger - // version and/or OS version used. - if (data.startsWith("warning:")) - qq->showApplicationOutput(data); - break; - } - -#ifdef Q_OS_LINUX - if (data.startsWith("Pending break") && data.contains("\" resolved")) { - qDebug() << "SCHEDULING -break-list"; - //m_breakListOnStopNeeded = true; - } -#endif - -#if 0 - if (m_slurpingPTypeOutput) - qDebug() << "SLURP: " << output.data; - - // "No symbol \"__dlopen\" in current context." - // "No symbol \"dlopen\" in current context." - if (output.data.startsWith("No symbol ") - && output.data.contains("dlopen")) { - m_dlopened = true; - return; - } - - // output of 'ptype <foo>' - if (output.data.startsWith("type = ")) { - if (output.data.endsWith("{") || output.data.endsWith("{\\n")) { - // multi-line output started here... - m_slurpingPTypeOutput = true; - m_slurpedPTypeOutput = output.data; - } else { - // Happens for simple types. Process it immediately - m_watchHandler->handleTypeContents(output.data); - } - return; - } - if (m_slurpingPTypeOutput) { - m_slurpedPTypeOutput += '\n'; - m_slurpedPTypeOutput += output.data; - if (output.data.startsWith("}")) { - // this is the last line... - m_slurpingPTypeOutput = false; - m_watchHandler->handleTypeContents(m_slurpedPTypeOutput); - m_slurpedPTypeOutput.clear(); - } - return; - } -#endif -} - static bool isExitedReason(const QString &reason) { return reason == QLatin1String("exited-normally") // inferior exited normally @@ -1133,33 +1101,70 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) { const QString reason = data.findChild("reason").data(); - QString console = data.findChild("consolestreamoutput").data(); - if (console.contains("Stopped due to shared library event") || reason.isEmpty()) { - ++m_shared; - //if (m_shared == 2) - // tryLoadCustomDumpers(); - //qDebug() << "SHARED LIBRARY EVENT " << data.toString() << m_shared; - if (qq->useFastStart()) { - if (1 || m_shared <= 16) { // libpthread? - sendCommand("info shared", GdbInfoShared); - //sendCommand("sharedlibrary gdbdebugger "); - //continueInferior(); - } else { - // auto-load from now on - sendCommand("info shared"); - sendCommand("set auto-solib-add on"); - sendCommand("-file-list-exec-source-files", GdbQuerySources); - sendCommand("-break-list", BreakList); - //sendCommand("bt"); - //QVariant var = QVariant::fromValue<GdbMi>(data); - //sendCommand("p 1", GdbAsyncOutput2, var); // dummy - continueInferior(); - } - } else { - // slow start requested. - q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString()))); + //MAC: bool isFirstStop = data.findChild("bkptno").data() == "1"; + //!MAC: startSymbolName == data.findChild("frame").findChild("func") + if (m_waitingForFirstBreakpointToBeHit) { + m_waitingForFirstBreakpointToBeHit = false; + // + // that's the "early stop" + // + #if defined(Q_OS_WIN) + sendCommand("info thread", GdbInfoThreads); + #endif + #if defined(Q_OS_LINUX) + sendCommand("info proc", GdbInfoProc); + #endif + #if defined(Q_OS_MAC) + sendCommand("info pid", GdbInfoProc, QVariant(), true); + #endif + sendCommand("-file-list-exec-source-files", GdbQuerySources); + tryLoadCustomDumpers(); + + // intentionally after tryLoadCustomDumpers(), + // otherwise we'd interupt solib loading. + if (qq->wantsAllPluginBreakpoints()) { + sendCommand("set auto-solib-add on"); + sendCommand("set stop-on-solib-events 0"); + sendCommand("sharedlibrary .*"); + } else if (qq->wantsSelectedPluginBreakpoints()) { + sendCommand("set auto-solib-add on"); + sendCommand("set stop-on-solib-events 1"); + sendCommand("sharedlibrary "+qq->selectedPluginBreakpointsPattern()); + } else if (qq->wantsNoPluginBreakpoints()) { + // should be like that already + sendCommand("set auto-solib-add off"); + sendCommand("set stop-on-solib-events 0"); + } + // nicer to see a bit of the world we live in + reloadModules(); + // this will "continue" if done + m_waitingForBreakpointSynchronizationToContinue = true; + QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization())); + return; + } + + QString msg = data.findChild("consolestreamoutput").data(); + if (msg.contains("Stopped due to shared library event") || reason.isEmpty()) { + if (qq->wantsSelectedPluginBreakpoints()) { + qDebug() << "SHARED LIBRARY EVENT " << data.toString(); + qDebug() << "PATTERN" << qq->selectedPluginBreakpointsPattern(); + sendCommand("sharedlibrary " + qq->selectedPluginBreakpointsPattern()); continueInferior(); + q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString()))); + return; } + m_modulesListOutdated = true; + // fall through + } + + // seen on XP after removing a breakpoint while running + // stdout:945*stopped,reason="signal-received",signal-name="SIGTRAP", + // signal-meaning="Trace/breakpoint trap",thread-id="2", + // frame={addr="0x7c91120f",func="ntdll!DbgUiConnectToDbg", + // args=[],from="C:\\WINDOWS\\system32\\ntdll.dll"} + if (reason == "signal-received" + && data.findChild("signal-name").toString() == "SIGTRAP") { + continueInferior(); return; } @@ -1214,11 +1219,15 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) } if (isStoppedReason(reason) || reason.isEmpty()) { + if (m_modulesListOutdated) { + reloadModules(); + m_modulesListOutdated = false; + } // Need another round trip if (reason == "breakpoint-hit") { q->showStatusMessage(tr("Stopped at breakpoint")); GdbMi frame = data.findChild("frame"); - //qDebug() << frame.toString(); + //qDebug() << "HIT BREAKPOINT: " << frame.toString(); m_currentFrame = frame.findChild("addr").data() + '%' + frame.findChild("func").data() + '%'; @@ -1265,30 +1274,6 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data) { qq->notifyInferiorStopped(); - // - // Breakpoints - // - //qDebug() << "BREAK ASYNC: " << output.toString(); - //sendListBreakpoints(); - //attemptBreakpointSynchronization(); - //if (m_breakListOnStopNeeded) - // sendListBreakpoints(); - - // something reasonably 'invariant' - // Linux: - //"79*stopped,reason="end-stepping-range",reason="breakpoint-hit",bkptno="1", - //thread-id="1",frame={addr="0x0000000000405d8f",func="run1", - //args=[{name="argc",value="1"},{name="argv",value="0x7fffb7c23058"}], - //file="test1.cpp",fullname="/home/apoenitz/dev/work/test1/test1.cpp" - //,line="261"}" - // Mac: (but only sometimes) - // "82*stopped,bkpt={number="0",type="step - // resume",disp="keep",enabled="y",addr="0x43127171",at="<Find:: - // Internal::FindToolWindow::invokeFindIncremental() - // +225>",thread="1",shlib="/Users/epreuss/dev/ide/main/bin/ - // workbench.app/Contents/PlugIns/Trolltech/libFind.1.0.0.dylib", - // frame="0xbfffd800",thread="1",times="1"}, - // // Stack // @@ -1370,7 +1355,6 @@ void GdbEngine::handleExecRun(const GdbResultRecord &response) if (response.resultClass == GdbResultRunning) { qq->notifyInferiorRunning(); q->showStatusMessage(tr("Running...")); - //reloadModules(); } else if (response.resultClass == GdbResultError) { QString msg = response.data.findChild("msg").data(); if (msg == "Cannot find bounds of current function") { @@ -1458,12 +1442,8 @@ void GdbEngine::exitDebugger() if (m_gdbProc.state() != QProcess::NotRunning) qDebug() << "PROBLEM STOPPING DEBUGGER"; - m_shortToFullName.clear(); - m_fullToShortName.clear(); - m_varToType.clear(); - m_dataDumperState = DataDumperUninitialized; - m_shared = 0; m_outputCollector.shutdown(); + initializeVariables(); //q->settings()->m_debugDumpers = false; } @@ -1530,12 +1510,7 @@ bool GdbEngine::startDebugger() q->showStatusMessage(tr("Gdb Running")); sendCommand("show version", GdbShowVersion); - if (qq->useFastStart()) { - sendCommand("set auto-solib-add off"); - sendCommand("set stop-on-solib-events 1"); - } //sendCommand("-enable-timings"); - //sendCommand("set stop-on-solib-events 1"); sendCommand("set print static-members off"); // Seemingly doesn't work. //sendCommand("define hook-stop\n-thread-list-ids\n-stack-list-frames\nend"); //sendCommand("define hook-stop\nprint 4\nend"); @@ -1604,16 +1579,31 @@ bool GdbEngine::startDebugger() } } + if (q->startMode() == q->startInternal) { + emit gdbInputAvailable(QString(), QString()); + sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols); + //sendCommand("file " + fileName, GdbFileExecAndSymbols); + #ifdef Q_OS_MAC + sendCommand("sharedlibrary apply-load-rules all"); + #endif + setTokenBarrier(); + if (!q->m_processArgs.isEmpty()) + sendCommand("-exec-arguments " + q->m_processArgs.join(" ")); + sendCommand("set auto-solib-add off"); + sendCommand("x/2i " + startSymbolName(), GdbStart); + } + if (q->startMode() == q->attachExternal) { sendCommand("attach " + QString::number(q->m_attachedPID)); } - if (q->startMode() == q->startInternal || q->startMode() == q->startExternal) { - sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols); + if (q->startMode() == q->startExternal) { + //sendCommand("-file-exec-and-symbols " + fileName, GdbFileExecAndSymbols); + sendCommand("file " + fileName, GdbFileExecAndSymbols); #ifdef Q_OS_MAC sendCommand("sharedlibrary apply-load-rules all"); #endif - sendCommand("-file-list-exec-source-files", GdbQuerySources); + //sendCommand("-file-list-exec-source-files", GdbQuerySources); //sendCommand("-gdb-set stop-on-solib-events 1"); } @@ -1625,8 +1615,6 @@ bool GdbEngine::startDebugger() else qq->breakHandler()->setAllPending(); - QTimer::singleShot(0, this, SLOT(attemptBreakpointSynchronization())); - return true; } @@ -1639,25 +1627,26 @@ void GdbEngine::continueInferior() sendCommand("-exec-continue", GdbExecContinue); } -void GdbEngine::runInferior() +void GdbEngine::handleStart(const GdbResultRecord &response) { - q->resetLocation(); - // FIXME: this ignores important startup messages - setTokenBarrier(); - if (!q->m_processArgs.isEmpty()) - sendCommand("-exec-arguments " + q->m_processArgs.join(" ")); - qq->notifyInferiorRunningRequested(); - emit gdbInputAvailable(QString(), QString()); - sendCommand("-exec-run", GdbExecRun); -#if defined(Q_OS_WIN) - sendCommand("info proc", GdbInfoProc); -#endif -#if defined(Q_OS_LINUX) - sendCommand("info proc", GdbInfoProc); -#endif -#if defined(Q_OS_MAC) - sendCommand("info pid", GdbInfoProc, QVariant(), true); -#endif + if (response.resultClass == GdbResultDone) { + // stdout:&"x/2i _start\n" + // stdout:~"0x404540 <_start>:\txor %ebp,%ebp\n" + // stdout:~"0x404542 <_start+2>:\tmov %rdx,%r9\n" + QString msg = response.data.findChild("consolestreamoutput").data(); + QRegExp needle("0x([0-9a-f]+) <" + startSymbolName() + "\\+.*>:"); + if (needle.indexIn(msg) != -1) { + //qDebug() << "STREAM: " << msg << needle.cap(1); + sendCommand("tbreak *0x" + needle.cap(1)); + m_waitingForFirstBreakpointToBeHit = true; + sendCommand("-exec-run"); + qq->notifyInferiorRunningRequested(); + } else { + qDebug() << "PARSING START ADDRESS FAILED" << msg; + } + } else if (response.resultClass == GdbResultError) { + qDebug() << "PARSING START ADDRESS FAILED" << response.toString(); + } } void GdbEngine::stepExec() @@ -2108,11 +2097,14 @@ void GdbEngine::handleBreakInsert1(const GdbResultRecord &record, int index) void GdbEngine::attemptBreakpointSynchronization() { + // Non-lethal check for nested calls + static bool inBreakpointSychronization = false; + QTC_ASSERT(!inBreakpointSychronization, /**/); + inBreakpointSychronization = true; + BreakHandler *handler = qq->breakHandler(); - //qDebug() << "BREAKPOINT SYNCHRONIZATION "; foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) { - //qDebug() << " SYNCHRONIZATION REMOVING" << data; QString bpNumber = data->bpNumber; if (!bpNumber.trimmed().isEmpty()) sendCommand("-break-delete " + bpNumber, BreakDelete, 0, true); @@ -2178,13 +2170,13 @@ void GdbEngine::attemptBreakpointSynchronization() } } - if (updateNeeded) { - //interruptAndContinue(); - //sendListBreakpoints(); + if (!updateNeeded && m_waitingForBreakpointSynchronizationToContinue) { + m_waitingForBreakpointSynchronizationToContinue = false; + // we continue the execution + continueInferior(); } - if (!updateNeeded && q->status() == DebuggerProcessStartingUp) - qq->notifyStartupFinished(); + inBreakpointSychronization = false; } @@ -3472,8 +3464,6 @@ void GdbEngine::handleDumpCustomValue1(const GdbResultRecord &record, && msg.startsWith("The program being debugged stopped while") && msg.contains("qDumpObjectData440")) { // Fake full stop - sendCommand("-file-list-exec-source-files", GdbQuerySources); - sendCommand("-break-list", BreakList); sendCommand("p 0", GdbAsyncOutput2); // dummy return; } @@ -3603,7 +3593,7 @@ void GdbEngine::updateLocals() // '2' is 'list with type and value' sendSynchronizedCommand("-stack-list-locals 2", StackListLocals); // stage 2/2 - tryLoadCustomDumpers(); + //tryLoadCustomDumpers(); } void GdbEngine::handleStackListArguments(const GdbResultRecord &record) @@ -3949,74 +3939,66 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString & sendCommand("-var-assign assign " + value, WatchVarAssign); } - void GdbEngine::tryLoadCustomDumpers() { if (m_dataDumperState != DataDumperUninitialized) return; PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS"); - m_dataDumperState = DataDumperLoadTried; + m_dataDumperState = DataDumperUnavailable; #if defined(Q_OS_LINUX) QString lib = q->m_buildDir + "/qtc-gdbmacros/libgdbmacros.so"; - if (QFileInfo(lib).isExecutable()) { + if (QFileInfo(lib).exists()) { + m_dataDumperState = DataDumperLoadTried; //sendCommand("p dlopen"); - //if (qq->useFastStart()) - // sendCommand("set stop-on-solib-events 0"); QString flag = QString::number(RTLD_NOW); - sendSynchronizedCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")", + sendCommand("sharedlibrary libc"); // for malloc + sendCommand("sharedlibrary libdl"); // for dlopen + sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")", WatchDumpCustomSetup); // some older systems like CentOS 4.6 prefer this: - sendSynchronizedCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")", + sendCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")", WatchDumpCustomSetup); - sendSynchronizedCommand("sharedlibrary " + dotEscape(lib)); - //if (qq->useFastStart()) - // sendCommand("set stop-on-solib-events 1"); - } else { - qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: " - << lib << QFileInfo(lib).isExecutable(); + sendCommand("sharedlibrary " + dotEscape(lib)); } #endif #if defined(Q_OS_MAC) QString lib = q->m_buildDir + "/qtc-gdbmacros/libgdbmacros.dylib"; - if (QFileInfo(lib).isExecutable()) { - //sendCommand("p dlopen"); // FIXME: remove me - //if (qq->useFastStart()) - // sendCommand("set stop-on-solib-events 0"); + if (QFileInfo(lib).exists()) { + m_dataDumperState = DataDumperLoadTried; + sendCommand("sharedlibrary libc"); // for malloc + sendCommand("sharedlibrary libdl"); // for dlopen QString flag = QString::number(RTLD_NOW); - sendSynchronizedCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")", + sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")", WatchDumpCustomSetup); - sendSynchronizedCommand("sharedlibrary " + dotEscape(lib)); - //if (qq->useFastStart()) - // sendCommand("set stop-on-solib-events 1"); - } else { - qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: " - << lib << QFileInfo(lib).isExecutable(); + sendCommand("sharedlibrary " + dotEscape(lib)); } #endif #if defined(Q_OS_WIN) QString lib = q->m_buildDir + "/qtc-gdbmacros/debug/gdbmacros.dll"; if (QFileInfo(lib).exists()) { - //if (qq->useFastStart()) - // sendCommand("set stop-on-solib-events 0"); + m_dataDumperState = DataDumperLoadTried; + sendCommand("sharedlibrary .*"); // for LoadLibraryA //sendCommand("handle SIGSEGV pass stop print"); //sendCommand("set unwindonsignal off"); - sendSynchronizedCommand("call LoadLibraryA(\"" + lib + "\")", + sendCommand("call LoadLibraryA(\"" + lib + "\")", WatchDumpCustomSetup); - sendSynchronizedCommand("sharedlibrary " + dotEscape(lib)); - //if (qq->useFastStart()) - // sendCommand("set stop-on-solib-events 1"); - } else { - qDebug() << "DEBUG HELPER LIBRARY IS NOT USABLE: " - << lib << QFileInfo(lib).isExecutable(); + sendCommand("sharedlibrary " + dotEscape(lib)); } #endif - // retreive list of dumpable classes - sendSynchronizedCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)", - GdbQueryDataDumper1); - sendSynchronizedCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper2); + if (m_dataDumperState == DataDumperLoadTried) { + // retreive list of dumpable classes + sendCommand("call qDumpObjectData440(1,%1+1,0,0,0,0,0,0)", + GdbQueryDataDumper1); + sendCommand("p (char*)qDumpOutBuffer", GdbQueryDataDumper2); + } else { + gdbOutputAvailable("", QString("DEBUG HELPER LIBRARY IS NOT USABLE: " + " %1 EXISTS: %2, EXECUTABLE: %3").arg(lib) + .arg(QFileInfo(lib).exists()) + .arg(QFileInfo(lib).isExecutable())); + } } diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index a603aee375dc5732cbd066b79fb06f97ef8f36b2..0d710e359cf7139c7f45e3d98448a7fa9090d8c9 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -113,7 +113,6 @@ private: void exitDebugger(); void continueInferior(); - void runInferior(); void interruptInferior(); void runToLineExec(const QString &fileName, int lineNumber); @@ -145,7 +144,8 @@ private: bool supportsThreads() const; - void init(); // called by destructor + void initializeConnections(); + void initializeVariables(); void queryFullName(const QString &fileName, QString *fullName); QString fullName(const QString &fileName); QString shortName(const QString &fullName); @@ -179,7 +179,7 @@ private slots: private: int terminationIndex(const QByteArray &buffer, int &length); - void handleStreamOutput(const QString &output, char code); + void handleStart(const GdbResultRecord &response); void handleAsyncOutput2(const GdbMi &data); void handleAsyncOutput(const GdbMi &data); void handleResultRecord(const GdbResultRecord &response); @@ -189,6 +189,7 @@ private: void handleExecRunToFunction(const GdbResultRecord &response); void handleInfoShared(const GdbResultRecord &response); void handleInfoProc(const GdbResultRecord &response); + void handleInfoThreads(const GdbResultRecord &response); void handleShowVersion(const GdbResultRecord &response); void handleQueryPwd(const GdbResultRecord &response); void handleQuerySources(const GdbResultRecord &response); @@ -215,7 +216,6 @@ private: int m_oldestAcceptableToken; int m_gdbVersion; // 6.8.0 is 680 - int m_shared; // awful hack to keep track of used files QHash<QString, QString> m_shortToFullName; @@ -330,6 +330,10 @@ private: QString m_currentFrame; QMap<QString, QString> m_varToType; + bool m_waitingForBreakpointSynchronizationToContinue; + bool m_waitingForFirstBreakpointToBeHit; + bool m_modulesListOutdated; + DebuggerManager *q; IDebuggerManagerAccessForEngines *qq; }; diff --git a/src/plugins/debugger/gdboptionpage.ui b/src/plugins/debugger/gdboptionpage.ui index ef485ccbf8333ed3c531900ee4b18f61c753d859..884080c1a302628b7a72e412cdd1c1fb05ecbe68 100644 --- a/src/plugins/debugger/gdboptionpage.ui +++ b/src/plugins/debugger/gdboptionpage.ui @@ -6,26 +6,20 @@ <rect> <x>0</x> <y>0</y> - <width>465</width> - <height>372</height> + <width>398</width> + <height>385</height> </rect> </property> <property name="windowTitle"> <string>Form</string> </property> - <layout class="QVBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>9</number> - </property> - <item> - <widget class="QGroupBox" name="groupBox"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QGroupBox" name="groupBoxLocations"> <property name="title"> <string>Locations</string> </property> - <layout class="QGridLayout"> + <layout class="QGridLayout" name="gridLayout_3"> <property name="margin"> <number>9</number> </property> @@ -74,27 +68,80 @@ </layout> </widget> </item> - <item> - <widget class="QCheckBox" name="checkBoxUseCustomDumpers"> - <property name="toolTip"> - <string>Checking this will make the debugger try to use code to format certain data (QObject, QString, std::string etc.) nicely.</string> - </property> - <property name="text"> - <string>Use custom display for Qt and Standard Library objects</string> + <item row="1" column="0"> + <widget class="QGroupBox" name="groupBoxPluginDebugging"> + <property name="title"> + <string>Behaviour of breakpoint setting in plugins</string> </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QRadioButton" name="radioButtonAllPluginBreakpoints"> + <property name="toolTip"> + <string>This is the slowest but safest option.</string> + </property> + <property name="text"> + <string>Try to set breakpoints in plugins always automatically.</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QRadioButton" name="radioButtonSelectedPluginBreakpoints"> + <property name="text"> + <string>Try to set breakpoints in selected plugins</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Preferred</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>10</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="labelSelectedPluginBreakpoints"> + <property name="text"> + <string>Matching regular expression: </string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEditSelectedPluginBreakpointsPattern"/> + </item> + </layout> + </item> + <item row="3" column="0"> + <widget class="QRadioButton" name="radioButtonNoPluginBreakpoints"> + <property name="text"> + <string>Never set breakpoints in plugins automatically</string> + </property> + </widget> + </item> + </layout> </widget> </item> - <item> - <widget class="QCheckBox" name="checkBoxFastStart"> + <item row="2" column="0"> + <widget class="QCheckBox" name="checkBoxUseCustomDumpers"> <property name="toolTip"> - <string>Checking this will make the debugger start fast by loading only very few debug symbols on start up. This might lead to situations where breakpoints can not be set properly. So uncheck this option if you experience breakpoint related problems.</string> + <string>Checking this will make the debugger try to use code to format certain data (QObject, QString, std::string etc.) nicely.</string> </property> <property name="text"> - <string>Fast debugger start</string> + <string>Use custom display for Qt and Standard Library objects</string> </property> </widget> </item> - <item> + <item row="3" column="0"> <widget class="QCheckBox" name="checkBoxSkipKnownFrames"> <property name="toolTip"> <string>When this option is checked, 'Step Into' compresses several steps into one in certain situations, leading to 'less noisy' debugging. So will, e.g., the atomic @@ -105,7 +152,7 @@ </property> </widget> </item> - <item> + <item row="4" column="0"> <widget class="QCheckBox" name="checkBoxUseToolTips"> <property name="toolTip"> <string>Checking this will make enable tooltips for variable values during debugging. Since this can slow down debugging and does not provide reliable information as it does not use scope information, it is switched off by default.</string> @@ -115,7 +162,7 @@ </property> </widget> </item> - <item> + <item row="5" column="0"> <widget class="QCheckBox" name="checkBoxDebugDumpers"> <property name="toolTip"> <string notr="true">This is an internal tool to make debugging the Custom Data Dumper code easier. Using this action is in general not needed unless you want do debug Qt Creator itself.</string> @@ -125,29 +172,15 @@ </property> </widget> </item> - <item> - <widget class="QCheckBox" name="autoStartBox"> - <property name="text"> - <string>Auto run executable on debugger startup</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="autoQuitBox"> - <property name="text"> - <string>Quit debugger when the executable exits</string> - </property> - </widget> - </item> - <item> - <spacer> + <item row="6" column="0"> + <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>415</width> - <height>41</height> + <width>10</width> + <height>1</height> </size> </property> </spacer> diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index 1558d140ee62ed6d4a467c15d24b0243a7e1d19e..ee1e15793f3bc564c25089cd91f120cbd3b902e9 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -62,7 +62,6 @@ public: virtual void nextIExec() = 0; virtual void continueInferior() = 0; - virtual void runInferior() = 0; virtual void interruptInferior() = 0; virtual void runToLineExec(const QString &fileName, int lineNumber) = 0; diff --git a/src/plugins/designer/formwindoweditor.cpp b/src/plugins/designer/formwindoweditor.cpp index a683dccd86451d2a560199880fad483a34d276f4..869443a9aaf88784b6df3597d846cf4a11e36143 100644 --- a/src/plugins/designer/formwindoweditor.cpp +++ b/src/plugins/designer/formwindoweditor.cpp @@ -45,6 +45,8 @@ #include <QtDesigner/QDesignerFormWindowInterface> #include <QtDesigner/QDesignerFormEditorInterface> #include <QtDesigner/QDesignerFormWindowManagerInterface> +#include <QtDesigner/QDesignerPropertyEditorInterface> +#include <QtDesigner/QDesignerWidgetDataBaseInterface> #include <qt_private/formwindowbase_p.h> #include <qt_private/qtresourcemodel_p.h> @@ -325,3 +327,25 @@ void FormWindowEditor::activate() { m_editorWidget->activate(); } + +QString FormWindowEditor::contextHelpId() const +{ + // TODO [13.2.09]: Replace this by QDesignerIntegrations context help Id + // in the upcoming version of Qt + QDesignerFormEditorInterface *core = FormEditorW::instance()->designerEditor(); + QObject *o = core->propertyEditor()->object(); + if (!o) + return QString(); + const QDesignerWidgetDataBaseInterface *db = core->widgetDataBase(); + const int dbIndex = db->indexOfObject(o, true); + if (dbIndex == -1) + return QString(); + QString className = db->item(dbIndex)->name(); + if (className == QLatin1String("Line")) + className = QLatin1String("QFrame"); + else if (className == QLatin1String("Spacer")) + className = QLatin1String("QSpacerItem"); + else if (className == QLatin1String("QLayoutWidget")) + className = QLatin1String("QLayout"); + return className; +} diff --git a/src/plugins/designer/formwindoweditor.h b/src/plugins/designer/formwindoweditor.h index e854ccac915a69141600f6ead2e86e483a33c041..bce29c2f5a8844e8d3cb24c3b34c84b8a4db8bd0 100644 --- a/src/plugins/designer/formwindoweditor.h +++ b/src/plugins/designer/formwindoweditor.h @@ -63,7 +63,6 @@ class EditorWidget; class FormWindowEditor : public Core::IEditor { Q_OBJECT - public: FormWindowEditor(const QList<int> &context, QDesignerFormWindowInterface *form, @@ -84,8 +83,9 @@ public: bool restoreState(const QByteArray &state); // ContextInterface - QList<int> context() const; - QWidget *widget(); + virtual QList<int> context() const; + virtual QWidget *widget(); + virtual QString contextHelpId() const; QDesignerFormWindowInterface *formWindow() const; QWidget *integrationContainer(); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 007aac874de5171e7292680433c83e83c8e9e590..87f06931200b13a411d29487b5c42593a0217616 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -207,20 +207,20 @@ void GitClient::diff(const QString &workingDirectory, QStringList arguments; arguments << QLatin1String("diff") << diffArgs; m_plugin->outputWindow()->append(formatCommand(binary, arguments)); - command->addJob(arguments); + command->addJob(arguments, m_settings.timeout); } else { // Files diff. if (!unstagedFileNames.empty()) { QStringList arguments; arguments << QLatin1String("diff") << diffArgs << QLatin1String("--") << unstagedFileNames; m_plugin->outputWindow()->append(formatCommand(binary, arguments)); - command->addJob(arguments); + command->addJob(arguments, m_settings.timeout); } if (!stagedFileNames.empty()) { QStringList arguments; arguments << QLatin1String("diff") << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames; m_plugin->outputWindow()->append(formatCommand(binary, arguments)); - command->addJob(arguments); + command->addJob(arguments, m_settings.timeout); } } command->execute(); @@ -503,7 +503,7 @@ void GitClient::executeGit(const QString &workingDirectory, { m_plugin->outputWindow()->append(formatCommand(QLatin1String(Constants::GIT_BINARY), arguments)); GitCommand *command = createCommand(workingDirectory, editor, outputToWindow); - command->addJob(arguments); + command->addJob(arguments, m_settings.timeout); command->execute(); } diff --git a/src/plugins/git/gitcommand.cpp b/src/plugins/git/gitcommand.cpp index fa62401b0119c1d22f789935af2b9a7ab2d3ec74..8362926cecc431acbe9525067b96566f4171d74c 100644 --- a/src/plugins/git/gitcommand.cpp +++ b/src/plugins/git/gitcommand.cpp @@ -55,8 +55,9 @@ static inline QStringList environmentToList(const ProjectExplorer::Environment & return ProjectExplorer::Environment::systemEnvironment().toStringList(); } -GitCommand::Job::Job(const QStringList &a) : - arguments(a) +GitCommand::Job::Job(const QStringList &a, int t) : + arguments(a), + timeout(t) { } @@ -67,9 +68,9 @@ GitCommand::GitCommand(const QString &workingDirectory, { } -void GitCommand::addJob(const QStringList &arguments) +void GitCommand::addJob(const QStringList &arguments, int timeout) { - m_jobs.push_back(Job(arguments)); + m_jobs.push_back(Job(arguments, timeout)); } void GitCommand::execute() @@ -109,7 +110,7 @@ void GitCommand::run() qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments; process.start(QLatin1String(Constants::GIT_BINARY), m_jobs.at(j).arguments); - if (!process.waitForFinished()) { + if (!process.waitForFinished(m_jobs.at(j).timeout * 1000)) { ok = false; error += QLatin1String("Error: Git timed out"); break; diff --git a/src/plugins/git/gitcommand.h b/src/plugins/git/gitcommand.h index a587b74876140a3b6a29873b5c02456ada586080..32b76bf3485912c314727c0fb7592979b49e173c 100644 --- a/src/plugins/git/gitcommand.h +++ b/src/plugins/git/gitcommand.h @@ -49,7 +49,7 @@ public: ProjectExplorer::Environment &environment); - void addJob(const QStringList &arguments); + void addJob(const QStringList &arguments, int timeout); void execute(); private: @@ -61,9 +61,10 @@ Q_SIGNALS: private: struct Job { - explicit Job(const QStringList &a); + explicit Job(const QStringList &a, int t); QStringList arguments; + int timeout; }; QStringList environment() const; diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp index 2b528a72d2a8c477ff902c20ddf5285057489420..02a1acc1d9eaaf14c4c04f136d49482ecff6080a 100644 --- a/src/plugins/git/gitsettings.cpp +++ b/src/plugins/git/gitsettings.cpp @@ -40,15 +40,17 @@ static const char *groupC = "Git"; static const char *sysEnvKeyC = "SysEnv"; static const char *pathKeyC = "Path"; static const char *logCountKeyC = "LogCount"; +static const char *timeoutKeyC = "TimeOut"; -enum { defaultLogCount = 10 }; +enum { defaultLogCount = 10 , defaultTimeOut = 30}; namespace Git { namespace Internal { GitSettings::GitSettings() : adoptPath(false), - logCount(defaultLogCount) + logCount(defaultLogCount), + timeout(defaultTimeOut) { } @@ -58,6 +60,7 @@ void GitSettings::fromSettings(QSettings *settings) adoptPath = settings->value(QLatin1String(sysEnvKeyC), false).toBool(); path = settings->value(QLatin1String(pathKeyC), QString()).toString(); logCount = settings->value(QLatin1String(logCountKeyC), defaultLogCount).toInt(); + timeout = settings->value(QLatin1String(timeoutKeyC), defaultTimeOut).toInt(); settings->endGroup(); } @@ -67,12 +70,13 @@ void GitSettings::toSettings(QSettings *settings) const settings->setValue(QLatin1String(sysEnvKeyC), adoptPath); settings->setValue(QLatin1String(pathKeyC), path); settings->setValue(QLatin1String(logCountKeyC), logCount); + settings->setValue(QLatin1String(timeoutKeyC), timeout); settings->endGroup(); } bool GitSettings::equals(const GitSettings &s) const { - return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount; + return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount && timeout == s.timeout; } } diff --git a/src/plugins/git/gitsettings.h b/src/plugins/git/gitsettings.h index 59169922605e83c8d02d2016169220c6e5579dca..c2463eb326da6d3cf69e21503cb37f539b8fc97f 100644 --- a/src/plugins/git/gitsettings.h +++ b/src/plugins/git/gitsettings.h @@ -56,6 +56,7 @@ struct GitSettings bool adoptPath; QString path; int logCount; + int timeout; }; inline bool operator==(const GitSettings &p1, const GitSettings &p2) diff --git a/src/plugins/git/settingspage.cpp b/src/plugins/git/settingspage.cpp index a3b82194cec1a886ac72e2d9428cc1caed0eb227..121c7cd889b1ad048d9c3069d96d82757d6686d3 100644 --- a/src/plugins/git/settingspage.cpp +++ b/src/plugins/git/settingspage.cpp @@ -52,6 +52,7 @@ GitSettings SettingsPageWidget::settings() const rc.path = m_ui.pathLineEdit->text(); rc.adoptPath = m_ui.environmentGroupBox->isChecked() && !rc.path.isEmpty(); rc.logCount = m_ui.logCountSpinBox->value(); + rc.timeout = m_ui.timeoutSpinBox->value(); return rc; } @@ -60,6 +61,7 @@ void SettingsPageWidget::setSettings(const GitSettings &s) m_ui.environmentGroupBox->setChecked(s.adoptPath); m_ui.pathLineEdit->setText(s.path); m_ui.logCountSpinBox->setValue(s.logCount); + m_ui.timeoutSpinBox->setValue(s.timeout); } void SettingsPageWidget::setSystemPath() diff --git a/src/plugins/git/settingspage.ui b/src/plugins/git/settingspage.ui index 94c04493aabb47f69ea469348f3d3304a2d08868..1a594bf4313fc8354d13d125bbae783e6593fa2e 100644 --- a/src/plugins/git/settingspage.ui +++ b/src/plugins/git/settingspage.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>403</width> - <height>183</height> + <height>251</height> </rect> </property> <property name="windowTitle"> @@ -69,10 +69,14 @@ </widget> </item> <item> - <layout class="QFormLayout" name="logFormLayout"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::ExpandingFieldsGrow</enum> - </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="logCountLabel"> + <property name="text"> + <string>Log commit display count:</string> + </property> + </widget> + </item> <item row="0" column="1"> <widget class="QSpinBox" name="logCountSpinBox"> <property name="toolTip"> @@ -83,10 +87,23 @@ </property> </widget> </item> - <item row="0" column="0"> - <widget class="QLabel" name="logCountLabel"> + <item row="1" column="0"> + <widget class="QLabel" name="timeoutLabel"> <property name="text"> - <string>Log commit display count:</string> + <string>Timeout (seconds):</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="timeoutSpinBox"> + <property name="minimum"> + <number>10</number> + </property> + <property name="maximum"> + <number>300</number> + </property> + <property name="value"> + <number>30</number> </property> </widget> </item> diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index 96b16d59d31731bd465ef1f93aac14c9c6c72d16..32125bb100774bb2c57446bf1da9b5dbf9d50cc9 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -170,16 +170,24 @@ bool MinGWToolChain::equals(ToolChain *other) const void MinGWToolChain::addToEnvironment(ProjectExplorer::Environment &env) { + //qDebug()<<"MinGWToolChain::addToEnvironment"; QString binDir = m_mingwPath + "/bin"; if (QFileInfo(binDir).exists()) env.prependOrSetPath(binDir); +// if (QFileInfo(binDir).exists()) +// qDebug()<<"Adding "<<binDir<<" to the PATH"; } MSVCToolChain::MSVCToolChain(const QString &name) : m_name(name), m_valuesSet(false) { - + if (m_name.isEmpty()) { // Could be because system qt doesn't set this + QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", + QSettings::NativeFormat); + if (registry.allKeys().count()) + m_name = registry.allKeys().first(); + } } ToolChain::ToolChainType MSVCToolChain::type() const @@ -211,10 +219,11 @@ QList<HeaderPath> MSVCToolChain::systemHeaderPaths() //TODO fix this code ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); addToEnvironment(env); -#ifdef QTCREATOR_WITH_MSVC_INCLUDES - return env.value("INCLUDE").split(QLatin1Char(';')); -#endif - return QList<HeaderPath>(); + QList<HeaderPath> headerPaths; + foreach(const QString &path, env.value("INCLUDE").split(QLatin1Char(';'))) { + headerPaths.append(HeaderPath(path, HeaderPath::GlobalHeaderPath)); + } + return headerPaths; } void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env) @@ -222,6 +231,8 @@ void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env) if (!m_valuesSet) { QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", QSettings::NativeFormat); + if (m_name.isEmpty()) + return; QString path = registry.value(m_name).toString(); ProjectExplorer::Environment oldEnv(env); QString desc; @@ -264,11 +275,12 @@ void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env) m_valuesSet = true; } + //qDebug()<<"MSVC Environment:"; QList< QPair<QString, QString> >::const_iterator it, end; end = m_values.constEnd(); for (it = m_values.constBegin(); it != end; ++it) { env.set((*it).first, (*it).second); - qDebug()<<"variable:"<<(*it).first<<"value:"<<(*it).second; + //qDebug()<<"variable:"<<(*it).first<<"value:"<<(*it).second; } } @@ -325,4 +337,6 @@ void WinCEToolChain::addToEnvironment(ProjectExplorer::Environment &env) CeSdkHandler cesdkhandler; cesdkhandler.parse(path); cesdkhandler.find(m_platform).addToEnvironment(env); + //qDebug()<<"WinCE Final Environment:"; + //qDebug()<<env.toStringList(); } diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index 455d480b8606ddba7615d66048d0df059e4b5fd4..0e7e16c5ffd4cc53195696b6ed89638fa9daf309 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -40,6 +40,7 @@ public: enum ToolChainType { GCC, + LinuxICC, MinGW, MSVC, WINCE, diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index 6a27c484b808dc19d8c066fe8fdaeb15daf2d765..d4741cdcfca5d21d48f70b3cd4e4a5f88422a532 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -404,8 +404,10 @@ void Qt4Project::scheduleUpdateCodeModel() ProjectExplorer::ToolChain *Qt4Project::toolChain(const QString &buildConfiguration) const { + if (debug) + qDebug()<<"Qt4Project::toolChain() for buildconfiguration:"<<buildConfiguration; Q_UNUSED(buildConfiguration); - ToolChain *m_test; + ToolChain *m_test= 0; QtVersion *version = qtVersion(activeBuildConfiguration()); ToolChain::ToolChainType t = version->toolchainType(); if (t == ToolChain::MinGW) { @@ -415,20 +417,27 @@ ProjectExplorer::ToolChain *Qt4Project::toolChain(const QString &buildConfigurat qtVersion(activeBuildConfiguration())->addToEnvironment(env); qmake_cxx = env.searchInPath(qmake_cxx); m_test = ToolChain::createMinGWToolChain(qmake_cxx, version->mingwDirectory()); + qDebug()<<"Mingw ToolChain"; } else if(t == ToolChain::MSVC) { m_test = ToolChain::createMSVCToolChain(version->msvcVersion()); + //qDebug()<<"MSVC ToolChain ("<<version->msvcVersion()<<")"; } else if(t == ToolChain::WINCE) { m_test = ToolChain::createWinCEToolChain(version->msvcVersion(), version->wincePlatform()); - } else if(t == ToolChain::GCC) { + //qDebug()<<"WinCE ToolChain ("<<version->msvcVersion()<<","<<version->wincePlatform()<<")"; + } else if(t == ToolChain::GCC || t == ToolChain::LinuxICC) { QStringList list = rootProjectNode()->variableValue(Internal::CxxCompilerVar); QString qmake_cxx = list.isEmpty() ? QString::null : list.first(); Environment env = Environment::systemEnvironment(); qtVersion(activeBuildConfiguration())->addToEnvironment(env); qmake_cxx = env.searchInPath(qmake_cxx); m_test = ToolChain::createGccToolChain(qmake_cxx); + //qDebug()<<"GCC ToolChain ("<<qmake_cxx<<")"; + } else { + qDebug()<<"Could not detect ToolChain for"<<version->mkspec(); + qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines."; } - if (m_test == m_toolChain) { + if (ToolChain::equals(m_test, m_toolChain)) { delete m_test; } else { delete m_toolChain; @@ -457,8 +466,18 @@ void Qt4Project::updateCodeModel() const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS")); ToolChain *tc = toolChain(activeBuildConfiguration()); - QByteArray predefinedMacros = tc->predefinedMacros(); - QList<HeaderPath> allHeaderPaths = tc->systemHeaderPaths(); + QByteArray predefinedMacros; + QList<HeaderPath> allHeaderPaths; + if (tc) { + predefinedMacros = tc->predefinedMacros(); + allHeaderPaths = tc->systemHeaderPaths(); + //qDebug()<<"Predifined Macros"; + //qDebug()<<tc->predefinedMacros(); + //qDebug()<<""; + //qDebug()<<"System Header Paths"; + //foreach(const HeaderPath &hp, tc->systemHeaderPaths()) + // qDebug()<<hp.path(); + } foreach (HeaderPath headerPath, allHeaderPaths) { if (headerPath.kind() == HeaderPath::FrameworkHeaderPath) allFrameworkPaths.append(headerPath.path()); @@ -696,7 +715,9 @@ ProjectExplorer::Environment Qt4Project::baseEnvironment(const QString &buildCon { Environment env = useSystemEnvironment(buildConfiguration) ? Environment(QProcess::systemEnvironment()) : Environment(); qtVersion(buildConfiguration)->addToEnvironment(env); - toolChain(buildConfiguration)->addToEnvironment(env); + ToolChain *tc = toolChain(buildConfiguration); + if (tc) + tc->addToEnvironment(env); return env; } @@ -863,14 +884,14 @@ void Qt4Project::checkForDeletedApplicationProjects() foreach (Qt4ProFileNode * node, applicationProFiles()) paths.append(node->path()); - qDebug()<<"Still existing paths :"<<paths; +// qDebug()<<"Still existing paths :"<<paths; QList<QSharedPointer<Qt4RunConfiguration> > removeList; foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) { if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) { if (!paths.contains(qt4rc->proFilePath())) { removeList.append(qt4rc); - qDebug()<<"Removing runConfiguration for "<<qt4rc->proFilePath(); +// qDebug()<<"Removing runConfiguration for "<<qt4rc->proFilePath(); } } } diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 8abc994e919e2047d386cbbde1b5dfb7ecdaa1d0..8abe37fd201271320c06f9ff89b9298505744074 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -241,12 +241,17 @@ void QtVersionManager::addNewVersionsFromInstaller() // or NewQtVersions="qt 4.3.2=c:\\qt\\qt432=c:\\qtcreator\\mingw\\=prependToPath; // Duplicate entries are not added, the first new version is set as default. QSettings *settings = Core::ICore::instance()->settings(); - if (!settings->contains(newQtVersionsKey)) + + if (!settings->contains(newQtVersionsKey) && + !settings->contains(QLatin1String("Installer/")+newQtVersionsKey)) return; // qDebug()<<"QtVersionManager::addNewVersionsFromInstaller()"; QString newVersionsValue = settings->value(newQtVersionsKey).toString(); + if (newVersionsValue.isEmpty()) + newVersionsValue = settings->value(QLatin1String("Installer/")+newQtVersionsKey).toString(); + QStringList newVersionsList = newVersionsValue.split(';', QString::SkipEmptyParts); bool defaultVersionWasReset = false; foreach (QString newVersion, newVersionsList) { @@ -281,6 +286,7 @@ void QtVersionManager::addNewVersionsFromInstaller() } } settings->remove(newQtVersionsKey); + settings->remove(QLatin1String("Installer/")+newQtVersionsKey); updateUniqueIdToIndexMap(); } @@ -1183,14 +1189,17 @@ ProjectExplorer::ToolChain::ToolChainType QtVersion::toolchainType() const if (!isValid()) return ProjectExplorer::ToolChain::INVALID; const QString &spec = mkspec(); +// qDebug()<<"spec="<<spec; if (spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc"))) return ProjectExplorer::ToolChain::MSVC; - else if (spec == "win32-g++") + else if (spec.contains("win32-g++")) return ProjectExplorer::ToolChain::MinGW; else if (spec == QString::null) return ProjectExplorer::ToolChain::INVALID; - else if (spec.startsWith("wince")) + else if (spec.contains("wince")) return ProjectExplorer::ToolChain::WINCE; + else if (spec.contains("linux-icc")) + return ProjectExplorer::ToolChain::LinuxICC; else return ProjectExplorer::ToolChain::GCC; } @@ -1222,7 +1231,7 @@ QString QtVersion::msvcVersion() const QString QtVersion::wincePlatform() const { - qDebug()<<"QtVersion::wincePlatform returning"<<ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf"); +// qDebug()<<"QtVersion::wincePlatform returning"<<ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf"); return ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf"); } diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index d2af748cddf549b13690e095a3ec087c1fa981d5..b30fe23c880bb15e6cd531786bdb22df34913897 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -99,6 +99,7 @@ private slots: void typedef_2(); void typedef_3(); void const_1(); + void const_2(); }; void tst_Semantic::function_declaration_1() @@ -323,7 +324,7 @@ void tst_Semantic::typedef_3() void tst_Semantic::const_1() { QSharedPointer<Document> doc = document("\n" -"int foo(const void *s);\n" +"int foo(const int *s);\n" ); QCOMPARE(doc->errorCount, 0U); @@ -340,7 +341,30 @@ void tst_Semantic::const_1() QVERIFY(! arg->type().isConst()); QVERIFY(arg->type()->isPointerType()); QVERIFY(arg->type()->asPointerType()->elementType().isConst()); - QVERIFY(arg->type()->asPointerType()->elementType()->isVoidType()); + QVERIFY(arg->type()->asPointerType()->elementType()->isIntegerType()); +} + +void tst_Semantic::const_2() +{ + QSharedPointer<Document> doc = document("\n" +"int foo(char * const s);\n" + ); + + QCOMPARE(doc->errorCount, 0U); + QCOMPARE(doc->globals->symbolCount(), 1U); + + Declaration *decl = doc->globals->symbolAt(0)->asDeclaration(); + QVERIFY(decl); + QVERIFY(decl->type()->isFunctionType()); + Function *funTy = decl->type()->asFunctionType(); + QVERIFY(funTy->returnType()->isIntegerType()); + QCOMPARE(funTy->argumentCount(), 1U); + Argument *arg = funTy->argumentAt(0)->asArgument(); + QVERIFY(arg); + QVERIFY(arg->type().isConst()); + QVERIFY(arg->type()->isPointerType()); + QVERIFY(! arg->type()->asPointerType()->elementType().isConst()); + QVERIFY(arg->type()->asPointerType()->elementType()->isIntegerType()); } QTEST_APPLESS_MAIN(tst_Semantic)