From 84417cc12245aab83d02a2ede945c4bfdb8ebf6d Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 16 Nov 2016 15:08:30 +0100 Subject: [PATCH 01/27] Debugger: Use more direct access to QFile object guts This still does not solve the QFile dumper test fail with LLDB/Linux, but its one obstactle less. The remaining one is LLDB not reporting the QFile base object size at all. Change-Id: I3144cf9469c4456d21b8c220c9df1cd890348491 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/qttypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 65f4e1fbdd9..382a1aa4615 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -470,7 +470,7 @@ def qdump__QFile(d, value): offset = 144 if is32bit else 232 else: offset = 140 if is32bit else 232 - privAddress = d.extractPointer(value.address() + d.ptrSize()) + vtable, privAddress = value.split('pp') fileNameAddress = privAddress + offset d.putStringValue(fileNameAddress) d.putNumChild(1) From 1c4a5529f4f4320fe0c4ccddfe847b0b8edec4de Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 16 Nov 2016 16:21:40 +0100 Subject: [PATCH 02/27] Update QQC2 imports in qt5QtQuick2-bundle.json for Qt 5.8 Change-Id: I275ec57ecefaee8dc08981ad7eb57c40e47889ce Reviewed-by: Tim Jenssen --- .../qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json b/share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json index 53c6f6c4960..0454f97965a 100644 --- a/share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json +++ b/share/qtcreator/qml-type-descriptions/qt5QtQuick2-bundle.json @@ -43,6 +43,11 @@ "QtQuick.Controls 1.3", "QtQuick.Controls 1.4", "QtQuick.Controls 2.0", + "QtQuick.Controls 2.1", + "QtQuick.Controls.Material 2.0", + "QtQuick.Controls.Material 2.1", + "QtQuick.Controls.Universal 2.0", + "QtQuick.Controls.Universal 2.1", "QtQuick.Controls.Styles 1.0", "QtQuick.Controls.Styles 1.1", "QtQuick.Controls.Styles 1.2", @@ -57,6 +62,7 @@ "QtQuick.LocalStorage 2.0", "QtQuick.Particles 2.0", "QtQuick.Templates 2.0", + "QtQuick.Templates 2.1", "QtQuick.Window 2.0", "QtQuick.XmlListModel 2.0", "QtSensors 5.3", From 8c36249ffa1f9cdb5573e9d86e45d94b270c28f1 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 17 Nov 2016 10:17:53 +0100 Subject: [PATCH 03/27] Add missing overrides Change-Id: I7e27a273044542537423c8f4b9ab5235c3fabc22 Reviewed-by: Tobias Hunger --- src/plugins/diffeditor/diffeditorplugin.cpp | 8 ++++---- src/plugins/subversion/subversionclient.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 4eb0a07878a..023a188a837 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -106,7 +106,7 @@ public: DiffCurrentFileController(IDocument *document, const QString &fileName); protected: - void reload(); + void reload() override; private: QString m_fileName; @@ -164,7 +164,7 @@ public: DiffOpenFilesController(IDocument *document); protected: - void reload(); + void reload() override; }; DiffOpenFilesController::DiffOpenFilesController(IDocument *document) : @@ -224,7 +224,7 @@ public: DiffModifiedFilesController(IDocument *document, const QStringList &fileNames); protected: - void reload(); + void reload() override; private: QStringList m_fileNames; @@ -286,7 +286,7 @@ public: const QString &rightFileName); protected: - void reload(); + void reload() override; private: QString m_leftFileName; diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index d17ba176254..2ce3e3c9be2 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -175,7 +175,7 @@ public: void setChangeNumber(int changeNumber); protected: - void reload(); + void reload() override; private slots: void slotTextualDiffOutputReceived(const QString &contents); From fd460a11dcba33e2ca30935a5da6425b583af068 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 17 Nov 2016 10:27:55 +0100 Subject: [PATCH 04/27] Add some missing consts Change-Id: I1c5122b893e7255237310562fcad16bc53f15fd7 Reviewed-by: Tobias Hunger --- src/plugins/diffeditor/diffeditorplugin.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 023a188a837..e27c3e892db 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -109,7 +109,7 @@ protected: void reload() override; private: - QString m_fileName; + const QString m_fileName; }; DiffCurrentFileController::DiffCurrentFileController(IDocument *document, const QString &fileName) : @@ -227,7 +227,7 @@ protected: void reload() override; private: - QStringList m_fileNames; + const QStringList m_fileNames; }; DiffModifiedFilesController::DiffModifiedFilesController(IDocument *document, const QStringList &fileNames) : @@ -289,8 +289,8 @@ protected: void reload() override; private: - QString m_leftFileName; - QString m_rightFileName; + const QString m_leftFileName; + const QString m_rightFileName; }; DiffExternalFilesController::DiffExternalFilesController(IDocument *document, const QString &leftFileName, From 85d288e3c3a0ca829e39e5aa6bfb7dc71ec69e90 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 17 Nov 2016 11:15:52 +0100 Subject: [PATCH 05/27] QmlDesigner: Disable disk cache in puppet The disk cache time stamp is only accurate up to a second and there might be .qmlc files from the actual application. Change-Id: I6ec9cfdda8eb7aba5a630ac577d2cef999a8132c Reviewed-by: Simon Hausmann Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp index 8df5df04c9f..65aa907a64c 100644 --- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp +++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp @@ -381,6 +381,7 @@ QProcessEnvironment PuppetCreator::processEnvironment() const environment.set(QLatin1String("QML_BAD_GUI_RENDER_LOOP"), QLatin1String("true")); environment.set(QLatin1String("QML_USE_MOCKUPS"), QLatin1String("true")); environment.set(QLatin1String("QML_PUPPET_MODE"), QLatin1String("true")); + environment.set(QLatin1String("QML_DISABLE_DISK_CACHE"), QLatin1String("true")); environment.set(QLatin1String("QT_AUTO_SCREEN_SCALE_FACTOR"), QLatin1String("1")); #ifndef QMLDESIGNER_TEST From 6890e4e1315bf71c547498ab49af42f66cb6e069 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 17 Nov 2016 11:03:06 +0100 Subject: [PATCH 06/27] QmlJSCheck: Allow Math. function in ui.qml files The Math. function like Math.max() are quite useful to define more complex layouts. Therefore we allow them. Change-Id: Ia95dcbcc1b8e96c117650dc8643da4a9de0ecdba Reviewed-by: J-P Nurmi Reviewed-by: Marco Benelli --- src/libs/qmljs/qmljscheck.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index df463e69e6a..483b563a043 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -1428,6 +1428,17 @@ static QString functionName(ExpressionNode *ast, SourceLocation *location) return QString(); } +static QString functionNamespace(ExpressionNode *ast) +{ + if (FieldMemberExpression *fme = cast(ast)) { + if (!fme->name.isEmpty()) { + SourceLocation location; + return functionName(fme->base, &location); + } + } + return QString(); +} + void Check::checkNewExpression(ExpressionNode *ast) { SourceLocation location; @@ -1612,12 +1623,18 @@ bool Check::visit(CallExpression *ast) SourceLocation location; const QString name = functionName(ast->base, &location); + const QString namespaceName = functionNamespace(ast->base); + // We have to allow the qsTr function for translation. - bool isTranslationFunction = (name == QLatin1String("qsTr") || name == QLatin1String("qsTrId")); + + const bool isTranslationFunction = (name == QLatin1String("qsTr") || name == QLatin1String("qsTrId")); + // We allow the Math. functions + + const bool isMathFunction = namespaceName == "Math"; // allow adding connections with the help of the qt quick designer ui bool isDirectInConnectionsScope = (!m_typeStack.isEmpty() && m_typeStack.last() == QLatin1String("Connections")); - if (!isTranslationFunction && !isDirectInConnectionsScope) + if (!isTranslationFunction && !isMathFunction && !isDirectInConnectionsScope) addMessage(ErrFunctionsNotSupportedInQmlUi, location); if (!name.isEmpty() && name.at(0).isUpper() From 0334438b400d81e28bd5bc8730b06cbaf97003b3 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 16 Nov 2016 17:37:42 +0100 Subject: [PATCH 07/27] Debugger: Use more direct access in std::deque dumper This effectively fixes the LLDB dumper for std::deque and std::stack by avoiding a code path in which LLDB returns wrong data (the type and offset for the _Deque_iterator::_M_first member - surprisingly the other three members there get reported correctly). Change-Id: Iae1ba8b81987442ed2d486b383a145a77ce49cd7 Reviewed-by: David Schulz Reviewed-by: hjk --- share/qtcreator/debugger/stdtypes.py | 37 +++++++++------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 5fa4522cfe5..2a34f27f2a1 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -64,44 +64,31 @@ def qdump__std__deque(d, value): innerSize = innerType.size() bufsize = 1 if innerSize < 512: - bufsize = int(512 / innerSize) + bufsize = 512 // innerSize - #(mapptr, mapsize, startCur, startFirst, startLast, startNode, - # finishCur, finishFirst, finishLast, finishNode) = d.split("pppppppppp", value) -# -# numInBuf = bufsize * (int((finishNode - startNode) / innerSize) - 1) -# numFirstItems = int((startLast - startCur) / innerSize) -# numLastItems = int((finishCur - finishFirst) / innerSize) + (mapptr, mapsize, startCur, startFirst, startLast, startNode, + finishCur, finishFirst, finishLast, finishNode) = value.split("pppppppppp") - impl = value["_M_impl"] - start = impl["_M_start"] - finish = impl["_M_finish"] - size = bufsize * ((finish["_M_node"].pointer() - start["_M_node"].pointer()) // d.ptrSize() - 1) - size += ((finish["_M_cur"].pointer() - finish["_M_first"].pointer()) // innerSize) - size += ((start["_M_last"].pointer() - start["_M_cur"].pointer()) // innerSize) + size = bufsize * ((finishNode - startNode) // d.ptrSize() - 1) + size += (finishCur - finishFirst) // innerSize + size += (startLast - startCur) // innerSize d.check(0 <= size and size <= 1000 * 1000 * 1000) d.putItemCount(size) if d.isExpanded(): with Children(d, size, maxNumChild=2000, childType=innerType): - pcur = start["_M_cur"].pointer() - pfirst = start["_M_first"] - plast = start["_M_last"].pointer() - pnode = start["_M_node"] + pcur = startCur + plast = startLast + pnode = startNode for i in d.childRange(): d.putSubItem(i, d.createValue(pcur, innerType)) pcur += innerSize if pcur == plast: - # FIXME: Remove pointer operation. - newnode = pnode + 1 # Type is std::_Deque_iterator::_Map_pointer\"} a.k.a 'Foo **' - #warn("TYPE: %s" % pnode.type) - #warn("PNODE: 0x%x %s" % (pnode.pointer(), pnode)) - #warn("NEWNODE: 0x%x %s" % (newnode.pointer(), newnode)) - pnode = newnode - #warn("PNODE 2: 0x%x %s" % (pnode.pointer(), pnode)) - pfirst = newnode.dereference().pointer() + newnode = pnode + d.ptrSize() + pfirst = d.extractPointer(newnode) plast = pfirst + bufsize * d.ptrSize() pcur = pfirst + pnode = newnode def qdump__std__deque__QNX(d, value): innerType = value.type[0] From 77c3cbd4f0844f99dfa015778ab7d53da792a985 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 17 Nov 2016 09:37:32 +0100 Subject: [PATCH 08/27] Fix updating ui resources after creating new form Before we have tried to update resources, however it was done too early and ui file, which has been created, was not inserted to any project yet. We were connected to ProjectTree::filesAdded signal and apparently whenever it is sent the added ui file is still not inserted to the project, thought the signal informs about that fact. Now we connect to every project's fileListChanged() signal instead. Task-number: QTCREATORBUG-15560 Change-Id: I11883a0d87fdc7c46897cef68466c1038dbaefb8 Reviewed-by: Tobias Hunger --- src/plugins/designer/resourcehandler.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/plugins/designer/resourcehandler.cpp b/src/plugins/designer/resourcehandler.cpp index 8f8d7919691..01c6ee6371b 100644 --- a/src/plugins/designer/resourcehandler.cpp +++ b/src/plugins/designer/resourcehandler.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -88,12 +87,16 @@ void ResourceHandler::ensureInitialized() return; m_initialized = true; - ProjectTree *tree = ProjectTree::instance(); - connect(tree, &ProjectTree::filesAdded, this, &ResourceHandler::updateResources); - connect(tree, &ProjectTree::filesRemoved, this, &ResourceHandler::updateResources); - connect(tree, &ProjectTree::foldersAdded, this, &ResourceHandler::updateResources); - connect(tree, &ProjectTree::foldersRemoved, this, &ResourceHandler::updateResources); + auto connector = [this](Project *p) { + connect(p, &Project::fileListChanged, this, &ResourceHandler::updateResources); + }; + + foreach (Project *p, SessionManager::projects()) + connector(p); + + connect(SessionManager::instance(), &SessionManager::projectAdded, this, connector); + m_originalUiQrcPaths = m_form->activeResourceFilePaths(); if (Designer::Constants::Internal::debug) qDebug() << "ResourceHandler::ensureInitialized() origPaths=" << m_originalUiQrcPaths; From 572ba812d2347c9289d8b9549a9265a311a3c251 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 17 Nov 2016 12:17:14 +0100 Subject: [PATCH 09/27] Debugger: Fix over-quoting in LLDB breakpoint reporting The 'output' bit is inserted at report time, not at callback script generation time. Change-Id: Ibb5c9b09d8391d1be86b8f110e32ab1c90f6bab2 Reviewed-by: David Schulz --- share/qtcreator/debugger/lldbbridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 5f257fb324d..6a5c691fd2e 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1384,7 +1384,7 @@ class Dumper(DumperBase): 'd = lldb.theDumper', 'output = d.hexencode(sys.stdout.getvalue())', 'sys.stdout = origout', - 'd.report("output={channel=\"stderr\",data=\"' + output + '\"}")', + 'd.report("output={channel=\"stderr\",data=\" + output + \"}")', 'if result is False:', ' d.reportState("continueafternextstop")', 'return True' From da54b1e6a9d551c099ccf171ad1a03ea598ac99f Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 17 Nov 2016 11:56:02 +0100 Subject: [PATCH 10/27] Clang: Tests: Fix compilation refactoringclient-test.cpp:126:76: error: no matching function for call to 'ClangRefactoring::RefactoringCompilerOptionsBuilder::build(CppTools::ProjectPart*, CppTools::ProjectFile::Kind&)' Broke with: commit 36d4d01cd374a21a8b7c229b261c5f1a23d1184e Clang: Take precompiled headers into account when parsing source files Change-Id: I7c5a2edec0859584ea2b33e144178060788cd4d9 Reviewed-by: Marco Bubke --- tests/unit/mockup/cpptools/cpptoolsreuse.h | 32 +++++++++++++++++++ .../unit/unittest/refactoringclient-test.cpp | 3 +- .../unit/unittest/refactoringengine-test.cpp | 3 +- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 tests/unit/mockup/cpptools/cpptoolsreuse.h diff --git a/tests/unit/mockup/cpptools/cpptoolsreuse.h b/tests/unit/mockup/cpptools/cpptoolsreuse.h new file mode 100644 index 00000000000..fec53886417 --- /dev/null +++ b/tests/unit/mockup/cpptools/cpptoolsreuse.h @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +namespace CppTools { + +CompilerOptionsBuilder::PchUsage getPchUsage() { return CompilerOptionsBuilder::PchUsage::None; } + +} // CppTools diff --git a/tests/unit/unittest/refactoringclient-test.cpp b/tests/unit/unittest/refactoringclient-test.cpp index 6badbee3c60..69b8259e1be 100644 --- a/tests/unit/unittest/refactoringclient-test.cpp +++ b/tests/unit/unittest/refactoringclient-test.cpp @@ -123,7 +123,8 @@ void RefactoringClient::SetUp() projectPart->files.push_back(projectFile); commandLine = RefactoringCompilerOptionsBuilder::build(projectPart.data(), - projectFile.kind); + projectFile.kind, + RefactoringCompilerOptionsBuilder::PchUsage::None); } } diff --git a/tests/unit/unittest/refactoringengine-test.cpp b/tests/unit/unittest/refactoringengine-test.cpp index e295ac34f1a..6efbebfb41f 100644 --- a/tests/unit/unittest/refactoringengine-test.cpp +++ b/tests/unit/unittest/refactoringengine-test.cpp @@ -108,7 +108,8 @@ void RefactoringEngine::SetUp() projectPart->files.push_back(projectFile); commandLine = RefactoringCompilerOptionsBuilder::build(projectPart.data(), - projectFile.kind); + projectFile.kind, + RefactoringCompilerOptionsBuilder::PchUsage::None); commandLine.push_back(qStringFilePath); } From eabccbdcb2057d8ac57a164b9869c4c8c5f8a796 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 17 Nov 2016 13:53:03 +0100 Subject: [PATCH 11/27] Debugger: Don't encapsulate integer in values for template args Change-Id: Ib1bb2b01ff8eb1ed11c0f5785f3b4bb5f50c411a Reviewed-by: hjk --- share/qtcreator/debugger/cdbbridge.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index 827502e1708..f6ed0439a4c 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -170,10 +170,7 @@ class Dumper(DumperBase): else: targs.append(self.Type(self, targ)) elif isinstance(targ, int): - value = self.Value(self) - value.type = self.lookupType('int') - value.ldata = targ.to_bytes(4, sys.byteorder) - targs.append(value) + targs.append(targ) else: error('CDBCRAP %s' % type(targ)) return targs From 61b408d1106cac160e61c108bd354ad696bf0008 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 17 Nov 2016 11:36:45 +0100 Subject: [PATCH 12/27] Debugger: Force flushing of GDB output ... after continue and step. Otherwise there would be no reaction after the inferior gets an external SIGKILL while stopped. Task-number: QTCREATORBUG-17280 Change-Id: I57933e92194a3320d7aba81055755477f34af382 Reviewed-by: David Schulz --- src/plugins/debugger/gdb/gdbengine.cpp | 13 ++++++++----- src/plugins/debugger/gdb/gdbengine.h | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index b9b40694789..8a8e649522c 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -966,6 +966,8 @@ void GdbEngine::runCommand(const DebuggerCommand &command) Q_ARG(QString, buffer)); } else { write(cmd.function.toUtf8() + "\r\n"); + if (command.flags & NeedsFlush) + write("p 0\r\n"); // Start Watchdog. if (m_commandTimer.interval() <= 20000) @@ -1103,6 +1105,8 @@ void GdbEngine::handleResultRecord(DebuggerResponse *response) // the exception now in a box. if (msg.startsWith("During startup program exited with")) notifyInferiorExited(); + else if (msg.contains("Command aborted.")) + notifyInferiorSpontaneousStop(); QString logMsg; if (!m_lastWinException.isEmpty()) logMsg = m_lastWinException + '\n'; @@ -2009,7 +2013,7 @@ void GdbEngine::continueInferiorInternal() cmd.callback = CB(handleExecuteContinue); runCommand(cmd); } else { - DebuggerCommand cmd("-exec-continue", RunRequest); + DebuggerCommand cmd("-exec-continue", RunRequest|NeedsFlush); cmd.callback = CB(handleExecuteContinue); runCommand(cmd); } @@ -2034,7 +2038,7 @@ void GdbEngine::executeStep() runCommand(cmd); } else { DebuggerCommand cmd; - cmd.flags = RunRequest; + cmd.flags = RunRequest|NeedsFlush; cmd.function = QLatin1String(isReverseDebugging() ? "reverse-step" : "-exec-step"); cmd.callback = CB(handleExecuteStep); runCommand(cmd); @@ -2084,7 +2088,7 @@ void GdbEngine::executeStepI() notifyInferiorRunRequested(); showStatusMessage(tr("Step by instruction requested..."), 5000); DebuggerCommand cmd; - cmd.flags = RunRequest; + cmd.flags = RunRequest|NeedsFlush; cmd.function = QLatin1String(isReverseDebugging() ? "reverse-stepi" : "-exec-step-instruction"); cmd.callback = CB(handleExecuteContinue); runCommand(cmd); @@ -2100,12 +2104,11 @@ void GdbEngine::executeStepOut() if (isNativeMixedActiveFrame()) { runCommand({"executeStepOut", RunRequest|PythonCommand}); } else { - runCommand({"-exec-finish", RunRequest, CB(handleExecuteContinue)}); // -exec-finish in 'main' results (correctly) in // 40^error,msg="\"finish\" not meaningful in the outermost frame." // However, this message does not seem to get flushed before // anything else happen - i.e. "never". Force some extra output. - runCommand({"print 32"}); + runCommand({"-exec-finish", RunRequest|NeedsFlush, CB(handleExecuteContinue)}); } } diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 02a933aa14e..1ee9aecb03e 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -154,6 +154,8 @@ private: ////////// Gdb Command Management ////////// NeedsStop = 1, // No need to wait for the reply before continuing inferior. Discardable = 2, + // Needs a dummy extra command to force GDB output flushing. + NeedsFlush = 4, // Callback expects ResultRunning instead of ResultDone. RunRequest = 16, // Callback expects ResultExit instead of ResultDone. From 1eafa1540e63d2853b5ff6cd5c4e4d740e976a51 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 9 Nov 2016 14:03:07 +0100 Subject: [PATCH 13/27] Debugger: Lower kit restrictions for debugging In some cases it can be useful to be able to debug although not having a complete functional kit present. (e.g. debugging a core file having an ABI for which you have a debugger but having no respective compiler) Change-Id: Ia2567c8e2dd6783e612802cc08f7767399aaf33f Reviewed-by: hjk --- src/plugins/debugger/debuggerdialogs.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index d950a26b3f8..b3317ca75db 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -107,7 +107,11 @@ DebuggerKitChooser::DebuggerKitChooser(Mode mode, QWidget *parent) { setKitMatcher([this](const Kit *k) { // Match valid debuggers and restrict local debugging to compatible toolchains. - if (DebuggerKitInformation::configurationErrors(k)) + auto errors = DebuggerKitInformation::configurationErrors(k); + // we do not care for mismatched ABI if we want *any* debugging + if (m_mode == AnyDebugging && errors == DebuggerKitInformation::DebuggerDoesNotMatch) + errors = DebuggerKitInformation::NoConfigurationError; + if (errors) return false; if (m_mode == LocalDebugging) return ToolChainKitInformation::targetAbi(k).os() == m_hostAbi.os(); From 952c3e3b644e067af511ea03c2b7af949895bb62 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 18 Nov 2016 08:43:55 +0100 Subject: [PATCH 14/27] Debugger: Remove some of the inferior call in QVariant dumper Change-Id: I1f1ac5c5ba59c36d3c3d6546b24a93d1b647f88a Reviewed-by: David Schulz --- share/qtcreator/debugger/qttypes.py | 38 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 382a1aa4615..6e306d3e2d4 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -1572,6 +1572,7 @@ qdumpHelper_QVariants_F = [ def qdump__QVariant(d, value): (data, typeStuff) = d.split('8sI', value) variantType = typeStuff & 0x3fffffff + isShared = bool(typeStuff & 0x40000000) # Well-known simple type. if variantType <= 6: @@ -1616,14 +1617,12 @@ def qdump__QVariant(d, value): #data = value['d']['data'] innerType = d.qtNamespace() + innert - isShared = bool(typeStuff & 0x40000000) #warn('SHARED: %s' % isShared) if isShared: base1 = d.extractPointer(value) #warn('BASE 1: %s %s' % (base1, innert)) base = d.extractPointer(base1) #warn('SIZE 1: %s' % size) - innerType = d.createType(d.qtNamespace() + innert) val = d.createValue(base, innerType) else: #warn('DIRECT ITEM 1: %s' % innerType) @@ -1643,19 +1642,9 @@ def qdump__QVariant(d, value): d.putType('%sQVariant (%s)' % (ns, variantType)) d.putNumChild(1) if d.isExpanded(): - typeName = None + innerType = None with Children(d): ev = d.parseAndEvaluate - data = d.call('const void *', value, 'constData') - - addr = value.address() - data = ev('((%sQVariant*)0x%x)->constData()' % (ns, addr)) - if data is None: - data = ev('((QVariant*)0x%x)->constData()' % addr) - if data is None: - d.putSpecialValue('notcallable') - return None - p = None if p is None: # Without debug info. @@ -1671,15 +1660,24 @@ def qdump__QVariant(d, value): return None ptr = p.pointer() (elided, blob) = d.encodeCArray(ptr, 1, 100) - typeName = d.hexdecode(blob) + innerType = d.hexdecode(blob) + # Prefer namespaced version. if len(ns) > 0: - if not d.lookupNativeType(ns + typeName) is None: - typeName = ns + typeName - data.type = d.createType(typeName + ' *') - d.putSubItem('data', data) - if not typeName is None: - d.putBetterType('%sQVariant (%s)' % (ns, typeName)) + if not d.lookupNativeType(ns + innerType) is None: + innerType = ns + innerType + + if isShared: + base1 = d.extractPointer(value) + base = d.extractPointer(base1) + val = d.createValue(base, innerType) + else: + val = d.createValue(data, innerType) + val.laddress = value.laddress + d.putSubItem('data', val) + + if not innerType is None: + d.putBetterType('%sQVariant (%s)' % (ns, innerType)) return None From c9067ff28c6cdc49a0c9a409cdc3a240d7973e04 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 17 Nov 2016 19:12:05 +0100 Subject: [PATCH 15/27] Debugger: Fix boost::unordered_set dumper for older boost versions Somewhere between 1.48 and 1.58 structure layout changed. Change-Id: Id8bcb473f364537342261dd2596f9f1bdacb5c79 Reviewed-by: hjk --- share/qtcreator/debugger/boosttypes.py | 63 ++++++++++---------------- share/qtcreator/debugger/dumper.py | 5 +- 2 files changed, 28 insertions(+), 40 deletions(-) diff --git a/share/qtcreator/debugger/boosttypes.py b/share/qtcreator/debugger/boosttypes.py index 938a0a29670..bccb6f39f70 100644 --- a/share/qtcreator/debugger/boosttypes.py +++ b/share/qtcreator/debugger/boosttypes.py @@ -108,45 +108,30 @@ def qdump__boost__posix_time__time_duration(d, value): def qdump__boost__unordered__unordered_set(d, value): - base = value.address() - ptrSize = d.ptrSize() - size = d.extractInt(base + 2 * ptrSize) + innerType = value.type[0] + newer = value.type.size() == 6 * d.ptrSize() # 48 for boost 1.58, 40 for boost 1.48 + if newer: + # boost 1.58 + # bases are 3? bytes, and mlf is actually a float, but since + # its followed by size_t maxload, it's # effectively padded to a size_t + bases, bucketCount, size, mlf, maxload, buckets = value.split('tttttp') + code = 'pp{%s}' % innerType.name + else: + # boost 1.48 + # Values are stored before the next pointers. Determine the offset. + buckets, bucketCount, size, mlf, maxload = value.split('ptttt') + code = '{%s}@p' % innerType.name + (pp, ssize, fields) = d.describeStruct(code) + offset = fields[2].offset() + d.putItemCount(size) if d.isExpanded(): - innerType = value.type[0] - bucketCount = d.extractInt(base + ptrSize) - #warn("A BUCKET COUNT: %s" % bucketCount) - #warn("X BUCKET COUNT: %s" % d.parseAndEvaluate("s1.table_.bucket_count_").value()) - try: - # boost 1.58 - table = value["table_"] - bucketsAddr = table["buckets_"].integer() - #warn("A BUCKETS: 0x%x" % bucketsAddr) - #warn("X BUCKETS: 0x%x" % d.parseAndEvaluate("s1.table_.buckets_").pointer()) - lastBucketAddr = bucketsAddr + bucketCount * ptrSize - #warn("A LAST BUCKET: 0x%x" % lastBucketAddr) - #warn("X LAST BUCKET: 0x%x" % d.parseAndEvaluate("s1.table_.get_bucket(s1.table_.bucket_count_)").pointer()) - previousStartAddr = lastBucketAddr - #warn("A PREVIOUS START: 0x%x" % previousStartAddr) - #warn("X PREVIOUS START: 0x%x" % d.parseAndEvaluate("s1.table_.get_previous_start()").pointer()) - item = d.extractPointer(previousStartAddr) - #warn("A KEY ADDR: 0x%x" % item) - #warn("X KEY ADDR: 0x%x" % d.parseAndEvaluate("s1.table_.get_previous_start()->next_").pointer()) - item = d.extractPointer(previousStartAddr) - #warn("A VALUE: %x" % d.extractInt(item + ptrSize)) - #warn("X VALUE: %x" % d.parseAndEvaluate("*(int*)(s1.table_.get_previous_start()->next_ + 1)").integer()) - with Children(d, size, maxNumChild=10000): - for j in d.childRange(): - d.putSubItem(j, d.createValue(item + 2 * ptrSize, innerType)) - item = d.extractPointer(item) - except: - # boost 1.48 - offset = int((innerType.size() + ptrSize - 1) / ptrSize) * ptrSize - with Children(d, size, maxNumChild=10000): - afterBuckets = d.extractPointer(base + 5 * ptrSize) - afterBuckets += bucketCount * ptrSize - item = d.extractPointer(afterBuckets) - for j in d.childRange(): - d.putSubItem(j, d.createValue(item - offset, innerType)) - item = d.extractPointer(item) + p = d.extractPointer(buckets + bucketCount * d.ptrSize()) + with Children(d, size, maxNumChild=10000): + for j in d.childRange(): + if newer: + p, dummy, val = d.split(code, p) + else: + val, pad, p = d.split(code, p - offset) + d.putSubItem(j, val) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 259cad968a7..c6723143ffb 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -3768,11 +3768,14 @@ class DumperBase: readingTypeName = False fieldType = self.createType(typeName) fieldAlign = fieldType.alignment() - builder.addField(n, fieldIsStruct = True, fieldType = fieldType, fieldAlign = fieldAlign) + builder.addField(n, fieldIsStruct = True, + fieldType = fieldType, fieldAlign = fieldAlign) typeName = None n = None else: typeName += c + elif c == 't': # size_t + builder.addField(ptrSize, self.ptrCode(), fieldAlign = ptrSize) elif c == 'p': # Pointer as int builder.addField(ptrSize, self.ptrCode(), fieldAlign = ptrSize) elif c == 'P': # Pointer as Value From a8697e4716ba6d51b6a842d2ce192101a150c8ec Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 18 Nov 2016 09:01:08 +0100 Subject: [PATCH 16/27] Debugger: Don't accumulate return value displays This fixes a regression introduced with d771ba89. Change-Id: Icc44ef9ad41f9e5cdb3848fae7a1ba8af2626344 Reviewed-by: Ulf Hermann --- src/plugins/debugger/watchhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index b0de8742511..04b065fd557 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -2004,7 +2004,7 @@ void WatchHandler::notifyUpdateStarted(const UpdateParameters &updateParameters) { QStringList inames = updateParameters.partialVariables(); if (inames.isEmpty()) - inames.append("local"); + inames = QStringList({ "local", "return" }); auto marker = [](WatchItem *item) { item->outdated = true; }; From f8c86fd95faffaa93f606d0ed3bdb1bcd7f27047 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 17 Nov 2016 13:47:28 +0100 Subject: [PATCH 17/27] Debugger: Detect msvc virtual function pointer table Change-Id: I51d82b692638932e35f22a5bb9286eecad577ed7 Reviewed-by: hjk --- share/qtcreator/debugger/dumper.py | 41 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index c6723143ffb..a710243f2a2 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -866,26 +866,27 @@ class DumperBase: baseIndex = 0 for item in value.members(True): #warn('FIELD: %s' % item) - if item.name is not None and item.name.startswith('_vptr.'): - with SubItem(self, '[vptr]'): - # int (**)(void) - self.putType(' ') - self.putField('sortgroup', 20) - self.putValue(item.name) - n = 10 - if self.isExpanded(): - with Children(self): - p = item.pointer() - for i in xrange(n): - deref = self.extractPointer(p) - if deref == 0: - n = i - break - with SubItem(self, i): - self.putItem(self.createPointerValue(deref, 'void')) - p += self.ptrSize() - self.putNumChild(n) - continue + if item.name is not None: + if item.name.startswith('_vptr.') or item.name.startswith('__vfptr'): + with SubItem(self, '[vptr]'): + # int (**)(void) + self.putType(' ') + self.putField('sortgroup', 20) + self.putValue(item.name) + n = 10 + if self.isExpanded(): + with Children(self): + p = item.pointer() + for i in xrange(n): + deref = self.extractPointer(p) + if deref == 0: + n = i + break + with SubItem(self, i): + self.putItem(self.createPointerValue(deref, 'void')) + p += self.ptrSize() + self.putNumChild(n) + continue if item.isBaseClass and dumpBase: baseIndex += 1 From 3b1308bb434e0c01976e80824258c85e0abef3e8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 18 Nov 2016 11:53:38 +0100 Subject: [PATCH 18/27] TextEditor: Remove exported class QuickFixOperations Define an operator << that accepts a raw pointer for the list of QuickFixOperation::Ptr instead. Fixes MSVC 17 warnings src/corelib/tools/qlist.h(423): warning C4661: 'QVector QList::toVector(void) const': no suitable definition provided for explicit template instantiation request ] src/corelib/tools/qlist.h(389): note: see declaration of 'QList::toVector' src/corelib/tools/qlist.h(423): warning C4661: 'QSet QList::toSet(void) const': no suitable definition provided for explicit template instantiation request src/corelib/tools/qlist.h(390): note: see declaration of 'QList::toSet' src/corelib/tools/qlist.h(423): warning C4661: 'QList QList::fromVector(const QVector &)': no suitable definition provided for explicit template instantiation request ... Task-number: QTBUG-57086 Change-Id: I879511656c39eb7a3eae54ea7daca3eca8ebe8d7 Reviewed-by: hjk Reviewed-by: David Schulz --- .../cppeditor/cppinsertvirtualmethods.cpp | 4 +- src/plugins/cppeditor/cppquickfixes.cpp | 194 +++++++++--------- .../cpptools/baseeditordocumentprocessor.h | 2 +- .../qmljscomponentfromobjectdef.cpp | 4 +- src/plugins/qmljseditor/qmljsquickfixes.cpp | 4 +- src/plugins/qmljseditor/qmljswrapinloader.cpp | 4 +- src/plugins/texteditor/quickfix.h | 11 +- 7 files changed, 110 insertions(+), 113 deletions(-) diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index c61e5bc31c5..cc97d5282d4 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -1222,11 +1222,9 @@ InsertVirtualMethods::~InsertVirtualMethods() void InsertVirtualMethods::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { - InsertVirtualMethodsOp *op = new InsertVirtualMethodsOp(interface, m_dialog); + QSharedPointer op(new InsertVirtualMethodsOp(interface, m_dialog)); if (op->isValid()) result.append(op); - else - delete op; } #ifdef WITH_TESTS diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index a4382a3d849..39aeb5897a5 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -427,7 +427,7 @@ void InverseLogicalComparison::match(const CppQuickFixInterface &interface, return; } - result.append(new InverseLogicalComparisonOp(interface, index, binary, invertToken)); + result << new InverseLogicalComparisonOp(interface, index, binary, invertToken); } namespace { @@ -517,7 +517,7 @@ void FlipLogicalOperands::match(const CppQuickFixInterface &interface, QuickFixO replacement = QLatin1String(tok.spell()); } - result.append(new FlipLogicalOperandsOp(interface, index, binary, replacement)); + result << new FlipLogicalOperandsOp(interface, index, binary, replacement); } namespace { @@ -696,13 +696,13 @@ void SplitSimpleDeclaration::match(const CppQuickFixInterface &interface, if (cursorPosition >= startOfDeclSpecifier && cursorPosition <= endOfDeclSpecifier) { // the AST node under cursor is a specifier. - result.append(new SplitSimpleDeclarationOp(interface, index, declaration)); + result << new SplitSimpleDeclarationOp(interface, index, declaration); return; } if (core_declarator && interface.isCursorOn(core_declarator)) { // got a core-declarator under the text cursor. - result.append(new SplitSimpleDeclarationOp(interface, index, declaration)); + result << new SplitSimpleDeclarationOp(interface, index, declaration); return; } } @@ -757,7 +757,7 @@ void AddBracesToIf::match(const CppQuickFixInterface &interface, QuickFixOperati IfStatementAST *ifStatement = path.at(index)->asIfStatement(); if (ifStatement && interface.isCursorOn(ifStatement->if_token) && ifStatement->statement && !ifStatement->statement->asCompoundStatement()) { - result.append(new AddBracesToIfOp(interface, index, ifStatement->statement)); + result << new AddBracesToIfOp(interface, index, ifStatement->statement); return; } @@ -768,7 +768,7 @@ void AddBracesToIf::match(const CppQuickFixInterface &interface, QuickFixOperati if (ifStatement && ifStatement->statement && interface.isCursorOn(ifStatement->statement) && !ifStatement->statement->asCompoundStatement()) { - result.append(new AddBracesToIfOp(interface, index, ifStatement->statement)); + result << new AddBracesToIfOp(interface, index, ifStatement->statement); return; } } @@ -1056,7 +1056,7 @@ void SplitIfStatement::match(const CppQuickFixInterface &interface, QuickFixOper } if (interface.isCursorOn(condition->binary_op_token)) { - result.append(new SplitIfStatementOp(interface, index, pattern, condition)); + result << new SplitIfStatementOp(interface, index, pattern, condition); return; } } @@ -1213,15 +1213,15 @@ void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOpe if (type == TypeChar) { unsigned actions = EncloseInQLatin1CharAction; QString description = msgQtStringLiteralDescription(replacement(actions)); - result.append(new WrapStringLiteralOp(interface, priority, actions, description, literal)); + result << new WrapStringLiteralOp(interface, priority, actions, description, literal); if (NumericLiteralAST *charLiteral = literal->asNumericLiteral()) { const QByteArray contents(file->tokenAt(charLiteral->literal_token).identifier->chars()); if (!charToStringEscapeSequences(contents).isEmpty()) { actions = DoubleQuoteAction | ConvertEscapeSequencesToStringAction; description = QApplication::translate("CppTools::QuickFix", "Convert to String Literal"); - result.append(new WrapStringLiteralOp(interface, priority, actions, - description, literal)); + result << new WrapStringLiteralOp(interface, priority, actions, + description, literal); } } } else { @@ -1235,21 +1235,21 @@ void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOpe | ConvertEscapeSequencesToCharAction | objectiveCActions; QString description = QApplication::translate("CppTools::QuickFix", "Convert to Character Literal and Enclose in QLatin1Char(...)"); - result.append(new WrapStringLiteralOp(interface, priority, actions, - description, literal)); + result << new WrapStringLiteralOp(interface, priority, actions, + description, literal); actions &= ~EncloseInQLatin1CharAction; description = QApplication::translate("CppTools::QuickFix", "Convert to Character Literal"); - result.append(new WrapStringLiteralOp(interface, priority, actions, - description, literal)); + result << new WrapStringLiteralOp(interface, priority, actions, + description, literal); } } actions = EncloseInQLatin1StringAction | objectiveCActions; - result.append(new WrapStringLiteralOp(interface, priority, actions, - msgQtStringLiteralDescription(replacement(actions), 4), literal)); + result << new WrapStringLiteralOp(interface, priority, actions, + msgQtStringLiteralDescription(replacement(actions), 4), literal); actions = EncloseInQStringLiteralAction | objectiveCActions; - result.append(new WrapStringLiteralOp(interface, priority, actions, - msgQtStringLiteralDescription(replacement(actions), 5), literal)); + result << new WrapStringLiteralOp(interface, priority, actions, + msgQtStringLiteralDescription(replacement(actions), 5), literal); } } @@ -1334,9 +1334,9 @@ void TranslateStringLiteral::match(const CppQuickFixInterface &interface, Symbol *s = r.declaration(); if (s->type()->isFunctionType()) { // no context required for tr - result.append(new WrapStringLiteralOp(interface, path.size() - 1, - WrapStringLiteral::TranslateTrAction, - description, literal)); + result << new WrapStringLiteralOp(interface, path.size() - 1, + WrapStringLiteral::TranslateTrAction, + description, literal); return; } } @@ -1352,17 +1352,17 @@ void TranslateStringLiteral::match(const CppQuickFixInterface &interface, // ... or global if none available! if (trContext.isEmpty()) trContext = QLatin1String("GLOBAL"); - result.append(new WrapStringLiteralOp(interface, path.size() - 1, - WrapStringLiteral::TranslateQCoreApplicationAction, - description, literal, trContext)); + result << new WrapStringLiteralOp(interface, path.size() - 1, + WrapStringLiteral::TranslateQCoreApplicationAction, + description, literal, trContext); return; } } // We need to use Q_TRANSLATE_NOOP - result.append(new WrapStringLiteralOp(interface, path.size() - 1, - WrapStringLiteral::TranslateNoopAction, - description, literal, trContext)); + result << new WrapStringLiteralOp(interface, path.size() - 1, + WrapStringLiteral::TranslateNoopAction, + description, literal, trContext); } namespace { @@ -1425,8 +1425,8 @@ void ConvertCStringToNSString::match(const CppQuickFixInterface &interface, if (!isQtStringLiteral(enclosingFunction)) qlatin1Call = 0; - result.append(new ConvertCStringToNSStringOp(interface, path.size() - 1, literal->asStringLiteral(), - qlatin1Call)); + result << new ConvertCStringToNSStringOp(interface, path.size() - 1, literal->asStringLiteral(), + qlatin1Call); } namespace { @@ -1513,7 +1513,7 @@ void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFi auto op = new ConvertNumericLiteralOp(interface, start, start + numberLength, replacement); op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Hexadecimal")); op->setPriority(priority); - result.append(op); + result << op; } if (value != 0) { @@ -1531,7 +1531,7 @@ void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFi auto op = new ConvertNumericLiteralOp(interface, start, start + numberLength, replacement); op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Octal")); op->setPriority(priority); - result.append(op); + result << op; } } @@ -1550,7 +1550,7 @@ void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFi auto op = new ConvertNumericLiteralOp(interface, start, start + numberLength, replacement); op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Decimal")); op->setPriority(priority); - result.append(op); + result << op; } } } @@ -1644,7 +1644,7 @@ void AddLocalDeclaration::match(const CppQuickFixInterface &interface, QuickFixO } if (!decl) { - result.append(new AddLocalDeclarationOp(interface, index, binary, nameAST)); + result << new AddLocalDeclarationOp(interface, index, binary, nameAST); return; } } @@ -1720,7 +1720,7 @@ void ConvertToCamelCase::match(const CppQuickFixInterface &interface, QuickFixOp return; for (int i = 1; i < newName.length() - 1; ++i) { if (ConvertToCamelCaseOp::isConvertibleUnderscore(newName, i)) { - result.append(new ConvertToCamelCaseOp(interface, path.size() - 1, newName)); + result << new ConvertToCamelCaseOp(interface, path.size() - 1, newName); return; } } @@ -1957,8 +1957,8 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa if (looksLikeAQtClass(include.mid(1, include.size() - 2))) qtHeaderFileIncludeOffered = true; - result.append(new AddIncludeForUndefinedIdentifierOp(interface, priority, - include)); + result << new AddIncludeForUndefinedIdentifierOp(interface, priority, + include); } } } @@ -1970,7 +1970,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa if (!qtHeaderFileIncludeOffered && looksLikeAQtClass(className)) { const QString include = findQtIncludeWithSameName(className, headerPaths); if (!include.isEmpty()) - result.append(new AddIncludeForUndefinedIdentifierOp(interface, 1, include)); + result << new AddIncludeForUndefinedIdentifierOp(interface, 1, include); } } @@ -2050,11 +2050,11 @@ void RearrangeParamDeclarationList::match(const CppQuickFixInterface &interface, return; if (prevParamListNode) - result.append(new RearrangeParamDeclarationListOp(interface, paramListNode->value, - prevParamListNode->value, RearrangeParamDeclarationListOp::TargetPrevious)); + result << new RearrangeParamDeclarationListOp(interface, paramListNode->value, + prevParamListNode->value, RearrangeParamDeclarationListOp::TargetPrevious); if (paramListNode->next) - result.append(new RearrangeParamDeclarationListOp(interface, paramListNode->value, - paramListNode->next->value, RearrangeParamDeclarationListOp::TargetNext)); + result << new RearrangeParamDeclarationListOp(interface, paramListNode->value, + paramListNode->next->value, RearrangeParamDeclarationListOp::TargetNext); } namespace { @@ -2172,14 +2172,14 @@ void ReformatPointerDeclaration::match(const CppQuickFixInterface &interface, // any AST and therefore no quick fix will be triggered. change = formatter.format(file->cppDocument()->translationUnit()->ast()); if (!change.isEmpty()) - result.append(new ReformatPointerDeclarationOp(interface, change)); + result << new ReformatPointerDeclarationOp(interface, change); } else { const QList suitableASTs = ReformatPointerDeclarationASTPathResultsFilter().filter(path); foreach (AST *ast, suitableASTs) { change = formatter.format(ast); if (!change.isEmpty()) { - result.append(new ReformatPointerDeclarationOp(interface, change)); + result << new ReformatPointerDeclarationOp(interface, change); return; } } @@ -2349,8 +2349,8 @@ void CompleteSwitchCaseStatement::match(const CppQuickFixInterface &interface, foreach (const QString &usedValue, usedValues) values.removeAll(usedValue); if (!values.isEmpty()) - result.append(new CompleteSwitchCaseStatementOp(interface, depth, - compoundStatement, values)); + result << new CompleteSwitchCaseStatementOp(interface, depth, + compoundStatement, values); return; } @@ -2493,12 +2493,12 @@ void InsertDeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOpe // Add several possible insertion locations for declaration DeclOperationFactory operation(interface, fileName, matchingClass, decl); - result.append(operation(InsertionPointLocator::Public, 5)); - result.append(operation(InsertionPointLocator::PublicSlot, 4)); - result.append(operation(InsertionPointLocator::Protected, 3)); - result.append(operation(InsertionPointLocator::ProtectedSlot, 2)); - result.append(operation(InsertionPointLocator::Private, 1)); - result.append(operation(InsertionPointLocator::PrivateSlot, 0)); + result << operation(InsertionPointLocator::Public, 5) + << operation(InsertionPointLocator::PublicSlot, 4) + << operation(InsertionPointLocator::Protected, 3) + << operation(InsertionPointLocator::ProtectedSlot, 2) + << operation(InsertionPointLocator::Private, 1) + << operation(InsertionPointLocator::PrivateSlot, 0); } } @@ -2708,7 +2708,7 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe } if (op) - result.append(op); + result << op; break; } } @@ -2718,10 +2718,10 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe // Insert Position: Outside Class if (!isFreeFunction) { - result.append(new InsertDefOperation(interface, decl, declAST, - InsertionLocation(), - DefPosOutsideClass, - interface.fileName())); + result << new InsertDefOperation(interface, decl, declAST, + InsertionLocation(), + DefPosOutsideClass, + interface.fileName()); } // Insert Position: Inside Class @@ -2732,9 +2732,9 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe const InsertionLocation loc = InsertionLocation(interface.fileName(), QString(), QString(), line, column); - result.append(new InsertDefOperation(interface, decl, declAST, loc, - DefPosInsideClass, QString(), - isFreeFunction)); + result << new InsertDefOperation(interface, decl, declAST, loc, + DefPosInsideClass, QString(), + isFreeFunction); return; } @@ -3137,12 +3137,12 @@ void GenerateGetterSetter::match(const CppQuickFixInterface &interface, { GenerateGetterSetterOperation *op = new GenerateGetterSetterOperation(interface); if (op->m_type != GenerateGetterSetterOperation::InvalidType) { - result.append(op); + result << op; if (op->m_type == GenerateGetterSetterOperation::GetterSetterType) { - result.append(new GenerateGetterSetterOperation( - interface, op, GenerateGetterSetterOperation::GetterType)); - result.append(new GenerateGetterSetterOperation( - interface, op, GenerateGetterSetterOperation::SetterType)); + result << new GenerateGetterSetterOperation( + interface, op, GenerateGetterSetterOperation::GetterType); + result << new GenerateGetterSetterOperation( + interface, op, GenerateGetterSetterOperation::SetterType); } } else { delete op; @@ -3730,13 +3730,11 @@ void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOpera // The current implementation doesn't try to be too smart since it preserves the original form // of the declarations. This might be or not the desired effect. An improvement would be to // let the user somehow customize the function interface. - result.append(new ExtractFunctionOperation(interface, - analyser.m_extractionStart, - analyser.m_extractionEnd, - refFuncDef, - funcReturn, - relevantDecls, - m_functionNameGetter)); + result << new ExtractFunctionOperation(interface, + analyser.m_extractionStart, + analyser.m_extractionEnd, + refFuncDef, funcReturn, relevantDecls, + m_functionNameGetter); } namespace { @@ -4055,7 +4053,7 @@ void ExtractLiteralAsParameter::match(const CppQuickFixInterface &interface, } const int priority = path.size() - 1; - result.append(new ExtractLiteralAsParameterOp(interface, priority, literal, function)); + result << new ExtractLiteralAsParameterOp(interface, priority, literal, function); } namespace { @@ -4402,8 +4400,8 @@ void ConvertFromAndToPointer::match(const CppQuickFixInterface &interface, } const int priority = path.size() - 1; - result.append(new ConvertFromAndToPointerOp(interface, priority, mode, isAutoDeclaration, - simpleDeclaration, declarator, identifier, symbol)); + result << new ConvertFromAndToPointerOp(interface, priority, mode, isAutoDeclaration, + simpleDeclaration, declarator, identifier, symbol); } namespace { @@ -4587,9 +4585,9 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface, if (getterName.isEmpty() && setterName.isEmpty() && signalName.isEmpty()) return; - result.append(new InsertQtPropertyMembersOp(interface, path.size() - 1, qtPropertyDeclaration, c, - generateFlags, getterName, setterName, - signalName, storageName)); + result << new InsertQtPropertyMembersOp(interface, path.size() - 1, qtPropertyDeclaration, c, + generateFlags, getterName, setterName, + signalName, storageName); } namespace { @@ -4628,7 +4626,7 @@ void ApplyDeclDefLinkChanges::match(const CppQuickFixInterface &interface, auto op = new ApplyDeclDefLinkOperation(interface, link); op->setDescription(FunctionDeclDefLink::tr("Apply Function Signature Changes")); - result.append(op); + result << op; } namespace { @@ -4827,12 +4825,12 @@ void MoveFuncDefOutside::match(const CppQuickFixInterface &interface, QuickFixOp const MoveFuncDefRefactoringHelper::MoveType type = moveOutsideMemberDefinition ? MoveFuncDefRefactoringHelper::MoveOutsideMemberToCppFile : MoveFuncDefRefactoringHelper::MoveToCppFile; - result.append(new MoveFuncDefOutsideOp(interface, type, funcAST, cppFileName)); + result << new MoveFuncDefOutsideOp(interface, type, funcAST, cppFileName); } if (classAST) - result.append(new MoveFuncDefOutsideOp(interface, MoveFuncDefRefactoringHelper::MoveOutside, - funcAST, QLatin1String(""))); + result << new MoveFuncDefOutsideOp(interface, MoveFuncDefRefactoringHelper::MoveOutside, + funcAST, QLatin1String("")); return; } @@ -4917,12 +4915,12 @@ void MoveAllFuncDefOutside::match(const CppQuickFixInterface &interface, QuickFi bool isHeaderFile = false; const QString cppFileName = correspondingHeaderOrSource(interface.fileName(), &isHeaderFile); if (isHeaderFile && !cppFileName.isEmpty()) { - result.append(new MoveAllFuncDefOutsideOp(interface, - MoveFuncDefRefactoringHelper::MoveToCppFile, - classAST, cppFileName)); + result << new MoveAllFuncDefOutsideOp(interface, + MoveFuncDefRefactoringHelper::MoveToCppFile, + classAST, cppFileName); } - result.append(new MoveAllFuncDefOutsideOp(interface, MoveFuncDefRefactoringHelper::MoveOutside, - classAST, QLatin1String(""))); + result << new MoveAllFuncDefOutsideOp(interface, MoveFuncDefRefactoringHelper::MoveOutside, + classAST, QLatin1String("")); } namespace { @@ -5105,11 +5103,11 @@ void MoveFuncDefToDecl::match(const CppQuickFixInterface &interface, QuickFixOpe } if (!declFileName.isEmpty() && !declText.isEmpty()) - result.append(new MoveFuncDefToDeclOp(interface, - interface.fileName(), - declFileName, - funcAST, declText, - defRange, declRange)); + result << new MoveFuncDefToDeclOp(interface, + interface.fileName(), + declFileName, + funcAST, declText, + defRange, declRange); } namespace { @@ -5312,7 +5310,7 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi const Name *name = nameAST->name; const int insertPos = interface.currentFile()->startOf(outerAST); - result.append(new AssignToLocalVariableOperation(interface, insertPos, outerAST, name)); + result << new AssignToLocalVariableOperation(interface, insertPos, outerAST, name); return; } } @@ -5493,9 +5491,9 @@ void OptimizeForLoop::match(const CppQuickFixInterface &interface, QuickFixOpera } if (optimizePostcrement || optimizeCondition) { - result.append(new OptimizeForLoopOperation(interface, forAst, optimizePostcrement, - (optimizeCondition) ? conditionExpression : 0, - conditionType)); + result << new OptimizeForLoopOperation(interface, forAst, optimizePostcrement, + (optimizeCondition) ? conditionExpression : 0, + conditionType); } } @@ -5660,10 +5658,10 @@ void EscapeStringLiteral::match(const CppQuickFixInterface &interface, QuickFixO } if (canEscape) - result.append(new EscapeStringLiteralOperation(interface, literal, true)); + result << new EscapeStringLiteralOperation(interface, literal, true); if (canUnescape) - result.append(new EscapeStringLiteralOperation(interface, literal, false)); + result << new EscapeStringLiteralOperation(interface, literal, false); } @@ -5977,7 +5975,7 @@ void ConvertQt4Connect::match(const CppQuickFixInterface &interface, QuickFixOpe changes.replace(file->endOf(arg3), file->endOf(arg3), receiverAccessFunc); changes.replace(file->startOf(arg4), file->endOf(arg4), newMethod); - result.append(new ConvertQt4ConnectOperation(interface, changes)); + result << new ConvertQt4ConnectOperation(interface, changes); return; } } diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index 3ac8a3524d9..f40c09ae761 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -30,6 +30,7 @@ #include "cpptools_global.h" #include +#include #include #include @@ -41,7 +42,6 @@ namespace TextEditor { class TextDocument; -class QuickFixOperations; } namespace CppTools { diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp index daf05a6abd9..ff58c4cb1f5 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp @@ -246,13 +246,13 @@ void ComponentFromObjectDef::match(const QmlJSQuickFixInterface &interface, Quic return; // check that the node is not the root node if (i > 0 && !cast(path.at(i - 1))) { - result.append(new Operation(interface, objDef)); + result << new Operation(interface, objDef); return; } } else if (UiObjectBinding *objBinding = cast(node)) { if (!interface->currentFile()->isCursorOn(objBinding->qualifiedTypeNameId)) return; - result.append(new Operation(interface, objBinding)); + result << new Operation(interface, objBinding); return; } } diff --git a/src/plugins/qmljseditor/qmljsquickfixes.cpp b/src/plugins/qmljseditor/qmljsquickfixes.cpp index e5e1fef8295..83ed0e3b538 100644 --- a/src/plugins/qmljseditor/qmljsquickfixes.cpp +++ b/src/plugins/qmljseditor/qmljsquickfixes.cpp @@ -77,7 +77,7 @@ class SplitInitializerOp: public QmlJSQuickFixFactory } if (objectInitializer) - result.append(new Operation(interface, objectInitializer)); + result << new Operation(interface, objectInitializer); } class Operation: public QmlJSQuickFixOperation @@ -135,7 +135,7 @@ public: foreach (const StaticAnalysis::Message &message, messages) { if (interface->currentFile()->isCursorOn(message.location)) { - result.append(new Operation(interface, message)); + result << new Operation(interface, message); return; } } diff --git a/src/plugins/qmljseditor/qmljswrapinloader.cpp b/src/plugins/qmljseditor/qmljswrapinloader.cpp index b95a4a8fe7b..a99ca687bc1 100644 --- a/src/plugins/qmljseditor/qmljswrapinloader.cpp +++ b/src/plugins/qmljseditor/qmljswrapinloader.cpp @@ -186,13 +186,13 @@ void WrapInLoader::match(const QmlJSQuickFixInterface &interface, QuickFixOperat return; // check that the node is not the root node if (i > 0 && !cast(path.at(i - 1))) { - result.append(new Operation(interface, objDef)); + result << new Operation(interface, objDef); return; } } else if (UiObjectBinding *objBinding = cast(node)) { if (!interface->currentFile()->isCursorOn(objBinding->qualifiedTypeNameId)) return; - result.append(new Operation(interface, objBinding)); + result << new Operation(interface, objBinding); return; } } diff --git a/src/plugins/texteditor/quickfix.h b/src/plugins/texteditor/quickfix.h index efb9f10619f..715d9e09b79 100644 --- a/src/plugins/texteditor/quickfix.h +++ b/src/plugins/texteditor/quickfix.h @@ -85,12 +85,13 @@ private: QString _description; }; -class TEXTEDITOR_EXPORT QuickFixOperations : public QList +typedef QList QuickFixOperations; + +inline QuickFixOperations &operator<<(QuickFixOperations &list, QuickFixOperation *op) { -public: - using QList::append; - void append(QuickFixOperation *op) { append(QuickFixOperation::Ptr(op)); } -}; + list.append(QuickFixOperation::Ptr(op)); + return list; +} typedef QSharedPointer QuickFixInterface; From 3c3bccf0fbfbc2df00b508f780c923450e3e7560 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 18 Nov 2016 12:07:55 +0100 Subject: [PATCH 19/27] Debugger: Also support boost 1.55 unordered_maps Change-Id: Id9ac4ecc8c61d4224f5840df2ec0a75c3c305825 Reviewed-by: hjk --- share/qtcreator/debugger/boosttypes.py | 38 +++++++++++++++----------- share/qtcreator/debugger/dumper.py | 13 +++++++++ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/share/qtcreator/debugger/boosttypes.py b/share/qtcreator/debugger/boosttypes.py index bccb6f39f70..552b0594120 100644 --- a/share/qtcreator/debugger/boosttypes.py +++ b/share/qtcreator/debugger/boosttypes.py @@ -109,29 +109,35 @@ def qdump__boost__posix_time__time_duration(d, value): def qdump__boost__unordered__unordered_set(d, value): innerType = value.type[0] - newer = value.type.size() == 6 * d.ptrSize() # 48 for boost 1.58, 40 for boost 1.48 - if newer: - # boost 1.58 + if value.type.size() == 6 * d.ptrSize(): # 48 for boost 1.55+, 40 for 1.48 + # boost 1.58 or 1.55 # bases are 3? bytes, and mlf is actually a float, but since # its followed by size_t maxload, it's # effectively padded to a size_t bases, bucketCount, size, mlf, maxload, buckets = value.split('tttttp') - code = 'pp{%s}' % innerType.name + # Distinguish 1.58 and 1.55. 1.58 used one template argument, 1.55 two. + ittype = d.lookupType(value.type.name + '::iterator').target() + forward = len(ittype.templateArguments()) == 1 else: # boost 1.48 # Values are stored before the next pointers. Determine the offset. buckets, bucketCount, size, mlf, maxload = value.split('ptttt') + forward = False + + if forward: + # boost 1.58 + code = 'pp{%s}' % innerType.name + def children(p): + while True: + p, dummy, val = d.split(code, p) + yield val + else: + # boost 1.48 or 1.55 code = '{%s}@p' % innerType.name (pp, ssize, fields) = d.describeStruct(code) offset = fields[2].offset() - - d.putItemCount(size) - - if d.isExpanded(): - p = d.extractPointer(buckets + bucketCount * d.ptrSize()) - with Children(d, size, maxNumChild=10000): - for j in d.childRange(): - if newer: - p, dummy, val = d.split(code, p) - else: - val, pad, p = d.split(code, p - offset) - d.putSubItem(j, val) + def children(p): + while True: + val, pad, p = d.split(code, p - offset) + yield val + p = d.extractPointer(buckets + bucketCount * d.ptrSize()) + d.putItems(size, children(p), maxNumChild = 10000) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index a710243f2a2..e0051bc22dd 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -2586,6 +2586,13 @@ class DumperBase: return True return False + def putItems(self, count, generator, maxNumChild=10000): + self.putItemCount(count) + if self.isExpanded(): + with Children(self, count, maxNumChild=maxNumChild): + for i, val in zip(self.childRange(), generator): + self.putSubItem(i, val) + def putItem(self, value): self.preping('putItem') self.putItemX(value) @@ -3317,6 +3324,12 @@ class DumperBase: def unqualified(self): return self + def templateArguments(self): + tdata = self.typeData() + if tdata is None: + return self.dumper.listTemplateParameters(self.typeId) + return tdata.templateArguments + def templateArgument(self, position): tdata = self.typeData() #warn('TDATA: %s' % tdata) From 5b43ff7ad9dc25ba1c633671b04968477856706a Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 18 Nov 2016 13:00:32 +0100 Subject: [PATCH 20/27] Debugger: Make QV4 dumper test pass with Qt 5.8.0 The layout of a QV4Value has changed in Qt Declarative change 2afb54fb. Change-Id: Iab618cc128be242c786b9a7460e80e8e49ee6544 Reviewed-by: hjk --- share/qtcreator/debugger/dumper.py | 13 ++++ share/qtcreator/debugger/qttypes.py | 94 +++++++++++++++++------------ 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index e0051bc22dd..2d75b2eca58 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -2746,6 +2746,19 @@ class DumperBase: return tiVersion return None + def qtDeclarativeHookDataSymbolName(self): + return 'qtDeclarativeHookData' + + def qtDeclarativeTypeInfoVersion(self): + addr = self.symbolAddress(self.qtDeclarativeHookDataSymbolName()) + if addr: + # Only available with Qt 5.6+ + (hookVersion, x, tiVersion) = self.split('ppp', addr) + if hookVersion >= 1: + self.qtTypeInfoVersion = lambda: tiVersion + return tiVersion + return None + def addToCache(self, typeobj): typename = typeobj.name if typename in self.typesReported: diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 6e306d3e2d4..c59f77c9f0d 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -1961,40 +1961,6 @@ if False: QV4_ValueTypeInternal_Boolean_Type_Internal = QV4_ValueType_Boolean_Type | QV4_ConvertibleToInt QV4_ValueTypeInternal_Integer_Type_Internal = QV4_ValueType_Integer_Type | QV4_ConvertibleToInt -else: - # 64 bit. - QV4_NaNEncodeMask = 0xffff800000000000 - QV4_IsInt32Mask = 0x0002000000000000 - QV4_IsDoubleMask = 0xfffc000000000000 - QV4_IsNumberMask = QV4_IsInt32Mask | QV4_IsDoubleMask - QV4_IsNullOrUndefinedMask = 0x0000800000000000 - QV4_IsNullOrBooleanMask = 0x0001000000000000 - QV4_PointerMask = 0xfffffffffffffffd - - QV4_Masks_NaN_Mask = 0x7ff80000 - QV4_Masks_Type_Mask = 0xffff8000 - QV4_Masks_IsDouble_Mask = 0xfffc0000 - QV4_Masks_Immediate_Mask = 0x00018000 - QV4_Masks_IsNullOrUndefined_Mask = 0x00008000 - QV4_Masks_IsNullOrBoolean_Mask = 0x00010000 - QV4_Masks_Tag_Shift = 32 - - QV4_ValueType_Undefined_Type = QV4_Masks_IsNullOrUndefined_Mask - QV4_ValueType_Null_Type = QV4_Masks_IsNullOrUndefined_Mask | QV4_Masks_IsNullOrBoolean_Mask - QV4_ValueType_Boolean_Type = QV4_Masks_IsNullOrBoolean_Mask - QV4_ValueType_Integer_Type = 0x20000 | QV4_Masks_IsNullOrBoolean_Mask - QV4_ValueType_Managed_Type = 0 - QV4_ValueType_Empty_Type = QV4_ValueType_Undefined_Type | 0x4000 - - QV4_ValueTypeInternal_Null_Type_Internal = QV4_ValueType_Null_Type - QV4_ValueTypeInternal_Boolean_Type_Internal = QV4_ValueType_Boolean_Type - QV4_ValueTypeInternal_Integer_Type_Internal = QV4_ValueType_Integer_Type - - QV4_IsDouble_Shift = 64-14 - QV4_IsNumber_Shift = 64-15 - QV4_IsConvertibleToInt_Shift = 64-16 - QV4_IsManaged_Shift = 64-17 - def QV4_getValue(d, jsval): # (Dumper, QJSValue *jsval) -> QV4::Value * dd = d.split('Q', jsval)[0] @@ -2104,6 +2070,56 @@ def qdump_32__QV4__Value(d, value): d.putFields(value) def qdump_64__QV4__Value(d, value): + dti = d.qtDeclarativeTypeInfoVersion() + new = dti is not None and dti >= 2 + if new: + QV4_NaNEncodeMask = 0xfffc000000000000 + QV4_Masks_Immediate_Mask = 0x00020000 # bit 49 + + QV4_ValueTypeInternal_Empty_Type_Internal = QV4_Masks_Immediate_Mask | 0 + QV4_ConvertibleToInt = QV4_Masks_Immediate_Mask | 0x10000 # bit 48 + QV4_ValueTypeInternal_Null_Type_Internal = QV4_ConvertibleToInt | 0x08000 + QV4_ValueTypeInternal_Boolean_Type_Internal = QV4_ConvertibleToInt | 0x04000 + QV4_ValueTypeInternal_Integer_Type_Internal = QV4_ConvertibleToInt | 0x02000 + + QV4_ValueType_Undefined_Type = 0 # Dummy to make generic code below pass. + + else: + QV4_NaNEncodeMask = 0xffff800000000000 + QV4_Masks_Immediate_Mask = 0x00018000 + + QV4_IsInt32Mask = 0x0002000000000000 + QV4_IsDoubleMask = 0xfffc000000000000 + QV4_IsNumberMask = QV4_IsInt32Mask | QV4_IsDoubleMask + QV4_IsNullOrUndefinedMask = 0x0000800000000000 + QV4_IsNullOrBooleanMask = 0x0001000000000000 + + QV4_Masks_NaN_Mask = 0x7ff80000 + QV4_Masks_Type_Mask = 0xffff8000 + QV4_Masks_IsDouble_Mask = 0xfffc0000 + QV4_Masks_IsNullOrUndefined_Mask = 0x00008000 + QV4_Masks_IsNullOrBoolean_Mask = 0x00010000 + + QV4_ValueType_Undefined_Type = QV4_Masks_IsNullOrUndefined_Mask + QV4_ValueType_Null_Type = QV4_Masks_IsNullOrUndefined_Mask \ + | QV4_Masks_IsNullOrBoolean_Mask + QV4_ValueType_Boolean_Type = QV4_Masks_IsNullOrBoolean_Mask + QV4_ValueType_Integer_Type = 0x20000 | QV4_Masks_IsNullOrBoolean_Mask + QV4_ValueType_Managed_Type = 0 + QV4_ValueType_Empty_Type = QV4_ValueType_Undefined_Type | 0x4000 + + QV4_ValueTypeInternal_Null_Type_Internal = QV4_ValueType_Null_Type + QV4_ValueTypeInternal_Boolean_Type_Internal = QV4_ValueType_Boolean_Type + QV4_ValueTypeInternal_Integer_Type_Internal = QV4_ValueType_Integer_Type + + QV4_PointerMask = 0xfffffffffffffffd + + QV4_Masks_Tag_Shift = 32 + QV4_IsDouble_Shift = 64-14 + QV4_IsNumber_Shift = 64-15 + QV4_IsConvertibleToInt_Shift = 64-16 + QV4_IsManaged_Shift = 64-17 + v = value.split('Q')[0] tag = v >> QV4_Masks_Tag_Shift vtable = v & QV4_PointerMask @@ -2117,15 +2133,19 @@ def qdump_64__QV4__Value(d, value): elif (v >> QV4_IsDouble_Shift): d.putBetterType('%sQV4::Value (double)' % ns) d.putValue('%x' % (v ^ QV4_NaNEncodeMask), 'float:8') - elif tag == QV4_ValueType_Undefined_Type: + elif tag == QV4_ValueType_Undefined_Type and not new: d.putBetterType('%sQV4::Value (undefined)' % ns) d.putValue('(undefined)') elif tag == QV4_ValueTypeInternal_Null_Type_Internal: d.putBetterType('%sQV4::Value (null?)' % ns) d.putValue('(null?)') elif v == 0: - d.putBetterType('%sQV4::Value (null)' % ns) - d.putValue('(null)') + if new: + d.putBetterType('%sQV4::Value (undefined)' % ns) + d.putValue('(undefined)') + else: + d.putBetterType('%sQV4::Value (null)' % ns) + d.putValue('(null)') #elif ((v >> QV4_IsManaged_Shift) & ~1) == 1: # d.putBetterType('%sQV4::Value (null/undef)' % ns) # d.putValue('(null/undef)') From 96b907a1e833032839ac2afb4051ddf371c0d495 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 18 Nov 2016 13:47:38 +0100 Subject: [PATCH 21/27] Debugger: Fix QFiniteStack dumper and add missing auto test Change-Id: If5f242f8d5184a0f2c62f6211f2ba89cda0cac07 Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 5 +-- tests/auto/debugger/tst_dumpers.cpp | 62 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index c59f77c9f0d..25faf326a31 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -578,11 +578,10 @@ def qform__QFiniteStack(): return arrayForms() def qdump__QFiniteStack(d, value): - alloc = int(value['_alloc']) - size = int(value['_size']) + array, alloc, size = value.split('pii') d.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000) d.putItemCount(size) - d.putPlotData(value['_array'], size, value.type[0]) + d.putPlotData(array, size, value.type[0]) def qdump__QFlags(d, value): diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 0c78e88ff63..f77c7480989 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -3041,6 +3041,68 @@ void tst_Dumpers::dumper_data() + Check("ptr53", "", "@QWeakPointer"); + QTest::newRow("QFiniteStack") + << Data("#include \n" + fooData, + + "QFiniteStack s1;\n" + "s1.allocate(2);\n" + "s1.push(1);\n" + "s1.push(2);\n\n" + + "QFiniteStack s2;\n" + "s2.allocate(100000);\n" + "for (int i = 0; i != 10000; ++i)\n" + " s2.push(i);\n\n" + + "QFiniteStack s3;\n" + "s3.allocate(10);\n" + "s3.push(new Foo(1));\n" + "s3.push(0);\n" + "s3.push(new Foo(2));\n" + "unused(&s3);\n\n" + + "QFiniteStack s4;\n" + "s4.allocate(10);\n" + "s4.push(1);\n" + "s4.push(2);\n" + "s4.push(3);\n" + "s4.push(4);\n\n" + + "QFiniteStack s5;\n" + "s5.allocate(10);\n" + "s5.push(true);\n" + "s5.push(false);\n\n") + + + QmlPrivateProfile() + + + BigArrayProfile() + + + Check("s1", "<2 items>", "@QFiniteStack") + + Check("s1.0", "[0]", "1", "int") + + Check("s1.1", "[1]", "2", "int") + + + Check("s2", "<10000 items>", "@QFiniteStack") + + Check("s2.0", "[0]", "0", "int") + + Check("s2.8999", "[8999]", "8999", "int") + + + Check("s3", "<3 items>", "@QFiniteStack") + + Check("s3.0", "[0]", "", "Foo") + + Check("s3.0.a", "1", "int") + + Check("s3.1", "[1]", "0x0", "Foo *") + + Check("s3.2", "[2]", "", "Foo") + + Check("s3.2.a", "2", "int") + + + Check("s4", "<4 items>", "@QFiniteStack") + + Check("s4.0", "[0]", "", "Foo") + + Check("s4.0.a", "1", "int") + + Check("s4.3", "[3]", "", "Foo") + + Check("s4.3.a", "4", "int") + + + Check("s5", "<2 items>", "@QFiniteStack") + + Check("s5.0", "[0]", "1", "bool") // 1 -> true is done on display + + Check("s5.1", "[1]", "0", "bool"); + + /* QTest::newRow("QStandardItemModel") << Data("#include \n", From 8f12ade7bd1afc7f249e507f216dd3601d0ad38f Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 18 Nov 2016 14:39:28 +0100 Subject: [PATCH 22/27] CppEditor: Compile fix after 3b1308bb Change-Id: I55f8f175e8cd49b455b94872770a7bd02baa7492 Reviewed-by: Friedemann Kleint --- src/plugins/cppeditor/cppquickfix_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 3434f87b72d..3364b89b56d 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -301,7 +301,7 @@ public: void match(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) { - result.append(new AddIncludeForUndefinedIdentifierOp(cppQuickFixInterface, 0, m_include)); + result << new AddIncludeForUndefinedIdentifierOp(cppQuickFixInterface, 0, m_include); } private: From fa5cd03c1179540cae745b8fb26a8b2451f87263 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 18 Nov 2016 16:15:55 +0100 Subject: [PATCH 23/27] Debugger: Add libc++ std::{deque,stack} dumpers Change-Id: Ibf95c76b89fb7673241e680c233c7514c667f261 Reviewed-by: hjk --- share/qtcreator/debugger/stdtypes.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 2a34f27f2a1..a6de8e187a1 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -90,6 +90,21 @@ def qdump__std__deque(d, value): pcur = pfirst pnode = newnode +def qdump__std____1__deque(d, value): + mptr, mfirst, mbegin, mend, start, size = value.split("pppptt") + d.check(0 <= size and size <= 1000 * 1000 * 1000) + d.putItemCount(size) + if d.isExpanded(): + innerType = value.type[0] + innerSize = innerType.size() + ptrSize = d.ptrSize() + bufsize = (4096 // innerSize) if innerSize < 256 else 16 + with Children(d, size, maxNumChild=2000, childType=innerType): + for i in d.childRange(): + k, j = divmod(start + i, bufsize) + base = d.extractPointer(mfirst + k * ptrSize) + d.putSubItem(i, d.createValue(base + j * innerSize, innerType)) + def qdump__std__deque__QNX(d, value): innerType = value.type[0] innerSize = innerType.size() @@ -521,6 +536,10 @@ def qdump__std__stack(d, value): def qdump__std____debug__stack(d, value): qdump__std__stack(d, value) +def qdump__std____1__stack(d, value): + d.putItem(value["c"]) + d.putBetterType(value.type) + def qform__std__string(): return [Latin1StringFormat, SeparateLatin1StringFormat, Utf8StringFormat, SeparateUtf8StringFormat ] From ba87a5dace1a30e4582ecbdfa154e3d0ae160ecb Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 18 Nov 2016 17:24:55 +0100 Subject: [PATCH 24/27] Debugger: Make QFiniteStack dumper work on macOS qfinitestack_p.h is not self-contained, #include manually to get access to malloc(). Change-Id: I628e5e2a872d361bb7b246ec7333efb3c94dae98 Reviewed-by: hjk --- tests/auto/debugger/tst_dumpers.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index f77c7480989..be41a3fc8c1 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -3042,7 +3042,8 @@ void tst_Dumpers::dumper_data() QTest::newRow("QFiniteStack") - << Data("#include \n" + fooData, + << Data("#include \n" // Needed on macOS. + "#include \n" + fooData, "QFiniteStack s1;\n" "s1.allocate(2);\n" From 3ab464dffd2b8bd7beefee8fdf2997d289e1437e Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 18 Nov 2016 16:06:44 +0100 Subject: [PATCH 25/27] QmlDesigner: Improve the "export unchecked" icon Change-Id: I1031d21c535d4a710f1f917e13bec30fb310a8c4 Reviewed-by: Thomas Hartmann --- .../components/navigator/export_unchecked.png | Bin 116 -> 113 bytes .../navigator/export_unchecked@2x.png | Bin 120 -> 117 bytes src/tools/icons/qtcreatoricons.svg | 12 +++++++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmldesigner/components/navigator/export_unchecked.png b/src/plugins/qmldesigner/components/navigator/export_unchecked.png index 8f981200da00922bef1139c947b59cd2ba90e383..377c97fa8a326ab23948a95e84b633417a9d01ca 100644 GIT binary patch delta 77 zcmXRZoS^B!z`#&nU;qFAf5YmdKI;Vst04{(S$N&HU diff --git a/src/plugins/qmldesigner/components/navigator/export_unchecked@2x.png b/src/plugins/qmldesigner/components/navigator/export_unchecked@2x.png index cbfb9d512a56f07bbb88e3cd3c3f513d1c11023f..6a309be703ef1f624d7d6d9d9c2e9537236b3d43 100644 GIT binary patch delta 81 zcmb;@ouKK%z`#&nU;qFAf5YYgr+Are!QBUo8^en@ajI5cq2WSpirQ&38( m_1J>BQb`gL|D3*CGpt$FI7@0uFEcPOFnGH9xvX + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccccc" /> + d="m 354,310 0,1 5,0 0,-1 z m 0,-2 0,1 5,0 0,-1 z m 0,-2 0,1 5,0 0,-1 z" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccccccccccccc" /> Date: Fri, 18 Nov 2016 14:01:01 +0100 Subject: [PATCH 26/27] Don't crash when Help mode uses WebEngine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTCREATORBUG-17296 Change-Id: I8527c340e2b5af1e7f0b0d1f62ff03cd30c06ff2 Reviewed-by: Michael BrĂ¼ning Reviewed-by: Eike Ziller --- src/app/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/main.cpp b/src/app/main.cpp index 85fe4e5e896..de23bea974d 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -311,6 +311,7 @@ int main(int argc, char **argv) setrlimit(RLIMIT_NOFILE, &rl); #endif + SharedTools::QtSingleApplication::setAttribute(Qt::AA_ShareOpenGLContexts); SharedTools::QtSingleApplication app((QLatin1String(appNameC)), argc, argv); loadFonts(); From 97c9213358181547e02795740369bc451e26648f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 18 Nov 2016 10:05:10 +0100 Subject: [PATCH 27/27] qtcreatorcdbext.pro: Fix architecture detection Previously, the detection relied on the variable CPU which is no longer set current versions of MSVC. Use newly introduced variable VSCMD_ARG_TGT_ARCH (MSVC 2017) or Platform (MSVC 2015) to detect 64bit. Task-number: QTBUG-57086 Change-Id: Ie71b73a04af597d5b638fd08171ee9bfb3b4ccb8 Reviewed-by: Oliver Wolff Reviewed-by: David Schulz --- src/libs/qtcreatorcdbext/qtcreatorcdbext.pro | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libs/qtcreatorcdbext/qtcreatorcdbext.pro b/src/libs/qtcreatorcdbext/qtcreatorcdbext.pro index 0e8d7908322..78812f57182 100644 --- a/src/libs/qtcreatorcdbext/qtcreatorcdbext.pro +++ b/src/libs/qtcreatorcdbext/qtcreatorcdbext.pro @@ -24,12 +24,14 @@ DEF_FILE=$$PWD/qtcreatorcdbext.def # Find out whether we are _building_ 64/32bit and determine target # directories accordingly. # -# Newer MSVC versions set CPU, olders do not, so use hacky check on -# LIBPATH if CPU is not available -ENV_CPU=$$(CPU) +# Check for VSCMD_ARG_TGT_ARCH (VS 17) or Platform=X64 (VS 13, 15) +# For older versions, fall back to hacky check on LIBPATH + +ENV_TARGET_ARCH=$$(VSCMD_ARG_TGT_ARCH) +isEmpty(ENV_TARGET_ARCH):ENV_TARGET_ARCH = $$(Platform) ENV_LIBPATH=$$(LIBPATH) -contains(ENV_CPU, ^AMD64$) { +contains(ENV_TARGET_ARCH, .*64$) { DIRNAME=$${BASENAME}64 CDB_PLATFORM=amd64 @@ -38,7 +40,7 @@ contains(ENV_CPU, ^AMD64$) { } else { LIBS+= -L$$CDB_PATH/lib/x64 -ldbgeng } -} else:isEmpty(ENV_CPU):contains(ENV_LIBPATH, ^.*amd64.*$) { +} else:isEmpty(ENV_TARGET_ARCH):contains(ENV_LIBPATH, ^.*amd64.*$) { DIRNAME=$${BASENAME}64 CDB_PLATFORM=amd64